/*
 * ════════════════════════════════════════════════════════════════════════
 *  Notarium design system — tokens + components
 * ════════════════════════════════════════════════════════════════════════
 *
 * Identity: the wax seal and the bound protocol — authority, permanence,
 * calm. Bordeaux (#7f1d2b) is *identity*; compliance green (#1e6b4f) is the
 * emotional promise ("i orden") and is therefore semantically load-bearing:
 * cleared frister and signed/registered documents are green, never bordeaux.
 * Amber is "a frist is approaching". Red is "overdue" and nothing else — if
 * red ever becomes decoration it stops meaning danger.
 *
 * ── How the file is layered ─────────────────────────────────────────────
 *   1. Raw palette   (--nt-c-*)  — hue ramps. Theme-independent. Never used
 *                                  directly in a component; only referenced
 *                                  by semantic tokens.
 *   2. Semantic      (--nt-*)    — what a color *means* (surface, border,
 *                                  ok, danger…). Redefined per theme.
 *   3. Domain alias  (--nt-frist-*, --nt-doc-*) — a frist/document status
 *                                  named by the domain, pointing at a
 *                                  semantic family. Declared once: custom
 *                                  properties resolve against the computed
 *                                  value on the same element (:root), so the
 *                                  dark override of the family flows through.
 *   4. Components    (.nt-*)     — the visual system, built only from (2)+(3).
 *
 * ── Theme ───────────────────────────────────────────────────────────────
 * 3-state, stamped on <html> server-side from the user's stored preference
 * (NavigationHelper#nav_theme_attribute — there is no client-side toggle):
 *   data-theme="dark"  → force dark
 *   data-theme="light" → force light
 *   absent             → follow the OS (prefers-color-scheme)
 * The two dark blocks below are byte-identical on purpose — CSS has no way
 * to share one declaration list between a selector and a media query, and we
 * refuse to make no-JS users lose their OS dark preference. KEEP THEM IN SYNC.
 *
 * ── Cascade note (load-bearing) ─────────────────────────────────────────
 * This file is unlayered; Tailwind's output lives in @layer, so unlayered
 * rules here WIN over Tailwind utilities on the same property. Therefore:
 * never style bare h1/h2/p/a globally (a view's `text-3xl` would lose), and
 * give components size *modifiers* (.nt-btn-sm) rather than expecting
 * utilities to override their padding.
 */

/* ══════════════════════════════════════════════════════════════════════
   0. BREAKPOINT REGISTRY
   ══════════════════════════════════════════════════════════════════════

   CSS custom properties cannot be used in a media query — `@media
   (min-width: var(--nt-bp-md))` is invalid and fails silently — so the
   canonical set is written here and typed by hand everywhere else. Read this
   before inventing a number.

   THE CANONICAL SET
     40rem   640px   phone → small tablet. One column becomes two.
     52rem   832px   tablet. The marketing nav swaps to the burger here
                     (marketing_nav.css) and the workspace hides secondary
                     chrome.
     65rem  1040px   desktop. Sidebars, asides and split heroes appear.
     80rem  1280px   wide desktop. Refinements only — nothing may become
                     unreachable below it.
     860px           MARKETING ONLY, and deliberately in px: the forside's
                     frist track and the closing band are laid out against a
                     fixed 1180px shell (--nt-shell), not against text, so
                     they must not move when a reader enlarges their font.

   Use rem everywhere else. A max-width query in px ignores the user's font
   size, which is exactly the reader a responsive layout is for.

   PAIRING RULE
   A `max-width: 40rem` and a `min-width: 40rem` both match AT 640px. Where
   the two halves of one switch are written as a pair, only one of them may
   own the boundary — prefer stating the whole switch as `min-width`.

   KNOWN DEVIATIONS — each has a reason, none is a licence for a new one:
     30rem, 34rem   last-resort reflows (error card, key/value rows) that
                    have to fire well below the phone breakpoint.
     46rem, 48rem   koncern + findability grids, and the navbar's own
                    "hide the secondary chrome" step.
     64rem          navbar.css and koncern_palette.css. NOT rounded to 65rem
                    on purpose: 64rem is exactly 1024px, which is iPad
                    landscape, and moving it 16px up drops that device onto
                    the phone navigation.
     62rem          marketing.css teaser + FAQ grids.
     900px, 940px,  the event landings, the auth split and the forside hero.
     960px, 1000px, Each is tuned to a specific two-column composition
     1500px         rather than to a device class.
   ══════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════
   1. RAW PALETTE — hue ramps, theme-independent
   ══════════════════════════════════════════════════════════════════════ */

:root {
  --nt-c-white: #ffffff;

  /* Warm paper ground */
  --nt-c-paper-50: #faf8f4;
  --nt-c-paper-100: #f5f2ea;
  --nt-c-paper-200: #ece8de;
  --nt-c-paper-300: #e2dccf;
  --nt-c-paper-400: #ddd6c9;
  --nt-c-paper-500: #c6bda9;

  /* Ink (light-theme text + inverse surfaces) */
  --nt-c-ink-900: #16181d;
  --nt-c-ink-800: #23262d;
  --nt-c-ink-700: #34383f;
  --nt-c-ink-600: #4b4f58;
  --nt-c-ink-500: #6b6f78;
  --nt-c-ink-400: #83878f;
  --nt-c-ink-300: #9fa3a9;
  --nt-c-ink-200: #c2c5c9;

  /* Night (dark-theme grounds — warm, never blue-black) */
  --nt-c-night-950: #0d0c0a;
  --nt-c-night-900: #15130f;
  --nt-c-night-850: #1a1713;
  --nt-c-night-800: #1d1a15;
  --nt-c-night-700: #24211b;
  --nt-c-night-600: #2c2822;
  --nt-c-night-500: #37332b;
  --nt-c-night-400: #494336;
  --nt-c-night-300: #6a6355;

  /* Bone (dark-theme text) */
  --nt-c-bone-100: #ece9e2;
  --nt-c-bone-200: #d5d1c8;
  --nt-c-bone-300: #b3afa6;
  --nt-c-bone-400: #8f8b82;

  /* Seal bordeaux — identity */
  --nt-c-seal-50: #f9edee;
  --nt-c-seal-100: #f1dade;
  --nt-c-seal-200: #e0b8be;
  --nt-c-seal-300: #d98d97;
  --nt-c-seal-350: #c05a68;
  --nt-c-seal-400: #b04b59;
  --nt-c-seal-500: #93283a;
  --nt-c-seal-600: #7f1d2b;
  --nt-c-seal-700: #6a1824;
  --nt-c-seal-800: #52121b;

  /* Compliance green — "i orden" */
  --nt-c-green-50: #e6f0eb;
  --nt-c-green-100: #cfe4d8;
  --nt-c-green-200: #a8cdba;
  --nt-c-green-300: #8fc7b0;
  --nt-c-green-400: #4d9d7c;
  --nt-c-green-500: #2a7f5e;
  --nt-c-green-600: #1e6b4f;
  --nt-c-green-700: #17553f;
  --nt-c-green-800: #113f2f;

  /* Amber — a frist is approaching */
  --nt-c-amber-50: #f9efe2;
  --nt-c-amber-100: #f2e0c8;
  --nt-c-amber-200: #ecd0ab;
  --nt-c-amber-300: #e2b184;
  --nt-c-amber-400: #cf8a4a;
  --nt-c-amber-500: #b0611b;
  --nt-c-amber-600: #9c5517;
  --nt-c-amber-700: #8d4d14;

  /* Red — overdue, and nothing else */
  --nt-c-red-50: #f8e8e6;
  --nt-c-red-100: #f2d3cf;
  --nt-c-red-200: #e8b3ac;
  --nt-c-red-300: #d97a70;
  --nt-c-red-400: #c65a4f;
  --nt-c-red-500: #a12a1f;
  --nt-c-red-600: #8d241a;
  --nt-c-red-700: #7a1f16;

  /* Petrol — informational / "upcoming", calm and unalarming */
  --nt-c-petrol-50: #e7eef3;
  --nt-c-petrol-100: #d3e0e9;
  --nt-c-petrol-200: #aec8d8;
  --nt-c-petrol-300: #79a9c7;
  --nt-c-petrol-400: #4f83a4;
  --nt-c-petrol-500: #35678a;
  --nt-c-petrol-600: #2f5d7c;
  --nt-c-petrol-700: #244a64;

  /* Dark-mode tint grounds: each status hue mixed down into the night
     ground. These are NOT on the ramps above — a saturated dark green is a
     different color from "green mixed into near-black". */
  --nt-c-green-ink: #17251f;
  --nt-c-green-ink-2: #22392e;
  --nt-c-amber-ink: #2a2016;
  --nt-c-amber-ink-2: #3d3020;
  --nt-c-red-ink: #2b1a17;
  --nt-c-red-ink-2: #402521;
  --nt-c-petrol-ink: #16222b;
  --nt-c-petrol-ink-2: #21353f;
  --nt-c-seal-ink: #2c1a1d;
  --nt-c-seal-ink-2: #452429;
}

/* ══════════════════════════════════════════════════════════════════════
   2a. NON-COLOR TOKENS — identical in both themes
   ══════════════════════════════════════════════════════════════════════ */

:root {
  /* Type */
  --nt-font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --nt-font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --nt-font-serif: "Source Serif 4", "Iowan Old Style", Georgia, serif;
  --nt-font-mono: "JetBrains Mono", "SFMono-Regular", ui-monospace, monospace;

  --nt-text-xs: 0.72rem;
  --nt-text-sm: 0.82rem;
  --nt-text-base: 0.94rem;
  --nt-text-md: 1.02rem;
  --nt-text-lg: 1.18rem;
  --nt-text-xl: 1.45rem;
  --nt-text-2xl: 1.85rem;
  --nt-text-3xl: 2.35rem;

  /* Spacing — 4px base */
  --nt-space-1: 0.25rem;
  --nt-space-2: 0.5rem;
  --nt-space-3: 0.75rem;
  --nt-space-4: 1rem;
  --nt-space-5: 1.25rem;
  --nt-space-6: 1.5rem;
  --nt-space-8: 2rem;
  --nt-space-10: 2.5rem;
  --nt-space-12: 3rem;
  --nt-space-16: 4rem;
  --nt-space-20: 5rem;
  --nt-space-24: 6rem;

  /* Radius */
  --nt-radius-xs: 4px;
  --nt-radius-sm: 4px;
  --nt-radius: 10px;
  --nt-radius-lg: 16px;
  --nt-radius-xl: 22px;
  --nt-radius-full: 999px;

  /* Motion. Every transition in this file uses these, so the
     prefers-reduced-motion block at the bottom only has to zero them. */
  --nt-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --nt-ease-in: cubic-bezier(0.55, 0, 1, 0.45);
  --nt-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --nt-ease-seal: cubic-bezier(0.34, 1.4, 0.5, 1);
  --nt-duration-fast: 120ms;
  --nt-duration: 180ms;
  --nt-duration-slow: 280ms;
  --nt-duration-slower: 420ms;

  /* Stacking */
  --nt-z-sticky: 20;
  --nt-z-dropdown: 40;
  --nt-z-overlay: 60;
  --nt-z-toast: 80;

  /* Measure */
  --nt-page-max: 72rem;
  --nt-prose-max: 44rem;
  --nt-doc-width: 46rem;
}

/* ══════════════════════════════════════════════════════════════════════
   2b. SEMANTIC TOKENS — light (the default)
   ══════════════════════════════════════════════════════════════════════ */

:root {
  color-scheme: light;

  /* Ground & surfaces, sunken → raised */
  --nt-bg: var(--nt-c-paper-50);
  --nt-bg-accent: var(--nt-c-paper-100);
  --nt-surface-sunken: var(--nt-c-paper-200);
  --nt-surface: var(--nt-c-white);
  --nt-surface-raised: var(--nt-c-paper-100);
  --nt-surface-overlay: var(--nt-c-white);
  --nt-surface-inverse: var(--nt-c-ink-900);
  --nt-scrim: rgba(22, 24, 29, 0.44);

  /* The staff bar has its own pair rather than reusing surface-inverse:
     inverting in dark mode would put a near-white slab across the top of a
     dark screen, which is loud rather than distinct. In dark it goes
     bordeaux-tinted black instead — still unmistakably not the customer app. */
  --nt-staff-bar: var(--nt-c-ink-900);
  --nt-staff-bar-text: var(--nt-c-paper-50);

  /* Text */
  --nt-text: var(--nt-c-ink-900);
  --nt-text-secondary: var(--nt-c-ink-600);
  --nt-text-tertiary: var(--nt-c-ink-500);
  --nt-text-disabled: var(--nt-c-ink-300);
  --nt-text-inverse: var(--nt-c-paper-50);

  /* Borders */
  --nt-border-subtle: var(--nt-c-paper-300);
  --nt-border: var(--nt-c-paper-400);
  --nt-border-strong: var(--nt-c-paper-500);
  --nt-border-inverse: var(--nt-c-ink-700);

  /* Identity */
  --nt-seal: var(--nt-c-seal-600);
  --nt-seal-hover: var(--nt-c-seal-700);
  --nt-seal-active: var(--nt-c-seal-800);
  --nt-seal-soft: var(--nt-c-seal-50);
  --nt-seal-tint: var(--nt-c-seal-100);
  --nt-seal-border: var(--nt-c-seal-200);
  --nt-seal-text: var(--nt-c-seal-600);
  --nt-on-seal: #fdf9f5;

  /* Focus */
  --nt-focus: var(--nt-c-seal-600);
  --nt-focus-ring: rgba(127, 29, 43, 0.28);

  /* Status family: ok — "i orden" */
  --nt-ok: var(--nt-c-green-600);
  --nt-ok-soft: var(--nt-c-green-50);
  --nt-ok-tint: var(--nt-c-green-100);
  --nt-ok-border: var(--nt-c-green-200);
  --nt-ok-text: var(--nt-c-green-700);
  --nt-on-ok: #f4faf7;

  /* Status family: warn — approaching */
  --nt-warn: var(--nt-c-amber-500);
  --nt-warn-soft: var(--nt-c-amber-50);
  --nt-warn-tint: var(--nt-c-amber-100);
  --nt-warn-border: var(--nt-c-amber-200);
  --nt-warn-text: var(--nt-c-amber-700);
  --nt-on-warn: #fffaf3;

  /* Status family: danger — overdue / destructive */
  --nt-danger: var(--nt-c-red-500);
  --nt-danger-soft: var(--nt-c-red-50);
  --nt-danger-tint: var(--nt-c-red-100);
  --nt-danger-border: var(--nt-c-red-200);
  --nt-danger-text: var(--nt-c-red-600);
  --nt-on-danger: #fff7f5;

  /* Status family: info — planned, nothing to do yet */
  --nt-info: var(--nt-c-petrol-600);
  --nt-info-soft: var(--nt-c-petrol-50);
  --nt-info-tint: var(--nt-c-petrol-100);
  --nt-info-border: var(--nt-c-petrol-200);
  --nt-info-text: var(--nt-c-petrol-700);
  --nt-on-info: #f5fafd;

  /* Status family: neutral — draft, archived, cancelled */
  --nt-neutral: var(--nt-c-ink-500);
  --nt-neutral-soft: var(--nt-c-paper-100);
  --nt-neutral-tint: var(--nt-c-paper-200);
  --nt-neutral-border: var(--nt-c-paper-400);
  --nt-neutral-text: var(--nt-c-ink-600);
  --nt-on-neutral: var(--nt-c-paper-50);

  /* Document paper. Only the EDGE lives here: the sheet's paper, ink and rule
     are declared once, in the visual workstream's block further down this file
     (search "--nt-doc-shadow"). They used to be declared in both places with
     different values, and because the two dark selectors did not have the same
     specificity, forced dark and OS dark rendered two different sheets. */
  --nt-doc-paper-edge: var(--nt-c-paper-300);

  /* Elevation — three steps, no more. 1 = resting, 2 = card, 3 = floating. */
  --nt-shadow-1: 0 1px 2px rgba(22, 24, 29, 0.05);
  --nt-shadow-2: 0 1px 2px rgba(22, 24, 29, 0.04), 0 3px 10px rgba(22, 24, 29, 0.06);
  --nt-shadow-3: 0 2px 6px rgba(22, 24, 29, 0.06), 0 16px 40px rgba(22, 24, 29, 0.14);
  --nt-shadow-focus: 0 0 0 3px var(--nt-focus-ring);
}

/* ══════════════════════════════════════════════════════════════════════
   2c. SEMANTIC TOKENS — dark, forced
   ⚠ KEEP IDENTICAL TO 2d BELOW.
   ══════════════════════════════════════════════════════════════════════ */

:root[data-theme="dark"] {
  color-scheme: dark;

  --nt-bg: var(--nt-c-night-900);
  --nt-bg-accent: var(--nt-c-night-850);
  --nt-surface-sunken: var(--nt-c-night-950);
  --nt-surface: var(--nt-c-night-800);
  --nt-surface-raised: var(--nt-c-night-700);
  --nt-surface-overlay: var(--nt-c-night-700);
  --nt-surface-inverse: var(--nt-c-bone-100);
  --nt-scrim: rgba(0, 0, 0, 0.64);

  --nt-staff-bar: var(--nt-c-seal-ink);
  --nt-staff-bar-text: var(--nt-c-bone-100);

  --nt-text: var(--nt-c-bone-100);
  --nt-text-secondary: var(--nt-c-bone-300);
  --nt-text-tertiary: var(--nt-c-bone-400);
  --nt-text-disabled: var(--nt-c-night-300);
  --nt-text-inverse: var(--nt-c-night-900);

  --nt-border-subtle: var(--nt-c-night-600);
  --nt-border: var(--nt-c-night-500);
  --nt-border-strong: var(--nt-c-night-400);
  --nt-border-inverse: var(--nt-c-bone-200);

  --nt-seal: var(--nt-c-seal-400);
  --nt-seal-hover: var(--nt-c-seal-350);
  --nt-seal-active: var(--nt-c-seal-300);
  --nt-seal-soft: var(--nt-c-seal-ink);
  --nt-seal-tint: var(--nt-c-seal-ink-2);
  --nt-seal-border: var(--nt-c-seal-ink-2);
  --nt-seal-text: var(--nt-c-seal-300);
  --nt-on-seal: #fdf9f5;

  --nt-focus: var(--nt-c-seal-300);
  --nt-focus-ring: rgba(217, 141, 151, 0.32);

  --nt-ok: var(--nt-c-green-400);
  --nt-ok-soft: var(--nt-c-green-ink);
  --nt-ok-tint: var(--nt-c-green-ink-2);
  --nt-ok-border: var(--nt-c-green-ink-2);
  --nt-ok-text: var(--nt-c-green-300);
  --nt-on-ok: var(--nt-c-night-950);

  --nt-warn: var(--nt-c-amber-400);
  --nt-warn-soft: var(--nt-c-amber-ink);
  --nt-warn-tint: var(--nt-c-amber-ink-2);
  --nt-warn-border: var(--nt-c-amber-ink-2);
  --nt-warn-text: var(--nt-c-amber-300);
  --nt-on-warn: var(--nt-c-night-950);

  --nt-danger: var(--nt-c-red-400);
  --nt-danger-soft: var(--nt-c-red-ink);
  --nt-danger-tint: var(--nt-c-red-ink-2);
  --nt-danger-border: var(--nt-c-red-ink-2);
  --nt-danger-text: var(--nt-c-red-300);
  --nt-on-danger: var(--nt-c-night-950);

  --nt-info: var(--nt-c-petrol-400);
  --nt-info-soft: var(--nt-c-petrol-ink);
  --nt-info-tint: var(--nt-c-petrol-ink-2);
  --nt-info-border: var(--nt-c-petrol-ink-2);
  --nt-info-text: var(--nt-c-petrol-300);
  --nt-on-info: var(--nt-c-night-950);

  --nt-neutral: var(--nt-c-bone-400);
  --nt-neutral-soft: var(--nt-c-night-700);
  --nt-neutral-tint: var(--nt-c-night-600);
  --nt-neutral-border: var(--nt-c-night-500);
  --nt-neutral-text: var(--nt-c-bone-300);
  --nt-on-neutral: var(--nt-c-night-950);

  /* Edge only — see the note in 2b. */
  --nt-doc-paper-edge: #cbc5b6;

  --nt-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.45);
  --nt-shadow-2: 0 1px 2px rgba(0, 0, 0, 0.4), 0 3px 10px rgba(0, 0, 0, 0.45);
  --nt-shadow-3: 0 2px 6px rgba(0, 0, 0, 0.5), 0 16px 40px rgba(0, 0, 0, 0.6);
  --nt-shadow-focus: 0 0 0 3px var(--nt-focus-ring);
}

/* ══════════════════════════════════════════════════════════════════════
   2d. SEMANTIC TOKENS — dark, following the OS
   ⚠ KEEP IDENTICAL TO 2c ABOVE.
   ══════════════════════════════════════════════════════════════════════ */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --nt-bg: var(--nt-c-night-900);
    --nt-bg-accent: var(--nt-c-night-850);
    --nt-surface-sunken: var(--nt-c-night-950);
    --nt-surface: var(--nt-c-night-800);
    --nt-surface-raised: var(--nt-c-night-700);
    --nt-surface-overlay: var(--nt-c-night-700);
    --nt-surface-inverse: var(--nt-c-bone-100);
    --nt-scrim: rgba(0, 0, 0, 0.64);

    --nt-staff-bar: var(--nt-c-seal-ink);
    --nt-staff-bar-text: var(--nt-c-bone-100);

    --nt-text: var(--nt-c-bone-100);
    --nt-text-secondary: var(--nt-c-bone-300);
    --nt-text-tertiary: var(--nt-c-bone-400);
    --nt-text-disabled: var(--nt-c-night-300);
    --nt-text-inverse: var(--nt-c-night-900);

    --nt-border-subtle: var(--nt-c-night-600);
    --nt-border: var(--nt-c-night-500);
    --nt-border-strong: var(--nt-c-night-400);
    --nt-border-inverse: var(--nt-c-bone-200);

    --nt-seal: var(--nt-c-seal-400);
    --nt-seal-hover: var(--nt-c-seal-350);
    --nt-seal-active: var(--nt-c-seal-300);
    --nt-seal-soft: var(--nt-c-seal-ink);
    --nt-seal-tint: var(--nt-c-seal-ink-2);
    --nt-seal-border: var(--nt-c-seal-ink-2);
    --nt-seal-text: var(--nt-c-seal-300);
    --nt-on-seal: #fdf9f5;

    --nt-focus: var(--nt-c-seal-300);
    --nt-focus-ring: rgba(217, 141, 151, 0.32);

    --nt-ok: var(--nt-c-green-400);
    --nt-ok-soft: var(--nt-c-green-ink);
    --nt-ok-tint: var(--nt-c-green-ink-2);
    --nt-ok-border: var(--nt-c-green-ink-2);
    --nt-ok-text: var(--nt-c-green-300);
    --nt-on-ok: var(--nt-c-night-950);

    --nt-warn: var(--nt-c-amber-400);
    --nt-warn-soft: var(--nt-c-amber-ink);
    --nt-warn-tint: var(--nt-c-amber-ink-2);
    --nt-warn-border: var(--nt-c-amber-ink-2);
    --nt-warn-text: var(--nt-c-amber-300);
    --nt-on-warn: var(--nt-c-night-950);

    --nt-danger: var(--nt-c-red-400);
    --nt-danger-soft: var(--nt-c-red-ink);
    --nt-danger-tint: var(--nt-c-red-ink-2);
    --nt-danger-border: var(--nt-c-red-ink-2);
    --nt-danger-text: var(--nt-c-red-300);
    --nt-on-danger: var(--nt-c-night-950);

    --nt-info: var(--nt-c-petrol-400);
    --nt-info-soft: var(--nt-c-petrol-ink);
    --nt-info-tint: var(--nt-c-petrol-ink-2);
    --nt-info-border: var(--nt-c-petrol-ink-2);
    --nt-info-text: var(--nt-c-petrol-300);
    --nt-on-info: var(--nt-c-night-950);

    --nt-neutral: var(--nt-c-bone-400);
    --nt-neutral-soft: var(--nt-c-night-700);
    --nt-neutral-tint: var(--nt-c-night-600);
    --nt-neutral-border: var(--nt-c-night-500);
    --nt-neutral-text: var(--nt-c-bone-300);
    --nt-on-neutral: var(--nt-c-night-950);

    /* Edge only — see the note in 2b. */
    --nt-doc-paper-edge: #cbc5b6;

    --nt-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.45);
    --nt-shadow-2: 0 1px 2px rgba(0, 0, 0, 0.4), 0 3px 10px rgba(0, 0, 0, 0.45);
    --nt-shadow-3: 0 2px 6px rgba(0, 0, 0, 0.5), 0 16px 40px rgba(0, 0, 0, 0.6);
    --nt-shadow-focus: 0 0 0 3px var(--nt-focus-ring);
  }
}

/* ══════════════════════════════════════════════════════════════════════
   3. DOMAIN ALIASES — frist + document statuses
   Screens name the domain, not the color; the mapping lives here so that
   "what color is an overdue frist" has exactly one answer in the codebase.
   Declared once — they resolve against the theme-resolved family on :root.
   ══════════════════════════════════════════════════════════════════════ */

:root {
  /* Frister (deadlines.status) */
  --nt-frist-upcoming: var(--nt-info);
  --nt-frist-upcoming-soft: var(--nt-info-soft);
  --nt-frist-upcoming-text: var(--nt-info-text);
  --nt-frist-upcoming-border: var(--nt-info-border);

  --nt-frist-due-soon: var(--nt-warn);
  --nt-frist-due-soon-soft: var(--nt-warn-soft);
  --nt-frist-due-soon-text: var(--nt-warn-text);
  --nt-frist-due-soon-border: var(--nt-warn-border);

  --nt-frist-overdue: var(--nt-danger);
  --nt-frist-overdue-soft: var(--nt-danger-soft);
  --nt-frist-overdue-text: var(--nt-danger-text);
  --nt-frist-overdue-border: var(--nt-danger-border);

  --nt-frist-cleared: var(--nt-ok);
  --nt-frist-cleared-soft: var(--nt-ok-soft);
  --nt-frist-cleared-text: var(--nt-ok-text);
  --nt-frist-cleared-border: var(--nt-ok-border);

  --nt-frist-cancelled: var(--nt-neutral);
  --nt-frist-cancelled-soft: var(--nt-neutral-soft);
  --nt-frist-cancelled-text: var(--nt-neutral-text);
  --nt-frist-cancelled-border: var(--nt-neutral-border);

  /* Documents (documents.status). "registered" is the terminal in-orden
     state — same green as signed, but rendered solid, so the two read as
     one family with a clear final step rather than as two different ideas. */
  --nt-doc-draft: var(--nt-neutral);
  --nt-doc-draft-soft: var(--nt-neutral-soft);
  --nt-doc-draft-text: var(--nt-neutral-text);
  --nt-doc-draft-border: var(--nt-neutral-border);

  --nt-doc-in-review: var(--nt-info);
  --nt-doc-in-review-soft: var(--nt-info-soft);
  --nt-doc-in-review-text: var(--nt-info-text);
  --nt-doc-in-review-border: var(--nt-info-border);

  --nt-doc-in-signing: var(--nt-warn);
  --nt-doc-in-signing-soft: var(--nt-warn-soft);
  --nt-doc-in-signing-text: var(--nt-warn-text);
  --nt-doc-in-signing-border: var(--nt-warn-border);

  --nt-doc-signed: var(--nt-ok);
  --nt-doc-signed-soft: var(--nt-ok-soft);
  --nt-doc-signed-text: var(--nt-ok-text);
  --nt-doc-signed-border: var(--nt-ok-border);

  --nt-doc-registered: var(--nt-ok);
  --nt-doc-registered-soft: var(--nt-ok);
  --nt-doc-registered-text: var(--nt-on-ok);
  --nt-doc-registered-border: var(--nt-ok);

  --nt-doc-archived: var(--nt-neutral);
  --nt-doc-archived-soft: var(--nt-neutral-soft);
  --nt-doc-archived-text: var(--nt-neutral-text);
  --nt-doc-archived-border: var(--nt-neutral-border);

  --nt-doc-superseded: var(--nt-neutral);
  --nt-doc-superseded-soft: var(--nt-neutral-soft);
  --nt-doc-superseded-text: var(--nt-neutral-text);
  --nt-doc-superseded-border: var(--nt-neutral-border);

  --nt-doc-void: var(--nt-danger);
  --nt-doc-void-soft: var(--nt-danger-soft);
  --nt-doc-void-text: var(--nt-danger-text);
  --nt-doc-void-border: var(--nt-danger-border);
}

/* ══════════════════════════════════════════════════════════════════════
   4. BASE
   ══════════════════════════════════════════════════════════════════════ */

html {
  background: var(--nt-bg);
}

body {
  background: var(--nt-bg);
  color: var(--nt-text);
  font-family: var(--nt-font-body);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection {
  background: var(--nt-seal-tint);
  color: var(--nt-text);
}

/* NOTE: the global focus ring is declared ONCE, in the public-surfaces
   section further down ("Focus, globally"). It used to be declared here too —
   seven element types at 2px offset — and again down there at five element
   types and 3px, so `select` and `textarea` got one ring and everything else
   got another, in a different colour once the theme went dark. The surviving
   rule carries the union of the two element lists. */

/* Screen-reader-only text.
   `inset-inline-start: 0` is load-bearing, not tidiness. Absolutely positioned
   with no offsets, the box sits at its STATIC position — and with no
   positioned ancestor its containing block is the initial one, so it is not
   clipped by any `overflow-x: auto` wrapper it happens to live inside. A
   caption inside a wide, horizontally scrolling table therefore anchored at
   x≈405 in a 375px viewport and dragged the whole page 30px sideways, with
   nothing visible to blame. Anchoring it removes the dependency on where it
   happens to sit. It stays 1px and clipped either way, so nothing moves. */
.nt-visually-hidden {
  position: absolute;
  inset-inline-start: 0;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.nt-page {
  max-width: var(--nt-page-max);
  margin: 0 auto;
  padding: var(--nt-space-8) var(--nt-space-6) var(--nt-space-16);
}

.nt-page-narrow {
  max-width: 52rem;
}

/* The section rhythm. Until this existed there was none: `.nt-app-column` set
   a measure but no gap, `.nt-card` carries no margin, and no `> * + *` rule
   lived anywhere in the stylesheets — so a page that stacked sibling
   `<section class="nt-card">` rendered them flush, borders touching. Five
   screens did exactly that.

   Two other rhythms already existed and disagreed (`.koncern-page` gap-8,
   `.nt-settings-page` gap-6). This is the one they converge on; gap-8 wins
   because a card is a heavy object and needs the room. Owning-the-gap rather
   than margin-per-child is deliberate: a `.nt-page-header` that sets its own
   `margin-bottom` then has to be un-set by whatever contains it, which is
   exactly why `.koncern-page` carries an override. */
.nt-stack {
  display: flex;
  flex-direction: column;
  gap: var(--nt-space-8);
}

/* Standalone, not a modifier. The shell's own comment tells a screen to
   "render its own .nt-stack-tight inside", so it has to work without
   .nt-stack — declaring only `gap` made it silently inert on a block element. */
.nt-stack-tight {
  display: flex;
  flex-direction: column;
  gap: var(--nt-space-5);
}

.nt-stack-tight > .nt-page-header { margin-bottom: 0; }

/* Inside a gap-driven stack the header's own margin would double the space. */
.nt-stack > .nt-page-header { margin-bottom: 0; }

/* A flex item's `min-width` resolves to `auto`, which means "never shrink
   below your content". A card containing a wide table therefore refuses to
   shrink, its own `overflow-x: auto` never engages, and the whole PAGE scrolls
   sideways instead of the table — which is how /begivenheder measured 405px in
   a 375px viewport with a scroll wrapper already in place.
   Making the shell a flex column is what exposed this, so the fix belongs
   here. */
.nt-stack > *,
.nt-stack-tight > * { min-width: 0; }

/* The workspace measure: sidebar + a table that has to fit five columns.
   Same value as --nt-page-max; named so a screen can ask for it explicitly
   rather than relying on the default. */
.nt-page-wide {
  max-width: var(--nt-page-max);
}

/* ══════════════════════════════════════════════════════════════════════
   5. TYPOGRAPHY
   ══════════════════════════════════════════════════════════════════════ */

.nt-display {
  font-family: var(--nt-font-display);
  font-weight: 600;
  font-optical-sizing: auto;
  letter-spacing: -0.015em;
  line-height: 1.14;
}

.nt-serif {
  font-family: var(--nt-font-serif);
}

.nt-mono {
  font-family: var(--nt-font-mono);
  font-size: 0.85em;
  letter-spacing: 0.01em;
  font-variant-ligatures: none;
}

/* Numbers that must line up in a column (kroner, dates, CVR). */
.nt-tabular {
  font-variant-numeric: tabular-nums;
}

/* NOTE: `.nt-eyebrow` and `.nt-lede` were declared HERE as well as in the
   public-surfaces section below. Every property the pair set here was reset
   by the later declaration — mono/uppercase/tertiary vs. the rule-prefixed
   eyebrow, and the whole lede — so nothing in this file ever rendered and the
   styleguide was documenting a variant no page had ever shown. One
   declaration each now, and it is the one further down. */

/* The text-colour utilities used to live here. They are declared at the very
   END of this file instead — see "TEXT COLOUR UTILITIES". Declaring them here
   put them ahead of every component that also sets a colour, so
   `class="nt-hint nt-warn-fg"` silently lost its colour to `.nt-hint`: equal
   specificity, later wins. A view had already grown a comment working around
   it. */

.nt-link {
  color: var(--nt-seal-text);
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--nt-seal-border);
  transition: text-decoration-color var(--nt-duration-fast) var(--nt-ease);
}

.nt-link:hover { text-decoration-color: currentColor; }

.nt-hr {
  border: 0;
  border-top: 1px solid var(--nt-border-subtle);
  margin: var(--nt-space-6) 0;
}

/* ══════════════════════════════════════════════════════════════════════
   6. WORDMARK & SEAL MARK
   ══════════════════════════════════════════════════════════════════════ */

.nt-wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-family: var(--nt-font-display);
  font-weight: 600;
  font-size: 1.3rem;
  letter-spacing: -0.01em;
  color: var(--nt-text);
  text-decoration: none;
}

.nt-wordmark .nt-seal-mark {
  flex: none;
  transition: transform var(--nt-duration-slow) var(--nt-ease-seal);
}

.nt-wordmark:hover .nt-seal-mark {
  transform: rotate(-8deg);
}

/* The seal mark is a line-art SVG that inherits currentColor; the ring is
   drawn in the seal color, the interior letterform in the same ink as its
   surroundings, so it works on paper, on inverse chrome, and on a card. */
.nt-seal-mark {
  display: inline-block;
  color: var(--nt-seal);
  vertical-align: middle;
}

.nt-seal-mark-inverse { color: var(--nt-c-seal-300); }

/* ══════════════════════════════════════════════════════════════════════
   7. BUTTONS
   ══════════════════════════════════════════════════════════════════════ */

.nt-btn {
  --nt-btn-px: 1.15rem;
  --nt-btn-py: 0.6rem;
  --nt-btn-fs: 0.92rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: var(--nt-btn-py) var(--nt-btn-px);
  border-radius: var(--nt-radius);
  border: 1px solid transparent;
  font-family: var(--nt-font-body);
  font-size: var(--nt-btn-fs);
  font-weight: 550;
  line-height: 1.25;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
  -webkit-appearance: none;
  appearance: none;
  transition:
    background-color var(--nt-duration-fast) var(--nt-ease),
    border-color var(--nt-duration-fast) var(--nt-ease),
    color var(--nt-duration-fast) var(--nt-ease),
    box-shadow var(--nt-duration-fast) var(--nt-ease),
    transform var(--nt-duration-fast) var(--nt-ease);
}

.nt-btn:active { transform: translateY(1px); }

.nt-btn-sm { --nt-btn-px: 0.75rem; --nt-btn-py: 0.36rem; --nt-btn-fs: 0.82rem; }
.nt-btn-lg { --nt-btn-px: 1.5rem; --nt-btn-py: 0.8rem; --nt-btn-fs: 1rem; }
.nt-btn-block { width: 100%; }

.nt-btn-primary {
  background: var(--nt-seal);
  color: var(--nt-on-seal);
  box-shadow: var(--nt-shadow-1);
}
.nt-btn-primary:hover { background: var(--nt-seal-hover); }
.nt-btn-primary:active { background: var(--nt-seal-active); }

.nt-btn-ok {
  background: var(--nt-ok);
  color: var(--nt-on-ok);
  box-shadow: var(--nt-shadow-1);
}
.nt-btn-ok:hover { filter: brightness(1.08); }

.nt-btn-ghost {
  background: var(--nt-surface);
  color: var(--nt-text);
  border-color: var(--nt-border);
}
.nt-btn-ghost:hover {
  border-color: var(--nt-border-strong);
  background: var(--nt-surface-raised);
}

.nt-btn-quiet {
  background: transparent;
  color: var(--nt-text-secondary);
}
.nt-btn-quiet:hover {
  background: var(--nt-surface-raised);
  color: var(--nt-text);
}

.nt-btn-danger {
  background: transparent;
  color: var(--nt-danger-text);
  border-color: var(--nt-danger-border);
}
.nt-btn-danger:hover {
  background: var(--nt-danger-soft);
  border-color: var(--nt-danger);
}

.nt-btn[disabled],
.nt-btn-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
  box-shadow: none;
}

/* Square icon-only button — 40px hit target at default size. */
.nt-btn-icon {
  --nt-btn-px: 0;
  --nt-btn-py: 0;
  width: 2.35rem;
  height: 2.35rem;
}

/* ══════════════════════════════════════════════════════════════════════
   8. CARDS
   ══════════════════════════════════════════════════════════════════════ */

.nt-card {
  background: var(--nt-surface);
  border: 1px solid var(--nt-border-subtle);
  border-radius: var(--nt-radius-lg);
  box-shadow: var(--nt-shadow-2);
}

.nt-card-flat { box-shadow: none; }
.nt-card-sunken { background: var(--nt-surface-raised); box-shadow: none; }

.nt-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--nt-space-4);
  padding: var(--nt-space-5) var(--nt-space-6);
  border-bottom: 1px solid var(--nt-border-subtle);
}

.nt-card-title {
  font-family: var(--nt-font-display);
  font-weight: 600;
  font-size: var(--nt-text-lg);
  letter-spacing: -0.01em;
  line-height: 1.2;
}

.nt-card-subtitle {
  font-size: var(--nt-text-sm);
  color: var(--nt-text-secondary);
  margin-top: 0.15rem;
}

.nt-card-body { padding: var(--nt-space-6); }
.nt-card-body-tight { padding: var(--nt-space-4) var(--nt-space-5); }

.nt-card-foot {
  padding: var(--nt-space-4) var(--nt-space-6);
  border-top: 1px solid var(--nt-border-subtle);
  background: var(--nt-surface-raised);
  border-radius: 0 0 var(--nt-radius-lg) var(--nt-radius-lg);
}

/* Whole-card link: lifts a hair and warms its border. */
.nt-card-link {
  display: block;
  text-decoration: none;
  color: inherit;
  transition:
    transform var(--nt-duration) var(--nt-ease),
    box-shadow var(--nt-duration) var(--nt-ease),
    border-color var(--nt-duration) var(--nt-ease);
}
.nt-card-link:hover {
  transform: translateY(-2px);
  box-shadow: var(--nt-shadow-3);
  border-color: var(--nt-border);
}

/* Accent rail — the card is "about" a status. */
.nt-card-accent { border-left: 3px solid var(--nt-accent, var(--nt-seal)); }
.nt-accent-ok { --nt-accent: var(--nt-ok); }
.nt-accent-warn { --nt-accent: var(--nt-warn); }
.nt-accent-danger { --nt-accent: var(--nt-danger); }
.nt-accent-info { --nt-accent: var(--nt-info); }
.nt-accent-seal { --nt-accent: var(--nt-seal); }

/* ══════════════════════════════════════════════════════════════════════
   9. PAGE HEADER
   ══════════════════════════════════════════════════════════════════════ */

.nt-page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--nt-space-4);
  flex-wrap: wrap;
  margin-bottom: var(--nt-space-6);
}

.nt-page-header-title {
  font-family: var(--nt-font-display);
  font-weight: 600;
  font-size: var(--nt-text-2xl);
  letter-spacing: -0.02em;
  line-height: 1.12;
}

.nt-page-header-subtitle {
  margin-top: 0.35rem;
  font-size: var(--nt-text-base);
  color: var(--nt-text-secondary);
  max-width: var(--nt-prose-max);
}

.nt-page-header-actions {
  display: flex;
  align-items: center;
  gap: var(--nt-space-2);
  flex-wrap: wrap;
}

/* ══════════════════════════════════════════════════════════════════════
   10. STAT CARD
   ══════════════════════════════════════════════════════════════════════ */

.nt-stat {
  display: block;
  padding: var(--nt-space-5);
  text-decoration: none;
  color: inherit;
}

.nt-stat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--nt-space-3);
  margin-bottom: var(--nt-space-3);
}

.nt-stat-label {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--nt-text-tertiary);
}

.nt-stat-icon {
  color: var(--nt-accent, var(--nt-seal));
  flex: none;
}

.nt-stat-value {
  font-family: var(--nt-font-display);
  font-weight: 600;
  font-size: var(--nt-text-3xl);
  line-height: 1;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
  color: var(--nt-stat-value-color, var(--nt-text));
}

.nt-stat-sub {
  margin-top: 0.5rem;
  font-size: var(--nt-text-sm);
  color: var(--nt-text-secondary);
}

.nt-stat-ok { --nt-accent: var(--nt-ok); --nt-stat-value-color: var(--nt-ok-text); }
.nt-stat-warn { --nt-accent: var(--nt-warn); --nt-stat-value-color: var(--nt-warn-text); }
.nt-stat-danger { --nt-accent: var(--nt-danger); --nt-stat-value-color: var(--nt-danger-text); }
.nt-stat-info { --nt-accent: var(--nt-info); --nt-stat-value-color: var(--nt-info-text); }

/* ══════════════════════════════════════════════════════════════════════
   11. BADGES / STATUS CHIPS & LAW CHIPS
   ══════════════════════════════════════════════════════════════════════ */

.nt-badge {
  --nt-badge-fg: var(--nt-neutral-text);
  --nt-badge-bg: var(--nt-neutral-soft);
  --nt-badge-bd: var(--nt-neutral-border);
  --nt-badge-dot: var(--nt-neutral);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.18rem 0.6rem;
  border-radius: var(--nt-radius-full);
  border: 1px solid var(--nt-badge-bd);
  background: var(--nt-badge-bg);
  color: var(--nt-badge-fg);
  font-size: var(--nt-text-xs);
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
}

.nt-badge-dot::before {
  content: "";
  width: 0.42em;
  height: 0.42em;
  border-radius: 50%;
  background: var(--nt-badge-dot);
  flex: none;
}

.nt-badge-neutral { --nt-badge-fg: var(--nt-neutral-text); --nt-badge-bg: var(--nt-neutral-soft); --nt-badge-bd: var(--nt-neutral-border); --nt-badge-dot: var(--nt-neutral); }
.nt-badge-ok { --nt-badge-fg: var(--nt-ok-text); --nt-badge-bg: var(--nt-ok-soft); --nt-badge-bd: var(--nt-ok-border); --nt-badge-dot: var(--nt-ok); }
.nt-badge-warn { --nt-badge-fg: var(--nt-warn-text); --nt-badge-bg: var(--nt-warn-soft); --nt-badge-bd: var(--nt-warn-border); --nt-badge-dot: var(--nt-warn); }
.nt-badge-danger { --nt-badge-fg: var(--nt-danger-text); --nt-badge-bg: var(--nt-danger-soft); --nt-badge-bd: var(--nt-danger-border); --nt-badge-dot: var(--nt-danger); }
.nt-badge-info { --nt-badge-fg: var(--nt-info-text); --nt-badge-bg: var(--nt-info-soft); --nt-badge-bd: var(--nt-info-border); --nt-badge-dot: var(--nt-info); }
.nt-badge-seal { --nt-badge-fg: var(--nt-seal-text); --nt-badge-bg: var(--nt-seal-soft); --nt-badge-bd: var(--nt-seal-border); --nt-badge-dot: var(--nt-seal); }

/* Solid: the terminal state (registered) — the stamp has landed. */
.nt-badge-solid { --nt-badge-bd: transparent; }
.nt-badge-solid.nt-badge-ok { --nt-badge-bg: var(--nt-ok); --nt-badge-fg: var(--nt-on-ok); --nt-badge-dot: var(--nt-on-ok); }
.nt-badge-solid.nt-badge-warn { --nt-badge-bg: var(--nt-warn); --nt-badge-fg: var(--nt-on-warn); --nt-badge-dot: var(--nt-on-warn); }
.nt-badge-solid.nt-badge-danger { --nt-badge-bg: var(--nt-danger); --nt-badge-fg: var(--nt-on-danger); --nt-badge-dot: var(--nt-on-danger); }
.nt-badge-solid.nt-badge-info { --nt-badge-bg: var(--nt-info); --nt-badge-fg: var(--nt-on-info); --nt-badge-dot: var(--nt-on-info); }
.nt-badge-solid.nt-badge-neutral { --nt-badge-bg: var(--nt-neutral); --nt-badge-fg: var(--nt-on-neutral); --nt-badge-dot: var(--nt-on-neutral); }
.nt-badge-solid.nt-badge-seal { --nt-badge-bg: var(--nt-seal); --nt-badge-fg: var(--nt-on-seal); --nt-badge-dot: var(--nt-on-seal); }

.nt-badge-mono {
  font-family: var(--nt-font-mono);
  font-weight: 500;
  letter-spacing: 0.01em;
}

/* Generic metadata chip (CVR numbers, kickers, counts). */
.nt-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.18rem 0.6rem;
  border-radius: var(--nt-radius-full);
  border: 1px solid var(--nt-border-subtle);
  background: var(--nt-surface-raised);
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  color: var(--nt-text-secondary);
}

/* Tone modifiers for the metadata chip. These were referenced from six places
   — company status in DomainHelper, the billing state, the signup CVR carry,
   and three DocumentsHelper builders — before they were ever declared, so all
   of them rendered as a neutral grey chip. A missing class is silent; nothing
   errors, the colour just never arrives.
   Tinted rather than solid: a chip is metadata, and it must not out-shout the
   `.nt-badge` next to it that carries the record's actual status. */
/* A TONED chip carries a dot, for the same reason .nt-badge always does:
   colour alone is not a status signal, and roughly one man in twelve cannot
   read the green/amber difference this component leans on. The dot is
   currentColor, so it follows each tone without a second token to keep in
   sync.
 *
 * Only the toned modifiers get it. A bare .nt-chip is not a status — it holds
 * a CVR number, a selskabsform, a template variable — and a dot in front of
 * "41 25 88 03" would be decoration pretending to be meaning. */
.nt-chip-ok::before,
.nt-chip-warn::before,
.nt-chip-danger::before,
.nt-chip-info::before {
  content: "";
  width: 0.42em;
  height: 0.42em;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

.nt-chip-ok {
  border-color: var(--nt-ok-border);
  background: var(--nt-ok-soft);
  color: var(--nt-ok-text);
}

.nt-chip-warn {
  border-color: var(--nt-warn-border);
  background: var(--nt-warn-soft);
  color: var(--nt-warn-text);
}

.nt-chip-danger {
  border-color: var(--nt-danger-border);
  background: var(--nt-danger-soft);
  color: var(--nt-danger-text);
}

.nt-chip-info {
  border-color: var(--nt-info-border);
  background: var(--nt-info-soft);
  color: var(--nt-info-text);
}

/* § reference. Monospace by rule: a paragraph number is a citation, not
   prose, and the reader must be able to copy it exactly. */
.nt-law-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.28rem;
  padding: 0.1rem 0.45rem;
  border-radius: var(--nt-radius-xs);
  border: 1px solid var(--nt-seal-border);
  background: var(--nt-seal-soft);
  color: var(--nt-seal-text);
  font-family: var(--nt-font-mono);
  font-size: 0.78em;
  font-weight: 500;
  letter-spacing: 0.01em;
  white-space: nowrap;
  text-decoration: none;
}

a.nt-law-chip { transition: background-color var(--nt-duration-fast) var(--nt-ease); }
a.nt-law-chip:hover { background: var(--nt-seal-tint); }

.nt-law-chip-source {
  color: var(--nt-text-tertiary);
  font-size: 0.9em;
}

/* ══════════════════════════════════════════════════════════════════════
   12. FORMS
   ══════════════════════════════════════════════════════════════════════ */

.nt-field { display: block; margin-bottom: var(--nt-space-4); }

.nt-label {
  display: block;
  font-size: var(--nt-text-sm);
  font-weight: 600;
  color: var(--nt-text-secondary);
  margin-bottom: 0.35rem;
  letter-spacing: 0.01em;
}

.nt-input,
.nt-textarea,
.nt-select {
  width: 100%;
  padding: 0.6rem 0.85rem;
  border-radius: var(--nt-radius);
  border: 1px solid var(--nt-border);
  background: var(--nt-surface);
  color: var(--nt-text);
  font-family: var(--nt-font-body);
  font-size: 0.95rem;
  line-height: 1.5;
  transition:
    border-color var(--nt-duration-fast) var(--nt-ease),
    box-shadow var(--nt-duration-fast) var(--nt-ease);
}

.nt-input::placeholder,
.nt-textarea::placeholder { color: var(--nt-text-disabled); }

.nt-input:focus,
.nt-textarea:focus,
.nt-select:focus {
  outline: none;
  border-color: var(--nt-focus);
  box-shadow: var(--nt-shadow-focus);
}

.nt-input[aria-invalid="true"],
.nt-textarea[aria-invalid="true"] {
  border-color: var(--nt-danger);
}

.nt-textarea { min-height: 7rem; resize: vertical; }

.nt-select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 2.2rem;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 1rem center, right 0.72rem center;
  background-size: 0.28rem 0.28rem, 0.28rem 0.28rem;
  background-repeat: no-repeat;
}

.nt-hint {
  margin-top: 0.35rem;
  font-size: var(--nt-text-xs);
  color: var(--nt-text-tertiary);
}

.nt-error {
  margin-top: 0.35rem;
  font-size: var(--nt-text-xs);
  color: var(--nt-danger-text);
}

/* Radio "cards" — the wizard's default answer pattern. */
.nt-choice {
  display: flex;
  gap: var(--nt-space-3);
  padding: var(--nt-space-4);
  border: 1px solid var(--nt-border);
  border-radius: var(--nt-radius);
  background: var(--nt-surface);
  cursor: pointer;
  transition:
    border-color var(--nt-duration-fast) var(--nt-ease),
    background-color var(--nt-duration-fast) var(--nt-ease);
}
.nt-choice:hover { border-color: var(--nt-border-strong); }
.nt-choice:has(input:checked) {
  border-color: var(--nt-seal);
  background: var(--nt-seal-soft);
}
.nt-choice:has(input:focus-visible) { box-shadow: var(--nt-shadow-focus); }

/* Validation summary — shared/_form_errors. Danger-toned but quiet: a rejected
   form is a correction, not a catastrophe, and shouting at someone who mistyped
   a CVR number is the wrong register for a legal product. */
.nt-form-errors {
  margin-bottom: var(--nt-space-5);
  padding: var(--nt-space-4) var(--nt-space-5);
  border-radius: var(--nt-radius);
  background: var(--nt-danger-soft);
  border: 1px solid var(--nt-danger-border);
  border-left: 3px solid var(--nt-danger);
  color: var(--nt-danger-text);
}

.nt-form-errors-title {
  display: flex;
  align-items: center;
  gap: var(--nt-space-2);
  font-weight: 600;
  font-size: var(--nt-text-base);
}

.nt-form-errors-list {
  margin: var(--nt-space-2) 0 0;
  padding-left: 1.6rem;
  list-style: disc;
  font-size: var(--nt-text-sm);
  color: var(--nt-text-secondary);
}

.nt-form-errors-list li + li { margin-top: 0.15rem; }

/* Rails wraps an invalid input in <div class="field_with_errors">, which turns
   a grid cell into a block and visibly breaks the form on the exact render
   where the user most needs it to hold still. config/initializers/form_errors.rb
   turns the wrapper into an inline marker; this is what it looks like. */
.field_with_errors { display: contents; }
.field_with_errors .nt-input,
.field_with_errors .nt-textarea,
.field_with_errors .nt-select {
  border-color: var(--nt-danger);
  background: var(--nt-danger-soft);
}

/* ══════════════════════════════════════════════════════════════════════
   13. TABLES
   ══════════════════════════════════════════════════════════════════════ */

.nt-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--nt-text-base);
}

.nt-table th {
  text-align: left;
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 500;
  color: var(--nt-text-tertiary);
  padding: var(--nt-space-3) var(--nt-space-5);
  border-bottom: 1px solid var(--nt-border-subtle);
  white-space: nowrap;
}

.nt-table td {
  padding: var(--nt-space-4) var(--nt-space-5);
  border-bottom: 1px solid var(--nt-border-subtle);
  vertical-align: middle;
}

.nt-table tbody tr:last-child td { border-bottom: 0; }

/* The summing row on the ejerbog — "I alt" must read as a rule under the
   column, not as one more line of data. */
.nt-table-total td {
  border-top: 2px solid var(--nt-border);
  font-weight: 600;
}
.nt-table tfoot .nt-table-total td { border-bottom: 0; }
.nt-table .text-right { text-align: right; }
.nt-table tbody tr { transition: background-color var(--nt-duration-fast) var(--nt-ease); }
.nt-table-hover tbody tr:hover { background: var(--nt-surface-raised); }

/* ══════════════════════════════════════════════════════════════════════
   14. PAGINATION
   ══════════════════════════════════════════════════════════════════════ */

.nt-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--nt-space-4);
  flex-wrap: wrap;
  padding: var(--nt-space-4) var(--nt-space-5);
  border-top: 1px solid var(--nt-border-subtle);
}

.nt-pagination-nav { display: flex; align-items: center; gap: 0.25rem; }

.nt-page-link,
.nt-page-current,
.nt-page-gap {
  min-width: 2rem;
  text-align: center;
  padding: 0.3rem 0.6rem;
  border-radius: var(--nt-radius-sm);
  font-size: var(--nt-text-sm);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
}

.nt-page-link {
  color: var(--nt-text-secondary);
  transition: background-color var(--nt-duration-fast) var(--nt-ease), color var(--nt-duration-fast) var(--nt-ease);
}
.nt-page-link:hover { background: var(--nt-surface-raised); color: var(--nt-text); }

.nt-page-current {
  background: var(--nt-seal);
  color: var(--nt-on-seal);
  font-weight: 600;
}

.nt-page-gap { color: var(--nt-text-disabled); user-select: none; }

/* ══════════════════════════════════════════════════════════════════════
   14b. KEY / VALUE — structured jsonb rendered for humans
   Used by shared/_param_value (vedtægter params, filing data, wizard answers).
   ══════════════════════════════════════════════════════════════════════ */

.nt-kv { display: grid; gap: var(--nt-space-3); }

.nt-kv-nested {
  gap: var(--nt-space-1);
  margin-top: var(--nt-space-1);
  padding-left: var(--nt-space-4);
  border-left: 1px solid var(--nt-border-subtle);
}

.nt-kv-row {
  display: grid;
  grid-template-columns: minmax(9rem, 14rem) 1fr;
  gap: var(--nt-space-4);
  align-items: baseline;
}

/* Below ~34rem the two columns become one; a 9rem label column next to a
   sentence is unreadable on a phone. */
@media (max-width: 34rem) {
  .nt-kv-row { grid-template-columns: 1fr; gap: 0.15rem; }
}

.nt-kv-key {
  font-size: var(--nt-text-sm);
  font-weight: 600;
  color: var(--nt-text-secondary);
}

/* overflow-wrap is load-bearing: these values come from a jsonb column and can
   be one unbroken 200-character string, which used to run out of its grid cell
   and print over the neighbouring one. */
.nt-kv-value {
  font-size: var(--nt-text-base);
  min-width: 0;
  overflow-wrap: anywhere;
}

.nt-kv-list {
  list-style: disc;
  padding-left: 1.2rem;
  display: grid;
  gap: var(--nt-space-1);
}

.nt-kv-list .nt-kv-nested { border-left: 0; padding-left: 0; }

/* ══════════════════════════════════════════════════════════════════════
   15. EMPTY STATE
   ══════════════════════════════════════════════════════════════════════ */

.nt-empty {
  padding: var(--nt-space-12) var(--nt-space-6);
  text-align: center;
}

.nt-empty-icon {
  width: 3rem;
  height: 3rem;
  margin: 0 auto var(--nt-space-4);
  border-radius: var(--nt-radius);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--nt-surface-raised);
  border: 1px solid var(--nt-border-subtle);
  color: var(--nt-text-tertiary);
}

.nt-empty-title {
  font-family: var(--nt-font-display);
  font-weight: 600;
  font-size: var(--nt-text-lg);
  letter-spacing: -0.01em;
}

.nt-empty-body {
  margin: 0.4rem auto 0;
  max-width: 30rem;
  font-size: var(--nt-text-base);
  color: var(--nt-text-secondary);
}

.nt-empty-cta {
  margin-top: var(--nt-space-5);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--nt-space-2);
  flex-wrap: wrap;
}

/* ══════════════════════════════════════════════════════════════════════
   16. SKELETONS
   ══════════════════════════════════════════════════════════════════════ */

.nt-skeleton {
  position: relative;
  overflow: hidden;
  border-radius: var(--nt-radius-xs);
  background: var(--nt-surface-raised);
}

.nt-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--nt-surface-sunken), transparent);
  animation: nt-shimmer 1.5s var(--nt-ease-in-out) infinite;
}

.nt-skeleton-line { height: 0.7rem; }
.nt-skeleton-short { width: 45%; }

/* shared/_skeleton_block — the non-table placeholder. */
.nt-skeleton-block {
  display: flex;
  flex-direction: column;
  gap: var(--nt-space-3);
  padding: var(--nt-space-5);
}

.nt-skeleton-block-paragraph { gap: var(--nt-space-2); }
.nt-skeleton-block-paragraph .nt-skeleton-line { height: 0.6rem; }

/* Chat: alternating sides, so the placeholder has the SHAPE of a conversation
   rather than the shape of a list. Recognising "this is a thread loading" at a
   glance is the whole job. */
.nt-skeleton-block-thread { gap: var(--nt-space-4); }
.nt-skeleton-block-thread .nt-skeleton-line { height: 2.1rem; border-radius: var(--nt-radius); }
.nt-skeleton-block-thread .nt-skeleton-line.is-alt { align-self: flex-end; }

/* The shimmer is a nice-to-have; the layout reservation is the point. With
   reduced motion the block still holds the space, it just sits still — a
   travelling highlight is exactly the kind of movement that setting is for. */
@media (prefers-reduced-motion: reduce) {
  .nt-skeleton::after { display: none; }
  .nt-skeleton { background: var(--nt-surface-sunken); }
}

/* Anything mid-fetch dims slightly and stops taking clicks. Applied to the
   turbo-frame itself via aria-busy, so it needs no wrapper markup and it works
   for every frame in the app, including ones added later. */
[aria-busy="true"] {
  cursor: progress;
}

[aria-busy="true"] > * {
  opacity: 0.72;
  transition: opacity var(--nt-duration) var(--nt-ease);
}

@keyframes nt-shimmer {
  100% { transform: translateX(100%); }
}

/* ══════════════════════════════════════════════════════════════════════
   17. TOASTS & FLASH
   ══════════════════════════════════════════════════════════════════════ */

.nt-toast-region {
  position: fixed;
  top: var(--nt-space-4);
  right: var(--nt-space-4);
  z-index: var(--nt-z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--nt-space-2);
  width: min(24rem, calc(100vw - 2rem));
  pointer-events: none;
}

.nt-toast-region > * { pointer-events: auto; }

.nt-toast {
  --nt-toast-accent: var(--nt-neutral);
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  padding: 0.75rem 0.85rem;
  border-radius: var(--nt-radius);
  border: 1px solid var(--nt-border-subtle);
  border-left: 3px solid var(--nt-toast-accent);
  background: var(--nt-surface-overlay);
  box-shadow: var(--nt-shadow-3);
  font-size: var(--nt-text-base);
  color: var(--nt-text);
  animation: nt-toast-in var(--nt-duration-slow) var(--nt-ease) both;
}

.nt-toast-ok { --nt-toast-accent: var(--nt-ok); }
.nt-toast-warn { --nt-toast-accent: var(--nt-warn); }
.nt-toast-danger { --nt-toast-accent: var(--nt-danger); }
.nt-toast-info { --nt-toast-accent: var(--nt-info); }

.nt-toast-icon { color: var(--nt-toast-accent); flex: none; margin-top: 0.1rem; }
.nt-toast-body { flex: 1; min-width: 0; }

.nt-toast-close {
  flex: none;
  border: 0;
  background: transparent;
  color: var(--nt-text-tertiary);
  cursor: pointer;
  padding: 0.15rem;
  border-radius: var(--nt-radius-xs);
  line-height: 0;
  transition: color var(--nt-duration-fast) var(--nt-ease);
}
.nt-toast-close:hover { color: var(--nt-text); }

.nt-toast-dismissing { animation: nt-toast-out var(--nt-duration-slow) var(--nt-ease-in) both; }

@keyframes nt-toast-in {
  from { opacity: 0; transform: translateX(0.75rem) scale(0.98); }
  to { opacity: 1; transform: none; }
}

@keyframes nt-toast-out {
  from { opacity: 1; transform: none; max-height: 12rem; }
  to { opacity: 0; transform: translateX(0.75rem); max-height: 0; margin-bottom: -0.5rem; }
}

/* Inline flash — same semantics, in the document flow (auth cards, forms). */
.nt-flash {
  --nt-flash-accent: var(--nt-neutral);
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.7rem 0.9rem;
  border-radius: var(--nt-radius);
  border: 1px solid var(--nt-border-subtle);
  border-left: 3px solid var(--nt-flash-accent);
  background: var(--nt-surface);
  font-size: var(--nt-text-base);
}

.nt-flash-ok { --nt-flash-accent: var(--nt-ok); background: var(--nt-ok-soft); color: var(--nt-ok-text); }
.nt-flash-warn { --nt-flash-accent: var(--nt-warn); background: var(--nt-warn-soft); color: var(--nt-warn-text); }
.nt-flash-danger { --nt-flash-accent: var(--nt-danger); background: var(--nt-danger-soft); color: var(--nt-danger-text); }
.nt-flash-info { --nt-flash-accent: var(--nt-info); background: var(--nt-info-soft); color: var(--nt-info-text); }

/* ══════════════════════════════════════════════════════════════════════
   18. MODAL & SLIDE-OVER (native <dialog>)
   ══════════════════════════════════════════════════════════════════════ */

.nt-dialog {
  padding: 0;
  border: 0;
  background: transparent;
  max-width: 100vw;
  max-height: 100dvh;
  color: var(--nt-text);
}

.nt-dialog::backdrop {
  background: var(--nt-scrim);
  backdrop-filter: blur(2px);
}

/* — Modal — */
.nt-modal-dialog {
  width: 100%;
  margin: auto;
}

.nt-modal {
  width: min(var(--nt-modal-w, 34rem), calc(100vw - 2rem));
  margin: 0 auto;
  background: var(--nt-surface-overlay);
  border: 1px solid var(--nt-border-subtle);
  border-radius: var(--nt-radius-lg);
  box-shadow: var(--nt-shadow-3);
  overflow: hidden;
  animation: nt-modal-in var(--nt-duration-slow) var(--nt-ease) both;
}

.nt-modal-sm { --nt-modal-w: 26rem; }
.nt-modal-md { --nt-modal-w: 34rem; }
.nt-modal-lg { --nt-modal-w: 46rem; }

.nt-modal-exit { animation: nt-modal-out var(--nt-duration-fast) var(--nt-ease-in) both; }

@keyframes nt-modal-in {
  from { opacity: 0; transform: translateY(0.75rem) scale(0.985); }
  to { opacity: 1; transform: none; }
}

@keyframes nt-modal-out {
  from { opacity: 1; transform: none; }
  to { opacity: 0; transform: translateY(0.4rem) scale(0.99); }
}

/* — Slide-over — */
.nt-slideover-dialog {
  margin: 0 0 0 auto;
  height: 100dvh;
  max-height: 100dvh;
}

.nt-slideover {
  display: flex;
  flex-direction: column;
  width: min(var(--nt-slideover-w, 30rem), 100vw);
  height: 100dvh;
  background: var(--nt-surface-overlay);
  border-left: 1px solid var(--nt-border-subtle);
  box-shadow: var(--nt-shadow-3);
  transform: translateX(100%);
  transition: transform var(--nt-duration-slow) var(--nt-ease);
}

.nt-slideover-sm { --nt-slideover-w: 24rem; }
.nt-slideover-md { --nt-slideover-w: 30rem; }
.nt-slideover-lg { --nt-slideover-w: 40rem; }
.nt-slideover-xl { --nt-slideover-w: 50rem; }

.nt-slideover-enter { transform: translateX(0); }
.nt-slideover-exit { transform: translateX(100%); }

/* — Shared panel chrome — */
.nt-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--nt-space-4);
  padding: var(--nt-space-4) var(--nt-space-5);
  border-bottom: 1px solid var(--nt-border-subtle);
  flex: none;
}

.nt-panel-title {
  font-family: var(--nt-font-display);
  font-weight: 600;
  font-size: var(--nt-text-lg);
  letter-spacing: -0.01em;
}

.nt-panel-body {
  padding: var(--nt-space-5);
  overflow-y: auto;
  flex: 1;
}

.nt-panel-close {
  border: 0;
  background: transparent;
  color: var(--nt-text-tertiary);
  cursor: pointer;
  padding: 0.3rem;
  border-radius: var(--nt-radius-sm);
  line-height: 0;
  transition: background-color var(--nt-duration-fast) var(--nt-ease), color var(--nt-duration-fast) var(--nt-ease);
}
.nt-panel-close:hover { background: var(--nt-surface-raised); color: var(--nt-text); }

.nt-panel-loading { display: flex; flex-direction: column; gap: 0.6rem; }

/* ══════════════════════════════════════════════════════════════════════
   19. DROPDOWN / MENU
   ══════════════════════════════════════════════════════════════════════ */

.nt-dropdown { position: relative; display: inline-flex; }

.nt-menu {
  position: absolute;
  top: calc(100% + 0.4rem);
  right: 0;
  z-index: var(--nt-z-dropdown);
  min-width: 12rem;
  padding: 0.3rem;
  background: var(--nt-surface-overlay);
  border: 1px solid var(--nt-border-subtle);
  border-radius: var(--nt-radius);
  box-shadow: var(--nt-shadow-3);
  animation: nt-menu-in var(--nt-duration-fast) var(--nt-ease) both;
}

.nt-menu-left { right: auto; left: 0; }
.nt-menu-exit { animation: nt-menu-out var(--nt-duration-fast) var(--nt-ease-in) both; }

@keyframes nt-menu-in {
  from { opacity: 0; transform: translateY(-0.25rem) scale(0.98); }
  to { opacity: 1; transform: none; }
}

@keyframes nt-menu-out {
  from { opacity: 1; transform: none; }
  to { opacity: 0; transform: translateY(-0.2rem) scale(0.99); }
}

.nt-menu-item {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0.45rem 0.6rem;
  border: 0;
  border-radius: var(--nt-radius-sm);
  background: transparent;
  color: var(--nt-text);
  font-family: var(--nt-font-body);
  font-size: var(--nt-text-base);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--nt-duration-fast) var(--nt-ease);
}

.nt-menu-item:hover,
.nt-menu-item:focus-visible { background: var(--nt-surface-raised); }
.nt-menu-item[aria-current="true"] { color: var(--nt-seal-text); font-weight: 600; }
.nt-menu-item-danger { color: var(--nt-danger-text); }

.nt-menu-sep {
  height: 1px;
  margin: 0.3rem 0;
  background: var(--nt-border-subtle);
}

.nt-menu-label {
  padding: 0.4rem 0.6rem 0.25rem;
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--nt-text-tertiary);
}

/* NOTE: section 20 was the 3-state theme toggle — .nt-theme-toggle and
   .nt-theme-option, plus the inverted pair on the sysadmin bar. The control
   itself is gone: the theme is a stored user preference now (Indstillinger →
   Min profil), stamped on <html data-theme> by the layouts. Nothing rendered
   this markup any more. */

/* ══════════════════════════════════════════════════════════════════════
   21. APP CHROME — topbar, sysadmin bar, footer
   ══════════════════════════════════════════════════════════════════════ */

.nt-topbar {
  position: sticky;
  top: 0;
  z-index: var(--nt-z-sticky);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--nt-space-4);
  padding: 0.7rem var(--nt-space-6);
  background: color-mix(in srgb, var(--nt-surface) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--nt-border-subtle);
}

.nt-topbar-group { display: flex; align-items: center; gap: var(--nt-space-3); }

/* Sysadmin chrome: inverted, so staff can never mistake which surface they
   are on — the same mistake that gets a customer's data edited by accident.
   The bordeaux hairline under it is the "you are inside Notarium" tell. */
.nt-topbar-sysadmin {
  background: var(--nt-staff-bar);
  border-bottom: 2px solid var(--nt-seal);
  color: var(--nt-staff-bar-text);
}

.nt-topbar-sysadmin .nt-wordmark { color: var(--nt-staff-bar-text); }
.nt-topbar-sysadmin .nt-muted,
.nt-topbar-sysadmin .nt-faint { color: color-mix(in srgb, var(--nt-staff-bar-text) 72%, transparent); }

.nt-topbar-sysadmin .nt-navlink { color: color-mix(in srgb, var(--nt-staff-bar-text) 68%, transparent); }
.nt-topbar-sysadmin .nt-navlink:hover {
  background: color-mix(in srgb, var(--nt-staff-bar-text) 12%, transparent);
  color: var(--nt-staff-bar-text);
}
.nt-topbar-sysadmin .nt-navlink[aria-current="page"] {
  color: var(--nt-staff-bar-text);
  background: color-mix(in srgb, var(--nt-staff-bar-text) 14%, transparent);
}

.nt-topbar-sysadmin .nt-btn-ghost {
  background: transparent;
  color: var(--nt-staff-bar-text);
  border-color: color-mix(in srgb, var(--nt-staff-bar-text) 32%, transparent);
}
.nt-topbar-sysadmin .nt-btn-ghost:hover {
  background: color-mix(in srgb, var(--nt-staff-bar-text) 12%, transparent);
  border-color: color-mix(in srgb, var(--nt-staff-bar-text) 55%, transparent);
}

/* The staff label. Mono + caps: this is a system marker, not brand voice. */
.nt-staff-badge {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.11em;
  padding: 0.15rem 0.5rem;
  border-radius: var(--nt-radius-xs);
  background: var(--nt-seal);
  color: var(--nt-on-seal);
  white-space: nowrap;
}

.nt-navlink {
  padding: 0.35rem 0.6rem;
  border-radius: var(--nt-radius-sm);
  font-size: var(--nt-text-base);
  color: var(--nt-text-secondary);
  text-decoration: none;
  transition: background-color var(--nt-duration-fast) var(--nt-ease), color var(--nt-duration-fast) var(--nt-ease);
}
.nt-navlink:hover { background: var(--nt-surface-raised); color: var(--nt-text); }
.nt-navlink[aria-current="page"] { color: var(--nt-seal-text); font-weight: 600; }

.nt-footer {
  max-width: var(--nt-page-max);
  margin: 0 auto;
  padding: var(--nt-space-10) var(--nt-space-6);
  border-top: 1px solid var(--nt-border-subtle);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--nt-space-4);
  flex-wrap: wrap;
  font-size: var(--nt-text-sm);
  color: var(--nt-text-tertiary);
}

/* ══════════════════════════════════════════════════════════════════════
   22. AUTH SHELL
   ══════════════════════════════════════════════════════════════════════ */

.nt-auth-shell {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--nt-space-8) var(--nt-space-5);
  gap: var(--nt-space-6);
  /* A single wide, very soft bordeaux wash behind the card — the wax on the
     page, not a gradient for its own sake. */
  background:
    radial-gradient(60rem 32rem at 50% -12rem, var(--nt-seal-soft), transparent 70%),
    var(--nt-bg);
}

.nt-auth-card {
  width: 100%;
  max-width: 26rem;
  padding: var(--nt-space-8) var(--nt-space-6);
}

/* NOTE: `.nt-auth-aside` was declared here as a small horizontal row of
   meta text under the auth card. The auth SHELL further down claims the same
   name for the left-hand panel — `display: none` below 940px, `grid` above —
   and being later it won outright, so this rule has never rendered. The panel
   is the one the layout actually marks up (layouts/auth.html.erb), so the
   name belongs to it and this one is gone rather than renamed: nothing
   referenced it. */

/* ══════════════════════════════════════════════════════════════════════
   22b. ERROR PAGES
   The 404/403/422/500/503 surface. Same wax-on-paper wash as the auth shell,
   because both are "you are outside the app but still inside Notarium".

   ⚠ EVERY RULE IN THIS SECTION IS DUPLICATED, RESOLVED TO LITERAL COLORS,
   INSIDE public/400.html, public/403.html, public/404.html, public/406-…html,
   public/422.html, public/500.html AND public/503.html. Those files are served
   when Rails cannot run at all (boot failure, between deploys), so they cannot
   use the asset pipeline. If you change a rule here, change it in all seven —
   the whole point is that a customer cannot tell which one they got.
   ══════════════════════════════════════════════════════════════════════ */

.nt-error-shell {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--nt-space-8) var(--nt-space-5);
  gap: var(--nt-space-6);
  background:
    radial-gradient(60rem 32rem at 50% -12rem, var(--nt-seal-soft), transparent 70%),
    var(--nt-bg);
}

.nt-error-wordmark { color: var(--nt-text); text-decoration: none; }

.nt-error-main { width: 100%; display: flex; justify-content: center; }

.nt-error-card {
  width: 100%;
  max-width: 34rem;
  padding: var(--nt-space-8) var(--nt-space-8) var(--nt-space-6);
  background: var(--nt-surface);
  border: 1px solid var(--nt-border-subtle);
  border-radius: var(--nt-radius-lg);
  box-shadow: var(--nt-shadow-2);
  /* The status colour arrives as a 3px rail on the left edge, the same signal
     the frist cards use — colour is never the only cue, the code chip repeats
     it in text. */
  border-left: 3px solid var(--nt-accent-color, var(--nt-seal));
}

.nt-error-seal   { --nt-accent-color: var(--nt-seal); --nt-accent-soft: var(--nt-seal-soft); --nt-accent-text: var(--nt-seal-text); }
.nt-error-warn   { --nt-accent-color: var(--nt-warn); --nt-accent-soft: var(--nt-warn-soft); --nt-accent-text: var(--nt-warn-text); }
.nt-error-danger { --nt-accent-color: var(--nt-danger); --nt-accent-soft: var(--nt-danger-soft); --nt-accent-text: var(--nt-danger-text); }
.nt-error-info   { --nt-accent-color: var(--nt-info); --nt-accent-soft: var(--nt-info-soft); --nt-accent-text: var(--nt-info-text); }
.nt-error-ok     { --nt-accent-color: var(--nt-ok); --nt-accent-soft: var(--nt-ok-soft); --nt-accent-text: var(--nt-ok-text); }

/* The status code as a struck chip, in the mono face the app already uses for
   CVR numbers and § references — a number you might have to read aloud. */
.nt-error-code {
  display: inline-block;
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  padding: 0.2rem 0.55rem;
  border-radius: var(--nt-radius-full);
  background: var(--nt-accent-soft);
  color: var(--nt-accent-text);
  border: 1px solid currentColor;
}

.nt-error-title {
  margin-top: var(--nt-space-4);
  font-family: var(--nt-font-display);
  font-weight: 600;
  font-optical-sizing: auto;
  font-size: var(--nt-text-2xl);
  letter-spacing: -0.015em;
  line-height: 1.14;
  color: var(--nt-text);
}

.nt-error-body {
  margin-top: var(--nt-space-3);
  font-size: var(--nt-text-md);
  color: var(--nt-text-secondary);
}

/* "Nothing was half-saved." On a system of record this line is the point of
   the page, so it gets its own tinted block rather than being a third
   paragraph nobody reads. */
.nt-error-reassurance {
  margin-top: var(--nt-space-4);
  padding: var(--nt-space-3) var(--nt-space-4);
  border-radius: var(--nt-radius);
  background: var(--nt-surface-raised);
  border: 1px solid var(--nt-border-subtle);
  font-size: var(--nt-text-sm);
  color: var(--nt-text-secondary);
}

.nt-error-actions {
  margin-top: var(--nt-space-6);
  padding-top: var(--nt-space-5);
  border-top: 1px solid var(--nt-border-subtle);
}

.nt-error-actions-label {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--nt-text-tertiary);
}

.nt-error-actions-row {
  margin-top: var(--nt-space-3);
  display: flex;
  flex-wrap: wrap;
  gap: var(--nt-space-2);
}

.nt-error-ref {
  margin-top: var(--nt-space-5);
  padding: var(--nt-space-4);
  border-radius: var(--nt-radius);
  background: var(--nt-surface-sunken);
  border: 1px dashed var(--nt-border);
}

.nt-error-ref-label {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--nt-text-tertiary);
}

.nt-error-ref-value {
  margin-top: 0.15rem;
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-base);
  font-weight: 600;
  color: var(--nt-text);
  overflow-wrap: anywhere;
  user-select: all;
}

.nt-error-ref-help {
  margin-top: var(--nt-space-2);
  font-size: var(--nt-text-xs);
  color: var(--nt-text-tertiary);
}

.nt-error-footline {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  letter-spacing: 0.08em;
  color: var(--nt-text-tertiary);
}

@media (max-width: 30rem) {
  .nt-error-card { padding: var(--nt-space-6) var(--nt-space-5); }
  .nt-error-actions-row .nt-btn { width: 100%; }
}

/* ══════════════════════════════════════════════════════════════════════
   23. DOCUMENT PAGE — the paper frame live previews live inside
   ══════════════════════════════════════════════════════════════════════ */

.nt-doc-frame {
  padding: var(--nt-space-6);
  background: var(--nt-surface-sunken);
  border-radius: var(--nt-radius-lg);
  display: flex;
  justify-content: center;
  overflow-x: auto;
}

.nt-doc-frame-bare { padding: 0; background: transparent; }

/*
 * A4 by aspect-ratio, not by fixed height: a short document still reads as
 * a page, and a long one grows instead of clipping (min-height:auto on an
 * aspect-ratio box resolves to the content size).
 */
.nt-doc-sheet {
  position: relative;
  width: 100%;
  max-width: var(--nt-doc-width);
  aspect-ratio: 1 / 1.4142;
  padding: clamp(1.75rem, 6%, 3.5rem) clamp(1.5rem, 8%, 4rem);
  background: var(--nt-doc-paper);
  color: var(--nt-doc-ink);
  border: 1px solid var(--nt-doc-paper-edge);
  border-radius: 2px;
  font-family: var(--nt-font-serif);
  font-size: 0.95rem;
  line-height: 1.65;
  /* Two stacked shadows fake the sheet lifting off the desk. */
  box-shadow:
    0 1px 1px rgba(0, 0, 0, 0.06),
    0 10px 30px rgba(0, 0, 0, 0.13);
}

.nt-doc-sheet-a5 { aspect-ratio: 1 / 1.4142; max-width: 32rem; }

/* Bound edge: the faint gutter shadow of a page in a protokol. */
.nt-doc-sheet::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 1.5rem;
  border-radius: 2px 0 0 2px;
  background: linear-gradient(90deg, rgba(0, 0, 0, 0.05), transparent);
  pointer-events: none;
}

.nt-doc-eyebrow {
  font-family: var(--nt-font-mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--nt-doc-ink-soft);
  margin-bottom: 1.4rem;
}

/* Scoped to the sheet, at (0,2,0), for the same reason document.css restates
   `.nt-doc`'s metrics one notch stronger: the marketing hero's prop declares
   `.nt-doc-title` too (§31), Propshaft loads nothing after this file that
   could undo it, and a bare selector here LOST to that prop — every real
   document title on the wizard preview, the vault and the signing page was
   rendering at the prop's 1.62em, uppercase, because a front-page decoration
   said so. The prop's own rule is scoped to `.nt-sheet` now; this one is the
   document. */
.nt-doc-sheet .nt-doc-title {
  font-family: var(--nt-font-display);
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 1.2;
  letter-spacing: -0.012em;
  margin-bottom: 0.4rem;
  color: var(--nt-doc-ink);
}

.nt-doc-subtitle {
  font-family: var(--nt-font-serif);
  font-size: 0.92rem;
  color: var(--nt-doc-ink-soft);
  margin-bottom: 1.6rem;
}

.nt-doc-section {
  margin-top: 1.3rem;
}

.nt-doc-section-title {
  font-family: var(--nt-font-serif);
  font-weight: 600;
  font-size: 0.95rem;
  margin-bottom: 0.3rem;
  color: var(--nt-doc-ink);
}

.nt-doc-rule {
  border: 0;
  border-top: 1px solid var(--nt-doc-rule);
  margin: 1.4rem 0;
}

.nt-doc-signature {
  margin-top: 2rem;
  border-top: 1px solid var(--nt-doc-ink-soft);
  padding-top: 0.4rem;
  width: 14rem;
  font-size: 0.8rem;
  color: var(--nt-doc-ink-soft);
}

/* Scoped for the same reason as `.nt-doc-title` above — and here the stakes
   were higher than a typeface: the marketing prop's `bottom: 4.4%` is exactly
   the percentage this rule's comment was written to replace, so the bug
   below had been silently back in place on every tall preview. */
.nt-doc-sheet .nt-doc-footer {
  position: absolute;
  left: clamp(1.5rem, 8%, 4rem);
  right: clamp(1.5rem, 8%, 4rem);
  /* Fixed, not a percentage: 4% of a tall preview sheet (2131px measured on a
     three-page referat) is 85px — deeper than the 4.5rem the sheet reserves,
     so the footer sat ON the last line of the document. */
  bottom: 1.5rem;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-family: var(--nt-font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  color: var(--nt-doc-ink-soft);
  border-top: 1px solid var(--nt-doc-rule);
  padding-top: 0.4rem;
}

/* NOTE: `.nt-doc-flash` and its keyframes were declared here too, as a
   two-pass alternating wash in a hardcoded amber. The document-preview region
   below declares both again — one pass, 600 ms, seal via color-mix — and being
   later it won. Two declarations of one animation is how a highlight quietly
   changes behaviour when someone reorders the file, so only the later one
   remains. */

/* ══════════════════════════════════════════════════════════════════════
   24. HOMEPAGE
   ══════════════════════════════════════════════════════════════════════ */

.nt-home-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--nt-space-4);
  max-width: var(--nt-page-max);
  margin: 0 auto;
  padding: var(--nt-space-5) var(--nt-space-6);
}

.nt-hero {
  position: relative;
  max-width: var(--nt-page-max);
  margin: 0 auto;
  padding: var(--nt-space-20) var(--nt-space-6) var(--nt-space-16);
  text-align: center;
}

.nt-hero::before {
  content: "";
  position: absolute;
  inset: -6rem 0 auto;
  height: 34rem;
  background: radial-gradient(48rem 24rem at 50% 0%, var(--nt-seal-soft), transparent 72%);
  pointer-events: none;
  z-index: -1;
}

.nt-hero h1 {
  font-family: var(--nt-font-display);
  font-size: clamp(2.5rem, 6vw, 4.1rem);
  font-weight: 600;
  font-optical-sizing: auto;
  letter-spacing: -0.025em;
  line-height: 1.04;
  margin: 0 0 var(--nt-space-5);
  text-wrap: balance;
}

.nt-hero-pitch {
  max-width: 36rem;
  margin: 0 auto var(--nt-space-8);
  font-size: var(--nt-text-md);
  color: var(--nt-text-secondary);
  text-wrap: pretty;
}

.nt-hero-cta {
  display: flex;
  gap: var(--nt-space-3);
  justify-content: center;
  flex-wrap: wrap;
}

/* NOTE: `.nt-section` used to be declared here as a centred 72rem container.
   It is now declared once, in the marketing shell region below, as pure
   vertical rhythm. The two collided: marketing bands are `nt-band nt-section`
   on the SAME element, so this rule's max-width clipped every coloured and ink
   full-bleed band to a centred box while `.nt-section-tight` — declared once —
   spanned the viewport. Neighbouring bands therefore had different widths.
   Nothing in the workspace ever used this meaning. */

/* ══════════════════════════════════════════════════════════════════════
   25. STYLEGUIDE HELPERS (/sysadmin/styleguide only)
   ══════════════════════════════════════════════════════════════════════ */

.nt-sg-section { scroll-margin-top: 5rem; margin-bottom: var(--nt-space-16); }

.nt-sg-section-title {
  font-family: var(--nt-font-display);
  font-size: var(--nt-text-xl);
  font-weight: 600;
  letter-spacing: -0.015em;
  padding-bottom: var(--nt-space-2);
  border-bottom: 1px solid var(--nt-border);
  margin-bottom: var(--nt-space-5);
}

.nt-sg-swatch {
  border: 1px solid var(--nt-border-subtle);
  border-radius: var(--nt-radius);
  overflow: hidden;
  background: var(--nt-surface);
}

.nt-sg-swatch-chip { height: 3.25rem; }

.nt-sg-swatch-meta {
  padding: 0.4rem 0.55rem;
  border-top: 1px solid var(--nt-border-subtle);
  font-family: var(--nt-font-mono);
  font-size: 0.66rem;
  color: var(--nt-text-secondary);
  word-break: break-all;
}

.nt-sg-spec {
  margin-top: var(--nt-space-3);
  padding: var(--nt-space-3) var(--nt-space-4);
  background: var(--nt-surface-sunken);
  border: 1px solid var(--nt-border-subtle);
  border-radius: var(--nt-radius-sm);
  font-family: var(--nt-font-mono);
  font-size: 0.7rem;
  line-height: 1.7;
  color: var(--nt-text-secondary);
  white-space: pre-wrap;
  overflow-x: auto;
}

.nt-sg-demo {
  padding: var(--nt-space-5);
  border: 1px dashed var(--nt-border);
  border-radius: var(--nt-radius);
  background: var(--nt-bg-accent);
}

.nt-sg-toc {
  position: sticky;
  top: 4.5rem;
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

/* ══════════════════════════════════════════════════════════════════════
   26. STAFF SURFACE
   Components that exist only under /sysadmin — the filing checklist, the
   queue rows, the impersonation bar. They reuse the same tokens as the
   customer surface; only the density changes. Staff read these screens
   forty times a day, so they are tighter than anything a customer sees.
   ══════════════════════════════════════════════════════════════════════ */

/* -- Impersonation ---------------------------------------------------- */

/* Fixed, bordeaux, undismissable. Bottom-right so it never covers a form's
   submit row, and above every overlay so a modal cannot hide it. */
.nt-impersonation-bar {
  position: fixed;
  right: var(--nt-space-4);
  bottom: var(--nt-space-4);
  z-index: 9999;
  display: flex;
  align-items: center;
  gap: var(--nt-space-3);
  padding: var(--nt-space-2) var(--nt-space-3);
  border-radius: var(--nt-radius);
  background: var(--nt-seal);
  color: var(--nt-on-seal, #fff);
  box-shadow: var(--nt-shadow-3);
  font-size: var(--nt-text-sm);
  max-width: min(30rem, calc(100vw - 2rem));
}

.nt-impersonation-text { line-height: 1.3; }

.nt-impersonation-stop {
  flex: none;
  padding: 0.15rem 0.55rem;
  border-radius: var(--nt-radius-xs);
  border: 1px solid rgba(255, 255, 255, 0.35);
  background: rgba(255, 255, 255, 0.18);
  color: inherit;
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  cursor: pointer;
  transition: background-color var(--nt-duration-fast) var(--nt-ease);
}

.nt-impersonation-stop:hover { background: rgba(255, 255, 255, 0.32); }

/* -- Staff toolbar (filters + search above a list) --------------------- */

.nt-toolbar {
  display: flex;
  align-items: flex-end;
  gap: var(--nt-space-3);
  flex-wrap: wrap;
  margin-bottom: var(--nt-space-4);
}

.nt-filter-row { display: flex; gap: 0.25rem; flex-wrap: wrap; }

.nt-filter {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.7rem;
  border-radius: var(--nt-radius-full);
  border: 1px solid var(--nt-border-subtle);
  background: var(--nt-surface);
  color: var(--nt-text-secondary);
  font-size: var(--nt-text-sm);
  white-space: nowrap;
  transition: border-color var(--nt-duration-fast) var(--nt-ease),
              color var(--nt-duration-fast) var(--nt-ease);
}

.nt-filter:hover { border-color: var(--nt-border-strong); color: var(--nt-text); }

.nt-filter[aria-current="true"] {
  background: var(--nt-seal);
  border-color: var(--nt-seal);
  color: var(--nt-on-seal, #fff);
}

.nt-filter-count {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  opacity: 0.75;
}

/* An input sized to sit inside a table row without changing its height. */
.nt-input-sm {
  padding: 0.3rem 0.5rem;
  font-size: var(--nt-text-sm);
}

/* -- Queue rows -------------------------------------------------------- */

/* The frist column is the reason this table exists; it gets a colour rail so
   the eye lands on the most urgent row before reading a single word. */
.nt-queue-rail {
  display: inline-block;
  width: 3px;
  align-self: stretch;
  border-radius: 2px;
  background: var(--nt-border);
}

.nt-queue-rail-danger { background: var(--nt-danger); }
.nt-queue-rail-warn   { background: var(--nt-warn); }
.nt-queue-rail-info   { background: var(--nt-info); }
.nt-queue-rail-ok     { background: var(--nt-ok); }

.nt-queue-frist {
  display: flex;
  align-items: center;
  gap: var(--nt-space-3);
}

.nt-queue-days {
  font-family: var(--nt-font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--nt-text-sm);
  white-space: nowrap;
}

.nt-queue-days-danger { color: var(--nt-danger-text); font-weight: 600; }
.nt-queue-days-warn   { color: var(--nt-warn-text); }

/* -- Checklist (the Virk copy surface) --------------------------------- */

.nt-checklist-section + .nt-checklist-section { margin-top: var(--nt-space-6); }

.nt-checklist-field {
  display: grid;
  grid-template-columns: minmax(9rem, 14rem) 1fr auto;
  gap: var(--nt-space-3);
  align-items: start;
  padding: var(--nt-space-3) 0;
  border-bottom: 1px solid var(--nt-border-subtle);
}

.nt-checklist-field:last-child { border-bottom: 0; }

@media (max-width: 40rem) {
  .nt-checklist-field { grid-template-columns: 1fr auto; }
  .nt-checklist-label { grid-column: 1 / -1; }
}

.nt-checklist-label {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--nt-text-tertiary);
  padding-top: 0.15rem;
}

/* Values are pasted into Virk verbatim, so they must preserve their own line
   breaks (a ledelse field is several people) and never be re-wrapped by us. */
.nt-checklist-value {
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--nt-text);
}

.nt-checklist-value-mono {
  font-family: var(--nt-font-mono);
  font-variant-numeric: tabular-nums;
}

.nt-checklist-missing {
  color: var(--nt-danger-text);
  font-style: italic;
}

.nt-copy-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0.5rem;
  border-radius: var(--nt-radius-xs);
  border: 1px solid var(--nt-border-subtle);
  background: var(--nt-surface);
  color: var(--nt-text-tertiary);
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  cursor: pointer;
  transition: color var(--nt-duration-fast) var(--nt-ease),
              border-color var(--nt-duration-fast) var(--nt-ease);
}

.nt-copy-btn:hover { color: var(--nt-text); border-color: var(--nt-border-strong); }
.nt-copy-btn[data-copied="true"] { color: var(--nt-ok-text); border-color: var(--nt-ok-border); }

/* -- The CPR block ----------------------------------------------------- */

/* Deliberately loud. This is the one place in Notarium where CPR is on
   screen; the operator must know it is temporary before they read a digit. */
.nt-cpr-block {
  border: 1px solid var(--nt-danger-border);
  background: var(--nt-danger-soft);
  border-radius: var(--nt-radius);
  padding: var(--nt-space-4) var(--nt-space-5);
}

.nt-cpr-notice {
  display: flex;
  gap: var(--nt-space-2);
  align-items: flex-start;
  color: var(--nt-danger-text);
  font-size: var(--nt-text-sm);
  margin-bottom: var(--nt-space-3);
}

.nt-cpr-value {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-md);
  letter-spacing: 0.03em;
}

/* -- Definition lists (detail pages) ----------------------------------- */

.nt-dl {
  display: grid;
  grid-template-columns: minmax(8rem, 12rem) 1fr;
  gap: var(--nt-space-2) var(--nt-space-4);
  font-size: var(--nt-text-sm);
}

.nt-dl dt {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--nt-text-tertiary);
}

.nt-dl dd { color: var(--nt-text); margin: 0; word-break: break-word; }

/* -- Code / payload rendering ------------------------------------------ */

.nt-code {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  line-height: 1.55;
  white-space: pre;
  overflow-x: auto;
  padding: var(--nt-space-4);
  border-radius: var(--nt-radius-sm);
  background: var(--nt-surface-sunken);
  color: var(--nt-text-secondary);
  max-height: 32rem;
}

.nt-hash {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  color: var(--nt-text-tertiary);
  word-break: break-all;
}

/* ══════════════════════════════════════════════════════════════════════
   26b. THE WIZARD — layout, controls, the decide moment
   Everything below is either a control the pack's field vocabulary needs
   (money_cents, percent, boolean, table, stakeholder_list, document_upload)
   or one of the three moments the wizard is judged on: the hard stop, the
   jurist hand-off, and the beslutning.
   ══════════════════════════════════════════════════════════════════════ */

:root {
  /* Document typography now lives with the document: --doc-lead/-gap/
     -clause-indent are declared in document.css's token host, beside the
     .doc-* rules that read them. Nothing here reads the old --nt-doc-*
     proportion tokens any more. */

  /* Two panes. The paper column is allowed to be a little wider than the
     question column: a document that has to wrap every eight words does not
     read like a document. */
  --nt-wizard-gap: 1.5rem;
  /* Clears the sticky .nt-topbar (0.7rem padding either side of a ~1.6rem
     row) plus a breath of air, so the pinned sheet does not slide under it. */
  --nt-wizard-sticky: 4.5rem;
}

/* ── the two panes ───────────────────────────────────────────────────── */

/* The wizard is the one page in the workspace that needs the whole window:
   two panes, and one of them is a sheet of A4. The reading-width column that
   is right for a settings form starves it, so the page container widens when
   a wizard is on it — no layout template has to know the wizard exists.

   BOTH containers, because the workspace does not use `.nt-page`: it wraps
   its content in `.nt-app-column` (navbar.css §1). For as long as only
   `.nt-page` was listed here the widening was dead on the one screen the
   whole rule exists for. */
.nt-app-column:has(.nt-wizard),
.nt-page:has(.nt-wizard) { max-width: 92rem; }

/* THE CONTAINER EXISTS ONLY WHERE IT IS QUERIED.

   `container-type: inline-size` computes to `contain: layout style
   inline-size`, and `contain: layout` makes an element the containing block
   for every `position: fixed` descendant. A shell that is a container at every
   width therefore anchors anything fixed inside it to a box that is thousands
   of pixels tall on a phone — which is exactly the surface the mobile sheet
   needs to be fixed to the VIEWPORT.

   65rem is where the container first reaches the 62rem the two-pane rule below
   asks for: `.nt-app-column` is `min(92rem, 100vw − 2 × var(--nt-space-6))`,
   so 62rem of container needs 62 + 3 = 65rem of viewport. Below that nothing
   queries the container and nothing needs it to exist. */
@media (min-width: 65rem) {
  .nt-wizard-shell { container-type: inline-size; }
}

.nt-wizard {
  display: grid;
  gap: var(--nt-wizard-gap);
  align-items: start;
}

/* The two wrappers the mobile sheet is built out of are INERT here: the panel
   stays a direct grid item and the desktop layout does not know they exist.
   They are in the markup at every width so the question never has to move in
   the DOM between breakpoints — moving it would tear down its form, and with
   it whatever the customer had typed. */
.nt-wz-sheet,
.nt-wz-sheet-scroll { display: contents; }

/* A container query, not a media query: what decides whether two panes fit is
   the width left inside the workspace column after the sidebar and the page
   gutters have taken their share — a different number from the viewport's. */
@container (min-width: 62rem) {
  .nt-wizard { grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr); }

  /* The rail spans the whole width above both panes — which is what it always
     looked like, back when it was rendered outside the grid entirely. It is
     inside now so that the ≥80rem rule below can make it a real third column;
     there is no way to move a sibling into a grid. */
  #wizard-progress { grid-column: 1 / -1; }

  /* The paper stays in view while the question column scrolls — and, because
     this container lives OUTSIDE the turbo-frame that is replaced after every
     answer, its scroll position survives the swap for free. */
  .nt-wizard-paper {
    position: sticky;
    top: var(--nt-wizard-sticky);
    /* dvh, not vh: on a phone with a retracting URL bar `vh` is the LARGE
       viewport, so the bottom of the sheet sits under the browser chrome.

       And the sticky offset is subtracted ONCE. `top` has already moved the
       sheet down by it; taking it off the height a second time left a whole
       navbar of empty desk under the paper. What comes off the second time is
       a breath of air, so the sheet does not end flush with the window. */
    max-height: calc(100dvh - var(--nt-wizard-sticky) - var(--nt-space-6));
    overflow-y: auto;
    overscroll-behavior: contain;
    border-radius: var(--nt-radius-lg);
  }
}

/* THREE COLUMNS, on a screen that has the width for them.

   At 80rem of workspace column the horizontal step strip stops being the right
   shape: eleven chips scrolled sideways above the question is a compromise for
   a narrow page, and a wide one can simply show all eleven as a list beside
   it. The rail becomes a real column — sticky, so it stays beside the question
   through a long screen — and the chips flip to a vertical stack in wizard.css
   off the same query.

   14rem is the width at which `rail_label`'s 30-character truncation fits on
   one line at --nt-text-sm; wider and the column starts eating the paper. */
@container (min-width: 80rem) {
  .nt-wizard { grid-template-columns: 14rem minmax(0, 1fr) minmax(0, 1.06fr); }

  #wizard-progress {
    grid-column: 1;
    grid-row: 1 / -1;
    align-self: start;
    position: sticky;
    top: var(--nt-wizard-sticky);
    max-height: calc(100dvh - var(--nt-wizard-sticky) - var(--nt-space-6));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

.nt-wizard-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--nt-space-3);
}

.nt-wizard-actions-right {
  display: flex;
  align-items: center;
  gap: var(--nt-space-3);
}

/* DOM order and reading order deliberately disagree here.

   "Næste" is rendered FIRST inside the form so that it is the form's default
   submit button — press Enter in any field and you move forward, which is
   what a keyboard user means every time. Visually it still belongs on the
   right, with "Tilbage" on the left, so the two groups are reordered back.

   The auto margin does the same job as `justify-content: space-between` when
   both groups are present, and the right job when only one is: on the first
   step there is no "Tilbage", and without it the Næste group would sit alone
   at the left edge. */
.nt-wizard-actions > .nt-wizard-actions-left { order: 1; }

.nt-wizard-actions > .nt-wizard-actions-right {
  order: 2;
  margin-inline-start: auto;
}

/* ── the question ────────────────────────────────────────────────────── */

.nt-question-help {
  color: var(--nt-text-secondary);
  margin-bottom: var(--nt-space-5);
  max-width: 48ch;
}

/* The line that explains why a screen the customer never asked for is in
   front of them: "det her er en generalforsamling, og sådan er det". */
.nt-reassurance {
  margin-bottom: var(--nt-space-4);
  padding: var(--nt-space-2) var(--nt-space-3);
  border-left: 2px solid var(--nt-seal);
  border-radius: 0 var(--nt-radius-xs) var(--nt-radius-xs) 0;
  background: var(--nt-seal-soft);
  color: var(--nt-text-secondary);
  font-size: var(--nt-text-sm);
}

.nt-legal-note {
  margin-top: var(--nt-space-6);
  padding-top: var(--nt-space-4);
  border-top: 1px solid var(--nt-border-subtle);
}

.nt-legal-note-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nt-space-2);
}

/* ── fields ──────────────────────────────────────────────────────────── */

.nt-field + .nt-field { margin-top: var(--nt-space-5); }

/* A field with its own rhythm removed, for when the LAYOUT owns the spacing:
   a field sitting in a grid or flex row beside a button, where the stacked
   form margin is exactly wrong.
 *
 * This exists as a real modifier because a utility CANNOT do it. This file is
 * unlayered and Tailwind's output lives in @layer, so `.nt-field mb-0` loses
 * to `.nt-field` no matter the specificity or the source order (see the
 * cascade note at the top of this file). Two screens shipped with a dead
 * `mb-0` on exactly this pattern — the invite row on Team og brugere and the
 * inbound-emails filter — where the field's margin box kept the input 17.6px
 * clear of the row's bottom edge while the button beside it sat flush, under
 * `items-end`. Reach for this, never for a margin utility.
 *
 * Both selectors are needed: the adjacent-sibling rule above is (0,2,0), so a
 * bare `.nt-field-flush` at (0,1,0) would lose the margin-top half. */
.nt-field-flush,
.nt-field-flush + .nt-field-flush { margin: 0; }

.nt-fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }

.nt-optional { font-weight: 400; color: var(--nt-text-tertiary); }

.nt-hint-quiet { color: var(--nt-text-disabled); }

/* The "foreslået" marker. Small, quiet, and the whole reason a screen full of
   pre-filled answers reads as a confirmation rather than as someone else's
   form. */
.nt-suggested {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  margin-left: 0.4rem;
  padding: 0.05rem 0.4rem 0.1rem;
  border-radius: var(--nt-radius-full);
  background: var(--nt-ok-soft);
  color: var(--nt-ok-text);
  border: 1px solid var(--nt-ok-border);
  font-family: var(--nt-font-body);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  vertical-align: 0.06em;
  white-space: nowrap;
}

.nt-suggested-icon { flex: none; }

/* ── enum: the radio cards ───────────────────────────────────────────── */

.nt-choice-set {
  display: flex;
  flex-direction: column;
  gap: var(--nt-space-2);
  margin-top: var(--nt-space-2);
}

.nt-choice { align-items: flex-start; }
.nt-choice input[type="radio"] { margin-top: 0.22rem; flex: none; accent-color: var(--nt-seal); }
.nt-choice-body { min-width: 0; display: block; }

.nt-choice-title { display: block; font-weight: 600; line-height: 1.35; }

.nt-choice-help {
  display: block;
  margin-top: 0.2rem;
  font-size: var(--nt-text-sm);
  color: var(--nt-text-secondary);
  line-height: 1.45;
}

/* ── boolean: Ja / Nej ───────────────────────────────────────────────── */

.nt-segmented {
  display: inline-flex;
  margin-top: var(--nt-space-2);
  padding: 3px;
  gap: 3px;
  border: 1px solid var(--nt-border);
  border-radius: var(--nt-radius);
  background: var(--nt-surface-sunken);
}

.nt-segment { position: relative; display: block; cursor: pointer; }

/* The radio is real and focusable — only its painted box is hidden, so the
   control is a radiogroup to a screen reader and a segmented control to
   everyone else. */
.nt-segment input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.nt-segment-face {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  min-width: 5.5rem;
  padding: 0.44rem 0.95rem;
  border-radius: calc(var(--nt-radius) - 3px);
  color: var(--nt-text-secondary);
  font-size: var(--nt-text-base);
  font-weight: 600;
  transition:
    background-color var(--nt-duration-fast) var(--nt-ease),
    color var(--nt-duration-fast) var(--nt-ease);
}

.nt-segment:hover .nt-segment-face { color: var(--nt-text); }

.nt-segment input:checked + .nt-segment-face {
  background: var(--nt-surface);
  color: var(--nt-text);
  box-shadow: var(--nt-shadow-1);
}

.nt-segment input:focus-visible + .nt-segment-face { box-shadow: var(--nt-shadow-focus); }

.nt-segment .nt-suggested { margin-left: 0.1rem; }

/* ── affixed inputs: kr., % ──────────────────────────────────────────── */

.nt-affix-field { position: relative; display: block; max-width: 20rem; }
.nt-affix-field-narrow { max-width: 11rem; }
.nt-affix-field .nt-input { padding-right: 3rem; }

.nt-affix {
  position: absolute;
  top: 50%;
  right: 0.85rem;
  transform: translateY(-50%);
  font-size: var(--nt-text-sm);
  color: var(--nt-text-tertiary);
  pointer-events: none;
}

/* Amounts are read down a column, not along a sentence: tabular figures and
   right alignment are what let a customer check a fordeling at a glance. */
.nt-input-amount {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.nt-input-date { max-width: 12rem; }
.nt-input-person { max-width: 26rem; }
.nt-textarea-grow { min-height: 4.5rem; resize: none; }

/* ── date, echoed in Danish ──────────────────────────────────────────── */

.nt-date-field {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nt-space-3);
}

.nt-date-echo {
  font-family: var(--nt-font-serif);
  font-size: var(--nt-text-md);
  color: var(--nt-text-secondary);
}

/* ── repeatable rows (stakeholder_list) ──────────────────────────────── */

.nt-repeat {
  display: flex;
  flex-direction: column;
  gap: var(--nt-space-2);
  margin-top: var(--nt-space-2);
}

.nt-repeat-row { display: flex; align-items: center; gap: var(--nt-space-2); }
.nt-repeat-row .nt-input { flex: 1 1 auto; }
.nt-repeat-foot { margin-top: var(--nt-space-2); }

.nt-icon-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.9rem;
  height: 1.9rem;
  border: 1px solid transparent;
  border-radius: var(--nt-radius-sm);
  background: transparent;
  color: var(--nt-text-tertiary);
  cursor: pointer;
  transition:
    color var(--nt-duration-fast) var(--nt-ease),
    background-color var(--nt-duration-fast) var(--nt-ease);
}

.nt-icon-btn:hover { background: var(--nt-surface-sunken); color: var(--nt-danger-text); }
.nt-icon-btn:focus-visible { outline: none; box-shadow: var(--nt-shadow-focus); }

/* 30px is a fine mouse target and a bad thumb target — and this is the button
   that DELETES a row of a stakeholder list. On a coarse pointer it grows to
   the 44px floor through the MIN sizes, so the icon inside keeps its size and
   the button keeps its quiet weight; growing the glyph instead would make a
   destructive ghost button the loudest thing in the row. */
@media (pointer: coarse) {
  .nt-icon-btn {
    min-width: 2.75rem;
    min-height: 2.75rem;
  }
}

/* ── table: the editable grid ────────────────────────────────────────── */

.nt-grid-wrap { margin-top: var(--nt-space-2); }

.nt-grid-scroll {
  overflow-x: auto;
  border: 1px solid var(--nt-border-subtle);
  border-radius: var(--nt-radius);
  background: var(--nt-surface);
}

.nt-grid { width: 100%; border-collapse: collapse; font-size: var(--nt-text-sm); }

.nt-grid th {
  text-align: left;
  padding: 0.5rem 0.6rem;
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--nt-text-tertiary);
  background: var(--nt-surface-raised);
  border-bottom: 1px solid var(--nt-border-subtle);
  white-space: nowrap;
}

.nt-grid td {
  padding: 0.25rem 0.35rem;
  border-bottom: 1px solid var(--nt-border-subtle);
  vertical-align: middle;
}

.nt-grid tbody tr:last-child td { border-bottom: 0; }
.nt-grid .nt-grid-numeric { text-align: right; }
.nt-grid th.nt-grid-actions,
.nt-grid td.nt-grid-actions { width: 2.4rem; text-align: center; padding: 0.25rem; }

/* Cell inputs are borderless until touched: a grid where every cell is drawn
   as a box is a spreadsheet, and a fordeling should read as a table you may
   correct — not as a data-entry form. */
.nt-grid-input {
  width: 100%;
  min-width: 5rem;
  padding: 0.35rem 0.45rem;
  border: 1px solid transparent;
  border-radius: var(--nt-radius-xs);
  background: transparent;
  color: var(--nt-text);
  font-family: var(--nt-font-body);
  font-size: var(--nt-text-sm);
  transition:
    border-color var(--nt-duration-fast) var(--nt-ease),
    background-color var(--nt-duration-fast) var(--nt-ease);
}

/* A name needs room; an amount does not. Names truncated to "Sønderby Inves"
   in a fordeling the customer is about to sign is not acceptable, so the text
   cells claim width and the wrapper scrolls sideways if the sum overflows. */
.nt-grid-input:not(.nt-input-amount) { min-width: 9rem; }

.nt-grid-input:hover { border-color: var(--nt-border-subtle); }

.nt-grid-input:focus {
  outline: none;
  border-color: var(--nt-focus);
  background: var(--nt-surface);
  box-shadow: var(--nt-shadow-focus);
}

.nt-grid-select { appearance: auto; }

.nt-grid-affix { position: relative; display: flex; align-items: center; }
.nt-grid-affix .nt-grid-input { padding-right: 2.1rem; }

.nt-grid-affix-unit {
  position: absolute;
  right: 0.5rem;
  font-size: var(--nt-text-xs);
  color: var(--nt-text-disabled);
  pointer-events: none;
}

.nt-grid tfoot td,
.nt-grid tfoot th {
  padding: 0.5rem 0.6rem;
  border-top: 1.5px solid var(--nt-border);
  background: var(--nt-surface-raised);
  font-weight: 600;
  color: var(--nt-text);
}

.nt-grid tfoot th {
  text-transform: none;
  font-family: var(--nt-font-body);
  letter-spacing: 0;
  font-size: var(--nt-text-sm);
}

.nt-grid-total { font-variant-numeric: tabular-nums; white-space: nowrap; }

.nt-grid-empty {
  padding: var(--nt-space-4);
  font-size: var(--nt-text-sm);
  color: var(--nt-text-tertiary);
}

.nt-grid-foot { margin-top: var(--nt-space-2); }

/* ── document_upload: the honest stub ────────────────────────────────── */

.nt-dropzone {
  display: flex;
  align-items: flex-start;
  gap: var(--nt-space-3);
  margin-top: var(--nt-space-2);
  padding: var(--nt-space-4);
  border: 1px dashed var(--nt-border);
  border-radius: var(--nt-radius);
  background: var(--nt-surface-sunken);
}

.nt-dropzone-filled {
  border-style: solid;
  border-color: var(--nt-ok-border);
  background: var(--nt-ok-soft);
}

.nt-dropzone-icon { flex: none; margin-top: 0.1rem; color: var(--nt-text-tertiary); }
.nt-dropzone-filled .nt-dropzone-icon { color: var(--nt-ok); }
.nt-dropzone-title { font-weight: 600; font-size: var(--nt-text-base); }
.nt-dropzone-body { font-size: var(--nt-text-sm); color: var(--nt-text-secondary); margin-top: 0.1rem; }
.nt-dropzone-filled .nt-dropzone-body { color: var(--nt-ok-text); }

/* "Dokumentet eftersendes" — a deliberate answer, not a default. Rendered as
   a real checkbox because that is exactly what it is: one thing the customer
   is asserting about a document that is not here yet. */
.nt-defer {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-top: var(--nt-space-3);
  font-size: var(--nt-text-sm);
  color: var(--nt-text-secondary);
  cursor: pointer;
}

.nt-defer input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  flex: none;
  accent-color: var(--nt-seal);
  cursor: pointer;
}

.nt-defer:hover { color: var(--nt-text); }

/* "Dokumentet eftersendes". A deliberate answer, so it looks like a control
   the customer operates — not like fine print under a disabled dropzone. */
.nt-defer {
  display: flex;
  align-items: center;
  gap: var(--nt-space-2);
  margin-top: var(--nt-space-2);
  padding: var(--nt-space-2) var(--nt-space-3);
  border: 1px solid var(--nt-border-subtle);
  border-radius: var(--nt-radius-sm);
  font-size: var(--nt-text-sm);
  color: var(--nt-text-secondary);
  cursor: pointer;
  transition: border-color var(--nt-duration-fast) var(--nt-ease),
              background var(--nt-duration-fast) var(--nt-ease);
}

.nt-defer:hover { border-color: var(--nt-border); background: var(--nt-surface-sunken); }
.nt-defer:has(input:checked) { border-color: var(--nt-seal); color: var(--nt-text); }
.nt-defer input { accent-color: var(--nt-seal); }

/* ── errors and the hard stop ────────────────────────────────────────── */

.nt-error-region { margin-top: 0.4rem; }
.nt-error-stop { font-weight: 600; }

.nt-fieldset-invalid .nt-choice,
.nt-fieldset-invalid .nt-segmented { border-color: var(--nt-danger-border); }

/* § 180 and its siblings. A red border alone says "typo"; this says "we will
   not write that down", which is a different sentence. */
.nt-stop {
  display: flex;
  align-items: flex-start;
  gap: var(--nt-space-3);
  padding: var(--nt-space-4) var(--nt-space-5);
  border: 1px solid var(--nt-danger-border);
  border-left: 3px solid var(--nt-danger);
  border-radius: var(--nt-radius);
  background: var(--nt-danger-soft);
}

.nt-stop-icon { flex: none; margin-top: 0.1rem; color: var(--nt-danger); }
.nt-stop-title { font-weight: 700; color: var(--nt-danger-text); }
.nt-stop-body { margin-top: 0.15rem; font-size: var(--nt-text-sm); color: var(--nt-text-secondary); }

/* Næste is held back, never disabled: the server is what refuses, and a dead
   control the customer cannot press is a control that cannot explain itself. */
.nt-btn-held {
  background: var(--nt-neutral-tint);
  color: var(--nt-text-tertiary);
  box-shadow: none;
}

.nt-btn-held:hover { background: var(--nt-neutral-tint); color: var(--nt-text-secondary); }

/* ── the jurist hand-off ─────────────────────────────────────────────── */

.nt-handoff {
  padding: var(--nt-space-5) var(--nt-space-6);
  border: 1px solid var(--nt-seal-border);
  border-radius: var(--nt-radius-lg);
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--nt-seal) 7%, var(--nt-surface)),
      var(--nt-surface));
  box-shadow: var(--nt-shadow-1);
}

.nt-handoff[data-state="arriving"] {
  animation: nt-handoff-in var(--nt-duration-slow) var(--nt-ease) both;
}

@keyframes nt-handoff-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

.nt-handoff-eyebrow {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--nt-seal-text);
}

.nt-handoff-title {
  margin-top: 0.35rem;
  font-family: var(--nt-font-display);
  font-size: var(--nt-text-lg);
  font-weight: 600;
  color: var(--nt-text);
}

.nt-handoff-message {
  margin-top: var(--nt-space-3);
  color: var(--nt-text);
  line-height: 1.6;
  max-width: 60ch;
}

.nt-handoff-note {
  margin-top: var(--nt-space-3);
  font-size: var(--nt-text-sm);
  color: var(--nt-text-secondary);
}

.nt-handoff-included {
  margin-top: var(--nt-space-3);
  padding-top: var(--nt-space-3);
  border-top: 1px solid var(--nt-seal-border);
  font-size: var(--nt-text-sm);
  font-weight: 600;
  color: var(--nt-seal-text);
}

/* ── autosave ────────────────────────────────────────────────────────── */

.nt-autosave {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 1.2rem;
  font-size: var(--nt-text-xs);
  color: var(--nt-text-tertiary);
  opacity: 0;
  transition: opacity var(--nt-duration) var(--nt-ease);
}

.nt-autosave[data-state="saving"],
.nt-autosave[data-state="saved"],
.nt-autosave[data-state="failed"] { opacity: 1; }

.nt-autosave-mark {
  width: 0.65rem;
  height: 0.65rem;
  border-radius: var(--nt-radius-full);
  flex: none;
}

.nt-autosave[data-state="saving"] .nt-autosave-mark {
  border: 1.5px solid var(--nt-border-strong);
  border-top-color: var(--nt-seal);
  animation: nt-spin 700ms linear infinite;
}

.nt-autosave[data-state="saved"] { color: var(--nt-ok-text); }

.nt-autosave[data-state="saved"] .nt-autosave-mark {
  background: var(--nt-ok);
  box-shadow: 0 0 0 2px var(--nt-ok-soft);
}

.nt-autosave[data-state="failed"] { color: var(--nt-danger-text); font-weight: 600; }
.nt-autosave[data-state="failed"] .nt-autosave-mark { background: var(--nt-danger); }

@keyframes nt-spin { to { transform: rotate(360deg); } }

/* ── the decide moment ───────────────────────────────────────────────── */

.nt-commit { display: block; }

.nt-commit-panel {
  padding: var(--nt-space-6);
  border: 1px solid var(--nt-seal-border);
  border-radius: var(--nt-radius-lg);
  background: var(--nt-surface);
  box-shadow: var(--nt-shadow-2);
}

.nt-commit-panel[data-state="open"] {
  animation: nt-commit-in var(--nt-duration) var(--nt-ease) both;
}

.nt-commit-panel:focus-visible { outline: none; box-shadow: var(--nt-shadow-focus), var(--nt-shadow-2); }

@keyframes nt-commit-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

.nt-commit-eyebrow {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--nt-seal-text);
}

.nt-commit-title {
  margin-top: 0.3rem;
  font-family: var(--nt-font-display);
  font-size: var(--nt-text-xl);
  font-weight: 600;
  line-height: 1.2;
}

.nt-commit-body { margin-top: var(--nt-space-3); color: var(--nt-text-secondary); max-width: 56ch; }

.nt-commit-list {
  margin-top: var(--nt-space-4);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: var(--nt-text-sm);
}

.nt-commit-list li { display: flex; align-items: center; gap: 0.5rem; color: var(--nt-text); }
.nt-commit-list svg { color: var(--nt-text-tertiary); flex: none; }

.nt-commit-actions {
  margin-top: var(--nt-space-5);
  padding-top: var(--nt-space-4);
  border-top: 1px solid var(--nt-border-subtle);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nt-space-3);
}

/* NOTE: the old wizard stepper lived here — .nt-progress-card, -head,
   .nt-progress, -fill and .nt-progress-note. It stacked a text counter, a
   percentage, a bar and a rail in one card: four indicators of one fact.
   Replaced by the single component in wizard.css. Nothing referenced any
   of these afterwards — checked against views, JS and helpers.

   The note used to claim `.nt-rail*` survived that sweep because the
   company-event state rail picked it up. It did not: the classes were swept
   with the rest and three screens went on rendering an unstyled <ol> for
   months. The component below is the rail those screens were always asking
   for. */

/* ══════════════════════════════════════════════════════════════════════
   THE STATE RAIL

   Six statuses of a legal event, and the three steps of onboarding, drawn as
   one component: what is behind us, where we are, what is still ahead.

   It borrows the wizard stepper's visual language on purpose — opaque pills
   on a spine, green for settled, the seal for "here" — but depends on none of
   it. `.nt-wz-chip` lives in wizard.css and answers to the wizard's markup;
   sharing a class between the two would mean either sheet could break the
   other's screen, and the two components move for different reasons.

   MARKUP — two shapes, both supported, because the two callers differ:

     <ol class="nt-rail" aria-label="…">                    (company_events/show)
       <li class="nt-rail-step nt-rail-done">
         <span class="nt-rail-tick">✓</span> Kladde
       </li>
       <li class="nt-rail-step nt-rail-here" aria-current="step">Underskrevet</li>
       <li class="nt-rail-step nt-rail-todo">Anmeldt</li>
     </ol>

     <ol class="nt-rail" aria-label="…">                    (onboarding/*)
       <li>
         <span class="nt-rail-step nt-rail-done">
           <svg class="nt-rail-tick">…</svg><span>Selskab</span>
         </span>
       </li>
     </ol>

   So: `.nt-rail-step` is EITHER the <li> or a <span> inside it, and
   `.nt-rail-tick` is EITHER a wrapper around the check or the check itself.
   Every rule below is written to hold both ways — do not "simplify" one of
   the two shapes out of these selectors without changing both callers.

   `aria-current="step"` carries "here" for a screen reader and is styled the
   same as `.nt-rail-here`, so "hvor er vi" is answerable without seeing the
   fill — colour is never the only signal.
   ══════════════════════════════════════════════════════════════════════ */

.nt-rail {
  /* One number for both the space between the pills and the length of the
     spine segment that fills it. They are the same distance. */
  --nt-rail-gap: var(--nt-space-3);

  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--nt-space-2) var(--nt-rail-gap);
  list-style: none;
  margin: 0;
  padding: 0;
}

.nt-rail > li {
  position: relative;
  display: flex;
  align-items: center;
  min-width: 0;
}

/* The spine, one segment at a time, drawn INTO the gap from out of flow.
   Out of flow because in the event-page shape the <li> *is* the pill, so a
   ::after in flow would land inside its border. It also means the segment
   trailing the last pill on a wrapped row costs no layout — it reads as
   "continues below", which is right — and `.nt-app-main { overflow-x: clip }`
   keeps it from ever touching the page edge. */
.nt-rail > li:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 100%;
  top: 50%;
  width: var(--nt-rail-gap);
  height: 2px;
  transform: translateY(-50%);
  border-radius: var(--nt-radius-full);
  background: var(--nt-border-subtle);
}

/* Behind a settled step the spine is settled too: the filled run IS the
   progress bar, the same idea as `.nt-wz-spine-fill` without the JavaScript. */
.nt-rail > li.nt-rail-done::after,
.nt-rail > li:has(.nt-rail-done)::after { background: var(--nt-ok); }

.nt-rail-step {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
  padding: 0.22rem 0.7rem;
  border: 1px solid var(--nt-border-subtle);
  border-radius: var(--nt-radius-full);
  /* Opaque, so the spine reads as a line CONNECTING the steps rather than one
     drawn through them. */
  background: var(--nt-surface);
  color: var(--nt-text-tertiary);
  font-size: var(--nt-text-xs);
  line-height: 1.35;
  white-space: nowrap;
}

/* Left padding tightens when the pill carries a tick, so the disc sits inside
   the pill instead of beside a gap in it. */
.nt-rail-step:has(.nt-rail-tick) { padding-left: 0.28rem; }

.nt-rail-step > svg { flex: none; }

/* ── done: settled, and green means "i orden" everywhere in this product ── */
.nt-rail-done { color: var(--nt-text-secondary); }

/* `content-box` is load-bearing: this rule has to produce the same disc
   whether it is a WRAPPER around an 11px check or the 11px check itself. The
   drawing keeps its size, the padding makes the disc around it. */
.nt-rail-tick {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: content-box;
  width: 0.7rem;
  height: 0.7rem;
  padding: 0.2rem;
  border-radius: var(--nt-radius-full);
  background: var(--nt-ok);
  color: var(--nt-on-ok);
}

/* ── here: the one saturated moment on the rail ─────────────────────────── */
.nt-rail-here,
.nt-rail-step[aria-current="step"] {
  background: var(--nt-seal);
  border-color: var(--nt-seal);
  color: var(--nt-on-seal);
  font-weight: 600;
  box-shadow: var(--nt-shadow-1);
}

/* ── todo: not yet — and not refused. Dashed says "open, but not solid ground
      yet" without borrowing the disabled grey, which would read as "you
      cannot get there", and every one of these steps is reachable. ─────── */
.nt-rail-todo {
  border-style: dashed;
  color: var(--nt-text-tertiary);
}

/* ── review ──────────────────────────────────────────────────────────── */

.nt-review { display: flex; flex-direction: column; gap: var(--nt-space-5); }

.nt-review-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--nt-space-3);
  margin-bottom: 0.35rem;
}

.nt-review-card {
  border: 1px solid var(--nt-border-subtle);
  border-radius: var(--nt-radius);
  background: var(--nt-surface-raised);
  padding: var(--nt-space-3) var(--nt-space-4);
}

.nt-review-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--nt-space-3);
  padding: 0.3rem 0;
}

.nt-review-row + .nt-review-row { border-top: 1px solid var(--nt-border-subtle); }
.nt-review-term { font-size: var(--nt-text-sm); color: var(--nt-text-tertiary); }

.nt-review-value {
  margin: 0;
  font-size: var(--nt-text-sm);
  font-weight: 600;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.nt-consequences {
  margin-top: var(--nt-space-6);
  padding-top: var(--nt-space-5);
  border-top: 1px solid var(--nt-border-subtle);
}

.nt-consequence-list {
  margin-top: var(--nt-space-2);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: var(--nt-text-base);
}

.nt-consequence-list li { display: flex; align-items: flex-start; gap: 0.5rem; }
.nt-consequence-icon { flex: none; margin-top: 0.18rem; color: var(--nt-text-tertiary); }
.nt-consequence-list-quiet { font-size: var(--nt-text-sm); color: var(--nt-text-secondary); }

.nt-standing {
  margin-top: var(--nt-space-5);
  padding: var(--nt-space-4);
  border-radius: var(--nt-radius);
  background: var(--nt-surface-sunken);
}

.nt-standing-title {
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--nt-text-tertiary);
}

/* ══════════════════════════════════════════════════════════════════════
   26c. THE DOCUMENT SHEET — the frame, not the document

   The `.doc-*` vocabulary the country pack's templates emit used to live
   here, scoped under `.nt-doc-sheet`. It has moved to document.css, scoped
   under `.nt-doc` and re-tokenised onto that file's `--doc-*` vocabulary.

   The reason is not tidiness. Documents::PrintStylesheet inlines document.css
   and NOTHING else into the HTML Chromium prints, so for as long as the
   pack's typography lived in this file the wizard's pane showed a styled
   referat and the signed PDF printed the same markup unstyled. One
   stylesheet, one render: shared/_document_page now puts
   `nt-doc-sheet nt-doc nt-doc-tokens` on the sheet, so the preview, the event
   page, the signing page and Chromium all resolve the same rules.

   What stays here is the chrome AROUND the document — the paper's screen
   dressing lives in section 23; below is the loading/swap/flash behaviour.
   ══════════════════════════════════════════════════════════════════════ */

/* Reserve room for the running footer the sheet paints at its bottom edge, so
   a long document does not run underneath it. */
.nt-doc-sheet:has(.nt-doc-footer) { padding-bottom: 4.5rem; }

.nt-doc-sheet-loading { opacity: 0.7; }

/* A Turbo Stream replaces the whole frame; there is no outgoing node to fade
   against, so the incoming one starts part-way up. It is a FADE, never a
   slide: paper does not move. */
.nt-doc-entering { opacity: 0.35; }

.nt-doc-sheet,
.nt-doc-frame .nt-empty { transition: opacity var(--nt-duration) var(--nt-ease); }

/* The section that just changed, washed in seal at low alpha. Once, 600 ms,
   no bounce — a highlight that has to be waited out is a highlight that gets
   ignored. */
.nt-doc-flash { animation: nt-doc-flash 600ms var(--nt-ease) 1 both; }

@keyframes nt-doc-flash {
  0% { background-color: transparent; }
  30% { background-color: color-mix(in srgb, var(--nt-seal) 12%, transparent); }
  100% { background-color: transparent; }
}

/* ══════════════════════════════════════════════════════════════════════
   26d. THE INTENT CATALOG — "Hvad vil I gøre?"
   ══════════════════════════════════════════════════════════════════════ */

.nt-catalog-search { margin-bottom: var(--nt-space-5); }

.nt-search { position: relative; display: flex; align-items: center; }

.nt-search-icon {
  position: absolute;
  left: 0.85rem;
  display: inline-flex;
  color: var(--nt-text-tertiary);
  pointer-events: none;
}

.nt-search-input { padding-left: 2.4rem; padding-right: 2.4rem; }

.nt-search-clear {
  position: absolute;
  right: 0.55rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  border: 0;
  border-radius: var(--nt-radius-full);
  background: transparent;
  color: var(--nt-text-tertiary);
  cursor: pointer;
}

.nt-search-clear:hover { background: var(--nt-surface-sunken); color: var(--nt-text); }
.nt-search-clear:focus-visible { outline: none; box-shadow: var(--nt-shadow-focus); }

.nt-catalog-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--nt-space-3);
  margin-top: 0.35rem;
}

.nt-catalog {
  display: grid;
  gap: var(--nt-space-3);
}

@media (min-width: 40rem) {
  .nt-catalog { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.nt-catalog-cell { display: block; min-width: 0; }
.nt-catalog-cell[hidden] { display: none; }

.nt-intent {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--nt-space-3);
  width: 100%;
  height: 100%;
  padding: var(--nt-space-4) var(--nt-space-5);
  text-align: left;
  border: 1px solid var(--nt-border-subtle);
  border-radius: var(--nt-radius);
  background: var(--nt-surface);
  color: var(--nt-text);
  cursor: pointer;
  box-shadow: var(--nt-shadow-1);
  transition:
    border-color var(--nt-duration-fast) var(--nt-ease),
    box-shadow var(--nt-duration-fast) var(--nt-ease),
    transform var(--nt-duration-fast) var(--nt-ease);
}

.nt-intent:hover {
  border-color: var(--nt-seal-border);
  box-shadow: var(--nt-shadow-2);
  transform: translateY(-1px);
}

.nt-intent:focus-visible { outline: none; box-shadow: var(--nt-shadow-focus); }

.nt-intent-body { min-width: 0; display: block; }

.nt-intent-title {
  display: block;
  font-family: var(--nt-font-display);
  font-size: var(--nt-text-md);
  font-weight: 600;
  line-height: 1.25;
}

.nt-intent-summary {
  display: block;
  margin-top: 0.3rem;
  font-size: var(--nt-text-sm);
  color: var(--nt-text-secondary);
  line-height: 1.5;
}

.nt-intent-go {
  flex: none;
  margin-top: 0.15rem;
  color: var(--nt-text-disabled);
  transition: color var(--nt-duration-fast) var(--nt-ease), transform var(--nt-duration-fast) var(--nt-ease);
}

.nt-intent:hover .nt-intent-go { color: var(--nt-seal); transform: translateX(2px); }

/* The catch-all. Last, and visibly a different KIND of thing: nobody should
   reach a dead end, and nobody should pick the escape hatch by accident. */
.nt-catchall {
  display: grid;
  gap: var(--nt-space-4);
  margin-top: var(--nt-space-4);
  padding: var(--nt-space-5) var(--nt-space-6);
  border: 1px dashed var(--nt-border);
  border-radius: var(--nt-radius-lg);
  background: var(--nt-bg-accent);
}

@media (min-width: 768px) {
  .nt-catchall { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
}

.nt-catchall-eyebrow {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--nt-font-mono);
  font-size: var(--nt-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--nt-text-tertiary);
}

.nt-catchall-lede {
  margin-top: 0.4rem;
  font-size: var(--nt-text-sm);
  color: var(--nt-text-secondary);
  max-width: 42ch;
}

.nt-catchall-options { display: grid; gap: var(--nt-space-2); }
.nt-catchall .nt-intent { background: var(--nt-surface); box-shadow: none; }
.nt-intent-jurist .nt-intent-title { font-family: var(--nt-font-body); font-size: var(--nt-text-base); }

.nt-resume-list { display: flex; flex-direction: column; gap: var(--nt-space-1); }

.nt-resume-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--nt-space-3);
  padding: var(--nt-space-2) 0;
}

.nt-resume-item + .nt-resume-item { border-top: 1px solid var(--nt-border-subtle); }
.nt-resume-name { font-weight: 600; }

/* ══════════════════════════════════════════════════════════════════════
   27. REDUCED MOTION
   Every transition/animation above is expressed through the duration tokens
   or a named keyframe, so zeroing the tokens plus a blanket clamp leaves the
   system fully usable with no movement at all.
   ══════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  :root {
    --nt-duration-fast: 1ms;
    --nt-duration: 1ms;
    --nt-duration-slow: 1ms;
    --nt-duration-slower: 1ms;
  }

  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }

  .nt-card-link:hover { transform: none; }
  .nt-btn:active { transform: none; }
  .nt-wordmark:hover .nt-seal-mark { transform: none; }

  /* The wizard. The blanket clamp above already zeroes every duration; these
     are the rules that move something rather than merely time it, and each
     one has to be neutralised on its own.

     Note what is NOT removed: the flash still HAPPENS, it just happens
     instantly. "Which paragraph did my answer change" is information, not
     decoration, and a reader who asked for less motion still needs it. */
  .nt-intent:hover { transform: none; }
  .nt-intent:hover .nt-intent-go { transform: none; }
  .nt-home-intent:hover { transform: none; }
  .nt-home-intent:hover .nt-arrow { transform: none; }
  .nt-handoff[data-state="arriving"] { animation: none; }
  .nt-commit-panel[data-state="open"] { animation: none; }
  .nt-autosave[data-state="saving"] .nt-autosave-mark { animation: none; }
  .nt-doc-entering { opacity: 1; }
  .nt-wizard-paper { scroll-behavior: auto; }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * ▓▓  VISUAL EXCELLENCE WORKSTREAM — public surfaces  ▓▓
 *
 * Everything below this banner is owned by the visual workstream: the forside,
 * the auth experience, the seal artwork and the document typography. It is a
 * single appended block on purpose — the design-system workstream owns
 * everything above, so the two never touch the same lines.
 *
 * Companion file: motion.css (tokens --nt-motion-*, --nt-ease-*, reveal
 * utilities, keyframes). Load order is motion.css → notarium.css, so rules
 * here win at equal specificity.
 *
 * The idea, in one line: Notarium looks like a document, not like a dashboard.
 * A bound protocol supplies the layout grammar (a page edge, a marginal rail
 * for §-references, a stack of sheets) and the wax seal supplies the one
 * saturated moment. Everything else stays quiet so those two carry the page.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ── Extra tokens ─────────────────────────────────────────────────────────
 * Only additions; nothing above is redefined. The document tokens exist
 * because a rendered legal page is *paper* in both themes — inverting it to
 * dark would break the one metaphor the whole product rests on. In dark mode
 * the sheet just loses its glare.
 */

/* ── Legacy token aliases ─────────────────────────────────────────────────
 * The design system renamed the ground/ink/border tier while the marketing
 * site and this section were being written against the earlier names. Every
 * `var(--nt-hairline)` in the two older files therefore resolved to nothing,
 * and an invalid var makes the WHOLE declaration invalid at computed-value
 * time — so every hairline border on the public site silently disappeared,
 * along with a few box-shadows.
 *
 * Aliasing is the right repair rather than a find-and-replace: these are
 * references, not copies, so they follow the theme automatically and there is
 * exactly one place to delete them from once the old names are gone.
 *
 *   --nt-paper     → --nt-bg
 *   --nt-ink       → --nt-text
 *   --nt-ink-soft  → --nt-text-secondary
 *   --nt-ink-faint → --nt-text-tertiary
 *   --nt-hairline  → --nt-border
 *   --nt-seal-ink  → --nt-seal-text      (contrast-tuned per theme upstream)
 *   --nt-warn-ink  → --nt-warn-text
 */

:root {
  --nt-paper: var(--nt-bg);
  --nt-ink: var(--nt-text);
  --nt-ink-soft: var(--nt-text-secondary);
  --nt-ink-faint: var(--nt-text-tertiary);
  --nt-hairline: var(--nt-border);
  --nt-seal-ink: var(--nt-seal-text);
  --nt-warn-ink: var(--nt-warn-text);
  --nt-danger-ink: var(--nt-danger-text);
  --nt-ok-ink: var(--nt-ok-text);
}

:root {
  --nt-seal-lift: #a8384a;   /* lit edge of the wax */
  --nt-seal-deep: #5a1220;   /* the shadow side, and engraved lines */


  --nt-doc-paper: #fffdf9;
  --nt-doc-ink: #1a1c21;
  --nt-doc-ink-soft: #44484f;
  --nt-doc-ink-faint: #5b5f66;   /* 6.3:1 on the sheet; the footer is 9 px */
  --nt-doc-rule: #e4ddcf;
  --nt-doc-shadow: 63 42 30;  /* warm shadow, as "r g b" for rgb() with alpha */

  --nt-font-doc: "Source Serif 4", Georgia, "Times New Roman", serif;

  --nt-shell: 1180px;
  --nt-gutter: clamp(1.25rem, 4vw, 3rem);
}

/* (0,2,0), like section 2c — as a bare `[data-theme="dark"]` this block lost
   every token 2c also declares, and forced dark rendered a different sheet
   from OS dark. Any new dark override belongs here, not in 2c. */
:root[data-theme="dark"] {
  --nt-seal-lift: #c85f6e;
  --nt-seal-deep: #6d2530;

  --nt-cta-fill: #c9737e;
  --nt-cta-fill-hover: #d5828c;
  --nt-cta-ink: #1a1012;

  --nt-doc-paper: #e8e2d6;
  --nt-doc-ink: #22242a;
  --nt-doc-ink-soft: #44484f;
  --nt-doc-ink-faint: #5b5f66;   /* 4.9:1 on the dimmed sheet */
  --nt-doc-rule: #cbc3b2;
  --nt-doc-shadow: 0 0 0;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --nt-seal-lift: #c85f6e;
    --nt-seal-deep: #6d2530;

    --nt-cta-fill: #c9737e;
    --nt-cta-fill-hover: #d5828c;
    --nt-cta-ink: #1a1012;

    --nt-doc-paper: #e8e2d6;
    --nt-doc-ink: #22242a;
    --nt-doc-ink-soft: #44484f;
    --nt-doc-ink-faint: #5b5f66;
    --nt-doc-rule: #cbc3b2;
    --nt-doc-shadow: 0 0 0;
  }
}

/* ── Focus, globally ──────────────────────────────────────────────────────
 * One visible ring, keyboard-only, on every interactive surface. Two colours
 * so the ring survives both a paper ground and the ink-dark CTA band.
 */

/* Zero specificity on the element list, so any component can state its own
   focus treatment and win.
   `select` and `textarea` are in the list because the duplicate declaration
   this replaces (section 5) had them and this one did not.
   `--nt-focus`, not `--nt-seal`: they are the same bordeaux in light, but
   --nt-focus is the token tuned for a ring on a dark ground (seal-300 vs the
   dimmer seal-400) and is the reason it exists.
   NO `border-radius` here. It used to set --nt-radius-sm, which is not the
   outline's radius but the ELEMENT's: at (0,1,0) it beat every component that
   declares its own, so a .nt-btn's 10px corners snapped to 4px for as long as
   it held keyboard focus. An outline follows the element's own radius. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--nt-focus);
  outline-offset: 3px;
}

/* The RAW token, not the `--nt-paper` alias.
   `.nt-ink-ground` paints a fixed #17150f in both themes — it is a band of ink
   by construction, not a themed surface, which is why it also hardcodes its
   own `color: #f3ede2`. `--nt-paper` does flip: #faf8f4 in light, #15130f in
   dark. So this ring measured 17.2:1 on the band in light and 1.02:1 in dark —
   invisible, on the one CTA at the bottom of every marketing page. A ring on a
   theme-independent ground has to be theme-independent too. */
.nt-ink-ground :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline-color: var(--nt-c-paper-50);
}

/* ── Seal artwork ─────────────────────────────────────────────────────── */

.nt-seal { display: block; }

.nt-seal-legend {
  font-family: var(--nt-font-body);
  font-size: 8.4px;
  font-weight: 600;
  letter-spacing: 1.95px;
}

/* NOTE: `.nt-seal-monogram` styled a live <text> N inside the seal. All three
   seals now draw shared/marks/_monogram — the same glyph converted to an
   outline path — so no seal depends on the display webfont having loaded. That
   also fixes the PDF export, which renders from a file:// page with no network
   and no --nt-* tokens, where a webfont glyph was never guaranteed. */

.nt-mark { display: block; color: var(--nt-ink); }

.nt-mark-glyph {
  font-family: var(--nt-font-display);
  font-size: 15px;
  font-weight: 600;
}

/* Ambient life on the big display seals. */
.nt-seal-breathe { animation: nt-breathe 6.5s var(--nt-ease-in-out) infinite; }

/* ── Page shell & rhythm ──────────────────────────────────────────────── */

/* `.mk-container` is the same box under the marketing workstream's name — it
   was declared separately in marketing.css with byte-identical values, so a
   change to the page measure had to be made twice or the two edges drifted
   apart. One declaration, both names. `width: 100%` came from the .mk- copy
   and is kept: it is a no-op on a block box but matters the moment one of
   these is a flex or grid item. */
.nt-shell,
.mk-container {
  width: 100%;
  max-width: var(--nt-shell);
  margin-inline: auto;
  padding-inline: var(--nt-gutter);
}

.nt-band { position: relative; }
.nt-band-paper { background: var(--nt-paper); }
.nt-band-surface { background: var(--nt-surface); }
.nt-band-sunken { background: var(--nt-surface-sunken); }

.nt-band-surface,
.nt-band-sunken { border-block: 1px solid var(--nt-hairline); }

.nt-section { padding-block: clamp(4rem, 8vw, 7.5rem); }
.nt-section-tight { padding-block: clamp(2.75rem, 5vw, 4rem); }

/* Section heads. The eyebrow carries a real reference — a statute, a count,
   a stage of the pipeline — never a decorative label. */
.nt-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--nt-font-mono);
  font-size: 0.68rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--nt-text-secondary);   /* 11 px: tertiary is 4.1:1 here */
  margin: 0 0 1.1rem;
}

.nt-eyebrow::before {
  content: "";
  width: 1.6rem;
  height: 1px;
  background: var(--nt-seal);
  opacity: 0.7;
}

.nt-h1 {
  font-family: var(--nt-font-display);
  font-size: clamp(2.75rem, 6vw, 4.9rem);
  font-weight: 500;
  font-variation-settings: "opsz" 144, "SOFT" 16, "WONK" 1;
  letter-spacing: -0.032em;
  line-height: 0.98;
  margin: 0;
  text-wrap: balance;
}

.nt-h2 {
  font-family: var(--nt-font-display);
  font-size: clamp(1.9rem, 3.3vw, 2.85rem);
  font-weight: 500;
  font-variation-settings: "opsz" 72, "SOFT" 20, "WONK" 1;
  letter-spacing: -0.022em;
  line-height: 1.08;
  margin: 0 0 1rem;
  text-wrap: balance;
}

.nt-h3 {
  font-family: var(--nt-font-display);
  font-size: 1.22rem;
  font-weight: 600;
  font-variation-settings: "opsz" 24, "SOFT" 30, "WONK" 0;
  letter-spacing: -0.01em;
  line-height: 1.25;
  margin: 0 0 0.5rem;
}

.nt-lede {
  font-size: 1.06rem;
  line-height: 1.62;
  color: var(--nt-ink-soft);
  max-width: 46ch;
  margin: 0;
  text-wrap: pretty;
}

.nt-body { color: var(--nt-ink-soft); line-height: 1.62; margin: 0; }

/* A law chip. Mono, because a statute reference is data. */
.nt-law {
  display: inline-flex;
  align-items: center;
  padding: 0.1rem 0.42rem;
  border-radius: 3px;
  background: var(--nt-seal-soft);
  color: var(--nt-seal-ink);
  font-family: var(--nt-font-mono);
  font-size: 0.7rem;
  font-weight: 500;
  white-space: nowrap;
}

/* Section break: the double rule of a protocol book, with the § between. */
.nt-rule {
  display: flex;
  align-items: center;
  gap: 1rem;
  color: var(--nt-seal);
}

.nt-rule::before,
.nt-rule::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--nt-hairline);
}

.nt-rule span {
  font-family: var(--nt-font-display);
  font-size: 1rem;
  opacity: 0.6;
}

/* ── Navigation ───────────────────────────────────────────────────────── */

.nt-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--nt-paper);
  /* 93 %, not 84: the bar passes over the ink-dark CTA band, and a thinner
     tint turns muddy grey there instead of reading as paper. */
  background: color-mix(in oklab, var(--nt-paper) 93%, transparent);
  backdrop-filter: saturate(1.5) blur(14px);
  -webkit-backdrop-filter: saturate(1.5) blur(14px);
  border-bottom: 1px solid var(--nt-hairline);
}

.nt-nav-inner {
  max-width: var(--nt-shell);
  margin-inline: auto;
  padding: 0.85rem var(--nt-gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.nt-mark-lockup {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  text-decoration: none;
  color: var(--nt-ink);
}

.nt-mark-lockup .nt-seal {
  transition: transform var(--nt-motion-slow) var(--nt-ease-stamp);
}

.nt-mark-lockup:hover .nt-seal { transform: rotate(-9deg) scale(1.04); }

.nt-mark-name {
  font-family: var(--nt-font-display);
  font-size: 1.28rem;
  font-weight: 600;
  font-variation-settings: "opsz" 36, "SOFT" 18, "WONK" 1;
  letter-spacing: -0.015em;
}

.nt-nav-links {
  display: flex;
  align-items: center;
  gap: 1.6rem;
  font-size: 0.9rem;
}

/* :not(.nt-cta-btn) matters: this selector is more specific than the button's
   own, so without it the nav's primary button inherited muted link ink and
   rendered grey-on-bordeaux. */
.nt-nav-links a:not(.nt-cta-btn) {
  color: var(--nt-text-secondary);
  text-decoration: none;
  transition: color var(--nt-motion-fast) var(--nt-ease-out);
}

.nt-nav-links a:not(.nt-cta-btn):hover { color: var(--nt-text); }

/* NOTE: a `max-width: 800px` block lived here hiding `.nt-nav-hideable`.
   No template has carried that class since the marketing nav was rebuilt —
   marketing_nav.css and pages/_nav both name it as the bug they replaced (it
   hid Stiftelse, Begivenheder, Priser and Om on a tablet with no way to reach
   them). Removed rather than left as a trap, along with its off-register
   800px breakpoint. */

/* Under ~520 px the lockup plus two buttons overflowed the viewport by 35 px.
   Log ind is the one a returning customer needs in the bar; signing up is a
   scroll away on every page. */
@media (max-width: 520px) {
  .nt-nav-inner { gap: 0.75rem; }
  .nt-nav-links { gap: 0.6rem; }
  .nt-mark-name { font-size: 1.12rem; }
}

/* ── Buttons (public surfaces) ────────────────────────────────────────────
 * Depth without a drop shadow: an inset highlight along the top edge and a
 * darker rim below, the way pressed wax catches light.
 */

.nt-cta-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  padding: 0.78rem 1.4rem;
  border: 1px solid transparent;
  border-radius: 7px;
  font-family: var(--nt-font-body);
  font-size: 0.94rem;
  font-weight: 600;
  line-height: 1.15;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition:
    transform var(--nt-motion-fast) var(--nt-ease-out),
    box-shadow var(--nt-motion-fast) var(--nt-ease-out),
    background-color var(--nt-motion-fast) var(--nt-ease-out),
    border-color var(--nt-motion-fast) var(--nt-ease-out),
    color var(--nt-motion-fast) var(--nt-ease-out);
}

/* In dark the seal lightens to a rose, and paper-white text on it lands at
   3.9:1 — under AA for a 15 px semibold label. The dark treatment therefore
   inverts: a brighter fill carrying near-black type, which also gives the
   button a clear edge against the near-black ground. */
.nt-cta-btn-primary {
  background: var(--nt-cta-fill, var(--nt-seal));
  color: var(--nt-cta-ink, var(--nt-on-seal));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.18),
    0 1px 2px rgba(90, 18, 32, 0.28),
    0 6px 16px -8px rgba(90, 18, 32, 0.55);
}

.nt-cta-btn-primary:hover {
  background: var(--nt-seal-hover);
  transform: translate3d(0, -1px, 0);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.22),
    0 2px 4px rgba(90, 18, 32, 0.26),
    0 12px 26px -10px rgba(90, 18, 32, 0.6);
}

.nt-cta-btn-primary:active {
  transform: translate3d(0, 1px, 0);
  box-shadow: inset 0 2px 4px rgba(90, 18, 32, 0.35);
}

.nt-cta-btn-quiet {
  background: transparent;
  color: var(--nt-ink);
  border-color: var(--nt-hairline);
}

.nt-cta-btn-quiet:hover {
  background: var(--nt-surface);
  border-color: var(--nt-ink-faint);
  transform: translate3d(0, -1px, 0);
}

.nt-cta-btn-onink {
  background: var(--nt-paper);
  color: #1a1712;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 10px 30px -12px rgba(0, 0, 0, 0.7);
}

.nt-cta-btn-onink:hover { transform: translate3d(0, -1px, 0); }

.nt-cta-btn-ghostink {
  background: transparent;
  color: rgba(243, 237, 226, 0.9);
  border-color: rgba(243, 237, 226, 0.28);
}

.nt-cta-btn-ghostink:hover {
  border-color: rgba(243, 237, 226, 0.55);
  color: #fbf6ec;
}

.nt-cta-btn .nt-arrow { transition: transform var(--nt-motion-base) var(--nt-ease-out); }
.nt-cta-btn:hover .nt-arrow { transform: translateX(3px); }

/* ── HERO ─────────────────────────────────────────────────────────────── */

.nt-hero-band {
  position: relative;
  overflow: clip;
  padding-block: clamp(2rem, 3.5vw, 3.25rem) clamp(3rem, 6vw, 5rem);
}

/* One atmospheric gesture: warm light falling from behind the document. */
.nt-hero-band::before {
  content: "";
  position: absolute;
  inset: -18% -10% auto -10%;
  height: 85%;
  background:
    radial-gradient(52% 62% at 68% 26%, rgba(127, 29, 43, 0.075), transparent 72%),
    radial-gradient(46% 52% at 16% 6%, rgba(30, 107, 79, 0.05), transparent 70%);
  pointer-events: none;
}

.nt-hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(3rem, 5vw, 4.5rem);
  align-items: center;
}

/* The copy column carries slightly more weight than the document. An earlier
   pass gave the sheet the larger share and the two halves stopped reading as
   one composition — the page looked like a headline pinned beside a poster. */
@media (min-width: 1000px) {
  .nt-hero-grid { grid-template-columns: minmax(0, 1.04fr) minmax(0, 0.96fr); }
}

@media (min-width: 1500px) {
  .nt-hero-grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); }
}

.nt-hero-copy { max-width: 34rem; }

.nt-hero-h1 {
  font-family: var(--nt-font-display);
  font-size: clamp(3.1rem, 6.2vw, 5rem);
  font-weight: 500;
  font-variation-settings: "opsz" 144, "SOFT" 14, "WONK" 1;
  letter-spacing: -0.035em;
  line-height: 0.94;
  margin: 0 0 1.3rem;
}

/* One phrase of the hero headline is set in the compliance green — the same
   green that means "i orden" everywhere else in the product. It now falls on
   "Til fast pris.", because the price promise is what the line is selling. */
.nt-hero-h1 em { font-style: normal; color: var(--nt-ok); }

.nt-hero-lede {
  font-size: 1.1rem;
  line-height: 1.6;
  color: var(--nt-ink-soft);
  margin: 0 0 2rem;
  max-width: 33rem;
  text-wrap: pretty;
}

.nt-hero-note {
  margin: 0.9rem 0 0;
  font-size: 0.82rem;
  color: var(--nt-ink-faint);
  line-height: 1.5;
}

/* ── CVR teaser ───────────────────────────────────────────────────────── */

.nt-cvr-form { margin: 0; }

.nt-cvr-label {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--nt-ink);
  margin-bottom: 0.55rem;
}

.nt-cvr-field {
  display: flex;
  align-items: stretch;
  background: var(--nt-surface);
  border: 1px solid var(--nt-hairline);
  border-radius: 9px;
  padding: 0.32rem 0.32rem 0.32rem 0.9rem;
  box-shadow: var(--nt-shadow-1);
  transition:
    border-color var(--nt-motion-fast) var(--nt-ease-out),
    box-shadow var(--nt-motion-fast) var(--nt-ease-out),
    transform var(--nt-motion-fast) var(--nt-ease-out);
}

/* The ring is 2px of --nt-seal, not 3px of --nt-seal-soft.
   The input inside kills its own outline (`.nt-cvr-input:focus`) and hands the
   indicator to this wrapper, so this IS the focus indicator for the one
   control on the front page — and seal-soft is #f9edee, which measures 1.02:1
   against the paper it sits on. WCAG 2.2 wants ≥3:1 for a focus indicator;
   #7f1d2b on #faf8f4 is 9.4:1. The soft wash stays as the outer bloom, where
   being nearly invisible is the point. */
.nt-cvr-field:focus-within {
  border-color: var(--nt-seal);
  box-shadow: 0 0 0 2px var(--nt-seal), 0 0 0 5px var(--nt-seal-soft), var(--nt-shadow-2);
  transform: translate3d(0, -1px, 0);
}

.nt-cvr-prefix {
  align-self: center;
  font-family: var(--nt-font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--nt-ink-faint);
  padding-right: 0.7rem;
  border-right: 1px solid var(--nt-hairline);
  margin-right: 0.75rem;
}

.nt-cvr-input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--nt-ink);
  font-family: var(--nt-font-mono);
  font-size: 1.2rem;
  font-weight: 500;
  letter-spacing: 0.11em;
}

.nt-cvr-input::placeholder { color: var(--nt-ink-faint); opacity: 0.55; }
.nt-cvr-input:focus { outline: none; }

.nt-cvr-field .nt-cta-btn { padding-inline: 1.1rem; }

/* The graceful-degradation state: cvrapi.dk is down, or the number is not in
   the register. It has to look like a considered answer, not a failure — the
   CVR-less route out is the whole point of it. */
.nt-cvr-notice {
  background: var(--nt-surface);
  border: 1px solid var(--nt-hairline);
  border-left: 3px solid var(--nt-warn);
  border-radius: 12px;
  padding: 1.25rem 1.4rem 1.35rem;
  box-shadow: var(--nt-shadow-2);
  animation: nt-rise-in var(--nt-motion-slow) var(--nt-ease-entrance) both;
}

.nt-cvr-notice h3 {
  font-family: var(--nt-font-display);
  font-size: 1.12rem;
  font-weight: 600;
  font-variation-settings: "opsz" 24, "SOFT" 24, "WONK" 0;
  letter-spacing: -0.012em;
  margin: 0 0 0.4rem;
}

.nt-cvr-notice p {
  margin: 0 0 1.1rem;
  font-size: 0.9rem;
  line-height: 1.58;
  color: var(--nt-ink-soft);
}

/* The field comes back under every outcome, so a mistyped number costs a
   correction rather than a page. */
.nt-cvr-retry { margin-top: 1.1rem; }

.nt-cvr-retry-label {
  font-family: var(--nt-font-mono);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--nt-ink-faint);
  margin: 0 0 0.5rem;
}

.nt-cvr-retry .nt-cvr-label { display: none; }

@media (prefers-reduced-motion: reduce) {
  .nt-cvr-notice, .nt-cvr-card { animation: none; }
}

.nt-cvr-error {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0.6rem 0 0;
  font-size: 0.84rem;
  color: var(--nt-danger);
}

/* The half-built Selskabsmappe returned by a lookup. */
.nt-cvr-card {
  background: var(--nt-surface);
  border: 1px solid var(--nt-hairline);
  border-radius: 12px;
  box-shadow: var(--nt-shadow-3);
  overflow: hidden;
  animation: nt-rise-in var(--nt-motion-slow) var(--nt-ease-entrance) both;
}

.nt-cvr-card-head { padding: 1.1rem 1.25rem 1rem; }

.nt-cvr-card-eyebrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  font-family: var(--nt-font-mono);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--nt-ink-faint);
  margin-bottom: 0.5rem;
}

.nt-cvr-card-name {
  font-family: var(--nt-font-display);
  font-size: 1.55rem;
  font-weight: 600;
  font-variation-settings: "opsz" 48, "SOFT" 20, "WONK" 0;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0 0 0.3rem;
}

.nt-cvr-card-sub { font-size: 0.85rem; color: var(--nt-ink-soft); margin: 0; }

.nt-cvr-facts {
  margin: 0;
  padding: 0.35rem 1.25rem 1.05rem;
  display: grid;
  grid-template-columns: 8rem 1fr;
  gap: 0.42rem 1rem;
  font-size: 0.87rem;
}

.nt-cvr-facts dt {
  color: var(--nt-ink-faint);
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  padding-top: 0.08rem;
}

.nt-cvr-facts dd { margin: 0; color: var(--nt-ink); }

/* What the public register cannot tell us. Dotted rings rather than ticks:
   these are the holes the Selskabsmappe exists to fill, so they must read as
   open, not as failures. */
.nt-cvr-missing {
  padding: 0.9rem 1.25rem 1.05rem;
  border-top: 1px solid var(--nt-hairline);
  background: var(--nt-surface-raised);
}

.nt-cvr-missing-label {
  font-family: var(--nt-font-mono);
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--nt-ink-faint);
  margin: 0 0 0.55rem;
}

.nt-cvr-missing ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.34rem;
  font-size: 0.85rem;
  color: var(--nt-ink-soft);
}

.nt-cvr-missing li { display: grid; grid-template-columns: 0.9rem 1fr; gap: 0.55rem; align-items: start; }
.nt-cvr-missing li svg { margin-top: 0.28rem; color: var(--nt-ink-faint); }
.nt-cvr-missing-note { margin: 0.7rem 0 0; font-size: 0.76rem; line-height: 1.5; color: var(--nt-ink-faint); }

.nt-cvr-basis { margin: 0.5rem 0 0; font-size: 0.74rem; line-height: 1.5; color: var(--nt-ink-soft); }

/* Already past. Stated plainly, and immediately followed by the way out. */
.nt-cvr-deadline-late { background: var(--nt-danger-soft); }
.nt-cvr-deadline-late .nt-cvr-deadline-label,
.nt-cvr-deadline-late .nt-cvr-days { color: var(--nt-danger); }

.nt-cvr-deadline {
  padding: 1rem 1.25rem 1.15rem;
  border-top: 1px solid var(--nt-hairline);
  background: var(--nt-warn-soft);
}

.nt-cvr-deadline-ok { background: var(--nt-ok-soft); }

.nt-cvr-deadline-label {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--nt-warn-ink);
  margin: 0 0 0.25rem;
}

.nt-cvr-deadline-ok .nt-cvr-deadline-label { color: var(--nt-ok); }

.nt-cvr-deadline-date {
  font-family: var(--nt-font-display);
  font-size: 1.24rem;
  font-weight: 600;
  font-variation-settings: "opsz" 36, "SOFT" 20, "WONK" 0;
  letter-spacing: -0.015em;
  color: var(--nt-ink);
  margin: 0;
}

.nt-cvr-days {
  font-family: var(--nt-font-mono);
  font-weight: 600;
  color: var(--nt-warn-ink);
}

.nt-cvr-deadline-ok .nt-cvr-days { color: var(--nt-ok); }

.nt-cvr-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem;
  padding: 0.95rem 1.25rem;
  border-top: 1px solid var(--nt-hairline);
}

.nt-cvr-again {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: 0.85rem;
  color: var(--nt-ink-soft);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--nt-hairline);
}

.nt-cvr-again:hover { color: var(--nt-ink); text-decoration-color: currentColor; }

/* An action that exists in the design but not yet in the product. It keeps
   its full shape so the page reads as finished, but it does not pretend to
   be pressable. */
.nt-cta-btn-soon { cursor: default; opacity: 0.72; }
.nt-cta-btn-soon:hover { transform: none; }

.nt-cvr-soon {
  font-family: var(--nt-font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--nt-ink-faint);
}

/* ── THE SET PIECE: a referat that writes itself ──────────────────────────
 * Structure
 *   .nt-stage      positioning context, holds the fanned back sheets
 *   .nt-sheet      the A4 page (aspect 1 : √2)
 *   .nt-doc        the typeset body — Source Serif, real Danish referat text
 *   .nt-cue        anything that materialises; hidden until its phase lands
 *
 * timeline_controller adds is-p1 … is-p7 cumulatively, then is-restarting,
 * then strips them all and starts over. Every phase is a plain class, so the
 * whole sequence can be scrubbed by hand in devtools.
 */

.nt-stage {
  position: relative;
  display: flex;
  justify-content: center;
}

.nt-sheet-back {
  position: absolute;
  inset: 0;
  margin: auto;
  width: min(100%, 23.5rem);
  aspect-ratio: 1 / 1.414;
  border-radius: 3px;
  background: var(--nt-doc-paper);
  border: 1px solid var(--nt-doc-rule);
  box-shadow: 0 18px 40px -26px rgb(var(--nt-doc-shadow) / 0.5);
}

.nt-sheet-back-1 { transform: rotate(-2.6deg) translate3d(-12px, 9px, 0); opacity: 0.55; }
.nt-sheet-back-2 { transform: rotate(1.7deg) translate3d(10px, 5px, 0); opacity: 0.75; }

.nt-sheet {
  position: relative;
  width: min(100%, 23.5rem);
  aspect-ratio: 1 / 1.414;
  overflow: hidden;
  background: var(--nt-doc-paper);
  border: 1px solid var(--nt-doc-rule);
  border-radius: 3px;
  padding: 8.5% 9% 13%;
  color: var(--nt-doc-ink);
  font-family: var(--nt-font-doc);
  box-shadow:
    0 1px 1px rgb(var(--nt-doc-shadow) / 0.06),
    0 10px 24px -10px rgb(var(--nt-doc-shadow) / 0.16),
    0 40px 70px -30px rgb(var(--nt-doc-shadow) / 0.3);
  transition:
    opacity var(--nt-motion-slower) var(--nt-ease-out),
    transform var(--nt-motion-slower) var(--nt-ease-out);
}

.nt-timeline.is-restarting .nt-sheet {
  opacity: 0;
  transform: translate3d(0, -14px, 0) rotate(-1.2deg);
}

.nt-timeline.is-restarting .nt-cue { transition-duration: 0ms; }

/* Every materialising element: opacity plus a 6px lift — ink settling. */
.nt-cue {
  opacity: 0;
  transform: translate3d(0, 6px, 0);
  transition:
    opacity var(--nt-motion-slow) var(--nt-ease-ink),
    transform var(--nt-motion-slow) var(--nt-ease-ink);
  transition-delay: calc(var(--i, 0) * 80ms);
}

.nt-timeline.is-p1 [data-phase="1"],
.nt-timeline.is-p2 [data-phase="2"],
.nt-timeline.is-p3 [data-phase="3"],
.nt-timeline.is-p4 [data-phase="4"],
.nt-timeline.is-p5 [data-phase="5"],
.nt-timeline.is-p6 [data-phase="6"],
.nt-timeline.is-p7 [data-phase="7"] {
  opacity: 1;
  transform: none;
}

/* Document typography. Small on purpose — you are looking at a page from
   across a desk, and the *shape* of a legal document is the message. */
/* Sized so the whole referat — heading, dagsorden, three resolved points,
   the signature block — fits above the running footer at every width the
   two-column hero uses. Verified at 1280, 1440 and 1920. */
.nt-doc { font-size: clamp(0.44rem, 0.6vw, 0.53rem); line-height: 1.56; }

/* `.nt-sheet` — the prop, not the product. Every marketing use of these two
   classes is inside one (the forside hero, /stiftelse, the /priser invoice);
   every real document is inside `.nt-doc-sheet`, which states its own values
   above. Unscoped, this block reached both. */
.nt-sheet .nt-doc-title {
  font-family: var(--nt-font-display);
  font-size: 1.62em;
  font-weight: 600;
  font-variation-settings: "opsz" 24, "SOFT" 24, "WONK" 0;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  line-height: 1.2;
  margin: 0 0 0.5em;
}

.nt-doc-meta {
  font-family: var(--nt-font-mono);
  font-size: 0.86em;
  letter-spacing: 0.02em;
  color: var(--nt-doc-ink-faint);
  margin: 0 0 1.1em;
  padding-bottom: 1em;
  border-bottom: 1px solid var(--nt-doc-rule);
}

.nt-doc p { margin: 0 0 0.95em; }

.nt-doc-label {
  font-family: var(--nt-font-body);
  font-size: 0.8em;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--nt-doc-ink-soft);
  margin: 0 0 0.5em;
}

.nt-doc-agenda {
  margin: 0 0 1.15em;
  padding: 0;
  list-style: none;
  counter-reset: dagsorden;
}

.nt-doc-agenda li {
  counter-increment: dagsorden;
  display: grid;
  grid-template-columns: 1.6em 1fr;
  column-gap: 0.2em;
}

.nt-doc-agenda li::before {
  content: counter(dagsorden) ".";
  color: var(--nt-doc-ink-faint);
  font-variant-numeric: tabular-nums;
}

.nt-doc-ad {
  display: grid;
  grid-template-columns: 4.3em 1fr;
  column-gap: 0.5em;
  margin: 0 0 0.8em;
}

.nt-doc-ad > b {
  font-weight: 600;
  color: var(--nt-doc-ink-soft);
  white-space: nowrap;
}

/* Ad pkt. 4 is the live one: a placeholder waiting for an answer, and the
   resolved decision that replaces it. Both share one grid cell, so the page
   never reflows when the answer lands. */
.nt-doc-swap { display: grid; min-height: 4.9em; }
.nt-doc-swap > * { grid-area: 1 / 1; }

.nt-doc-pending {
  color: var(--nt-doc-ink-soft);
  font-style: italic;
  transition: opacity var(--nt-motion-base) var(--nt-ease-out);
}

.nt-doc-final {
  opacity: 0;
  transition: opacity var(--nt-motion-slow) var(--nt-ease-out);
  border-radius: 2px;
}

/* Which phase resolves a swap is declared on the element, so a second
   document (the stiftelsesdokument on /stiftelse) can run the same machinery
   on a different cue sheet without a single new rule. */
.nt-timeline.is-p3 .nt-doc-swap[data-resolve="3"] .nt-doc-pending,
.nt-timeline.is-p4 .nt-doc-swap[data-resolve="4"] .nt-doc-pending,
.nt-timeline.is-p5 .nt-doc-swap[data-resolve="5"] .nt-doc-pending,
.nt-timeline.is-p6 .nt-doc-swap[data-resolve="6"] .nt-doc-pending { opacity: 0; }

.nt-timeline.is-p3 .nt-doc-swap[data-resolve="3"] .nt-doc-final,
.nt-timeline.is-p4 .nt-doc-swap[data-resolve="4"] .nt-doc-final,
.nt-timeline.is-p5 .nt-doc-swap[data-resolve="5"] .nt-doc-final,
.nt-timeline.is-p6 .nt-doc-swap[data-resolve="6"] .nt-doc-final {
  opacity: 1;
  animation: nt-flash-ok 1.6s var(--nt-ease-out) 120ms both;
}

.nt-doc-amount { font-weight: 600; }

/* Signature block: label, the ink, the rule it sits on, the typeset name —
   in that order, the way a signed Danish protokollat actually reads. */
.nt-doc-annex {
  margin: 0.9em 0 0;
  padding-top: 0.7em;
  border-top: 1px solid var(--nt-doc-rule);
  font-family: var(--nt-font-mono);
  font-size: 0.82em;
  color: var(--nt-doc-ink-faint);
}

.nt-doc-sig { margin-top: 1.2em; }

.nt-doc-sig-label {
  display: block;
  font-size: 0.94em;
  color: var(--nt-doc-ink-soft);
  margin-bottom: 0.15em;
}

.nt-doc-sig-rule {
  display: block;
  width: 11em;
  height: 1px;
  background: var(--nt-doc-ink);
  opacity: 0.55;
  margin: 0 0 0.32em;
}

.nt-doc-sig-name { display: block; font-size: 0.88em; color: var(--nt-doc-ink-soft); }

/* The signature, drawn as ink rather than typeset. Sits on the rule with a
   negative bottom margin, so the pen crosses the line as a real one does. */
.nt-doc-hand {
  display: block;
  font-family: var(--nt-font-display);
  font-size: 1.7em;
  font-weight: 400;
  font-style: italic;
  font-variation-settings: "opsz" 9, "SOFT" 100, "WONK" 1;
  color: #2c3f68;
  transform: rotate(-2.6deg);
  transform-origin: left bottom;
  margin: 0.25em 0 -0.42em 0.5em;
}

/* The flying answer chip. Comes in from the left — the wizard's side. */
.nt-doc-chip {
  position: absolute;
  left: -1.7rem;
  top: 61.5%;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 0.42rem;
  padding: 0.4rem 0.72rem;
  border-radius: 999px;
  background: var(--nt-surface);
  border: 1px solid var(--nt-ok);
  color: var(--nt-ink);
  font-family: var(--nt-font-body);
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
  box-shadow: 0 10px 24px -10px rgba(30, 107, 79, 0.6), var(--nt-shadow-1);
  opacity: 0;
  transform: translate3d(-90px, 16px, 0) scale(0.9);
  transition:
    opacity var(--nt-motion-slow) var(--nt-ease-out),
    transform var(--nt-motion-slower) var(--nt-ease-stamp);
}

.nt-timeline.is-p4 .nt-doc-chip[data-in="4"],
.nt-timeline.is-p5 .nt-doc-chip[data-in="5"] {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
}

/* data-out is optional: a chip without one simply stays. */
.nt-timeline.is-p6 .nt-doc-chip[data-out="6"] {
  opacity: 0;
  transform: translate3d(0, -10px, 0) scale(0.96);
  transition-duration: var(--nt-motion-base), var(--nt-motion-base);
}

/* Between the signature (ends ~80 %) and the running footer (starts ~91 %):
   the clock starts the moment the document is signed. */
.nt-doc-chip-frist { top: 82.5%; border-color: var(--nt-warn); }
.nt-doc-chip-frist .nt-doc-chip-tick { background: var(--nt-warn); }

.nt-doc-chip-tick {
  display: grid;
  place-items: center;
  width: 0.95rem;
  height: 0.95rem;
  border-radius: 50%;
  background: var(--nt-ok);
  color: var(--nt-paper);
}

/* The stamp. */
.nt-doc-stamp {
  position: absolute;
  right: 6.5%;
  bottom: 10.5%;
  z-index: 4;
  width: 4.9rem;
  height: 4.9rem;
  display: grid;
  place-items: center;
  opacity: 0;
}

.nt-doc-stamp .nt-seal { grid-area: 1 / 1; width: 100%; height: 100%; }

.nt-doc-stamp-ring {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  border: 2px solid var(--nt-seal);
  opacity: 0;
}

.nt-timeline.is-p6 .nt-doc-stamp[data-phase="6"],
.nt-timeline.is-p7 .nt-doc-stamp[data-phase="7"] {
  opacity: 1;
  animation: nt-stamp 620ms var(--nt-ease-stamp) both;
}

.nt-timeline.is-p6 .nt-doc-stamp[data-phase="6"] .nt-doc-stamp-ring,
.nt-timeline.is-p7 .nt-doc-stamp[data-phase="7"] .nt-doc-stamp-ring {
  animation: nt-stamp-ring 900ms var(--nt-ease-out) 180ms both;
}

/* The running footer the rendered PDF carries, with the seal status in it.
   Scoped to the prop — see the note on `.nt-sheet .nt-doc-title` above. */
.nt-sheet .nt-doc-footer {
  position: absolute;
  left: 9%;
  right: 9%;
  bottom: 4.4%;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 0.4rem;
  border-top: 1px solid var(--nt-doc-rule);
  font-family: var(--nt-font-mono);
  font-size: 0.55rem;
  letter-spacing: 0.02em;
  color: var(--nt-doc-ink-faint);
}

.nt-doc-status {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--nt-ok);
  opacity: 0;
  transform: translate3d(0, 4px, 0);
  transition:
    opacity var(--nt-motion-slow) var(--nt-ease-out) 420ms,
    transform var(--nt-motion-slow) var(--nt-ease-out) 420ms;
}

.nt-timeline.is-p6 .nt-doc-status[data-at="6"],
.nt-timeline.is-p7 .nt-doc-status[data-at="7"] { opacity: 1; transform: none; }

.nt-doc-status-dot {
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: var(--nt-ok);
}

/* A caption outside the sheet, so the animation reads as a demonstration and
   not as a document the visitor is expected to read. */
.nt-stage-caption {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  margin-top: 1.5rem;
  font-family: var(--nt-font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--nt-ink-faint);
}

/* Reduced motion: the finished, signed page — no cycling, nothing to wait for. */
@media (prefers-reduced-motion: reduce) {
  .nt-cue,
  .nt-doc-final,
  .nt-doc-status,
  .nt-doc-stamp,
  .nt-sheet {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    animation: none !important;
  }

  .nt-doc-pending,
  .nt-doc-chip,
  .nt-doc-stamp-ring { display: none; }

  .nt-seal-breathe { animation: none; }
}

/* ── Frist band: the company year as a ruled line ─────────────────────── */

.nt-frist-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 2rem;
  margin-bottom: 3rem;
}

.nt-frist-title {
  font-family: var(--nt-font-display);
  font-size: 1.28rem;
  font-weight: 600;
  font-variation-settings: "opsz" 30, "SOFT" 24, "WONK" 0;
  letter-spacing: -0.012em;
  margin: 0;
}

.nt-frist-track {
  position: relative;
  height: 2px;
  background: var(--nt-hairline);
  border-radius: 2px;
}

.nt-frist-fill {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--nt-ok), color-mix(in oklab, var(--nt-ok) 40%, var(--nt-warn)));
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1700ms var(--nt-ease-out) 120ms;
}

/* --fill stops the rule short of the pending deadline: the year is not over. */
.is-revealed .nt-frist-fill { transform: scaleX(var(--fill, 1)); }

/* Fixed height reserves the room the absolutely-positioned stops need; the
   labels wrap to three lines at the narrowest desktop width. */
.nt-frist-stops { position: relative; height: 6.25rem; margin: 0; padding: 0; list-style: none; }

.nt-frist-stop {
  position: absolute;
  top: -10px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 9.5rem;
  text-align: center;
}

.nt-frist-dot {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--nt-surface);
  border: 2px solid var(--nt-hairline);
  display: grid;
  place-items: center;
  color: var(--nt-paper);
  opacity: 0;
  transform: scale(0.4);
  transition:
    opacity var(--nt-motion-base) var(--nt-ease-out),
    transform var(--nt-motion-slow) var(--nt-ease-stamp),
    background-color var(--nt-motion-base) var(--nt-ease-out),
    border-color var(--nt-motion-base) var(--nt-ease-out),
    box-shadow var(--nt-motion-base) var(--nt-ease-out);
  transition-delay: calc(320ms + var(--i, 0) * 330ms);
}

.is-revealed .nt-frist-dot { opacity: 1; transform: scale(1); }

.is-revealed .nt-frist-stop-done .nt-frist-dot {
  background: var(--nt-ok);
  border-color: var(--nt-ok);
}

.is-revealed .nt-frist-stop-next .nt-frist-dot {
  background: var(--nt-surface);
  border-color: var(--nt-warn);
  box-shadow: 0 0 0 4px var(--nt-warn-soft);
}

.nt-frist-dot svg {
  opacity: 0;
  transform: scale(0.3);
  transition:
    opacity var(--nt-motion-fast) var(--nt-ease-out),
    transform var(--nt-motion-base) var(--nt-ease-stamp);
  transition-delay: calc(540ms + var(--i, 0) * 330ms);
}

.is-revealed .nt-frist-stop-done .nt-frist-dot svg { opacity: 1; transform: scale(1); }

.nt-frist-when {
  margin-top: 0.8rem;
  font-family: var(--nt-font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: var(--nt-text-secondary);   /* 11 px — the tertiary tier is 4.1:1 */
}

.nt-frist-what {
  margin-top: 0.18rem;
  font-size: 0.78rem;
  line-height: 1.35;
  color: var(--nt-ink);
  font-weight: 550;
}

.nt-frist-stop-next .nt-frist-what { color: var(--nt-warn-ink); }

.nt-frist-foot {
  margin: 0.75rem 0 0;
  font-size: 0.85rem;
  line-height: 1.6;
  color: var(--nt-ink-soft);
  max-width: 62ch;
}

/* The chip runs inline with the sentence it qualifies. */
.nt-frist-foot .nt-law { margin-right: 0.4rem; transform: translateY(-1px); }

/* On a phone the horizontal axis stops working; the stops become a vertical
   list with the rule running down the left, which is the same information. */
@media (max-width: 860px) {
  .nt-frist-track { display: none; }

  .nt-frist-stops {
    height: auto;
    display: grid;
    gap: 1.15rem;
    border-left: 2px solid var(--nt-hairline);
    padding-left: 1.35rem;
  }

  .nt-frist-stop {
    position: static;
    transform: none;
    width: auto;
    flex-direction: row;
    align-items: center;
    gap: 0.9rem;
    text-align: left;
  }

  .nt-frist-dot { margin-left: -2.25rem; flex: 0 0 auto; }
  .nt-frist-when { margin: 0; min-width: 5.5rem; }
  .nt-frist-what { margin: 0; }
}

/* ── Pillars ──────────────────────────────────────────────────────────── */

.nt-pillars {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1px;
  background: var(--nt-hairline);
  border: 1px solid var(--nt-hairline);
  border-radius: 12px;
  overflow: hidden;
}

.nt-pillar {
  background: var(--nt-surface);
  padding: 1.9rem 1.6rem 2rem;
  position: relative;
  transition: background-color var(--nt-motion-base) var(--nt-ease-out);
}

.nt-pillar:hover { background: var(--nt-surface-raised); }
.nt-pillar .nt-mark { margin-bottom: 1.1rem; }

.nt-pillar-index {
  position: absolute;
  top: 1.5rem;
  right: 1.4rem;
  font-family: var(--nt-font-mono);
  font-size: 0.68rem;
  color: var(--nt-ink-faint);
  opacity: 0.6;
}

.nt-pillar p { font-size: 0.9rem; color: var(--nt-ink-soft); line-height: 1.58; margin: 0; }

/* ── Intent catalog (the forside's demo) ──────────────────────────────────
 * `.nt-home-*`, not `.nt-catalog` / `.nt-intent`. Those two names belong to
 * the WORKSPACE event catalog (§ "Event catalog", and
 * workspace/company_events/_intent) — a different component with a different
 * shape that happens to answer the same question. Both were declared under
 * the bare names; this block is later, so it won on both surfaces and the
 * signed-in catalog had been wearing the front page's padding, radius and
 * row alignment. Renamed here rather than there because the marketing markup
 * is the one this workstream owns.
 */

.nt-home-catalog { position: relative; }

.nt-home-catalog-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
}

@media (min-width: 900px) {
  .nt-home-catalog-body { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr); gap: 2.5rem; }
}

.nt-home-intents { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }

.nt-home-intent {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  padding: 0.82rem 1rem;
  border: 1px solid var(--nt-hairline);
  border-radius: 8px;
  background: var(--nt-surface);
  color: var(--nt-ink);
  font-size: 0.94rem;
  font-weight: 550;
  cursor: pointer;
  transition:
    border-color var(--nt-motion-fast) var(--nt-ease-out),
    background-color var(--nt-motion-fast) var(--nt-ease-out),
    transform var(--nt-motion-fast) var(--nt-ease-out),
    box-shadow var(--nt-motion-fast) var(--nt-ease-out);
}

.nt-home-intent:hover {
  border-color: color-mix(in oklab, var(--nt-seal) 45%, var(--nt-hairline));
  transform: translate3d(2px, 0, 0);
}

.nt-home-intent .nt-arrow {
  color: var(--nt-ink-faint);
  transition:
    transform var(--nt-motion-base) var(--nt-ease-out),
    color var(--nt-motion-fast) var(--nt-ease-out);
}

.nt-home-intent:hover .nt-arrow { transform: translateX(3px); color: var(--nt-seal); }

/* Every plan occupies the SAME grid cell, so the panel is permanently as tall
   as the tallest plan and switching intents changes paint only — never
   layout. An earlier build expanded a card in place on hover; the whole page
   jumped, which is exactly what this structure makes impossible. */
.nt-plans { display: grid; }

.nt-plan {
  grid-area: 1 / 1;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--nt-motion-base) var(--nt-ease-out);
}

.nt-plan-inner {
  border: 1px solid var(--nt-hairline);
  border-radius: 12px;
  background: var(--nt-surface-raised);
  padding: 1.5rem 1.5rem 1.35rem;
  box-shadow: var(--nt-shadow-1);
}

.nt-plan-eyebrow {
  font-family: var(--nt-font-mono);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--nt-ink-faint);
  margin: 0 0 1.1rem;
}

.nt-plan-steps { list-style: none; margin: 0 0 1.25rem; padding: 0; display: grid; }

.nt-plan-step {
  display: grid;
  grid-template-columns: 1.55rem 1fr auto;
  align-items: center;
  gap: 0.7rem;
  padding: 0.52rem 0;
  border-bottom: 1px dashed var(--nt-hairline);
  font-size: 0.9rem;
}

.nt-plan-step:last-child { border-bottom: 0; }

.nt-plan-num {
  display: grid;
  place-items: center;
  width: 1.55rem;
  height: 1.55rem;
  border-radius: 50%;
  background: var(--nt-surface);
  border: 1px solid var(--nt-hairline);
  font-family: var(--nt-font-mono);
  font-size: 0.68rem;
  color: var(--nt-ink-soft);
}

.nt-plan-out {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  padding-top: 1rem;
  border-top: 1px solid var(--nt-hairline);
  font-size: 0.84rem;
  color: var(--nt-ink-soft);
}

.nt-plan-out b { color: var(--nt-ink); font-weight: 600; }

/* Sibling-selector tabs: no JS, no :has(), keyboard-native via radios. */
.nt-home-catalog input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }

#nt-i-1:checked ~ .nt-home-catalog-body #nt-p-1,
#nt-i-2:checked ~ .nt-home-catalog-body #nt-p-2,
#nt-i-3:checked ~ .nt-home-catalog-body #nt-p-3,
#nt-i-4:checked ~ .nt-home-catalog-body #nt-p-4,
#nt-i-5:checked ~ .nt-home-catalog-body #nt-p-5,
#nt-i-6:checked ~ .nt-home-catalog-body #nt-p-6 {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
}

#nt-i-1:checked ~ .nt-home-catalog-body [for="nt-i-1"],
#nt-i-2:checked ~ .nt-home-catalog-body [for="nt-i-2"],
#nt-i-3:checked ~ .nt-home-catalog-body [for="nt-i-3"],
#nt-i-4:checked ~ .nt-home-catalog-body [for="nt-i-4"],
#nt-i-5:checked ~ .nt-home-catalog-body [for="nt-i-5"],
#nt-i-6:checked ~ .nt-home-catalog-body [for="nt-i-6"] {
  border-color: var(--nt-seal);
  background: var(--nt-seal-soft);
  box-shadow: inset 3px 0 0 var(--nt-seal);
  transform: translate3d(2px, 0, 0);
}

#nt-i-1:checked ~ .nt-home-catalog-body [for="nt-i-1"] .nt-arrow,
#nt-i-2:checked ~ .nt-home-catalog-body [for="nt-i-2"] .nt-arrow,
#nt-i-3:checked ~ .nt-home-catalog-body [for="nt-i-3"] .nt-arrow,
#nt-i-4:checked ~ .nt-home-catalog-body [for="nt-i-4"] .nt-arrow,
#nt-i-5:checked ~ .nt-home-catalog-body [for="nt-i-5"] .nt-arrow,
#nt-i-6:checked ~ .nt-home-catalog-body [for="nt-i-6"] .nt-arrow {
  color: var(--nt-seal);
  transform: translateX(3px);
}

#nt-i-1:focus-visible ~ .nt-home-catalog-body [for="nt-i-1"],
#nt-i-2:focus-visible ~ .nt-home-catalog-body [for="nt-i-2"],
#nt-i-3:focus-visible ~ .nt-home-catalog-body [for="nt-i-3"],
#nt-i-4:focus-visible ~ .nt-home-catalog-body [for="nt-i-4"],
#nt-i-5:focus-visible ~ .nt-home-catalog-body [for="nt-i-5"],
#nt-i-6:focus-visible ~ .nt-home-catalog-body [for="nt-i-6"] {
  outline: 2px solid var(--nt-seal);
  outline-offset: 2px;
}

/* The cascade is attached to the *selected* panel, not to every panel: an
   animation only starts when it is newly applied, so scoping it here is what
   makes the plan visibly re-compile on each switch. */
#nt-i-1:checked ~ .nt-home-catalog-body #nt-p-1 :is(.nt-plan-step, .nt-plan-out),
#nt-i-2:checked ~ .nt-home-catalog-body #nt-p-2 :is(.nt-plan-step, .nt-plan-out),
#nt-i-3:checked ~ .nt-home-catalog-body #nt-p-3 :is(.nt-plan-step, .nt-plan-out),
#nt-i-4:checked ~ .nt-home-catalog-body #nt-p-4 :is(.nt-plan-step, .nt-plan-out),
#nt-i-5:checked ~ .nt-home-catalog-body #nt-p-5 :is(.nt-plan-step, .nt-plan-out),
#nt-i-6:checked ~ .nt-home-catalog-body #nt-p-6 :is(.nt-plan-step, .nt-plan-out) {
  animation: nt-rise-in 420ms var(--nt-ease-entrance) both;
}

.nt-plan-step:nth-child(1) { animation-delay: 40ms; }
.nt-plan-step:nth-child(2) { animation-delay: 110ms; }
.nt-plan-step:nth-child(3) { animation-delay: 180ms; }
.nt-plan-step:nth-child(4) { animation-delay: 250ms; }
.nt-plan-step:nth-child(5) { animation-delay: 320ms; }
.nt-plan-out { animation-delay: 380ms; }

@media (prefers-reduced-motion: reduce) {
  .nt-plan-step,
  .nt-plan-out { animation: none !important; }
  .nt-plan { transition: none; }
}

/* ── How it works ─────────────────────────────────────────────────────── */

.nt-steps {
  position: relative;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 2rem 1.75rem;
}

.nt-step { position: relative; }

.nt-step-num {
  display: inline-grid;
  place-items: center;
  width: 2.35rem;
  height: 2.35rem;
  margin-bottom: 1rem;
  border-radius: 50%;
  background: var(--nt-seal-soft);
  border: 1px solid var(--nt-seal-border, var(--nt-hairline));
  font-family: var(--nt-font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  /* seal-text is tuned against seal-soft; the seal fill on a plain surface
     measured 3.3:1 in dark. */
  color: var(--nt-seal-text);
  box-shadow: var(--nt-shadow-1);
}

/* The pipeline is a genuine sequence, so it gets a connecting line. */
.nt-step::before {
  content: "";
  position: absolute;
  top: 1.17rem;
  left: 2.9rem;
  right: -1.75rem;
  height: 1px;
  background: repeating-linear-gradient(90deg, var(--nt-hairline) 0 5px, transparent 5px 10px);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--nt-motion-slower) var(--nt-ease-out);
  transition-delay: calc(240ms + var(--i, 0) * 150ms);
}

.is-revealed .nt-step::before { transform: scaleX(1); }
.nt-step:last-child::before { display: none; }

@media (max-width: 900px) {
  .nt-step::before { display: none; }
}

.nt-step p { font-size: 0.9rem; color: var(--nt-ink-soft); line-height: 1.58; margin: 0; }

/* ── Priser ───────────────────────────────────────────────────────────── */

.nt-prices {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.15rem;
  align-items: stretch;
}

.nt-price {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--nt-surface);
  border: 1px solid var(--nt-hairline);
  border-radius: 12px;
  padding: 1.7rem 1.5rem 1.6rem;
  box-shadow: var(--nt-shadow-1);
}

/* The feature list absorbs the height difference so every card's action sits
   on the same baseline — three prices should be comparable at a glance. */
.nt-price .nt-cta-btn { margin-top: auto; width: 100%; }

.nt-price-featured {
  border-color: color-mix(in oklab, var(--nt-seal) 40%, var(--nt-hairline));
  box-shadow: var(--nt-shadow-3);
}

.nt-price-featured::before {
  content: "";
  position: absolute;
  inset: -1px -1px auto -1px;
  height: 3px;
  border-radius: 12px 12px 0 0;
  background: linear-gradient(90deg, var(--nt-seal-deep), var(--nt-seal), var(--nt-seal-lift));
}

.nt-price-tag {
  padding: 0.16rem 0.62rem;
  border-radius: 999px;
  background: var(--nt-seal);
  color: var(--nt-on-seal);
  font-family: var(--nt-font-mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.nt-price-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.6rem;
}

.nt-price-name {
  font-family: var(--nt-font-display);
  font-size: 1.15rem;
  font-weight: 600;
  font-variation-settings: "opsz" 24, "SOFT" 24, "WONK" 0;
  margin: 0;
}

.nt-price-amount { display: flex; align-items: baseline; gap: 0.35rem; margin-bottom: 0.3rem; }

.nt-price-amount b {
  font-family: var(--nt-font-display);
  font-size: 2.5rem;
  font-weight: 500;
  font-variation-settings: "opsz" 96, "SOFT" 14, "WONK" 1;
  letter-spacing: -0.03em;
  line-height: 1;
}

.nt-price-unit { font-size: 0.82rem; color: var(--nt-ink-faint); }
.nt-price-note { font-size: 0.84rem; color: var(--nt-ink-soft); margin: 0 0 1.15rem; min-height: 2.6em; }

.nt-price-list {
  list-style: none;
  margin: 0 0 1.5rem;
  padding: 1.1rem 0 0;
  border-top: 1px solid var(--nt-hairline);
  display: grid;
  gap: 0.55rem;
  font-size: 0.87rem;
  color: var(--nt-ink-soft);
}

.nt-price-list li { display: grid; grid-template-columns: 1rem 1fr; gap: 0.55rem; align-items: start; }
.nt-price-list svg { margin-top: 0.28rem; color: var(--nt-ok); }

.nt-price-foot { margin: 1.7rem 0 0; font-size: 0.86rem; color: var(--nt-ink-soft); text-align: center; }

/* ── Trust ────────────────────────────────────────────────────────────── */

.nt-trust-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2.5rem;
  align-items: center;
}

@media (min-width: 960px) {
  .nt-trust-grid { grid-template-columns: minmax(0, 0.78fr) minmax(0, 1fr); gap: 4rem; }
}

.nt-trust-motif {
  display: grid;
  place-items: center;
  padding: clamp(2rem, 4vw, 3.25rem);
  aspect-ratio: 1 / 0.82;
  background: radial-gradient(70% 70% at 50% 38%, var(--nt-surface), var(--nt-surface-sunken));
  border: 1px solid var(--nt-hairline);
  border-radius: 16px;
}

.nt-trust-motif .nt-mark { width: min(15rem, 78%); height: auto; color: var(--nt-ink-soft); }

.nt-trust-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.4rem; }
.nt-trust-item { display: grid; grid-template-columns: 1.65rem 1fr; gap: 0.95rem; }
.nt-trust-item svg { color: var(--nt-ok); margin-top: 0.15rem; }

.nt-trust-item h3 {
  font-family: var(--nt-font-body);
  font-size: 0.95rem;
  font-weight: 650;
  margin: 0 0 0.2rem;
}

.nt-trust-item p { font-size: 0.88rem; color: var(--nt-ink-soft); margin: 0; line-height: 1.55; }

/* ── FAQ ──────────────────────────────────────────────────────────────── */

.nt-faq { max-width: 46rem; margin-inline: auto; }

.nt-faq-item { border-bottom: 1px solid var(--nt-hairline); }
.nt-faq-item:first-of-type { border-top: 1px solid var(--nt-hairline); }

.nt-faq-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.15rem 0.25rem;
  cursor: pointer;
  list-style: none;
  font-family: var(--nt-font-display);
  font-size: 1.06rem;
  font-weight: 600;
  font-variation-settings: "opsz" 20, "SOFT" 26, "WONK" 0;
  letter-spacing: -0.008em;
  transition: color var(--nt-motion-fast) var(--nt-ease-out);
}

.nt-faq-q::-webkit-details-marker { display: none; }
.nt-faq-q:hover { color: var(--nt-seal); }

.nt-faq-sign {
  flex: 0 0 auto;
  width: 1.1rem;
  height: 1.1rem;
  position: relative;
  color: var(--nt-ink-faint);
  transition:
    transform var(--nt-motion-base) var(--nt-ease-out),
    color var(--nt-motion-fast) var(--nt-ease-out);
}

.nt-faq-sign::before,
.nt-faq-sign::after {
  content: "";
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1.5px;
  background: currentColor;
  border-radius: 2px;
}

.nt-faq-sign::after { transform: rotate(90deg); }
.nt-faq-item[open] .nt-faq-sign { transform: rotate(135deg); color: var(--nt-seal); }

.nt-faq-a {
  padding: 0 3rem 1.3rem 0.25rem;
  font-size: 0.94rem;
  line-height: 1.65;
  color: var(--nt-ink-soft);
  animation: nt-rise-in 320ms var(--nt-ease-out) both;
}

.nt-faq-a p { margin: 0 0 0.7rem; }
.nt-faq-a p:last-child { margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
  .nt-faq-a { animation: none; }
}

/* ── Closing CTA on ink ───────────────────────────────────────────────── */

.nt-ink-ground {
  position: relative;
  overflow: clip;
  /* A flat colour under the gradient: if the gradient ever fails to paint,
     light text on this band must still land on something dark. */
  background-color: #17150f;
  background-image: linear-gradient(155deg, #221f1a 0%, #17150f 58%, #100e0a 100%);
  color: #f3ede2;
}

.nt-ink-ground::before {
  content: "";
  position: absolute;
  inset: auto -20% -60% 32%;
  aspect-ratio: 1;
  background: radial-gradient(circle, rgba(168, 56, 74, 0.3), transparent 62%);
  pointer-events: none;
}

.nt-cta-inner {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2.5rem;
  align-items: center;
  justify-items: start;
}

@media (min-width: 860px) {
  .nt-cta-inner { grid-template-columns: minmax(0, 1fr) auto; gap: 4rem; }
}

.nt-cta-h {
  font-family: var(--nt-font-display);
  font-size: clamp(2rem, 4vw, 3.1rem);
  font-weight: 500;
  font-variation-settings: "opsz" 120, "SOFT" 14, "WONK" 1;
  letter-spacing: -0.03em;
  line-height: 1.02;
  margin: 0 0 1rem;
  color: #fbf6ec;
}

.nt-cta-p { color: rgba(243, 237, 226, 0.72); font-size: 1.02rem; margin: 0 0 1.9rem; max-width: 34rem; }
.nt-cta-row { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; }
.nt-cta-seal { filter: drop-shadow(0 24px 40px rgba(0, 0, 0, 0.55)); }

/* ── Footer ───────────────────────────────────────────────────────────── */

.nt-foot { border-top: 1px solid var(--nt-hairline); background: var(--nt-paper); }

.nt-foot-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 2.25rem;
  padding-block: 3.25rem 2.25rem;
}

.nt-foot-brand { max-width: 20rem; }
.nt-foot-brand p { margin: 0.9rem 0 0; font-size: 0.85rem; color: var(--nt-ink-faint); line-height: 1.55; }

.nt-foot-col h4 {
  font-family: var(--nt-font-mono);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--nt-ink-faint);
  margin: 0 0 0.9rem;
  font-weight: 500;
}

.nt-foot-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.55rem; }
.nt-foot-col a { color: var(--nt-ink-soft); text-decoration: none; font-size: 0.88rem; }
.nt-foot-col a:hover { color: var(--nt-ink); }

.nt-foot-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.25rem 2rem;
  border-top: 1px solid var(--nt-hairline);
  font-size: 0.8rem;
  color: var(--nt-ink-faint);
}

/* ── AUTH ─────────────────────────────────────────────────────────────────
 * Split: a motif panel showing what the product makes, and the form. The
 * sheet and the seal are the same artwork as the forside hero, so logging in
 * feels like walking into the same building.
 */

.nt-auth {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  background: var(--nt-paper);
}

@media (min-width: 940px) {
  .nt-auth { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); }
}

.nt-auth-aside {
  position: relative;
  display: none;
  overflow: clip;
  padding: 3rem;
  background:
    radial-gradient(64% 58% at 30% 22%, rgba(127, 29, 43, 0.1), transparent 70%),
    linear-gradient(160deg, var(--nt-surface-raised), var(--nt-surface-sunken));
  border-right: 1px solid var(--nt-hairline);
  place-content: center;
}

@media (min-width: 940px) {
  .nt-auth-aside { display: grid; }
}

.nt-auth-aside-inner { position: relative; max-width: 26rem; }

.nt-auth-quote {
  font-family: var(--nt-font-display);
  font-size: clamp(1.6rem, 2.4vw, 2.1rem);
  font-weight: 500;
  font-variation-settings: "opsz" 72, "SOFT" 18, "WONK" 1;
  letter-spacing: -0.025em;
  line-height: 1.1;
  margin: 2.5rem 0 0.85rem;
}

.nt-auth-quote em { font-style: normal; color: var(--nt-ok); }
.nt-auth-quote-sub { font-size: 0.93rem; color: var(--nt-ink-soft); margin: 0; max-width: 24rem; line-height: 1.55; }

/* A small, always-finished version of the referat sheet. */
.nt-auth-sheet {
  position: relative;
  width: 17.5rem;
  aspect-ratio: 1 / 1.414;
  background: var(--nt-doc-paper);
  border: 1px solid var(--nt-doc-rule);
  border-radius: 3px;
  padding: 1.5rem 1.5rem 1.2rem;
  color: var(--nt-doc-ink);
  font-family: var(--nt-font-doc);
  box-shadow:
    0 2px 3px rgb(var(--nt-doc-shadow) / 0.07),
    0 22px 44px -18px rgb(var(--nt-doc-shadow) / 0.28);
  animation: nt-sheet-in 700ms var(--nt-ease-entrance) both;
}

.nt-auth-sheet-title {
  font-family: var(--nt-font-display);
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0 0 0.75rem;
  padding-bottom: 0.65rem;
  border-bottom: 1px solid var(--nt-doc-rule);
}

.nt-auth-rules { display: grid; gap: 0.42rem; }

.nt-auth-rules i {
  display: block;
  height: 3px;
  border-radius: 2px;
  background: var(--nt-doc-ink);
  opacity: 0.13;
}

.nt-auth-rules i:nth-child(3n) { width: 62%; }
.nt-auth-rules i:nth-child(4n) { width: 84%; }
.nt-auth-rules i.is-gap { opacity: 0; height: 0.55rem; }

.nt-auth-sheet .nt-seal {
  position: absolute;
  right: 1.1rem;
  bottom: 1.1rem;
  transform: rotate(-8deg);
}

.nt-auth-panel {
  display: grid;
  align-content: center;
  padding: clamp(2.25rem, 6vw, 4rem) clamp(1.25rem, 6vw, 4.5rem);
  background: var(--nt-paper);
}

.nt-auth-inner { width: 100%; max-width: 24rem; margin-inline: auto; }

.nt-auth-back {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.84rem;
  color: var(--nt-ink-faint);
  text-decoration: none;
  margin-bottom: 2.4rem;
}

.nt-auth-back:hover { color: var(--nt-ink); }

.nt-auth-h {
  font-family: var(--nt-font-display);
  font-size: clamp(1.9rem, 3.6vw, 2.5rem);
  font-weight: 500;
  font-variation-settings: "opsz" 72, "SOFT" 16, "WONK" 1;
  letter-spacing: -0.028em;
  line-height: 1.05;
  margin: 0 0 0.7rem;
}

.nt-auth-sub { font-size: 0.95rem; color: var(--nt-ink-soft); margin: 0 0 2rem; line-height: 1.55; }

/* `.nt-field { margin-bottom: 1.1rem }` used to live here. It was written for
   the auth cards but landed unscoped, 4800 lines below the canonical
   `.nt-field` in section 12 — so it silently overrode it everywhere and the
   real declaration became dead. Deleted; auth fields now use the same
   --nt-space-4 rhythm as every other form in the product. */

.nt-field-label {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--nt-ink);
  margin-bottom: 0.45rem;
}

.nt-field-input {
  width: 100%;
  padding: 0.78rem 0.95rem;
  border: 1px solid var(--nt-hairline);
  border-radius: 8px;
  background: var(--nt-surface);
  color: var(--nt-ink);
  font-family: var(--nt-font-body);
  font-size: 0.98rem;
  box-shadow: inset 0 1px 2px rgba(22, 24, 29, 0.035);
  transition:
    border-color var(--nt-motion-fast) var(--nt-ease-out),
    box-shadow var(--nt-motion-fast) var(--nt-ease-out);
}

.nt-field-input::placeholder { color: var(--nt-ink-faint); }

.nt-field-input:focus {
  outline: none;
  border-color: var(--nt-seal);
  box-shadow: 0 0 0 3px var(--nt-seal-soft), inset 0 1px 2px rgba(22, 24, 29, 0.03);
}

.nt-field-input:user-invalid {
  border-color: var(--nt-danger);
  box-shadow: 0 0 0 3px var(--nt-danger-soft);
}

.nt-field-hint { margin: 0.5rem 0 0; font-size: 0.8rem; color: var(--nt-ink-faint); }

.nt-auth-submit { width: 100%; padding-block: 0.85rem; }

.nt-auth-foot {
  margin-top: 2.2rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--nt-hairline);
  font-size: 0.82rem;
  color: var(--nt-ink-faint);
  display: flex;
  align-items: center;
  gap: 0.5rem;
  line-height: 1.5;
}

.nt-auth-centered { text-align: center; }
.nt-auth-centered .nt-auth-foot { justify-content: center; }

.nt-auth-mailto {
  display: inline-block;
  margin-top: 0.15rem;
  font-family: var(--nt-font-mono);
  font-size: 0.86rem;
  color: var(--nt-ink);
  background: var(--nt-surface-raised);
  border: 1px solid var(--nt-hairline);
  border-radius: 6px;
  padding: 0.18rem 0.5rem;
}

/* The envelope on "tjek din indbakke".
 *
 *   .nt-env-back     the envelope seen behind the letter
 *   .nt-env-letter   the sheet, which rises out of the mouth and gets sealed
 *   .nt-env-pocket   the front, clipped to a V so the letter emerges from it
 *
 * Elements rather than an SVG, so the sheet carries the real seal artwork and
 * the real document-paper tokens. A 3-D flap was tried first and rejected: at
 * this size the rotation reads as a glitch.
 */
.nt-envelope {
  position: relative;
  width: 10rem;
  height: 6.5rem;
  /* Headroom the envelope's own box does not account for: the letter ends up
     46 px above it. */
  margin: 3.75rem auto 2.5rem;
}

.nt-env-back {
  position: absolute;
  inset: 0;
  border-radius: 6px;
  background: linear-gradient(168deg, var(--nt-surface-raised), var(--nt-surface-sunken));
  border: 1px solid var(--nt-hairline);
}

.nt-env-letter {
  position: absolute;
  left: 13%;
  right: 13%;
  bottom: 0.55rem;
  z-index: 2;
  display: grid;
  justify-items: center;
  align-content: start;
  gap: 0.34rem;
  padding: 0.62rem 0.6rem 0.7rem;
  border-radius: 2px;
  background: var(--nt-doc-paper);
  border: 1px solid var(--nt-doc-rule);
  box-shadow: 0 14px 22px -16px rgb(var(--nt-doc-shadow) / 0.65);
  animation: nt-letter-rise 950ms var(--nt-ease-entrance) 420ms both;
}

.nt-env-letter i {
  display: block;
  width: 66%;
  height: 2.5px;
  border-radius: 2px;
  background: var(--nt-doc-ink);
  opacity: 0.15;
}

.nt-env-letter i:first-child { width: 42%; }

.nt-env-letter .nt-seal {
  margin-top: 0.4rem;
  animation: nt-stamp 620ms var(--nt-ease-stamp) 1180ms both;
}

.nt-env-pocket {
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: 6px;
  background: linear-gradient(172deg, var(--nt-surface), var(--nt-surface-raised));
  /* The V is the envelope's mouth. drop-shadow strokes the clipped silhouette,
     because a border would be cut away along with everything else. */
  clip-path: polygon(0 24%, 50% 60%, 100% 24%, 100% 100%, 0 100%);
  filter: drop-shadow(0 -1px 0 var(--nt-hairline)) drop-shadow(0 1px 0 var(--nt-hairline));
}

/* The two folded creases of a real envelope front. */
.nt-env-pocket::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top right, transparent calc(50% - 0.5px), var(--nt-hairline) 50%, transparent calc(50% + 0.5px)),
    linear-gradient(to top left, transparent calc(50% - 0.5px), var(--nt-hairline) 50%, transparent calc(50% + 0.5px));
  opacity: 0.45;
}

@media (prefers-reduced-motion: reduce) {
  .nt-env-letter { animation: none; transform: translateY(-46px); }
  .nt-env-letter .nt-seal { animation: none; transform: rotate(-7deg); }
  .nt-auth-sheet { animation: none; transform: rotate(-2.2deg); }
}

/* Sysadmin: the same room with the lights down. Tokens are re-declared on the
   shell so the variant holds regardless of the visitor's theme — an operator
   surface must never be mistaken for the customer surface. */
.nt-auth-admin {
  /* Both vocabularies, because components from the design system and from
     this section both render inside the operator shell. */
  --nt-bg: #131210;
  --nt-text: #eae6de;
  --nt-text-secondary: #a9a49a;
  --nt-text-tertiary: #9a978f;   /* #7a766e is only 4.4:1 on this ground */
  --nt-border: #35312a;
  --nt-border-subtle: #2b2822;
  --nt-border-strong: #454036;

  --nt-paper: #131210;
  --nt-ink: #eae6de;
  --nt-ink-soft: #a9a49a;
  --nt-ink-faint: #9a978f;
  --nt-surface: #1c1a16;
  --nt-surface-raised: #232019;
  --nt-surface-sunken: #0e0d0b;
  --nt-hairline: #35312a;
  --nt-seal: #c05a68;
  --nt-seal-hover: #cf6b78;
  --nt-seal-soft: #33191d;
  --nt-seal-lift: #d97b86;
  --nt-seal-deep: #6d2530;
  --nt-on-seal: #fdf9f5;
  --nt-ok: #4d9d7c;
  --nt-ok-soft: #16241e;
  --nt-warn: #cf8a4a;
  --nt-danger: #c65a4f;
  --nt-danger-soft: #2b1a17;
  --nt-doc-paper: #e6e0d3;
  --nt-doc-ink: #22242a;
  --nt-doc-ink-soft: #565a63;
  --nt-doc-ink-faint: #83868e;
  --nt-doc-rule: #c9c1b0;
  --nt-doc-shadow: 0 0 0;

  background: var(--nt-paper);
  color: var(--nt-ink);
}

.nt-auth-admin .nt-auth-aside {
  background:
    radial-gradient(60% 50% at 28% 20%, rgba(192, 90, 104, 0.16), transparent 70%),
    linear-gradient(160deg, #1a1814, #0d0c0a);
  border-right-color: #2c2822;
}

.nt-auth-admin .nt-field-input { box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4); }

/* Contrast on the operator surface. The rosier seal that suits the wax at
   this brightness is only 4.1:1 behind white button text and 4.0:1 as chip
   text, so both get their own values instead. */
.nt-auth-admin .nt-cta-btn-primary { background: #8e303d; }
.nt-auth-admin .nt-cta-btn-primary:hover { background: #a53b49; }
.nt-auth-admin .nt-admin-badge { color: #e08d98; }
.nt-auth-admin .nt-admin-badge::before { background: #e08d98; }

.nt-admin-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.22rem 0.62rem;
  border-radius: 4px;
  border: 1px solid var(--nt-hairline);
  background: var(--nt-surface);
  font-family: var(--nt-font-mono);
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--nt-seal);
  margin-bottom: 1.1rem;
}

.nt-admin-badge::before {
  content: "";
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: var(--nt-seal);
}

/* Operator grid: hairline graph paper, only on the admin aside. */
.nt-admin-grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(234, 230, 222, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(234, 230, 222, 0.045) 1px, transparent 1px);
  background-size: 34px 34px;
  mask-image: radial-gradient(70% 60% at 40% 40%, #000, transparent 78%);
  pointer-events: none;
}

/* The broken seal — the expired-link state. Two halves of one artwork,
   clipped along a jagged line and pulled apart. */
.nt-seal-broken {
  position: relative;
  width: 7.5rem;
  height: 7.5rem;
  margin: 0 auto 1.75rem;
}

.nt-seal-broken .nt-seal { position: absolute; inset: 0; width: 100%; height: 100%; }

.nt-seal-broken .nt-seal:first-child {
  clip-path: polygon(0 0, 52% 0, 44% 22%, 56% 44%, 46% 66%, 54% 86%, 48% 100%, 0 100%);
  transform: translate3d(-6px, 2px, 0) rotate(-4deg);
}

.nt-seal-broken .nt-seal:last-child {
  clip-path: polygon(52% 0, 100% 0, 100% 100%, 48% 100%, 54% 86%, 46% 66%, 56% 44%, 44% 22%);
  transform: translate3d(6px, 5px, 0) rotate(3deg);
  filter: brightness(0.93);
}

/* A one-time code is data, so it is set like data: mono, tracked wide enough
   that a mistyped digit is obvious before you press enter. */
.nt-code-input {
  font-family: var(--nt-font-mono);
  font-size: 1.35rem;
  letter-spacing: 0.28em;
  text-align: center;
  padding-block: 0.85rem;
}

.nt-qr {
  display: flex;
  justify-content: center;
  padding: 1rem;
  margin-bottom: 1rem;
  background: #ffffff;   /* scanners want the quiet zone white in both themes */
  border: 1px solid var(--nt-hairline);
  border-radius: 10px;
}

.nt-qr svg { display: block; width: 10.5rem; height: 10.5rem; }

/* Backup codes as a ruled block — this gets printed or pasted, not clicked. */
.nt-codes {
  list-style: none;
  margin: 0 0 1.75rem;
  padding: 0.9rem 1rem;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.15rem 1rem;
  background: var(--nt-surface-sunken);
  border: 1px solid var(--nt-hairline);
  border-radius: 10px;
  font-family: var(--nt-font-mono);
  font-size: 0.9rem;
  counter-reset: code;
}

.nt-codes li {
  counter-increment: code;
  display: flex;
  gap: 0.6rem;
  padding: 0.28rem 0;
}

.nt-codes li::before {
  content: counter(code);
  color: var(--nt-ink-faint);
  font-size: 0.72rem;
  min-width: 1rem;
  padding-top: 0.12rem;
}

/* Success mark for the "confirmed elsewhere" state. */
.nt-auth-check {
  display: grid;
  place-items: center;
  width: 4.25rem;
  height: 4.25rem;
  margin: 0 auto 1.5rem;
  border-radius: 50%;
  background: var(--nt-ok-soft);
  color: var(--nt-ok);
  animation: nt-stamp 620ms var(--nt-ease-stamp) both;
}

@media (prefers-reduced-motion: reduce) {
  .nt-auth-check { animation: none; }
}

/* ── Shared bits ──────────────────────────────────────────────────────── */

.nt-public-flash {
  max-width: var(--nt-shell);
  margin-inline: auto;
  padding: 0.85rem var(--nt-gutter) 0;
}

.nt-arrow { display: inline-block; line-height: 1; }
.nt-inline { display: inline-flex; align-items: center; gap: 0.45rem; }

/* ── /stiftelse set pieces ────────────────────────────────────────────────
 * The flow band reuses the aarshjul's ruled line with five stops instead of
 * four and a third line of detail under each; the kapital ledger is a
 * four-row account where three rows carry the same number and the fourth is
 * zero — which is the entire argument, made without a paragraph.
 */

.nt-frist-stops-5 .nt-frist-stop { width: 11rem; }

.nt-frist-detail {
  margin-top: 0.28rem;
  font-size: 0.72rem;
  line-height: 1.4;
  color: var(--nt-text-secondary);
}

@media (max-width: 860px) {
  /* Three lines per stop, not two — `.nt-frist-detail` needs a row of its own,
     which the flex row the generic ≤860px rule builds cannot give it. So: a
     single-column grid with the dot lifted out of flow onto the rule.

     It used to be a two-column grid with a fixed 6.5rem first column for the
     dot. The dot was never in that column: `.nt-frist-dot { margin-left:
     -2.25rem }` had already pulled it onto the rail, so the column was 104px
     of dead gutter on a 390px phone and all five stops read in the right third
     of the screen. Reported from a real iPhone, not from a devtools width. */
  .nt-frist-stops-5 .nt-frist-stop {
    /* The desktop rail pins every stop to 11rem so five of them space evenly
       along the axis. Off the axis that is just a 176px box with 170px of
       phone left over beside it — the generic rule's `width: auto` loses to
       this selector's extra class, so it has to be undone by name. */
    width: auto;
    display: grid;
    /* A ZERO-width first column, and the dot overflows it by the same negative
       margin the four-stop rail uses. The dot needs a column of its own — it
       spans all three text rows — but it must not RESERVE any width, because
       the margin has already carried it out onto the rule.

       Zero rather than `position: absolute`, and static rather than relative,
       because each <li> carries an inline `left: 6% … 90%` for the desktop
       axis. Giving the stop a position other than static hands those inline
       percentages back their meaning, and the five stops march off the right
       edge of the phone in 20% steps. Inline styles cannot be reset from here
       without `!important`, so the layout simply must not depend on `left`. */
    grid-template-columns: 0 minmax(0, 1fr);
    column-gap: 0;
    row-gap: 0.15rem;
    align-items: start;
  }

  .nt-frist-stops-5 .nt-frist-dot {
    grid-column: 1;
    grid-row: 1 / span 3;
    align-self: start;
    margin-left: -2.25rem;
  }

  /* The date is a row of its own here, so the width the generic rule reserves
     for it BESIDE the label has nothing left to do. */
  .nt-frist-stops-5 .nt-frist-when { grid-column: 2; min-width: 0; }
  .nt-frist-stops-5 .nt-frist-what { grid-column: 2; }
  .nt-frist-stops-5 .nt-frist-detail { grid-column: 2; margin-top: 0; }
}

.nt-kapital-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2.5rem;
  align-items: start;
}

@media (min-width: 960px) {
  .nt-kapital-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr); gap: 4rem; }
}

.nt-prose-block { font-size: 0.98rem; line-height: 1.7; color: var(--nt-ink-soft); max-width: 38rem; }
.nt-prose-block p { margin: 0 0 1em; }
.nt-prose-block p:last-child { margin-bottom: 0; }

.nt-ledger {
  background: var(--nt-surface);
  border: 1px solid var(--nt-hairline);
  border-radius: 12px;
  box-shadow: var(--nt-shadow-2);
  overflow: hidden;
}

.nt-ledger-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 0;
  padding: 0.95rem 1.35rem;
  border-bottom: 1px solid var(--nt-hairline);
  background: var(--nt-surface-raised);
  font-family: var(--nt-font-mono);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--nt-ink-faint);
}

.nt-ledger-rows { margin: 0; padding: 0.4rem 1.35rem 0.9rem; }

.nt-ledger-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 1rem;
  padding: 0.85rem 0;
  border-bottom: 1px dashed var(--nt-hairline);
}

.nt-ledger-row:last-child { border-bottom: 0; }

.nt-ledger-row dt { font-size: 0.9rem; font-weight: 550; color: var(--nt-ink); }

.nt-ledger-note {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.76rem;
  font-weight: 400;
  line-height: 1.45;
  color: var(--nt-ink-faint);
}

.nt-ledger-row dd {
  margin: 0;
  font-family: var(--nt-font-display);
  font-size: 1.4rem;
  font-weight: 600;
  font-variation-settings: "opsz" 36, "SOFT" 18, "WONK" 0;
  letter-spacing: -0.02em;
  color: var(--nt-ink);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* The zero is the punchline, so it is the only figure in compliance green. */
.nt-ledger-row dd.is-zero { color: var(--nt-ok); }

.nt-ledger-foot {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 0;
  padding: 0.9rem 1.35rem 1.05rem;
  border-top: 1px solid var(--nt-hairline);
  background: var(--nt-ok-soft);
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--nt-ok);
}

.nt-ledger-foot .nt-doc-status-dot { margin-top: 0.42rem; flex: 0 0 auto; }

.nt-cta-note { margin: 1.1rem 0 0; font-size: 0.8rem; color: rgba(243, 237, 226, 0.6); }

/* Marks inside marketing cards inherit the card's ink. */
.mk-card .nt-mark { color: var(--nt-ink-soft); }

/* ── /priser set pieces ───────────────────────────────────────────────────
 * The invoice you do not get, on the same paper as the documents Notarium
 * produces — because the comparison only lands if both sides are drawn in
 * the same hand. The counter-offer is a slip stamped over its corner.
 */

.nt-invoice-stage { position: relative; display: flex; justify-content: center; padding: 0 0 4.5rem 1rem; }

.nt-invoice-sheet {
  width: min(100%, 27rem);
  aspect-ratio: auto;                 /* an invoice is not an A4 page of prose */
  padding: 2.1rem 2rem 1.9rem;
  font-size: clamp(0.5rem, 0.68vw, 0.62rem);
  transform: rotate(-1.4deg);
}

.nt-invoice-from {
  font-family: var(--nt-font-mono);
  font-size: 0.8em;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--nt-doc-ink-faint);
  margin: 0 0 0.7em;
}

.nt-invoice-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 0.4em;
  font-size: 1em;
}

.nt-invoice-table th,
.nt-invoice-table td { text-align: left; padding: 0.55em 0; vertical-align: baseline; }

.nt-invoice-table thead th {
  font-family: var(--nt-font-body);
  font-size: 0.76em;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--nt-doc-ink-soft);
  border-bottom: 1px solid var(--nt-doc-rule);
  padding-bottom: 0.55em;
}

.nt-invoice-table tbody td { border-bottom: 1px dotted var(--nt-doc-rule); color: var(--nt-doc-ink); }
.nt-invoice-table tbody td:first-child { padding-right: 1.2em; }
.nt-invoice-table .is-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.nt-invoice-table thead th:not(:first-child) { text-align: right; }

.nt-invoice-table tfoot td {
  padding-top: 0.8em;
  font-weight: 600;
  color: var(--nt-doc-ink);
  border-top: 2px solid var(--nt-doc-rule);
}

.nt-invoice-table .is-total {
  font-family: var(--nt-font-display);
  font-size: 1.5em;
  font-weight: 600;
  font-variation-settings: "opsz" 36, "SOFT" 18, "WONK" 0;
  letter-spacing: -0.02em;
}

.nt-invoice-rate {
  margin: 1.1em 0 0;
  font-family: var(--nt-font-mono);
  font-size: 0.78em;
  color: var(--nt-doc-ink-faint);
}

/* The slip: our price, stamped across the invoice's bottom corner. */
.nt-invoice-slip {
  position: absolute;
  right: -0.75rem;
  bottom: 0.25rem;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.95rem 1.15rem;
  border-radius: 10px;
  background: var(--nt-surface);
  border: 1px solid var(--nt-ok);
  box-shadow: 0 16px 34px -16px rgba(30, 107, 79, 0.5), var(--nt-shadow-2);
  transform: rotate(1.6deg);
}

.nt-invoice-slip-label {
  font-family: var(--nt-font-mono);
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--nt-ink-faint);
  margin: 0 0 0.15rem;
}

.nt-invoice-slip-amount {
  font-family: var(--nt-font-display);
  font-size: 1.85rem;
  font-weight: 600;
  font-variation-settings: "opsz" 48, "SOFT" 16, "WONK" 0;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--nt-ok);
  margin: 0;
}

.nt-invoice-slip-amount span {
  font-family: var(--nt-font-body);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--nt-ink-faint);
  margin-left: 0.3rem;
}

.nt-invoice-slip-note {
  margin: 0.3rem 0 0;
  font-size: 0.74rem;
  line-height: 1.4;
  color: var(--nt-ink-soft);
  max-width: 13rem;
}

@media (max-width: 560px) {
  .nt-invoice-stage { padding-bottom: 0; flex-direction: column; align-items: stretch; gap: 1rem; }
  .nt-invoice-sheet { transform: none; }
  .nt-invoice-slip { position: static; transform: none; }
}

/* The comparison table: our column is the one that is paid attention to. */
.nt-compare .is-ours { background: var(--nt-ok-soft); color: var(--nt-ink); font-weight: 550; }
.nt-compare thead .is-ours { color: var(--nt-ok); }
.nt-compare .is-them { color: var(--nt-ink-faint); }

/* ══════════════════════════════════════════════════════════════════════
   TEXT COLOUR UTILITIES — must stay LAST in this file
   ══════════════════════════════════════════════════════════════════════

   A single-property utility whose whole job is to override a component's
   colour has to be declared after every component, or it loses the cascade at
   equal specificity. These sat near the top for a long time, which is why
   `class="nt-hint nt-warn-fg"` rendered grey: `.nt-hint` also sets `color`,
   was declared later, and won. Nothing errors when that happens — the colour
   just never arrives.

   Anything appended below this block must not set `color` on a bare utility
   class. */

.nt-muted { color: var(--nt-text-secondary); }
.nt-faint { color: var(--nt-text-tertiary); }
.nt-ink { color: var(--nt-text); }
.nt-ok-fg { color: var(--nt-ok-text); }
.nt-warn-fg { color: var(--nt-warn-text); }
.nt-danger-fg { color: var(--nt-danger-text); }
.nt-seal-fg { color: var(--nt-seal-text); }
