/*
 * NorthThread design tokens, "ledger paper" (project brief Section 3a).
 *
 * All theming happens here by overriding Bootstrap 5.3 CSS variables at the
 * token and component-variable level. Never scatter hex values through views;
 * never fork Bootstrap. New styles belong in a commented section below.
 */

/* ===== Tokens ===== */
:root {
  --ink: #10192B;      /* near-black blue-slate, body text, table figures */
  --paper: #EEF2F7;    /* page stock: chrome (sidebar, top bar) sits on this */
  --canvas: #D3DBE6;   /* the app's working background, a step under the cards */
  --surface: #FFFFFF;  /* cards, tables */
  --accent: #1F4FD8;   /* brand blue, one step deeper than the site's, for buttons, links, active nav */
  --accent-hover: #183FB0;
  --credit: #1E8A4C;   /* ledger green, money recovered, passing checks */
  --debit: #C43D31;    /* ledger red, shortfalls, blockers */
  --amber: #B87A14;    /* warnings, waived exceptions (accents/large use) */
  --amber-ink: #96650F; /* amber darkened for small text, keeps WCAG AA on paper */
  --hairline: #B9C4D3; /* 1px borders instead of shadows */

  /* Map tokens onto Bootstrap */
  --bs-body-bg: var(--paper);
  --bs-body-color: var(--ink);
  --bs-emphasis-color: var(--ink);
  --bs-border-color: var(--hairline);
  --bs-border-radius: 6px;
  --bs-link-color: var(--accent);
  --bs-link-color-rgb: 31, 79, 216;
  --bs-link-hover-color: var(--accent-hover);
  --bs-link-hover-color-rgb: 24, 63, 176;
  --bs-primary: var(--accent);
  --bs-primary-rgb: 31, 79, 216;
  --bs-success: var(--credit);
  --bs-success-rgb: 30, 138, 76;
  --bs-danger: var(--debit);
  --bs-danger-rgb: 196, 61, 49;
  --bs-warning: var(--amber);
  --bs-warning-rgb: 184, 122, 20;
}

/* The brand ribbon gradient (same stops as the logo), the product's one
   decorative signature: the hero pipeline rail, usage meters, and money the
   engine found. Everything else stays in status colors. */
:root {
  --nt-gradient: linear-gradient(100deg, #0A1B4D 0%, #2154E8 55%, #9DBCFA 100%);
}

/* ===== Dark theme =====
   Token flips only; components derive from tokens and color-mix, so most of
   the app follows. Toggled from the topbar (controllers/theme_controller.js),
   persisted in localStorage, applied to <html> before first paint. */
[data-bs-theme="dark"] {
  --ink: #E4E9EF;
  --paper: #14181E;
  --canvas: #0E1116;
  --surface: #1A1F26;
  --accent: #7FA6F5;
  --accent-hover: #9DBCFA;
  --credit: #3FA96E;
  --debit: #E0705E;
  --amber: #C79136;
  --amber-ink: #D9A94A;
  --hairline: #2A313B;
  --bs-link-color-rgb: 127, 166, 245;
  --bs-link-hover-color-rgb: 157, 188, 250;
  --bs-primary-rgb: 127, 166, 245;
}

[data-bs-theme="dark"] .card {
  border-color: color-mix(in srgb, var(--ink) 10%, transparent);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 12px 32px -18px rgba(0, 0, 0, 0.6);
}

[data-bs-theme="dark"] .btn-primary { color: #0E1116; }

/* Bootstrap component variables (compiled colors don't follow --bs-primary) */
.btn-primary {
  --bs-btn-bg: var(--accent);
  --bs-btn-border-color: var(--accent);
  --bs-btn-hover-bg: var(--accent-hover);
  --bs-btn-hover-border-color: var(--accent-hover);
  --bs-btn-active-bg: var(--accent-hover);
  --bs-btn-active-border-color: var(--accent-hover);
  --bs-btn-disabled-bg: var(--accent);
  --bs-btn-disabled-border-color: var(--accent);
}

.btn-outline-primary {
  --bs-btn-color: var(--accent);
  --bs-btn-border-color: var(--accent);
  --bs-btn-hover-bg: var(--accent);
  --bs-btn-hover-border-color: var(--accent);
  --bs-btn-active-bg: var(--accent);
  --bs-btn-active-border-color: var(--accent);
}

.form-check-input:checked {
  background-color: var(--accent);
  border-color: var(--accent);
}

/* ===== Base ===== */
.card, .table {
  background-color: var(--surface);
}

/* Cards float on the canvas with layered soft shadows, not drawn borders.
   The faint ink border is only there so cards keep an edge on pale screens. */
.card {
  --bs-card-border-radius: 14px;
  --bs-card-inner-border-radius: 13px;
  border: 1px solid color-mix(in srgb, var(--ink) 5%, transparent);
  box-shadow:
    0 1px 2px rgba(27, 39, 51, 0.04),
    0 12px 32px -18px rgba(27, 39, 51, 0.16);
}

/* Quiet table chrome: muted sentence-case headers, whisper-faint row rules.
   Cells inherit the card's white, never the page background. */
.card .table {
  --bs-border-color: color-mix(in srgb, var(--ink) 6%, transparent);
  --bs-table-bg: transparent;
}

.card .table thead th {
  font-size: 0.76rem;
  letter-spacing: 0.01em;
  font-weight: 600;
  color: color-mix(in srgb, var(--ink) 58%, transparent);
  border-bottom-width: 1px;
}

.card .table-hover > tbody > tr:hover > * {
  background: color-mix(in srgb, var(--accent) 4%, transparent);
  box-shadow: none;
}

/* Pill badges, soft-tinted. */
.badge {
  border-radius: 999px;
  padding: 0.38em 0.75em;
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* Softer control corners across the app. */
.btn { --bs-btn-border-radius: 0.55rem; }
.form-control, .form-select { border-radius: 0.55rem; }

/* Tabular numerals wherever money or counts appear (non-negotiable). */
.num {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* Sticky headers on data tables (brief Section 3a). */
.card table thead th {
  position: sticky;
  top: 0;
  background: var(--surface);
  z-index: 2;
}

/* ===== App shell ===== */
.nt-shell {
  display: flex;
  min-height: 100vh;
}

.nt-sidebar {
  width: 224px;
  --bs-offcanvas-width: 264px; /* offcanvas mode below lg; desktop stays 224px */
  flex-shrink: 0;
  background: var(--surface);
  border-right: 1px solid color-mix(in srgb, var(--ink) 6%, transparent);
  padding: 1rem 0.75rem;
  display: flex;
  flex-direction: column;
}

.nt-wordmark {
  font-weight: 650;
  font-size: 1.05rem;
  letter-spacing: 0.01em;
  color: var(--ink);
  text-decoration: none;
  padding: 0.25rem 0.75rem 1.1rem;
  display: block;
}

.nt-wordmark:hover { color: var(--accent); }

.nt-nav .nav-link {
  color: color-mix(in srgb, var(--ink) 78%, transparent);
  border-radius: 9px;
  padding: 0.45rem 0.75rem;
  font-size: 0.925rem;
}

.nt-nav .nav-link:hover {
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  color: var(--ink);
}

.nt-nav .nav-link.active {
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  color: var(--accent);
  font-weight: 600;
}

.nt-nav .nav-link.disabled {
  color: color-mix(in srgb, var(--ink) 40%, transparent);
}

.nt-main {
  flex-grow: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--canvas);
}

.nt-topbar {
  background: var(--surface);
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 6%, transparent);
  padding: 0.5rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 52px;
}

/* The trail in the top bar: section, then page. */
.nt-trail { display: flex; align-items: center; gap: 0.4rem; min-width: 0; font-size: 0.88rem; }
.nt-trail-link { color: color-mix(in srgb, var(--ink) 55%, transparent); text-decoration: none; }
.nt-trail-link:hover { color: var(--accent); }
.nt-trail-sep { font-size: 0.65rem; color: color-mix(in srgb, var(--ink) 35%, transparent); }
.nt-trail-here { color: var(--ink); font-weight: 500; }

.nt-content {
  padding: 1.5rem;
  max-width: 1400px;
  width: 100%;
}

/* Single period-picker pill: "March 2026" + calendar icon. */
.nt-datepick {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
  border-radius: 10px;
  padding: 0.45rem 0.9rem;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(27, 39, 51, 0.05);
}

.nt-datepick:hover { border-color: color-mix(in srgb, var(--ink) 22%, transparent); }

.nt-datepick i { color: color-mix(in srgb, var(--ink) 55%, transparent); }

.nt-month-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.35rem;
}

.nt-month-cell {
  text-align: center;
  padding: 0.35rem 0.25rem;
  border-radius: 8px;
  font-size: 0.83rem;
  color: var(--ink);
  text-decoration: none;
}

.nt-month-cell:hover { background: color-mix(in srgb, var(--ink) 5%, transparent); }

.nt-month-active {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  font-weight: 600;
}

/* Topbar bell and user chip. */
.nt-bell {
  border: none;
  padding: 0.35rem 0.5rem;
  font-size: 1.15rem;
  color: color-mix(in srgb, var(--ink) 65%, transparent);
  border-radius: 10px;
}

.nt-bell:hover { background: color-mix(in srgb, var(--ink) 5%, transparent); color: var(--ink); }

.nt-bell-badge {
  position: absolute;
  top: 0;
  right: 0;
  background: var(--debit);
  color: #fff;
  font-size: 0.62rem;
  font-weight: 600;
  line-height: 1;
  padding: 0.22em 0.45em;
  border-radius: 999px;
  border: 2px solid var(--surface);
}

.nt-userchip {
  border: none;
  padding: 0.25rem 0.5rem;
  border-radius: 10px;
}

.nt-userchip:hover { background: color-mix(in srgb, var(--ink) 5%, transparent); }

.nt-avatar {
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.02em;
  color: #fff;
  background: linear-gradient(135deg, #163A5F, var(--accent) 60%, #149B62);
}

/* ===== Auth screens (centered card on paper) ===== */
.nt-auth {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
  background: var(--canvas);
}

.nt-auth-card {
  width: 100%;
  max-width: 420px;
}

/* ===== Severity badges (validation exceptions) ===== */
.badge.nt-blocker {
  background: color-mix(in srgb, var(--debit) 12%, transparent);
  color: var(--debit);
  border: 1px solid color-mix(in srgb, var(--debit) 35%, transparent);
}

.badge.nt-ok {
  background: color-mix(in srgb, var(--credit) 12%, transparent);
  color: var(--credit);
  border: 1px solid color-mix(in srgb, var(--credit) 35%, transparent);
}

.badge.nt-warning {
  background: color-mix(in srgb, var(--amber) 14%, transparent);
  color: var(--amber-ink);
  border: 1px solid color-mix(in srgb, var(--amber) 40%, transparent);
}

/* ===== Reconciliation Delta strip (the one deliberate moment of drama) ===== */
.nt-delta-strip {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-left: 4px solid var(--debit);
  border-radius: var(--bs-border-radius);
  padding: 1rem 1.5rem;
}

.nt-delta-strip.nt-delta-clear { border-left-color: var(--credit); }

.nt-delta-strip .nt-delta-figure {
  font-size: 2rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--debit);
}

.nt-delta-strip.nt-delta-clear .nt-delta-figure { color: var(--credit); }

/* ===== Empty states ===== */
.nt-empty {
  text-align: center;
  padding: 4rem 2rem;
  color: color-mix(in srgb, var(--ink) 75%, transparent);
}

/* ===== Marketing site ===== */
/* Display face: Fraunces (SIL OFL, self-hosted). Marketing pages only; the
   app keeps the system stack per the brief. */
@font-face {
  font-family: "Fraunces";
  src: url("/assets/fraunces-600-fd14a0a0.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Fraunces";
  src: url("/assets/fraunces-600-italic-8a947094.woff2") format("woff2");
  font-weight: 600;
  font-style: italic;
  font-display: swap;
}

.nt-marketing {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.nt-marketing h1, .nt-marketing h2 {
  font-family: "Fraunces", Georgia, "Times New Roman", serif;
  font-weight: 600;
}

.nt-marketing h2 {
  font-size: clamp(1.7rem, 3vw, 2.3rem);
  letter-spacing: -0.01em;
}

/* Vertical rhythm: whitespace does the separating, not boxes and bands. */
.nt-section {
  padding-block: clamp(2.75rem, 5vw, 3.5rem);
}

.nt-section-head {
  max-width: 640px;
  margin-inline: auto;
  text-align: center;
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}

.nt-section-head p {
  color: color-mix(in srgb, var(--ink) 62%, transparent);
  font-size: 1.05rem;
  margin-bottom: 0;
}

/* The one flourish inside headlines: serif italic in brand teal. Red is
   reserved for money that's missing, never decoration. */
/* Headlines are ink, always: brand is spoken for by the button, the links,
   the badge, and the definition rule. The italic does the emphasis. */
.nt-marketing h1 em, .nt-marketing h2 em {
  font-style: italic;
  color: var(--ink);
}

.nt-navbar {
  /* Opaque near-white. Paper is a shade darker than the hero below it, and
     any translucency turns the bar grey as it scrolls over the navy
     sections, which is the same grime by another route. */
  background: var(--nav-bg);
  border-bottom: 1px solid var(--hairline);
  /* Ledger rule across the very top, like the head of a bound register. */
  border-top: 3px solid var(--accent);
  padding-block: 0.9rem;
}

.nt-navbar .navbar-brand { font-size: 1.35rem; }

.nt-navbar .nav-link {
  color: var(--ink);
  font-size: 1.05rem;
  padding-inline: 0.95rem;
}

/* The nav CTA is a pill. A fully rounded button needs more room at the ends
   than a square one, or the label sits on the curve. */
.nt-navbar .btn {
  font-size: 0.95rem;
  --bs-btn-border-radius: 999px;
  padding-inline: 1.25rem;
}

.nt-navbar .nav-link.active {
  color: var(--accent);
  font-weight: 600;
}

.nt-brand {
  font-weight: 650;
  letter-spacing: 0.01em;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  text-decoration: none;
}

.nt-brand:hover { color: var(--accent); }

/* Brand mark: the ribbon-N logo (app/assets/images/logo.png). */
.nt-brand-logo {
  height: 2.1rem;
  width: auto;
  flex-shrink: 0;
}

/* Bigger on the marketing nav and auth pages, where the brand leads. */
.nt-navbar .nt-brand-logo { height: 2.7rem; }
.nt-auth .nt-brand-logo { height: 2.9rem; }

.nt-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 0.75rem;
  font-weight: 650;
  color: var(--accent);
  margin-bottom: 0.75rem;
}

/* Hero eyebrow: the audience callout as a pill badge with a live dot. */
.nt-eyebrow-lg {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: clamp(0.8rem, 1.1vw, 0.92rem);
  letter-spacing: 0.1em;
  padding: 0.5rem 1.1rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
}

.nt-eyebrow-lg::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
}

.nt-display {
  font-size: clamp(2rem, 4vw, 2.9rem);
  font-weight: 600;
  line-height: 1.26;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.nt-display-sm {
  font-size: clamp(1.8rem, 3.5vw, 2.5rem);
  font-weight: 650;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.nt-photo {
  border-radius: 10px;
  border: 1px solid var(--hairline);
  object-fit: cover;
  aspect-ratio: 4 / 3;
}

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

.nt-pillar {
  padding: 0.5rem;
  height: 100%;
  max-width: 340px;
  margin-inline: auto;
}

.nt-pillar-icon {
  font-size: 1.5rem;
  color: var(--accent);
  display: inline-block;
  margin-bottom: 0.75rem;
}

.nt-steps {
  padding-left: 0;
  list-style: none;
  counter-reset: step;
  margin-bottom: 1.5rem;
}

.nt-steps li {
  counter-increment: step;
  position: relative;
  padding-left: 3rem;
  margin-bottom: 1rem;
}

.nt-steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: -0.15rem;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--accent);
  font-weight: 650;
  display: flex;
  align-items: center;
  justify-content: center;
  font-variant-numeric: tabular-nums;
}

/* Pricing */
.nt-price-card {
  border: 1px solid var(--hairline);
  border-radius: 10px;
  background: var(--surface);
  padding: 1.75rem;
  height: 100%;
  position: relative;
}

.nt-price-featured {
  border-color: var(--accent);
  box-shadow: 0 8px 24px color-mix(in srgb, var(--accent) 12%, transparent);
}

.nt-price-flag {
  position: absolute;
  top: -0.7rem;
  left: 1.5rem;
  background: var(--accent);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
}

.nt-price {
  font-size: 2.25rem;
  font-weight: 650;
  color: var(--ink);
  margin-bottom: 1rem;
  text-align: left; /* .num right-aligns; prices anchor left in their card */
}

.nt-price-period {
  font-size: 0.95rem;
  font-weight: 400;
  color: color-mix(in srgb, var(--ink) 60%, transparent);
}

.nt-price-list {
  list-style: none;
  padding-left: 0;
  margin-bottom: 1.5rem;
  font-size: 0.9rem;
}

.nt-price-list li {
  margin-bottom: 0.5rem;
  padding-left: 1.5rem;
  position: relative; /* hanging indent: wrapped lines align after the check */
}

.nt-price-list .bi {
  color: var(--credit);
  position: absolute;
  left: 0;
}

/* About values / contact rows */
.nt-value {
  display: flex;
  gap: 0.9rem;
  align-items: flex-start;
}

.nt-value .bi {
  font-size: 1.25rem;
  color: var(--accent);
  margin-top: 0.1rem;
}

/* Footer: dark ink grounds the page. */
.nt-footer {
  background: var(--ink);
  color: color-mix(in srgb, var(--paper) 80%, transparent);
}

.nt-footer .nt-brand { color: var(--paper); }

.nt-footer .text-secondary {
  color: color-mix(in srgb, var(--paper) 55%, transparent) !important;
}

.nt-footer-heading {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: color-mix(in srgb, var(--paper) 50%, transparent);
  margin-bottom: 0.75rem;
}

.nt-footer a {
  color: color-mix(in srgb, var(--paper) 85%, transparent);
  text-decoration: none;
}

.nt-footer a:hover { color: #fff; }
.nt-footer li { margin-bottom: 0.4rem; }
.nt-footer .border-top { border-color: color-mix(in srgb, var(--paper) 15%, transparent) !important; }

/* ===== Home: hero, headline left, real dashboard shot right ===== */
/* A fine dot matrix reads as precision instrumentation; it fades out
   behind the headline so the copy sits on clean paper, with a soft mint
   wash behind the dashboard shot. */
.nt-hero-light {
  background:
    radial-gradient(ellipse 62% 75% at 26% 45%, var(--hero-wash) 32%, transparent 76%),
    radial-gradient(circle, color-mix(in srgb, var(--accent) 30%, transparent) 1.2px, transparent 1.8px) 0 0 / 24px 24px,
    radial-gradient(ellipse 50% 55% at 86% 12%, color-mix(in srgb, var(--accent) 10%, transparent), transparent 70%),
    linear-gradient(180deg, var(--hero-top) 0%, var(--hero-bottom) 100%);
  border-bottom: 1px solid var(--hairline);
  overflow: hidden;
}

/* The app shot: a faithful miniature of the real dashboard. */
.nt-app-shot {
  display: flex;
  background: linear-gradient(180deg, var(--surface-grad-top) 0%, var(--surface-grad-bottom) 100%);
  border: 1px solid var(--hairline);
  border-radius: 14px;
  overflow: hidden;
  box-shadow:
    0 1px 2px rgba(15, 33, 32, 0.06),
    0 24px 70px -24px rgba(15, 33, 32, 0.35);
}

.nt-app-side {
  flex: 0 0 168px;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.9rem 0.6rem;
  background: var(--surface);
  border-right: 1px solid var(--hairline);
  font-size: 0.8rem;
}

.nt-app-side-brand {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 650;
  font-size: 0.85rem;
  padding: 0.15rem 0.5rem 0.8rem;
  color: var(--ink);
}

.nt-app-side-logo { height: 1.1rem; width: auto; }

.nt-app-side-link {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.35rem 0.55rem;
  border-radius: 7px;
  color: color-mix(in srgb, var(--ink) 72%, transparent);
}

.nt-app-side-link i { font-size: 0.85rem; }

.nt-app-side-active {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent-ink, var(--accent));
  font-weight: 600;
}

.nt-app-main {
  flex: 1 1 auto;
  min-width: 0;
  padding: 1rem;
  background: var(--canvas);
}

.nt-app-tiles {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.6rem;
}

.nt-app-tile {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 9px;
  padding: 0.55rem 0.65rem;
  min-width: 0;
}

.nt-app-tile-label {
  font-size: 0.68rem;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nt-app-tile-value {
  font-size: 1.15rem;
  font-weight: 650;
  color: var(--ink);
  line-height: 1.3;
}

.nt-app-tile-note { font-size: 0.68rem; color: color-mix(in srgb, var(--ink) 55%, transparent); white-space: nowrap; }

.nt-app-tablecard {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 9px;
  overflow: hidden;
}

@media (max-width: 575px) {
  .nt-app-tiles { grid-template-columns: repeat(2, 1fr); }
}

/* Full-width one-sentence promise band. */
.nt-claim-band {
  background: linear-gradient(180deg, var(--sunk-top) 0%, var(--sunk-bottom) 100%);
  border-block: 1px solid var(--hairline);
  padding-block: clamp(2.5rem, 5vw, 3.5rem);
}

.nt-claim {
  font-family: "Fraunces", Georgia, "Times New Roman", serif;
  font-size: clamp(1.5rem, 3vw, 2.2rem);
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);
  max-width: 820px;
  margin-inline: auto;
}

.nt-claim em {
  font-style: italic;
  color: var(--ink);
}

/* Four-step pipeline strip under the hero: numbered beats with tinted
   icon tiles, chevroned left to right. Recover carries the credit tint.
   An opaque surface panel, so the hero's decorative backdrop never shows
   through it. */
.nt-step-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  background: linear-gradient(180deg, var(--sunk-top) 0%, var(--sunk-bottom) 100%);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 14px 36px -20px rgba(0, 0, 0, 0.55);
}

.nt-step {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  padding: 1.35rem 1.9rem 1.35rem 1.1rem;
  transition: background-color 0.15s ease;
}

.nt-step:hover { background: color-mix(in srgb, var(--accent) 4%, transparent); }

.nt-step-tile {
  flex-shrink: 0;
  width: 42px;
  height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 11px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  font-size: 1.15rem;
}

.nt-strip-num {
  display: block;
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: color-mix(in srgb, var(--accent) 80%, var(--ink));
  margin-bottom: 0.1rem;
}

.nt-step strong { display: block; font-size: 0.98rem; line-height: 1.3; }

.nt-step-text {
  display: block;
  font-size: 0.8rem;
  line-height: 1.45;
  color: color-mix(in srgb, var(--ink) 60%, transparent);
  margin-top: 0.1rem;
}

@media (max-width: 767px) {
  .nt-step-strip { grid-template-columns: 1fr 1fr; }
  .nt-step { padding-right: 1.1rem; }
  .nt-step:nth-child(2n) { border-left: 1px solid var(--hairline); }
  .nt-step:nth-child(n+3) { border-top: 1px solid var(--hairline); }
}

/* ===== Mono ledger labels (eyebrows, stat labels, CTA buttons) ===== */
.nt-mono {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.78rem;
  font-weight: 500;
}

.nt-eyebrow {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-weight: 500;
}

.btn.nt-mono { letter-spacing: 0.1em; padding-block: 0.85rem; }

/* ===== Scroll reveal ===== */
[data-controller~="reveal"] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}

[data-controller~="reveal"].is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-controller~="reveal"] { opacity: 1; transform: none; transition: none; }
}

/* ===== Icon tiles (color against the paper) ===== */
.nt-icon-tile {
  width: 46px;
  height: 46px;
  border-radius: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.35rem;
  margin-bottom: 0.9rem;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
}

.nt-icon-tile-credit {
  background: color-mix(in srgb, var(--credit) 12%, transparent);
  color: var(--credit);
}

.nt-icon-tile-debit {
  background: color-mix(in srgb, var(--debit) 10%, transparent);
  color: var(--debit);
}

.nt-icon-tile-amber {
  background: color-mix(in srgb, var(--amber) 14%, transparent);
  color: var(--amber-ink);
}

/* ===== Product window mockup (the hero shows the product, not a photo) ===== */
.nt-window {
  max-width: 880px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  box-shadow: 0 24px 60px -24px color-mix(in srgb, var(--ink) 35%, transparent);
  overflow: hidden;
  text-align: left;
}

.nt-window-bar {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.6rem 1rem;
  border-bottom: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--paper) 60%, var(--surface));
}

.nt-window-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--hairline);
}

.nt-window-url {
  margin-left: 0.75rem;
  font-size: 0.75rem;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  padding: 0.15rem 0.75rem;
  font-variant-numeric: tabular-nums;
}

.nt-window-body {
  padding: 1.25rem 1.5rem;
}

.nt-window-table th, .nt-window-table td {
  padding-block: 0.5rem;
}

.nt-chip {
  display: inline-block;
  font-size: 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 0.15rem 0.6rem;
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}

/* ===== Pain vignettes ===== */
/* Borderless: the red timestamp is enough signal; whitespace does the rest. */
/* ===== Old way vs NorthThread ===== */
.nt-compare {
  border-radius: 10px;
  padding: 1.75rem;
  height: 100%;
  border: 1px solid var(--hairline);
  background: linear-gradient(180deg, var(--surface-grad-top) 0%, var(--surface-grad-bottom) 100%);
}

.nt-compare ul {
  list-style: none;
  padding-left: 0;
  margin-bottom: 0;
}

.nt-compare li {
  display: flex;
  gap: 0.65rem;
  align-items: baseline;
  margin-bottom: 0.75rem;
  font-size: 0.95rem;
}

.nt-compare li:last-child { margin-bottom: 0; }

.nt-compare-old {
  background: transparent;
}

.nt-compare-old .bi {
  color: color-mix(in srgb, var(--debit) 70%, transparent);
  font-size: 0.8rem;
}

.nt-compare-old li { color: color-mix(in srgb, var(--ink) 75%, transparent); }

.nt-compare-new {
  background: var(--surface);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--hairline));
  box-shadow: 0 8px 24px color-mix(in srgb, var(--accent) 10%, transparent);
}

.nt-compare-new .bi { color: var(--credit); font-size: 0.9rem; }

/* ===== Dark money band (calculator) ===== */
.nt-dark {
  background: linear-gradient(160deg, var(--dark-top), var(--dark-bottom));
  color: var(--paper);
}

.nt-dark h2 { color: #fff; }

.nt-dark-muted { color: color-mix(in srgb, var(--paper) 72%, transparent); }

.nt-dark-card {
  background: color-mix(in srgb, #fff 6%, transparent);
  border: 1px solid color-mix(in srgb, #fff 18%, transparent);
  border-radius: 12px;
  padding: 2.5rem 2rem;
}

.nt-dark-figure {
  font-size: clamp(2.5rem, 5vw, 3.5rem);
  font-weight: 650;
  color: #fff;
  text-align: center;
  line-height: 1.1;
  margin-block: 0.5rem;
}

.nt-dark-rule {
  border-color: color-mix(in srgb, #fff 20%, transparent);
  opacity: 1;
}

.nt-slider-label {
  display: flex;
  justify-content: space-between;
  font-size: 0.85rem;
  margin-bottom: 0.25rem;
  color: #fff;
}

.nt-slider-label .num { color: #fff; font-weight: 650; }

.nt-range { margin-bottom: 1.25rem; }

.nt-range::-webkit-slider-thumb { background: var(--paper); }
.nt-range::-moz-range-thumb { background: var(--paper); }
.nt-range::-webkit-slider-runnable-track { background: color-mix(in srgb, #fff 25%, transparent); }
.nt-range::-moz-range-track { background: color-mix(in srgb, #fff 25%, transparent); }

/* ===== Feature checks ===== */
.nt-check-item {
  display: flex;
  gap: 0.7rem;
  align-items: baseline;
  padding-block: 0.45rem;
  font-size: 0.95rem;
  color: color-mix(in srgb, var(--ink) 82%, transparent);
}

.nt-check-item .bi { color: var(--credit); }

/* Honeypot: visually gone, still in the DOM for bots. */
.nt-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Accordion in brand colors */
.accordion-button:not(.collapsed) {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  color: var(--accent);
}

.accordion-button:focus {
  box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--accent) 25%, transparent);
}

/* ===== App shell refinements ===== */
.nt-nav .nav-link .bi {
  margin-right: 0.55rem;
  opacity: 0.75;
}

.nt-nav .nav-link.active .bi { opacity: 1; }

/* Sidebar section labels as tiny tinted pill eyebrows. */
.nt-nav-section {
  width: fit-content;
  margin: 1rem 0.5rem 0.35rem;
  padding: 0.14rem 0.55rem;
  border-radius: 999px;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  color: color-mix(in srgb, var(--accent) 80%, var(--ink));
}

.nt-sidebar-footer {
  margin-top: auto;
  padding: 0.75rem;
  border-top: 1px solid var(--hairline);
  font-size: 0.75rem;
  color: color-mix(in srgb, var(--ink) 50%, transparent);
}

/* ===== Dashboard: KPI cards, status badges, charts, empty states ===== */
/* Text block pinned to the top so titles line up across tiles even when
   captions wrap differently; only the icon bubble centers vertically. */
.nt-kpi {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 0.75rem;
}

.nt-kpi-bubble {
  flex-shrink: 0;
  align-self: center;
  width: 3.3rem;
  height: 3.3rem;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  color: var(--bubble);
  background: color-mix(in srgb, var(--bubble) 14%, transparent);
}

/* Tabular numerals stay, but KPI figures sit flush left under their label. */
.nt-kpi .num { text-align: left; }

/* Solid inner disc for glyphs with no filled variant (the dollar sign). */
.nt-kpi-coin {
  width: 1.95rem;
  height: 1.95rem;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
  background: var(--bubble);
  color: #fff;
}

.badge.nt-muted {
  background: color-mix(in srgb, var(--ink) 7%, transparent);
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

.badge.nt-inprogress {
  background: color-mix(in srgb, #2F6DB3 14%, transparent);
  color: #245683;
}

.badge.nt-sent {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}

.nt-legend-dot {
  display: inline-block;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: var(--dot);
  margin-right: 0.4rem;
}

.nt-empty {
  color: color-mix(in srgb, var(--ink) 55%, transparent);
  font-size: 0.85rem;
  padding: 1.25rem 0.5rem;
  text-align: center;
}

.nt-hairline-row + .nt-hairline-row { border-top: 1px solid color-mix(in srgb, var(--ink) 6%, transparent); }

.nt-daterange summary {
  cursor: pointer;
  color: var(--accent);
  list-style: none;
}

/* ===== Trial banners ===== */
.nt-trial-alert {
  background: color-mix(in srgb, var(--amber) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--amber) 40%, transparent);
  color: var(--ink);
}

.nt-trial-alert-ended {
  background: color-mix(in srgb, var(--debit) 8%, transparent);
  border-color: color-mix(in srgb, var(--debit) 35%, transparent);
}

/* Bootstrap has no min-w-0 utility (it is a Tailwind name), but the layouts
   rely on it for flex children that must shrink and truncate. Define it. */
.min-w-0 { min-width: 0; }

/* ===== App shell on small screens ===== */
/* Below lg the sidebar becomes a Bootstrap offcanvas opened from the topbar
   hamburger; paddings tighten so cards get the width. */
.nt-navtoggle {
  border: 0;
  padding: 0.15rem 0.4rem;
  font-size: 1.35rem;
  line-height: 1;
  color: var(--ink);
}

@media (max-width: 991.98px) {
  .nt-topbar { padding-inline: 0.75rem; }
  .nt-content { padding: 1rem 0.75rem; }
}

/* One quiet legal line at the bottom of every signed-in screen. */
.nt-app-footer {
  margin-top: auto;
  padding: 1.25rem 1.5rem 1rem;
  font-size: 0.78rem;
  text-align: center;
  color: color-mix(in srgb, var(--ink) 45%, transparent);
}

.nt-app-footer a {
  color: inherit;
  text-decoration-color: color-mix(in srgb, var(--ink) 25%, transparent);
}

.nt-app-footer a:hover { color: var(--accent); }

.nt-datepick span { white-space: nowrap; }

/* ===== Binder form: collapsible validation rules ===== */
.nt-rules {
  border-top: 1px solid var(--hairline);
  padding-top: 0.85rem;
  margin-bottom: 1rem;
}

.nt-rules-summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 0.95rem;
}

.nt-rules-summary:hover { color: var(--accent); }

/* ===== Flash fade-out ===== */
/* Success notices dismiss themselves (controllers/autodismiss_controller.js). */
.nt-flash-fading {
  opacity: 0;
  transition: opacity 0.5s ease;
}

/* ===== Field info tips ===== */
/* Circled "i" beside a form label; hover or focus shows the tooltip. */
.nt-info-tip {
  background: none;
  border: 0;
  padding: 0;
  margin-left: 0.3rem;
  font-size: 0.85em;
  line-height: 1;
  vertical-align: baseline;
  color: color-mix(in srgb, var(--ink) 45%, transparent);
}

.nt-info-tip:hover,
.nt-info-tip:focus-visible {
  color: var(--accent);
}

/* ===== Modern polish: gradient accents, sparklines, chips, glow, insights ===== */
/* Headline figures in the brand gradient (the homepage's recovered-revenue
   treatment, applied to money the engine found). */
.nt-gradient-number {
  background: var(--nt-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

[data-bs-theme="dark"] .nt-gradient-number {
  --nt-gradient: linear-gradient(100deg, #4C7BEF 0%, #7FA6F5 55%, #BBD0FC 100%);
}

/* Plan usage meter (Settings). */
.nt-usage-track {
  height: 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  overflow: hidden;
}

.nt-usage-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--nt-gradient);
}

/* Monospace reference chips: binder references, policy numbers. */
.nt-ref {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-size: 0.78em;
  padding: 0.12rem 0.45rem;
  border-radius: 6px;
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  color: color-mix(in srgb, var(--accent) 85%, var(--ink));
  text-decoration: none;
  white-space: nowrap;
}

a.nt-ref:hover {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
}

/* Soft pulsing glow on in-flight statuses: the engine is working. */
@keyframes nt-working {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 0%, transparent); }
  50% { box-shadow: 0 0 10px 1px color-mix(in srgb, var(--accent) 45%, transparent); }
}

.badge.nt-inprogress { animation: nt-working 2.2s ease-in-out infinite; }

/* Page titles, slightly larger and tighter. */
.nt-page-title {
  font-weight: 650;
  letter-spacing: -0.015em;
}

/* Theme toggle in the topbar. */
.nt-themetoggle {
  border: 0;
  padding: 0.3rem 0.5rem;
  font-size: 1.05rem;
  line-height: 1;
  color: color-mix(in srgb, var(--ink) 60%, transparent);
}

.nt-themetoggle:hover { color: var(--accent); }
.nt-themetoggle .bi-sun { display: none; }
[data-bs-theme="dark"] .nt-themetoggle .bi-sun { display: inline; }
[data-bs-theme="dark"] .nt-themetoggle .bi-moon-stars { display: none; }

/* ===== Dashboard redesign: hero pipeline, ops console, health rail ===== */
.nt-hero .card-body { padding: 1.1rem 1.6rem 1rem; }

.nt-hero-sub {
  font-size: 0.85rem;
  color: color-mix(in srgb, var(--ink) 45%, transparent);
}

/* Right-aligned technical metadata: "6 BINDERS / 3 PROVIDERS". */
.nt-hero-meta {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

.nt-hero-meta .num { font-weight: 650; color: var(--ink); }

/* The period pipeline: circle badges, labels, and file/binder counts. */
.nt-pipeline {
  display: flex;
  align-items: flex-start;
  max-width: 620px;
}

.nt-stage { position: relative; z-index: 1; min-width: 74px; }

.nt-stage-circle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  font-weight: 650;
  font-size: 1rem;
  border: 2px solid color-mix(in srgb, var(--ink) 22%, transparent);
  color: color-mix(in srgb, var(--ink) 60%, transparent);
  background: var(--surface);
}

.nt-stage-part {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--surface));
}

.nt-stage-full {
  border-color: var(--accent);
  color: #fff;
  background: var(--accent);
}

[data-bs-theme="dark"] .nt-stage-full { color: #0E1116; }

.nt-stage-label {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink);
  font-weight: 600;
}

.nt-stage-sub {
  font-size: 0.68rem;
  color: color-mix(in srgb, var(--ink) 52%, transparent);
  text-align: center;
  white-space: nowrap;
}

/* The continuous line behind the pipeline; each segment tucks under the
   circles beside it and fills teal once the stage to its left completes. */
.nt-stage-link {
  flex: 1 1 1.5rem;
  height: 2px;
  margin: 19px -30px 0;
  background: color-mix(in srgb, var(--ink) 14%, transparent);
}

.nt-stage-link-done { background: var(--accent); }

/* Section labels in the technical voice. */
.nt-section-label {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

/* Operations console: header row plus hairline-separated grid rows, each
   with a teal accent bar, monospace reference, and a five-step progress. */
.nt-ops-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1.05fr 0.7fr 0.6fr 92px;
  gap: 0.9rem;
  align-items: center;
}

.nt-ops-head {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
  color: color-mix(in srgb, var(--ink) 48%, transparent);
  padding: 0.35rem 0.75rem;
}

.nt-ops-line {
  position: relative;
  padding: 0.65rem 0.75rem;
  border-radius: 8px;
  border-top: 1px solid color-mix(in srgb, var(--ink) 6%, transparent);
}

.nt-ops-footer {
  border-top: 1px solid color-mix(in srgb, var(--ink) 6%, transparent);
  padding: 0.7rem 0.75rem 0.1rem;
}

.nt-ops-line::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.7rem;
  bottom: 0.7rem;
  width: 3px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 55%, transparent);
}

/* The bar carries the NorthThread status convention: teal healthy or done,
   blue processing, amber attention, red exception. */
.nt-ops-line.nt-bar-muted::before { background: color-mix(in srgb, var(--ink) 18%, transparent); }
.nt-ops-line.nt-bar-info::before { background: #2F6DB3; }
.nt-ops-line.nt-bar-amber::before { background: var(--amber); }
.nt-ops-line.nt-bar-ok::before,
.nt-ops-line.nt-bar-sent::before { background: var(--accent); }

.nt-ops-line:hover { background: color-mix(in srgb, var(--accent) 3%, transparent); }

@media (max-width: 1399.98px) {
  .nt-col-provider { display: none; }
  .nt-ops-grid { grid-template-columns: 1.5fr 1fr 0.7fr 0.6fr 92px; }
}

@media (max-width: 991.98px) {
  .nt-ops-grid { grid-template-columns: 1.5fr 1fr 92px; }
  .nt-col-optional { display: none; }
}

.nt-step-dots {
  display: flex;
  gap: 7px;
  justify-content: flex-end;
  align-items: center;
}

.nt-step-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 12%, transparent);
}

.nt-step-done { background: var(--credit); }

.nt-step-current {
  background: var(--surface);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--ink) 30%, transparent) inset, 0 0 0 1px var(--surface);
  outline: 1.5px solid color-mix(in srgb, var(--ink) 35%, transparent);
  outline-offset: 1px;
  width: 8px;
  height: 8px;
}

/* Search field with an inset icon. */
.nt-search { position: relative; }

.nt-search .bi-search {
  position: absolute;
  left: 0.6rem;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.8rem;
  color: color-mix(in srgb, var(--ink) 40%, transparent);
}

.nt-search input {
  padding-left: 1.9rem;
  width: 190px;
}

.nt-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 0.35rem;
  vertical-align: baseline;
  background: color-mix(in srgb, var(--ink) 25%, transparent);
}

.nt-tone-muted { background: color-mix(in srgb, var(--ink) 25%, transparent); }
.nt-tone-info { background: #2F6DB3; }
.nt-tone-amber { background: var(--amber); }
.nt-tone-ok { background: var(--credit); }
.nt-tone-red { background: var(--debit); }
.nt-tone-sent { background: var(--accent); }

/* Rail cards run tighter than content cards. */
.nt-rail-card .card-body { padding: 0.9rem 1.1rem; }

/* Data health stat trio, hairline separated. */
.nt-health-stats {
  display: flex;
  border-top: 1px solid color-mix(in srgb, var(--ink) 7%, transparent);
  padding-top: 0.7rem;
}

.nt-health-stats > div { flex: 1; padding-inline: 0.4rem; }
.nt-health-stats > div:first-child { padding-left: 0; }
.nt-health-stats > div + div { border-left: 1px solid color-mix(in srgb, var(--ink) 7%, transparent); padding-left: 0.75rem; }

.nt-health-num {
  font-weight: 650;
  font-size: 0.95rem;
  text-align: left;
}

.nt-health-cap {
  font-size: 0.7rem;
  color: color-mix(in srgb, var(--ink) 52%, transparent);
}

/* Small tinted icon squares in rail lists. */
.nt-mini-icon {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 7px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.78rem;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

/* Hero story labels over the flow graphic; the hero's left content yields
   the space so the pipeline never runs underneath. */

.nt-structured-pill {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-size: 0.62rem;
  font-weight: 650;
  letter-spacing: 0.14em;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  color: var(--credit);
  background: color-mix(in srgb, var(--credit) 12%, transparent);
}

.nt-recon-cta {
  border-left: 1px solid color-mix(in srgb, var(--ink) 7%, transparent);
  padding-left: 2rem;
}

@media (max-width: 767.98px) {
  .nt-recon-cta { border-left: 0; padding-left: calc(var(--bs-gutter-x) * 0.5); }
}

/* Sidebar tagline above the account footer. */
.nt-sidebar-tagline {
  padding: 0.75rem;
  font-size: 0.8rem;
  line-height: 1.45;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

/* Footer system status dot. */
.nt-status-ok {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--credit);
  margin-right: 0.35rem;
  vertical-align: baseline;
}

/* Health rail: quiet when clear, loud when not. */
.nt-health-check {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  color: var(--credit);
  background: color-mix(in srgb, var(--credit) 12%, transparent);
}

.nt-health-alert {
  font-size: 2rem;
  font-weight: 650;
  line-height: 1;
  color: var(--debit);
}

.nt-rail-section + .nt-rail-section {
  border-top: 1px solid color-mix(in srgb, var(--ink) 7%, transparent);
  margin-top: 1.1rem;
  padding-top: 1.1rem;
}

/* The data-flow motif: ragged source rows becoming an aligned ledger. */
.nt-dataflow {
  position: absolute;
  right: 1.75rem;
  bottom: 1rem;
  opacity: 0.85;
  pointer-events: none;
}

.nt-dataflow-inline {
  display: block;
  margin: 1.25rem auto 0.75rem;
  opacity: 0.9;
}

/* Data fragments stream from raw to structured. Killed by reduced motion. */
.nt-flowline {
  stroke-dasharray: 3 6;
  animation: nt-flow 2.8s linear infinite;
}

@keyframes nt-flow {
  to { stroke-dashoffset: -18; }
}

/* Attention strip: what needs doing, with somewhere to go. */
.nt-attention {
  border-left: 3px solid var(--amber);
  background: color-mix(in srgb, var(--amber) 4%, var(--surface));
}

.nt-attention-icon { color: var(--amber); font-size: 1.15rem; }

.nt-attention-title {
  font-weight: 650;
  font-size: 0.88rem;
  color: var(--amber-ink);
}

[data-bs-theme="dark"] .nt-attention-title { color: var(--amber); }

/* The dashboard's "needs attention" card: ink on paper with the accent
   as a rule, so colour stays reserved for money and checks. */
.nt-notice { border-left: 3px solid var(--accent); }
.nt-notice-icon { color: var(--accent); font-size: 1.1rem; }
.nt-notice-title { font-weight: 650; font-size: 0.88rem; color: var(--ink); }

/* Each attention item is its own link: quiet ink, arrow warms on hover. */
.nt-attention-row { color: var(--ink); border-radius: 6px; }
.nt-attention-row .bi-arrow-right { color: color-mix(in srgb, var(--ink) 40%, transparent); }
.nt-attention-row:hover { color: var(--accent); }
.nt-attention-row:hover .bi-arrow-right { color: var(--accent); }

/* ===== File page: guided steps and preview table ===== */
/* File identity glyph in the hero. */
.nt-file-glyph {
  flex-shrink: 0;
  width: 46px;
  height: 46px;
  border-radius: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.35rem;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 9%, transparent);
}

/* The file's journey: small circle pipeline, same language as the hero. */
.nt-fsteps {
  display: flex;
  align-items: flex-start;
  max-width: 620px;
}

.nt-fstep { text-align: center; min-width: 66px; }

.nt-fstep-circle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  font-size: 0.85rem;
  border: 2px solid color-mix(in srgb, var(--ink) 18%, transparent);
  color: color-mix(in srgb, var(--ink) 45%, transparent);
  background: var(--surface);
}

.nt-fstep-done {
  border-color: var(--accent);
  background: var(--accent);
  color: #fff;
}

[data-bs-theme="dark"] .nt-fstep-done { color: #0E1116; }

.nt-fstep-active {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--surface));
  animation: nt-working 1.8s ease-in-out infinite;
}

.nt-fstep-label {
  margin-top: 0.35rem;
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

.nt-fstep-link {
  flex: 1 1 1.2rem;
  height: 2px;
  margin: 14px -26px 0;
  background: color-mix(in srgb, var(--ink) 12%, transparent);
}

.nt-fstep-link-done { background: var(--accent); }

/* Divider between the side-by-side manual steps. */
@media (min-width: 768px) {
  .nt-flow-divide { border-left: 1px solid color-mix(in srgb, var(--ink) 7%, transparent); }
}

/* The suggested-setup panel: quiet teal confidence, one confirm. */
.nt-suggested {
  border-left: 3px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 3%, var(--surface));
}

.nt-flow-step {
  display: flex;
  gap: 0.9rem;
  padding-block: 0.85rem;
}

.nt-flow-step + .nt-flow-step {
  border-top: 1px solid color-mix(in srgb, var(--ink) 6%, transparent);
}

.nt-flow-num {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
  font-weight: 650;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  margin-top: 0.1rem;
}

/* Raw file preview: the file's own header row as the table head, numeric
   cells right aligned, faint zebra striping. */
.nt-preview tbody tr:nth-child(even) > * {
  background: color-mix(in srgb, var(--ink) 2%, transparent);
}

.nt-preview td, .nt-preview th { white-space: nowrap; }
.nt-preview { font-size: 0.84rem; }

/* ===== Upload dropzone ===== */
.nt-dropzone {
  border: 1.5px dashed color-mix(in srgb, var(--accent) 40%, transparent);
  border-radius: 14px;
  padding: 2.6rem 1.5rem;
  text-align: center;
  cursor: pointer;
  background:
    radial-gradient(color-mix(in srgb, var(--ink) 8%, transparent) 1px, transparent 1px) 0 0 / 14px 14px,
    color-mix(in srgb, var(--accent) 2%, var(--surface));
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}

.nt-dropzone:hover,
.nt-dropzone:focus-visible,
.nt-dropzone-active {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 10%, transparent),
              0 0 28px color-mix(in srgb, var(--accent) 18%, transparent);
}

.nt-dropzone-active { background-color: color-mix(in srgb, var(--accent) 6%, var(--surface)); }

.nt-dropzone-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  font-size: 1.7rem;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 5%, transparent);
}

.nt-dropzone-active .nt-dropzone-icon { animation: nt-working 1.6s ease-in-out infinite; }

.nt-dropzone-meta {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-size: 0.64rem;
  letter-spacing: 0.14em;
  color: color-mix(in srgb, var(--ink) 45%, transparent);
}

.nt-file-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.25rem;
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 6%, transparent);
  font-size: 0.88rem;
}

.nt-file-item .bi-file-earmark-spreadsheet { color: var(--accent); }

.nt-file-name {
  flex-grow: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nt-file-size { color: color-mix(in srgb, var(--ink) 50%, transparent); font-size: 0.8rem; }

.nt-file-remove {
  border: 0;
  background: none;
  padding: 0.1rem 0.3rem;
  color: color-mix(in srgb, var(--ink) 45%, transparent);
  border-radius: 6px;
}

.nt-file-remove:hover { color: var(--debit); background: color-mix(in srgb, var(--debit) 8%, transparent); }

/* ===== Reduced motion ===== */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ===== Marketing daylight theme =====
   The public site's palette: soft daylight, royal blue accents, gradient
   surfaces. Scoped to the marketing body so the app keeps its own ledger
   tokens and light/dark toggle. */
body.nt-marketing {
  --paper: #ECEFF4;
  --canvas: #E2E7EE;
  --surface: #F8F9FB;
  --ink: #141F2D;
  --hairline: #D6DCE5;
  --accent: #2154E8;
  --accent-hover: #1A44C4;
  --credit: #1E8A4C;
  --debit: #C43D31;
  --amber: #B87A14;
  --amber-ink: #96650F;
  --bs-link-color-rgb: 33, 84, 232;
  --bs-link-hover-color-rgb: 26, 68, 196;
  --bs-primary-rgb: 33, 84, 232;
  --bs-body-bg: var(--paper);
  --bs-body-color: var(--ink);
  --bs-emphasis-color: var(--ink);
  --bs-border-color: var(--hairline);
  --bs-secondary-color: rgba(16, 25, 43, 0.76);

  /* Surfaces that are gradients rather than flat tokens. Declared here so a
     palette can be swapped in one block: see the theme previews below. */
  --page-top: #F3F5F9;
  --page-mid: #E7EBF2;
  --page-bottom: #EDF0F5;
  --hero-wash: #F1F4F8;
  --hero-top: #F6F8FB;
  --hero-bottom: #EBEFF5;
  --surface-grad-top: #FFFFFF;
  --surface-grad-bottom: #F5F7FA;
  --sunk-top: #F8FAFD;
  --sunk-bottom: #EEF1F7;
  --nav-bg: #FFFFFF;
  --dark-top: #16233B;
  --dark-bottom: #101A2C;
  --dark-check: #6EE7A0;

  background: linear-gradient(180deg, var(--page-top) 0%, var(--page-mid) 55%, var(--page-bottom) 100%) fixed;
}

/* ===== Homepage =====
   A plain one-liner under a brand hairline, a flagged-to-fixed product
   sequence, a comparison the NorthThread card visually wins, and a
   photo-free CTA. */
body.nt-home .nt-home-fineprint {
  font-size: 0.78rem;
  color: color-mix(in srgb, var(--ink) 46%, transparent);
}

.nt-kicker {
  border-left: 3px solid var(--accent);
  padding-left: 0.85rem;
  font-size: 0.98rem;
  line-height: 1.6;
  color: color-mix(in srgb, var(--ink) 78%, transparent);
  max-width: 30em;
  margin-bottom: 1.5rem;
}

body.nt-home .nt-display { font-weight: 650; }

/* Flagged to fixed: equal-height cards, panels fill the column */
.nt-home-shot {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.nt-home-shot .nt-home-panel { flex: 1; }

.nt-home-shot-step {
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.35rem;
}

.nt-home-shot-title { font-weight: 650; margin-bottom: 0.7rem; }

.nt-home-panel {
  background: linear-gradient(180deg, #FFFFFF 0%, #F5F7FA 100%);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 1.1rem 1.2rem;
  box-shadow: 0 14px 32px -20px rgba(20, 31, 45, 0.35);
}

.nt-home-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 0.4rem 0;
  font-size: 0.92rem;
}

.nt-home-row + .nt-home-row { border-top: 1px solid var(--hairline); }
.nt-home-row-total { border-top: 2px solid var(--ink) !important; }
.nt-home-dim { color: color-mix(in srgb, var(--ink) 60%, transparent); }

.nt-home-source, .nt-home-file {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-size: 0.76rem;
  color: color-mix(in srgb, var(--ink) 62%, transparent);
  border-top: 1px dashed var(--hairline);
  margin-top: 0.6rem;
  padding-top: 0.7rem;
}

.nt-home-file { color: var(--credit); border-top-style: solid; }
.nt-home-file i, .nt-home-source i { font-size: 0.9rem; }

.nt-home-pass {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 650;
  color: var(--credit);
  padding-bottom: 0.5rem;
}

/* The comparison: both are finished cards; NorthThread's wins on fill,
   border weight, and its label. */
body.nt-home .nt-compare-old {
  background: linear-gradient(180deg, var(--sunk-top) 0%, var(--sunk-bottom) 100%);
  border: 1px solid var(--hairline);
}

body.nt-home .nt-compare-new {
  position: relative;
  background: linear-gradient(180deg, var(--surface-grad-top) 0%, var(--surface-grad-bottom) 100%);
  border: 1.5px solid color-mix(in srgb, var(--accent) 45%, transparent);
  box-shadow: 0 24px 48px -24px color-mix(in srgb, var(--accent) 35%, transparent);
}

body.nt-home .nt-home-job {
  position: absolute;
  top: -0.75rem;
  left: 1.4rem;
  font-size: 0.68rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #fff;
  background: var(--accent);
  border-radius: 999px;
  padding: 0.22rem 0.75rem;
}

/* Photo-free closing CTA: navy band with the delta strip as the image */
.nt-cta {
  display: grid;
  grid-template-columns: 3fr 2fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  background:
    radial-gradient(circle, rgba(236, 239, 244, 0.07) 1.2px, transparent 1.8px) 0 0 / 24px 24px,
    linear-gradient(120deg, var(--dark-top) 0%, var(--dark-bottom) 100%);
  border-radius: 16px;
  padding: clamp(2rem, 5vw, 3.5rem);
  color: #EDF0F5;
}

.nt-cta-copy h2 { color: #fff; }
.nt-cta-copy p { color: rgba(237, 240, 245, 0.75); }

.nt-cta-strip {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-left: 3px solid var(--debit);
  border-radius: 12px;
  padding: 1.4rem 1.6rem;
}

.nt-cta-strip-label {
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(237, 240, 245, 0.6);
}

.nt-cta-strip { border-left-color: var(--credit); }

.nt-cta-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.45rem 0;
  font-size: 0.92rem;
  color: rgba(237, 240, 245, 0.88);
}

.nt-cta-row + .nt-cta-row { border-top: 1px solid rgba(255, 255, 255, 0.1); }
.nt-cta-row i { color: var(--dark-check); font-size: 1rem; }
.nt-cta-row .num { margin-left: auto; font-weight: 650; color: #fff; }

@media (max-width: 860px) {
  .nt-cta { grid-template-columns: 1fr; }
}

/* ===== Interior marketing pages =====
   The homepage set the vocabulary: a dotted wash behind the header, a pill
   eyebrow, ink headlines, a brand hairline on the definition line, and a
   navy block to close. About, pricing, contact, and the legal pages use the
   same parts so the site reads as one document. */

.nt-page-hero {
  background:
    radial-gradient(ellipse 70% 90% at 22% 40%, var(--hero-wash) 30%, transparent 74%),
    radial-gradient(circle, color-mix(in srgb, var(--accent) 26%, transparent) 1.2px, transparent 1.8px) 0 0 / 24px 24px,
    linear-gradient(180deg, var(--hero-top) 0%, var(--hero-bottom) 100%);
  border-bottom: 1px solid var(--hairline);
  padding-block: clamp(2.75rem, 5vw, 4rem);
  overflow: hidden;
}

.nt-page-lede {
  max-width: 34rem;
  line-height: 1.65;
  color: color-mix(in srgb, var(--ink) 72%, transparent);
}

/* A quiet stat line for pages that can put a number behind a claim. */
.nt-figures {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.5rem, 4vw, 3rem);
  margin-top: 1.75rem;
}

.nt-figure-value {
  font-size: 1.5rem;
  font-weight: 650;
  color: var(--ink);
  line-height: 1.2;
}

.nt-figure-label {
  font-size: 0.82rem;
  color: color-mix(in srgb, var(--ink) 58%, transparent);
}

/* Belief cards on the about page: the same surface as the homepage panels. */
.nt-belief {
  height: 100%;
  padding: 1.4rem 1.5rem;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: linear-gradient(180deg, var(--surface-grad-top) 0%, var(--surface-grad-bottom) 100%);
}

.nt-belief-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 650;
  margin-bottom: 0.5rem;
}

.nt-belief-head .bi { color: var(--accent); font-size: 1.1rem; }

.nt-belief p {
  margin-bottom: 0;
  font-size: 0.92rem;
  line-height: 1.6;
  color: color-mix(in srgb, var(--ink) 70%, transparent);
}

/* Photo treatment matched to the app shot, so the one photograph on the
   site sits in the same frame as the product. */
.nt-photo-framed {
  width: 100%;
  border-radius: 14px;
  border: 1px solid var(--hairline);
  object-fit: cover;
  aspect-ratio: 5 / 4;
  box-shadow:
    0 1px 2px rgba(15, 33, 32, 0.06),
    0 24px 70px -24px rgba(15, 33, 32, 0.35);
}

/* Pricing: the recommended plan wins the way the homepage comparison does,
   on fill, border weight, and a label. */
.nt-price-card {
  background: linear-gradient(180deg, var(--sunk-top) 0%, var(--sunk-bottom) 100%);
  border-radius: 12px;
  padding: 1.75rem;
}

.nt-price-featured {
  background: linear-gradient(180deg, var(--surface-grad-top) 0%, var(--surface-grad-bottom) 100%);
  border: 1.5px solid color-mix(in srgb, var(--accent) 45%, transparent);
  box-shadow: 0 24px 48px -24px color-mix(in srgb, var(--accent) 35%, transparent);
}

.nt-price-note {
  font-size: 0.82rem;
  color: color-mix(in srgb, var(--ink) 58%, transparent);
  border-top: 1px solid var(--hairline);
  padding-top: 0.9rem;
  margin-top: 1.1rem;
  margin-bottom: 0;
}

/* Questions: hairlines, not Bootstrap's boxed accordion. */
.nt-faq .accordion-item {
  background: none;
  border: 0;
  border-top: 1px solid var(--hairline);
}

.nt-faq .accordion-item:last-child { border-bottom: 1px solid var(--hairline); }

.nt-faq .accordion-button {
  background: none;
  padding: 1.1rem 0;
  font-weight: 650;
  color: var(--ink);
  box-shadow: none;
}

.nt-faq .accordion-button:not(.collapsed) { color: var(--accent); }
.nt-faq .accordion-button:focus { box-shadow: none; }
.nt-faq .accordion-body { padding: 0 0 1.2rem; max-width: 46rem; }

/* Contact: what happens after you press send. */
.nt-next-step {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
  padding-block: 0.6rem;
  font-size: 0.9rem;
  color: color-mix(in srgb, var(--ink) 72%, transparent);
}

.nt-next-step .bi { color: var(--accent); margin-top: 0.15rem; }

/* Legal pages: a reading column, numbered rhythm, no decoration. */
.nt-legal {
  max-width: 44rem;
  margin-inline: auto;
}

.nt-legal h2 {
  font-size: 1.15rem;
  margin-top: 2.5rem;
  margin-bottom: 0.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--hairline);
}

.nt-legal h2:first-of-type { margin-top: 1.5rem; }

/* No rule above the first heading when nothing precedes it. */
.nt-legal > h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.nt-legal p, .nt-legal li {
  line-height: 1.7;
  color: color-mix(in srgb, var(--ink) 82%, transparent);
}

.nt-legal-meta {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

.nt-legal-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin-top: 3rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--hairline);
  font-size: 0.9rem;
}

.nt-toc {
  columns: 2;
  column-gap: 2rem;
  padding: 1.1rem 1.35rem;
  margin-bottom: 0.5rem;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: linear-gradient(180deg, var(--sunk-top) 0%, var(--sunk-bottom) 100%);
  list-style: none;
  font-size: 0.9rem;
}

.nt-toc li { break-inside: avoid; padding-block: 0.22rem; }

@media (max-width: 575px) {
  .nt-toc { columns: 1; }
}

/* The same fact row as the closing block, for light surfaces. The dark
   variant paints its figures white, which vanishes on paper. */
.nt-fact-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0;
  font-size: 0.92rem;
  color: color-mix(in srgb, var(--ink) 78%, transparent);
}

.nt-fact-row + .nt-fact-row { border-top: 1px solid var(--hairline); }
.nt-fact-row i { color: var(--credit); font-size: 1rem; }
.nt-fact-row .num { margin-left: auto; font-weight: 650; color: var(--ink); }

/* ===== Sign in and sign up =====
   The seam between the marketing site and the app. The body carries
   nt-marketing so these pages take the site palette rather than the app's
   ledger tokens, and there is no theme toggle here: arriving from a bright
   marketing page into a dark login is a jolt, and the brand blue on the
   button should be the same blue that got them here. */
.nt-auth {
  flex: 1;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
  background:
    radial-gradient(ellipse 60% 55% at 50% 32%, var(--hero-wash) 30%, transparent 72%),
    radial-gradient(circle, color-mix(in srgb, var(--accent) 26%, transparent) 1.2px, transparent 1.8px) 0 0 / 24px 24px,
    linear-gradient(180deg, var(--hero-top) 0%, var(--hero-bottom) 100%);
}

.nt-auth .card {
  border: 1px solid var(--hairline);
  border-radius: 14px;
  background: linear-gradient(180deg, var(--surface-grad-top) 0%, var(--surface-grad-bottom) 100%);
  box-shadow:
    0 1px 2px rgba(15, 33, 32, 0.06),
    0 24px 70px -24px rgba(15, 33, 32, 0.35);
}

/* Headings here are page furniture, not display type. */
.nt-auth h1 {
  font-family: inherit;
  font-weight: 650;
  letter-spacing: 0;
}

.nt-auth-foot {
  margin: 1.25rem 0 0;
  text-align: center;
  font-size: 0.85rem;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

.nt-auth-foot a { color: inherit; }
.nt-auth-foot a:hover { color: var(--accent); }
.nt-auth-foot span { margin-inline: 0.4rem; }

/* ===== First-run setup =====
   Replaces the dashboard until the first month has been validated. A new
   account has nothing to monitor, and a cockpit full of zeros teaches
   nothing, so the screen becomes the path instead. */
.nt-setup {
  max-width: 46rem;
  margin-inline: auto;
  padding-block: clamp(1.5rem, 4vw, 3rem);
}

.nt-setup-head { margin-bottom: 2rem; }

.nt-setup-title {
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 650;
  color: var(--ink);
  margin-bottom: 0.5rem;
}

.nt-setup-lede {
  color: color-mix(in srgb, var(--ink) 68%, transparent);
  max-width: 34rem;
  margin-bottom: 1.5rem;
}

.nt-setup-progress {
  height: 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 10%, transparent);
  overflow: hidden;
}

.nt-setup-progress-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 999px;
  transition: width 400ms ease;
}

.nt-setup-count {
  margin: 0.5rem 0 0;
  font-size: 0.8rem;
  color: color-mix(in srgb, var(--ink) 58%, transparent);
}

.nt-setup-list {
  list-style: none;
  padding: 0;
  margin: 0;
  border: 1px solid var(--hairline);
  border-radius: 14px;
  background: var(--surface);
  overflow: hidden;
}

.nt-setup-step {
  display: flex;
  gap: 1rem;
  padding: 1.25rem 1.4rem;
}

.nt-setup-step + .nt-setup-step { border-top: 1px solid var(--hairline); }

.nt-setup-step-mark {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  font-weight: 650;
  border: 1px solid var(--hairline);
  color: color-mix(in srgb, var(--ink) 55%, transparent);
  background: var(--canvas);
}

.nt-setup-step-current .nt-setup-step-mark {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.nt-setup-step-done .nt-setup-step-mark {
  background: color-mix(in srgb, var(--credit) 12%, transparent);
  border-color: color-mix(in srgb, var(--credit) 40%, transparent);
  color: var(--credit);
}

.nt-setup-step-title { font-weight: 650; color: var(--ink); }

.nt-setup-step-done .nt-setup-step-title {
  color: color-mix(in srgb, var(--ink) 55%, transparent);
  text-decoration: line-through;
  text-decoration-color: color-mix(in srgb, var(--ink) 25%, transparent);
}

.nt-setup-step-detail {
  margin: 0.2rem 0 0;
  font-size: 0.9rem;
  line-height: 1.55;
  color: color-mix(in srgb, var(--ink) 65%, transparent);
}

.nt-setup-step-done .nt-setup-step-detail { display: none; }

/* What to have to hand before starting a step that needs a document. */
.nt-setup-step-headsup {
  margin: 0.6rem 0 0;
  padding: 0.5rem 0.7rem;
  border-radius: 8px;
  border-left: 3px solid var(--amber);
  background: color-mix(in srgb, var(--amber) 8%, transparent);
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--amber-ink);
}

.nt-setup-step-headsup .bi { margin-right: 0.4rem; }

.nt-setup-foot {
  margin: 1.5rem 0 0;
  font-size: 0.85rem;
  color: color-mix(in srgb, var(--ink) 58%, transparent);
}

/* ===== Detected file kind =====
   What we worked out the upload is, with the reason, on one line. The line
   is a disclosure summary: "Not right?" opens the switch form beneath it.
   Sits inside the polled status frame so it lands the moment parsing
   finishes. */
.nt-detected {
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 5%, transparent);
  padding: 0.5rem 0.85rem;
}

.nt-detected-line {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  list-style: none;
  cursor: default;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--ink);
}

.nt-detected-line::-webkit-details-marker { display: none; }
.nt-detected-line .bi { color: var(--accent); position: relative; top: 1px; }
.nt-detected-gloss { color: color-mix(in srgb, var(--ink) 55%, transparent); }
.nt-detected-why { color: color-mix(in srgb, var(--ink) 65%, transparent); }

.nt-detected-fix {
  cursor: pointer;
  color: var(--accent);
  text-decoration: underline;
  white-space: nowrap;
}

.nt-detected[open] .nt-detected-fix {
  color: color-mix(in srgb, var(--ink) 55%, transparent);
  text-decoration: none;
}

.nt-detected-form {
  margin-top: 0.6rem;
  padding: 0.75rem 0.9rem;
  border-radius: 8px;
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
}

.nt-detected-form label { display: block; margin-bottom: 0.35rem; }

/* ===== Pending details on the upload page =====
   Shown below the hero while a job runs, replaced by the real content the
   moment the poll controller sees the job finish. A thin sweeping bar on
   top and a ring beside the copy: working, not broken. */
.nt-pending {
  position: relative;
  overflow: hidden;
  border-color: color-mix(in srgb, var(--accent) 22%, transparent);
}

.nt-pending-bar {
  position: absolute;
  top: 0;
  left: 0;
  height: 3px;
  width: 38%;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  animation: nt-pending-sweep 1.6s ease-in-out infinite;
}

@keyframes nt-pending-sweep {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(270%); }
}

.nt-pending-spinner {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 3px solid color-mix(in srgb, var(--accent) 18%, transparent);
  border-top-color: var(--accent);
  animation: nt-pending-spin 0.9s linear infinite;
}

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

@media (prefers-reduced-motion: reduce) {
  .nt-pending-bar, .nt-pending-spinner { animation: none; }
}

/* ===== Mapping review =====
   Who the file reports to, sized to answer the question, then the columns
   with their conversions. */
.nt-reporting-label {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
  margin-bottom: 0.15rem;
}

.nt-reporting-name {
  font-size: 1.25rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1.2;
  color: var(--ink);
}

.nt-missing { color: var(--debit); }

.nt-mapping { table-layout: fixed; }
.nt-mapping th { padding: 0.85rem 0.75rem; letter-spacing: 0.08em; }
.nt-mapping td { vertical-align: middle; padding: 0.75rem; }
.nt-mapping th:nth-child(1) { width: 18%; }
.nt-mapping th:nth-child(2) { width: 34%; }
.nt-mapping th:nth-child(3) { width: 4%; }
.nt-mapping th:nth-child(4) { width: 44%; }
.nt-mapping-review th:nth-child(1) { width: 16%; }
.nt-mapping-review th:nth-child(2) { width: 30%; }
.nt-mapping-review th:nth-child(4) { width: 38%; }
.nt-mapping-review th:nth-child(5) { width: 12%; }
.nt-mapping td:nth-child(2) { overflow-wrap: anywhere; }
.nt-mixed { color: var(--amber); }
.nt-converted { color: var(--accent); }

.nt-back { color: color-mix(in srgb, var(--ink) 60%, transparent); }
.nt-back:hover { color: var(--accent); }

.nt-file-glyph-sm { width: 34px; height: 34px; border-radius: 9px; font-size: 1.05rem; }

/* The step strip beside the title, smaller than on the upload page. */
.nt-fsteps-compact { flex: 0 0 auto; width: 400px; max-width: 100%; }
.nt-fsteps-compact .nt-fsteps { max-width: none; }
.nt-fsteps-compact .nt-fstep { min-width: 58px; }
.nt-fsteps-compact .nt-fstep-circle { width: 26px; height: 26px; font-size: 0.75rem; }
.nt-fsteps-compact .nt-fstep-link { margin: 12px -22px 0; }
.nt-fsteps-compact .nt-fstep-pip { width: 8px; height: 8px; }

/* Summary card: what happened, who it is for, what the format needs. */
.nt-summary-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr;
}

@media (max-width: 991px) { .nt-summary-grid { grid-template-columns: 1fr; } }

.nt-summary-main {
  display: flex;
  gap: 1.25rem;
  align-items: flex-start;
  padding: 1.25rem 1.5rem;
}

.nt-summary-cell {
  padding: 1.25rem 1.5rem;
  border-left: 1px solid color-mix(in srgb, var(--ink) 8%, transparent);
}

@media (max-width: 991px) {
  .nt-summary-cell { border-left: 0; border-top: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); }
}

.nt-summary-glyph {
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  border-radius: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  color: var(--accent);
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 16%, transparent), color-mix(in srgb, var(--accent) 5%, transparent));
}

.nt-stat {
  font-size: 1.6rem;
  font-weight: 650;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.nt-stat-ok { color: var(--credit); }
.nt-stat-accent { color: var(--accent); }
.nt-stat-bad { color: var(--debit); }

.nt-stat-label {
  font-size: 0.74rem;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

.nt-pill {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.74rem;
  font-weight: 500;
  color: color-mix(in srgb, var(--ink) 70%, transparent);
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}

.nt-pill-accent {
  color: color-mix(in srgb, var(--accent) 85%, var(--ink));
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

/* The one line that says what deserves attention. */
.nt-guidance {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding: 0.8rem 1rem;
  border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  background: color-mix(in srgb, var(--accent) 5%, transparent);
}

.nt-guidance > .bi { color: var(--accent); margin-top: 0.15rem; }

/* Pencil beside a matched row. */
.nt-iconbtn {
  border: 0;
  background: transparent;
  padding: 0.25rem 0.4rem;
  border-radius: 6px;
  color: color-mix(in srgb, var(--ink) 50%, transparent);
}

.nt-iconbtn:hover { color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }

/* Inline counts under the summary title. */
.nt-counts { display: flex; gap: 0.5rem; font-size: 0.92rem; color: color-mix(in srgb, var(--ink) 70%, transparent); }
.nt-counts .num { font-weight: 650; color: var(--ink); }
.nt-count-ok { color: var(--credit) !important; }
.nt-count-accent { color: var(--accent) !important; }
.nt-count-bad { color: var(--debit) !important; }

/* The field a column becomes: text that opens its select when clicked,
   with a quiet "···" on hover so it reads as changeable. */
.nt-field-btn {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: transparent;
  padding: 0.2rem 0.4rem;
  margin: -0.2rem -0.4rem;
  border-radius: 6px;
  color: var(--ink);
}

.nt-field-btn:hover { background: color-mix(in srgb, var(--accent) 6%, transparent); }
.nt-field-name { font-weight: 600; }
.nt-field-more { margin-left: 0.4rem; color: color-mix(in srgb, var(--ink) 40%, transparent); opacity: 0; letter-spacing: 0.1em; }
.nt-field-btn:hover .nt-field-more, .nt-field-btn:focus-visible .nt-field-more { opacity: 1; }

.nt-maps-arrow { color: var(--accent); font-size: 1.05rem; text-align: center; width: 2.5rem; }

/* Inferred field cards: the intelligence layer, kept light. */
.nt-inferred-list { display: grid; gap: 0.75rem; }
.nt-inferred-card { padding: 1rem 1.25rem; border-left: 3px solid var(--accent); }
.nt-inferred-confirm { border-left-color: var(--amber); }
.nt-inferred-missing { border-left-color: var(--debit); }

.nt-working {
  display: inline-block;
  padding: 0.25rem 0.6rem;
  border-radius: 6px;
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-size: 0.82rem;
  color: color-mix(in srgb, var(--accent) 85%, var(--ink));
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

/* "Why this mapping?" shows the working inline. */
.nt-why { max-width: 720px; }
.nt-why > summary { list-style: none; cursor: pointer; color: var(--accent); text-decoration: underline; }
.nt-why > summary::-webkit-details-marker { display: none; }
.nt-why[open] > summary { color: color-mix(in srgb, var(--ink) 55%, transparent); text-decoration: none; }

.nt-why-body {
  display: grid;
  gap: 0.25rem;
  margin-top: 0.6rem;
  padding: 0.75rem 0.9rem;
  border-radius: 8px;
  font-size: 0.84rem;
  line-height: 1.5;
  color: var(--ink);
  background: color-mix(in srgb, var(--ink) 4%, transparent);
}

/* Inferred: derived from other columns, not a match and not a worry. */
.badge.nt-inferred {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: color-mix(in srgb, var(--accent) 85%, var(--ink));
}

/* ===== Upload page: where you are, and what to do next =====
   nt-fstep-current marks the step waiting on the person (a ring with a
   solid pip, not pulsing: nothing is running). nt-next is the one card
   with the one button. nt-plan is the "what happens next" list. */
.nt-fstep-current {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--surface));
}

.nt-fstep-pip {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
}

.nt-fstep-here .nt-fstep-label { color: var(--ink); font-weight: 700; }

.nt-next { border-left: 3px solid var(--accent); }

.nt-next-label {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.25rem;
}

.nt-destination {
  padding: 0.5rem 0.85rem;
  border-radius: 8px;
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  min-width: 220px;
}

.nt-next-dest {
  padding: 0.6rem 0.85rem;
  border-radius: 8px;
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  max-width: 560px;
}

.nt-next-dest .nt-next-label { color: color-mix(in srgb, var(--ink) 55%, transparent); }

.nt-plan { display: grid; gap: 0.6rem; }

.nt-plan-step {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  opacity: 0.72;
}

.nt-plan-current, .nt-plan-done { opacity: 1; }

.nt-plan-num {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  font-size: 0.72rem;
  font-weight: 650;
  border: 1.5px solid color-mix(in srgb, var(--ink) 20%, transparent);
  color: color-mix(in srgb, var(--ink) 55%, transparent);
  margin-top: 0.1rem;
}

.nt-plan-current .nt-plan-num { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.nt-plan-done .nt-plan-num { border-color: var(--accent); background: var(--accent); color: #fff; }
[data-bs-theme="dark"] .nt-plan-done .nt-plan-num { color: #0E1116; }

.nt-plan-now {
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin-left: 0.35rem;
}

/* ===== Dashboard: tasks, the month's story, folds =====
   The dashboard leads with one task per binder. Colour is for meaning:
   the accent marks the next thing, red marks money or a check at stake. */
.nt-task { display: flex; align-items: center; gap: 1rem; padding: 0.8rem 0; }
.nt-task + .nt-task { border-top: 1px solid color-mix(in srgb, var(--ink) 7%, transparent); }
.nt-task-check { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; border: 2px solid color-mix(in srgb, var(--ink) 20%, transparent); display: inline-flex; align-items: center; justify-content: center; font-size: 0.85rem; color: var(--accent); }
.nt-task-done { opacity: 0.55; }
.nt-task-done .nt-task-check { background: var(--credit); border-color: var(--credit); color: #fff; }
.nt-task-done .fw-medium { text-decoration: line-through; }
.nt-task-flag { color: var(--ink); }
.nt-task-flag .nt-task-check { border-color: var(--debit); color: var(--debit); }
.nt-task-flag:hover { color: var(--accent); }

.nt-tl { display: grid; gap: 0; }
.nt-tl-step { display: flex; gap: 1rem; padding: 0.8rem 0; opacity: 0.7; }
.nt-tl-step + .nt-tl-step { border-top: 1px solid color-mix(in srgb, var(--ink) 7%, transparent); }
.nt-tl-done, .nt-tl-now { opacity: 1; }
.nt-tl-num { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 0.8rem; font-weight: 650; border: 2px solid color-mix(in srgb, var(--ink) 20%, transparent); color: color-mix(in srgb, var(--ink) 55%, transparent); }
.nt-tl-done .nt-tl-num { background: var(--accent); border-color: var(--accent); color: #fff; }
.nt-tl-now .nt-tl-num { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }

.nt-fold > summary { list-style: none; cursor: pointer; font-size: 0.88rem; font-weight: 600; color: color-mix(in srgb, var(--ink) 65%, transparent); }
.nt-fold > summary::-webkit-details-marker { display: none; }
.nt-fold > summary::before { content: "\203A"; display: inline-block; width: 1rem; transition: transform 0.15s; }
.nt-fold[open] > summary::before { transform: rotate(90deg); }
.nt-fold > summary:hover { color: var(--accent); }

.nt-bell-dot { position: absolute; top: 6px; right: 6px; width: 8px; height: 8px; border-radius: 50%; background: var(--debit); border: 2px solid var(--surface); }

/* ===== Light theme surfaces =====
   Three tones instead of one: chrome (sidebar, top bar) on paper, the
   working background a step darker, cards white with a real edge.
   Secondary text and row rules darkened so nothing melts into the page.
   Dark mode keeps its own values. */
:root:not([data-bs-theme="dark"]) .nt-sidebar {
  background-color: var(--paper) !important; /* offcanvas-lg forces transparent at desktop widths */
  border-right: 1px solid var(--hairline);
}

:root:not([data-bs-theme="dark"]) .nt-topbar {
  background: var(--paper);
  border-bottom: 1px solid var(--hairline);
}

:root:not([data-bs-theme="dark"]) .card {
  border: 1px solid color-mix(in srgb, var(--ink) 15%, transparent);
  box-shadow: 0 1px 2px rgba(27, 39, 51, 0.06);
}

:root:not([data-bs-theme="dark"]) .nt-hairline-row + .nt-hairline-row,
:root:not([data-bs-theme="dark"]) .nt-task + .nt-task,
:root:not([data-bs-theme="dark"]) .nt-tl-step + .nt-tl-step,
:root:not([data-bs-theme="dark"]) .nt-row-line + .nt-row-line,
:root:not([data-bs-theme="dark"]) .table > :not(caption) > * > * {
  border-color: color-mix(in srgb, var(--ink) 11%, transparent);
}

:root:not([data-bs-theme="dark"]) .nt-section-label,
:root:not([data-bs-theme="dark"]) .nt-hero-meta,
:root:not([data-bs-theme="dark"]) .nt-reporting-label,
:root:not([data-bs-theme="dark"]) .nt-fstep-label,
:root:not([data-bs-theme="dark"]) .nt-stat-label,
:root:not([data-bs-theme="dark"]) .nt-health-label {
  color: color-mix(in srgb, var(--ink) 68%, transparent);
}

:root:not([data-bs-theme="dark"]) .nt-hero-sub { color: color-mix(in srgb, var(--ink) 62%, transparent); }
:root:not([data-bs-theme="dark"]) .nt-nav .nav-link { color: color-mix(in srgb, var(--ink) 86%, transparent); }
:root:not([data-bs-theme="dark"]) .nt-pill { color: color-mix(in srgb, var(--ink) 78%, transparent); background: color-mix(in srgb, var(--ink) 8%, transparent); }
:root:not([data-bs-theme="dark"]) .nt-fold > summary { color: color-mix(in srgb, var(--ink) 78%, transparent); }
:root:not([data-bs-theme="dark"]) .nt-task-check { border-color: color-mix(in srgb, var(--ink) 32%, transparent); }
:root:not([data-bs-theme="dark"]) .nt-tl-num { border-color: color-mix(in srgb, var(--ink) 32%, transparent); color: color-mix(in srgb, var(--ink) 65%, transparent); }

/* ===== Meaning colours =====
   Green is done or cleared, blue is the next thing, amber is to fix, red
   is money or a check at stake. Applied to the step strips, the month's
   story, task markers, next-step glyphs and health. */
.nt-fstep-done, .nt-tl-done .nt-tl-num, .nt-task-ok { background: var(--credit) !important; border-color: var(--credit) !important; color: #fff !important; }
.nt-fstep-link-done { background: var(--credit); }
.nt-task-next { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.nt-task-warn { border-color: var(--amber); color: var(--amber-ink); background: color-mix(in srgb, var(--amber) 14%, transparent); }
.nt-task-busy { border-color: color-mix(in srgb, var(--ink) 30%, transparent); color: color-mix(in srgb, var(--ink) 55%, transparent); }
.nt-task-flag .nt-task-check { background: color-mix(in srgb, var(--debit) 10%, transparent); }

.nt-next-glyph { flex: 0 0 auto; width: 44px; height: 44px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; font-size: 1.3rem; color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.nt-next-glyph-done { color: var(--credit); background: color-mix(in srgb, var(--credit) 12%, transparent); }
.nt-next { border-left-color: var(--accent); }

.nt-health-warn { width: 30px; height: 30px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: var(--amber-ink); background: color-mix(in srgb, var(--amber) 16%, transparent); }

.nt-progress { position: relative; height: 6px; border-radius: 3px; background: color-mix(in srgb, var(--ink) 10%, transparent); max-width: 520px; overflow: hidden; }
.nt-progress span { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px; }
.nt-progress-in { background: color-mix(in srgb, var(--accent) 45%, transparent); }
.nt-progress-ready { background: var(--credit); }

/* The detected-kind line, no longer boxed: one meta line under the strip. */
.nt-detected { border: 0; background: transparent; padding: 0; }
.nt-detected-line { font-size: 0.88rem; }
.nt-detected-spark { color: var(--accent); margin-right: 0.15rem; }
.nt-sep { color: color-mix(in srgb, var(--ink) 35%, transparent); margin: 0 0.35rem; }

/* ===== App typeface and controls =====
   Geist and Geist Mono (SIL OFL, self-hosted, latin subset). The app
   moves off the system stack: a distinctive face with real weight range
   and tight headline tracking is most of what "modern" means on a page
   of cards. Mono is reserved for references and figures. Marketing pages
   keep Fraunces and their own stack. */
@font-face {
  font-family: "Geist";
  src: url("/assets/geist-latin-faa79069.woff2") format("woff2");
  font-weight: 300 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Geist Mono";
  src: url("/assets/geist-mono-latin-2dfee388.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}

:root {
  --font-ui: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --radius: 10px;
  --radius-lg: 16px;
  --control-h: 40px;
}

body:not(.nt-marketing) {
  font-family: var(--font-ui);
  font-size: 0.9375rem;
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
}

body:not(.nt-marketing) h1, body:not(.nt-marketing) h2, body:not(.nt-marketing) h3,
body:not(.nt-marketing) .fs-3, body:not(.nt-marketing) .fs-4, body:not(.nt-marketing) .fs-5,
body:not(.nt-marketing) .nt-page-title, body:not(.nt-marketing) .nt-reporting-name {
  font-family: var(--font-ui);
  font-weight: 650;
  letter-spacing: -0.022em;
}

body:not(.nt-marketing) .fs-4 { font-size: 1.55rem !important; }
body:not(.nt-marketing) .fs-5 { font-size: 1.2rem !important; }
body:not(.nt-marketing) .fs-6 { font-size: 1rem !important; font-weight: 650; letter-spacing: -0.01em; }

/* Figures and references in mono with tabular numerals; nothing else. */
.num, .nt-ref, .nt-hero-meta .num, .nt-working { font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: 0; }
.num { font-family: var(--font-ui); font-feature-settings: "tnum" 1; }

/* Captions: sentence case in the UI face, no more monospace shouting.
   One weight, one size, one colour, used the same way everywhere. */
.nt-section-label, .nt-next-label, .nt-reporting-label, .nt-var-switch-label,
.nt-fstep-label, .nt-stage-label, .nt-stat-label, .nt-health-label,
.nt-cal-head, .nt-board-head, .nt-dropzone-meta, .nt-hero-meta {
  font-family: var(--font-ui);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: none;
  color: color-mix(in srgb, var(--ink) 58%, transparent);
}

.nt-next-label { color: var(--accent); }
.nt-hero-meta { font-weight: 500; }
.nt-fstep-label { font-size: 0.74rem; margin-top: 0.45rem; }
.nt-plan-now { font-family: var(--font-ui); text-transform: none; letter-spacing: 0; font-size: 0.74rem; font-weight: 600; }
.nt-nav-section { font-family: var(--font-ui); text-transform: none; letter-spacing: 0; font-size: 0.72rem; font-weight: 600; }
.table > thead th, .table > thead > tr > th, .nt-ops-head, .nt-mapping th, .nt-preview th {
  font-family: var(--font-ui);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: none;
  color: color-mix(in srgb, var(--ink) 58%, transparent);
}

/* Controls drawn once, used everywhere: one height, one radius, a soft
   inner edge, a real focus ring, our own chevron. */
body:not(.nt-marketing) .form-control,
body:not(.nt-marketing) .form-select {
  min-height: var(--control-h);
  padding: 0.45rem 0.8rem;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  background-color: var(--surface);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 0.9375rem;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 1px 1px rgba(16, 25, 43, 0.04);
  transition: border-color 0.12s, box-shadow 0.12s;
}

body:not(.nt-marketing) .form-control-sm,
body:not(.nt-marketing) .form-select-sm { min-height: 34px; padding: 0.3rem 0.65rem; font-size: 0.875rem; border-radius: 8px; }

body:not(.nt-marketing) .form-select {
  padding-right: 2.4rem;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16' fill='none' stroke='%2310192B' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M4 6l4 4 4-4'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.85rem center;
  background-size: 14px 14px;
}

body:not(.nt-marketing) .form-control:focus,
body:not(.nt-marketing) .form-select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
  outline: 0;
}

body:not(.nt-marketing) .btn {
  min-height: var(--control-h);
  padding: 0.45rem 1rem;
  border-radius: var(--radius);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 0.9375rem;
  letter-spacing: -0.005em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  transition: background-color 0.12s, border-color 0.12s, box-shadow 0.12s, color 0.12s;
}

body:not(.nt-marketing) .btn-sm { min-height: 34px; padding: 0.3rem 0.8rem; font-size: 0.875rem; border-radius: 8px; }

body:not(.nt-marketing) .btn-primary {
  --bs-btn-bg: var(--accent);
  --bs-btn-border-color: var(--accent);
  --bs-btn-hover-bg: var(--accent-hover);
  --bs-btn-hover-border-color: var(--accent-hover);
  --bs-btn-active-bg: color-mix(in srgb, var(--accent-hover) 85%, #000);
  --bs-btn-active-border-color: color-mix(in srgb, var(--accent-hover) 85%, #000);
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 1px 2px rgba(16, 25, 43, 0.10);
}

body:not(.nt-marketing) .btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); box-shadow: 0 2px 6px color-mix(in srgb, var(--accent) 25%, transparent); }
body:not(.nt-marketing) .btn-primary:active { box-shadow: none; }

/* Secondary actions: a soft tint, no outline. */
body:not(.nt-marketing) .btn-outline-primary {
  --bs-btn-color: var(--accent);
  --bs-btn-bg: color-mix(in srgb, var(--accent) 10%, transparent);
  --bs-btn-border-color: transparent;
  --bs-btn-hover-color: var(--accent-hover);
  --bs-btn-hover-bg: color-mix(in srgb, var(--accent) 16%, transparent);
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-color: var(--accent-hover);
  --bs-btn-active-bg: color-mix(in srgb, var(--accent) 22%, transparent);
  --bs-btn-active-border-color: transparent;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-color: transparent;
}

body:not(.nt-marketing) .btn-outline-secondary {
  --bs-btn-color: var(--ink);
  --bs-btn-bg: var(--surface);
  --bs-btn-border-color: var(--hairline);
  --bs-btn-hover-color: var(--ink);
  --bs-btn-hover-bg: color-mix(in srgb, var(--ink) 4%, var(--surface));
  --bs-btn-hover-border-color: color-mix(in srgb, var(--ink) 28%, transparent);
  --bs-btn-active-color: var(--ink);
  --bs-btn-active-bg: color-mix(in srgb, var(--ink) 7%, var(--surface));
  --bs-btn-active-border-color: color-mix(in srgb, var(--ink) 28%, transparent);
  color: var(--ink);
  background: var(--surface);
  border-color: var(--hairline);
  box-shadow: 0 1px 1px rgba(16, 25, 43, 0.04);
}

body:not(.nt-marketing) .btn:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); }

body:not(.nt-marketing) .nt-datepick {
  min-height: var(--control-h);
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  background: var(--surface);
  font-weight: 600;
  padding: 0.4rem 0.9rem;
  gap: 0.5rem;
}

/* Cards: one radius, one edge, roomier body; link cards lift on hover. */
body:not(.nt-marketing) .card { --bs-card-border-radius: var(--radius-lg); --bs-card-inner-border-radius: 15px; }
body:not(.nt-marketing) .card > .card-body { padding: 1.25rem 1.5rem; }
body:not(.nt-marketing) .nt-hero .card-body { padding: 1.35rem 1.6rem 1.25rem; }
.badge { font-family: var(--font-ui); font-weight: 600; letter-spacing: 0; border-radius: 999px; padding: 0.3em 0.65em; }
.nt-pill { font-family: var(--font-ui); }

/* Motion: small, quick, and off when asked. */
.nt-task, .nt-tl-step, .nt-hairline-row { transition: background-color 0.12s; }
.nt-task:hover { background: color-mix(in srgb, var(--accent) 3%, transparent); }
a.nt-board-card, a.nt-tile { transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s; }
a.nt-board-card:hover, a.nt-tile:hover { transform: translateY(-2px); box-shadow: 0 8px 20px -12px rgba(16, 25, 43, 0.35); }
@media (prefers-reduced-motion: reduce) {
  body:not(.nt-marketing) .btn, .nt-task, .nt-tl-step, a.nt-board-card, a.nt-tile { transition: none; }
  a.nt-board-card:hover, a.nt-tile:hover { transform: none; }
}

/* ===== Upload page, two columns =====
   The next step on the left, the file's facts on the right, so the page
   uses the width instead of leaving half of it empty. */
.nt-facts { display: grid; grid-template-columns: auto 1fr; gap: 0.45rem 1rem; font-size: 0.9rem; }
.nt-facts dt { font-weight: 500; color: color-mix(in srgb, var(--ink) 58%, transparent); margin: 0; }
.nt-facts dd { margin: 0; color: var(--ink); min-width: 0; overflow-wrap: anywhere; }

/* ===== Dashboard header and story tiles ===== */
.nt-month-title { font-size: 1.9rem; font-weight: 700; letter-spacing: -0.03em; line-height: 1.1; margin: 0; }
.nt-tl-icon { width: 36px; height: 36px; border-radius: 10px; border: 0; font-size: 1.05rem; background: color-mix(in srgb, var(--ink) 6%, transparent); color: color-mix(in srgb, var(--ink) 55%, transparent); }
.nt-tl-now .nt-tl-icon { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); }
.nt-tl-done .nt-tl-icon { background: color-mix(in srgb, var(--credit) 14%, transparent) !important; color: var(--credit) !important; border: 0 !important; }
.nt-tl-step { padding: 1rem 0; }

/* ===== Submission page: figures and grouped issues ===== */
.nt-figure { font-size: clamp(1rem, 1.35vw, 1.3rem); font-weight: 650; letter-spacing: -0.02em; line-height: 1.15; white-space: nowrap; }
.nt-next-glyph-warn { color: var(--amber-ink); background: color-mix(in srgb, var(--amber) 16%, transparent); }
.nt-issue { border-left: 3px solid var(--debit); }
.nt-issue-warning { border-left-color: var(--amber); }
.nt-issue-fold > summary { list-style: none; cursor: pointer; padding: 1rem 1.25rem; }
.nt-issue-fold > summary::-webkit-details-marker { display: none; }
.nt-issue-glyph { flex: 0 0 auto; width: 36px; height: 36px; border-radius: 10px; display: inline-flex; align-items: center; justify-content: center; color: var(--debit); background: color-mix(in srgb, var(--debit) 10%, transparent); }
.nt-issue-warning .nt-issue-glyph { color: var(--amber-ink); background: color-mix(in srgb, var(--amber) 14%, transparent); }
.nt-issue-chev { color: color-mix(in srgb, var(--ink) 45%, transparent); transition: transform 0.15s; }
.nt-issue-fold[open] .nt-issue-chev { transform: rotate(180deg); }
.nt-issue-body { padding: 0 1.25rem 1rem; border-top: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); }

/* ===== Icons with colour =====
   Icon tiles carry the page: a tinted square with a bolder glyph, one
   tone per meaning. Blue is the product and the next thing, green is
   money in and done, amber is attention, red is money out, navy is
   institutions, ink is neutral. */
.nt-ico-blue { color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.nt-ico-green { color: var(--credit); background: color-mix(in srgb, var(--credit) 13%, transparent); }
.nt-ico-amber { color: var(--amber-ink); background: color-mix(in srgb, var(--amber) 16%, transparent); }
.nt-ico-red { color: var(--debit); background: color-mix(in srgb, var(--debit) 11%, transparent); }
.nt-ico-navy { color: #0F1E3D; background: color-mix(in srgb, #0F1E3D 10%, transparent); }
.nt-ico-ink { color: color-mix(in srgb, var(--ink) 70%, transparent); background: color-mix(in srgb, var(--ink) 7%, transparent); }
[data-bs-theme="dark"] .nt-ico-navy { color: #C9D3E8; background: rgba(201, 211, 232, 0.12); }

.nt-tile-ico { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; font-size: 1.15rem; }
.nt-row-ico { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; font-size: 0.9rem; }

/* Sidebar: icon tiles, a real active state, the account at the bottom. */
.nt-nav .nav-link { display: flex; align-items: center; gap: 0.65rem; padding: 0.4rem 0.6rem; border-radius: 10px; position: relative; }
.nt-nav .nav-link .bi { margin: 0; opacity: 1; font-size: 0.9rem; }
.nt-nav-ico { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; transition: transform 0.12s; }
.nt-nav .nav-link:hover .nt-nav-ico { transform: translateY(-1px); }
.nt-nav .nav-link.active { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px rgba(16, 25, 43, 0.06), 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent); }
.nt-nav .nav-link.active::before { content: ""; position: absolute; left: -0.75rem; top: 0.55rem; bottom: 0.55rem; width: 3px; border-radius: 3px; background: var(--accent); }
/* The active item keeps its own icon colour; the card and bar mark it. */
.nt-nav-section { background: transparent; color: color-mix(in srgb, var(--ink) 48%, transparent); padding: 0.15rem 0.6rem; margin: 1.1rem 0 0.25rem; font-size: 0.7rem; letter-spacing: 0.04em; text-transform: uppercase; }
.nt-sidebar-account { display: flex; align-items: center; gap: 0.65rem; padding: 0.75rem 0.6rem 0.25rem; border-top: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); font-size: 0.875rem; }
.nt-avatar { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 10px; display: inline-flex; align-items: center; justify-content: center; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.02em; color: #fff; background: linear-gradient(135deg, var(--accent), #0F1E3D); }

/* The month's story as tiles. */
.nt-story-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.75rem; }
@media (max-width: 991px) { .nt-story-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 575px) { .nt-story-grid { grid-template-columns: 1fr; } }
.nt-story-tile { padding: 1rem; border-radius: 14px; border: 1px solid color-mix(in srgb, var(--ink) 9%, transparent); background: color-mix(in srgb, var(--ink) 2%, var(--surface)); opacity: 0.85; }
.nt-story-done { opacity: 1; }
.nt-story-now { opacity: 1; background: var(--surface); border-color: color-mix(in srgb, var(--accent) 45%, transparent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 10%, transparent); }
.nt-story-ico { width: 36px; height: 36px; border-radius: 10px; display: inline-flex; align-items: center; justify-content: center; font-size: 1.05rem; color: color-mix(in srgb, var(--ink) 55%, transparent); background: color-mix(in srgb, var(--ink) 7%, transparent); }
.nt-story-now .nt-story-ico { color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.nt-story-done .nt-story-ico { color: var(--credit); background: color-mix(in srgb, var(--credit) 13%, transparent); }

/* Empty states: an icon tile, a line, a button. */
.nt-empty { text-align: center; padding: 3rem 1.5rem; max-width: 520px; margin: 0 auto; }
.nt-empty-ico { width: 56px; height: 56px; border-radius: 16px; display: inline-flex; align-items: center; justify-content: center; font-size: 1.5rem; color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); margin-bottom: 1rem; }

/* Dark mode: the select's chevron is drawn in ink, so redraw it light. */
[data-bs-theme="dark"] body:not(.nt-marketing) .form-select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16' fill='none' stroke='%23E4E9EF' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M4 6l4 4 4-4'/></svg>");
}

/* ===== Step strip, one design for every state =====
   Every step is the same ring. Green with a tick when done, blue with a
   dot when current, grey with a dot when not yet, pulsing blue while a
   job runs. The connecting line sits between the circles, never under
   them, and every label hangs from the same baseline. */
.nt-fsteps { display: flex; align-items: flex-start; max-width: none; }
.nt-fstep { display: flex; flex-direction: column; align-items: center; min-width: 72px; flex: 0 0 auto; }
.nt-fstep-circle, .nt-fstep-circle.nt-fstep-done, .nt-fstep-circle.nt-fstep-current, .nt-fstep-circle.nt-fstep-active {
  box-sizing: border-box;
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--ink) 22%, transparent);
  background: var(--surface) !important;
  color: color-mix(in srgb, var(--ink) 35%, transparent);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.85rem; line-height: 1;
  position: relative; z-index: 1;
}
.nt-fstep-pip { width: 10px; height: 10px; border-radius: 50%; background: currentColor; }
.nt-fstep-circle.nt-fstep-done { border-color: var(--credit) !important; color: var(--credit) !important; }
.nt-fstep-circle.nt-fstep-current { border-color: var(--accent); color: var(--accent); }
.nt-fstep-circle.nt-fstep-active { border-color: var(--accent); color: var(--accent); animation: nt-working 1.8s ease-in-out infinite; }
.nt-fstep-link { flex: 1 1 1.5rem; height: 2px; margin: 14px 0 0; background: color-mix(in srgb, var(--ink) 14%, transparent); min-width: 1rem; }
.nt-fstep-link-done { background: var(--credit); }
.nt-fstep-label { margin-top: 0.5rem; font-weight: 500; line-height: 1.2; color: color-mix(in srgb, var(--ink) 60%, transparent); }
.nt-fstep-here .nt-fstep-label { color: var(--ink); font-weight: 600; }
.nt-fsteps-compact .nt-fsteps { max-width: none; }
.nt-fsteps-compact .nt-fstep { min-width: 66px; }
.nt-fsteps-compact .nt-fstep-circle { width: 26px; height: 26px; font-size: 0.75rem; }
.nt-fsteps-compact .nt-fstep-pip { width: 8px; height: 8px; }
.nt-fsteps-compact .nt-fstep-link { margin-top: 12px; }

/* The upload hero strip stays a comfortable width. */
.nt-hero .nt-fsteps { max-width: 620px; }

/* Tables inside cards keep the card's rounded corners: the table paints
   its own white, so the card clips it. */
body:not(.nt-marketing) .card:has(> .table),
body:not(.nt-marketing) .card:has(> .table-responsive) { overflow: hidden; overflow-x: auto; }
body:not(.nt-marketing) .card > .table { border-radius: inherit; margin-bottom: 0; }
body:not(.nt-marketing) .card > .table thead th:first-child { border-top-left-radius: inherit; }
body:not(.nt-marketing) .card > .table thead th:last-child { border-top-right-radius: inherit; }
body:not(.nt-marketing) .card > .table thead th { background: color-mix(in srgb, var(--ink) 3%, var(--surface)); padding-top: 0.8rem; padding-bottom: 0.8rem; }
body:not(.nt-marketing) .card > .table > tbody > tr:last-child > td { border-bottom: 0; }
body:not(.nt-marketing) .card > .table > tbody > tr > td { padding-top: 0.75rem; padding-bottom: 0.75rem; }

/* Room under the last row so it does not sit on the curve. */
body:not(.nt-marketing) .card:has(> .table) { padding-bottom: 0.5rem; }
body:not(.nt-marketing) .card > .table > tbody > tr:last-child > td { padding-bottom: 0.9rem; }

/* Breathing room at the table's edges, matching the card body's inset. */
body:not(.nt-marketing) .card > .table > :not(caption) > * > :first-child { padding-left: 1.5rem; }
body:not(.nt-marketing) .card > .table > :not(caption) > * > :last-child { padding-right: 1.5rem; }

/* ===== Top bar cluster =====
   Icon buttons are 36px squares, the user chip hugs its content, and the
   bell's dot sits on the bell. The generic button rule does not apply. */
.nt-topbar .d-flex.align-items-center.gap-2 { gap: 0.35rem !important; }
body:not(.nt-marketing) .nt-themetoggle,
body:not(.nt-marketing) .nt-bell {
  width: 36px; height: 36px; min-height: 0; padding: 0; border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.05rem; color: color-mix(in srgb, var(--ink) 62%, transparent);
  box-shadow: none;
}
body:not(.nt-marketing) .nt-themetoggle:hover,
body:not(.nt-marketing) .nt-bell:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); color: var(--ink); }
.nt-bell-dot { top: 7px; right: 8px; }
body:not(.nt-marketing) .nt-userchip {
  min-height: 0; padding: 0.25rem 0.4rem 0.25rem 0.25rem; border-radius: 12px; gap: 0.5rem !important;
  box-shadow: none; border: 0; background: transparent; font-weight: 500;
}
body:not(.nt-marketing) .nt-userchip:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); }
body:not(.nt-marketing) .nt-userchip .bi-chevron-down { font-size: 0.7rem; margin-left: 0.1rem; }
body:not(.nt-marketing) .nt-userchip .nt-avatar { width: 30px; height: 30px; font-size: 0.68rem; border-radius: 9px; }

/* ===== Running state =====
   A light travels the whole border while a job runs. Drawn with a
   rotating conic gradient masked to a 2px ring, so the card's own
   background stays flat. Off for people who ask for less motion. */
@property --nt-angle { syntax: "<angle>"; initial-value: 0deg; inherits: false; }

.nt-running { position: relative; border-color: transparent; }
.nt-running::before {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  padding: 2px;
  background: conic-gradient(from var(--nt-angle), color-mix(in srgb, var(--accent) 18%, transparent) 0 62%, var(--accent) 78%, color-mix(in srgb, var(--accent) 18%, transparent) 94%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: nt-orbit 1.8s linear infinite;
  pointer-events: none;
}

@keyframes nt-orbit { to { --nt-angle: 360deg; } }

.nt-spinner {
  width: 20px; height: 20px; border-radius: 50%;
  border: 2.5px solid color-mix(in srgb, var(--accent) 22%, transparent);
  border-top-color: var(--accent);
  animation: nt-pending-spin 0.9s linear infinite;
}

.nt-waive { border-bottom: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); }

@media (prefers-reduced-motion: reduce) {
  .nt-running::before { animation: none; background: color-mix(in srgb, var(--accent) 45%, transparent); }
  .nt-spinner { animation: none; }
}

/* ===== Motion between states =====
   Nothing pops. Pages cross-fade (view transitions), frames and folds
   fade and rise as they arrive, flashes ease in. All of it short, and
   all of it off for people who ask for less motion. */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: 160ms ease-out both nt-fade-out; }
::view-transition-new(root) { animation: 220ms ease-out both nt-fade-in; }

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

turbo-frame > * { animation: nt-fade-in 240ms ease-out both; }
turbo-frame[busy] > * { opacity: 0.6; transition: opacity 160ms ease-out; }

details[open] > :not(summary) { animation: nt-fade-in 200ms ease-out both; }
.alert { animation: nt-fade-in 240ms ease-out both; }
.nt-running, .nt-next, .nt-issue, .nt-task { animation: nt-fade-in 240ms ease-out both; }

/* Morphed updates: a card whose content changed eases its colour and
   shadow rather than snapping. */
.card, .badge, .nt-fstep-circle, .nt-fstep-link { transition: background-color 200ms ease, border-color 200ms ease, box-shadow 200ms ease, color 200ms ease; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
  turbo-frame > *, details[open] > :not(summary), .alert, .nt-flash, .nt-running, .nt-next, .nt-issue, .nt-task { animation: none; }
}

/* The shell stays put between pages: sidebar and top bar are matched
   across the transition, so only the content cross-fades and rises. */
.nt-sidebar { view-transition-name: nt-sidebar; }
.nt-topbar { view-transition-name: nt-topbar; }
.nt-content { view-transition-name: nt-content; }
::view-transition-old(nt-sidebar), ::view-transition-new(nt-sidebar),
::view-transition-old(nt-topbar), ::view-transition-new(nt-topbar) { animation: none; mix-blend-mode: normal; }
::view-transition-old(nt-content) { animation: 140ms ease-out both nt-fade-out; }
::view-transition-new(nt-content) { animation: 280ms cubic-bezier(0.2, 0.8, 0.2, 1) both nt-fade-in; }
::view-transition-old(root), ::view-transition-new(root) { animation: none; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(nt-content), ::view-transition-new(nt-content) { animation: none; }
}

/* ===== Notifications: the bell menu and the page behind it =====
   view-transition-name gives the topbar its own stacking context, which
   trapped the bell menu beneath the page. Lifting the bar above the
   content lets its menus paint over the step strip. */
.nt-topbar { position: relative; z-index: 5; }

.nt-notif-menu { width: 380px; max-width: calc(100vw - 1.5rem); padding: 0; overflow: hidden; border-radius: 14px; border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); box-shadow: 0 12px 32px rgba(16, 25, 43, 0.14); }
.nt-notif-head { display: flex; justify-content: space-between; align-items: center; padding: 0.7rem 1rem; font-size: 0.82rem; font-weight: 600; color: color-mix(in srgb, var(--ink) 65%, transparent); border-bottom: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); }
.nt-notif-list { list-style: none; margin: 0; padding: 0; }
.nt-notif-list li + li { border-top: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); }
.nt-notif-item { display: flex; align-items: center; gap: 0.75rem; padding: 0.7rem 1rem; color: var(--ink); text-decoration: none; }
.nt-notif-item:hover, .nt-notif-item:focus-visible { background: color-mix(in srgb, var(--accent) 5%, transparent); color: var(--ink); }
.nt-notif-ico { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; font-size: 0.95rem; }
.nt-notif-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.nt-notif-title { font-size: 0.9rem; font-weight: 600; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nt-notif-detail { font-size: 0.78rem; color: color-mix(in srgb, var(--ink) 58%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nt-notif-count { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; line-height: 1.2; font-size: 0.9rem; }
.nt-notif-unit { font-size: 0.72rem; color: color-mix(in srgb, var(--ink) 55%, transparent); }
.nt-notif-money { font-size: 0.78rem; color: var(--debit); font-weight: 600; }
.nt-notif-foot { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; padding: 0.65rem 1rem; font-size: 0.85rem; font-weight: 600; color: var(--accent); text-decoration: none; border-top: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); background: color-mix(in srgb, var(--ink) 2%, transparent); }
.nt-notif-foot:hover { color: var(--accent); background: color-mix(in srgb, var(--accent) 6%, transparent); }
.nt-notif-empty { display: flex; align-items: center; gap: 0.75rem; padding: 0.9rem 1rem; font-size: 0.9rem; color: color-mix(in srgb, var(--ink) 65%, transparent); }

/* The page: the same rows, roomier, inside a card. */
.nt-notif-page { overflow: hidden; }
.nt-notif-page .nt-notif-item { padding: 0.95rem 1.25rem; gap: 1rem; }
.nt-notif-page .nt-notif-ico { width: 36px; height: 36px; border-radius: 10px; font-size: 1.05rem; }
.nt-notif-page .nt-notif-title { font-size: 0.95rem; white-space: normal; }
.nt-notif-page .nt-notif-detail { white-space: normal; }
@media (max-width: 575px) {
  .nt-notif-page .nt-notif-item { padding-inline: 1rem; }
}

/* ===== Add-binder modal on an upload ===== */
.modal-content { border-radius: 14px; border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); }
.modal-header, .modal-footer { border-color: color-mix(in srgb, var(--ink) 8%, transparent); }
.nt-binder-add { color: var(--accent); font-weight: 600; }
/* Rails wraps a field and its label in a block div when they carry an
   error, which pushed the label's info tip onto its own line. Let the
   wrapper vanish from layout; the alert above the form names the errors. */
.field_with_errors { display: contents; }

/* ===== Binder form: header tile, two columns, live preview ===== */
.nt-page-ico { flex: 0 0 auto; width: 44px; height: 44px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; font-size: 1.3rem; }
.nt-binder-layout { display: grid; grid-template-columns: minmax(0, 640px) minmax(260px, 320px); gap: 1.5rem; align-items: start; }
@media (max-width: 991.98px) { .nt-binder-layout { grid-template-columns: minmax(0, 640px); } }
.nt-binder-form .form-label { font-size: 0.85rem; font-weight: 600; margin-bottom: 0.3rem; }
.nt-binder-form .form-control, .nt-binder-form .form-select, .nt-binder-form .input-group-text { padding-top: 0.45rem; padding-bottom: 0.45rem; }
.nt-binder-form .input-group-text { color: color-mix(in srgb, var(--ink) 50%, transparent); background: color-mix(in srgb, var(--ink) 3%, var(--surface)); }
.nt-binder-form .form-text { font-size: 0.78rem; color: color-mix(in srgb, var(--ink) 58%, transparent); }
.nt-binder-form .nt-section-label + .mb-3 { margin-top: 0.1rem; }
.nt-ref-input { font-family: var(--font-mono); letter-spacing: 0.02em; }
.nt-quickpicks { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8rem; }
.nt-quickpicks .btn-link { font-size: 0.8rem; text-decoration: none; }
.nt-quickpicks .btn-link:hover { text-decoration: underline; }
.nt-cancel-link { font-size: 0.9rem; color: color-mix(in srgb, var(--ink) 60%, transparent); text-decoration: none; }
.nt-cancel-link:hover { color: var(--ink); text-decoration: underline; }
.nt-binder-preview { position: sticky; top: 1rem; }
.nt-preview-provider { font-weight: 600; font-size: 0.95rem; }
.nt-preview-ref { font-family: var(--font-mono); font-size: 1.2rem; font-weight: 600; letter-spacing: 0.02em; margin: 0.1rem 0 1rem; }
.nt-preview-empty { color: color-mix(in srgb, var(--ink) 40%, transparent); font-weight: 500; }
.nt-preview-facts { list-style: none; padding: 0; margin: 0 0 1rem; display: flex; flex-direction: column; gap: 0.65rem; font-size: 0.88rem; }
.nt-preview-facts li { display: flex; align-items: center; gap: 0.65rem; }
.nt-preview-ico { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; font-size: 0.95rem; }
.nt-optional { font-size: 0.72rem; font-weight: 500; color: color-mix(in srgb, var(--ink) 50%, transparent); margin-left: 0.25rem; }
.nt-caption-warn { color: var(--amber-ink) !important; }
.nt-preview-program { font-size: 1.05rem; font-weight: 600; margin-top: 0.1rem; }
.nt-preview-program + .nt-preview-ref { font-size: 0.95rem; font-weight: 500; margin-top: 0.15rem; }

/* ===== Capacity provider form: the library picker ===== */
.nt-library { list-style: none; margin: 0.5rem 0 0; padding: 0; max-height: 264px; overflow-y: auto; border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); border-radius: 10px; background: var(--surface); }
.nt-library li + li { border-top: 1px solid color-mix(in srgb, var(--ink) 6%, transparent); }
.nt-library-row { display: flex; align-items: center; gap: 0.75rem; width: 100%; text-align: left; padding: 0.55rem 0.75rem; border: 0; background: transparent; color: var(--ink); }
.nt-library-row:hover, .nt-library-row:focus-visible { background: color-mix(in srgb, var(--accent) 6%, transparent); outline: none; }
.nt-library-ico { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; font-size: 0.9rem; }
.nt-library-text { display: flex; flex-direction: column; min-width: 0; }
.nt-library-name { font-size: 0.9rem; font-weight: 600; line-height: 1.25; }
.nt-library-meta { font-size: 0.76rem; color: color-mix(in srgb, var(--ink) 58%, transparent); }
.nt-library-none { padding: 0.8rem 0.75rem; font-size: 0.85rem; color: color-mix(in srgb, var(--ink) 58%, transparent); }
.nt-library-foot { display: flex; justify-content: space-between; align-items: center; gap: 0.75rem; flex-wrap: wrap; font-size: 0.8rem; margin: 0.5rem 0 1rem; }
.nt-library-foot .btn-link { font-size: 0.8rem; text-decoration: none; }
.nt-library-foot .btn-link:hover { text-decoration: underline; }
.nt-picked { display: flex; align-items: flex-start; gap: 0.75rem; padding: 0.85rem 1rem; margin-bottom: 1rem; border-radius: 12px; border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); background: color-mix(in srgb, var(--accent) 5%, var(--surface)); }
.nt-picked .nt-library-name { font-size: 1rem; }
.nt-picked-standard { display: inline-flex; align-items: center; gap: 0.3rem; margin-top: 0.35rem; font-size: 0.8rem; font-weight: 500; color: var(--credit); }
.nt-picked-change { margin-left: auto; font-size: 0.8rem; text-decoration: none; white-space: nowrap; }
.nt-plan-line { white-space: nowrap; }
.nt-preview-kind { margin-top: 0.1rem; }
[data-bs-theme="dark"] .nt-library, [data-bs-theme="dark"] .nt-picked { background: color-mix(in srgb, var(--ink) 4%, var(--surface)); }

/* ===== Toasts: flash messages that never move the page =====
   A stack under the top bar, top right. Above the bar's menus. */
.nt-toasts { position: fixed; top: calc(52px + 0.75rem); right: 1.25rem; z-index: 1080; display: flex; flex-direction: column; gap: 0.5rem; width: 380px; max-width: calc(100vw - 1.5rem); pointer-events: none; }
.nt-toast { pointer-events: auto; display: flex; align-items: flex-start; gap: 0.7rem; padding: 0.7rem 0.75rem 0.7rem 0.8rem; border-radius: 12px; background: var(--surface); color: var(--ink); border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); border-left-width: 3px; box-shadow: 0 10px 28px rgba(16, 25, 43, 0.16); cursor: pointer; animation: nt-toast-in 220ms cubic-bezier(0.2, 0.8, 0.2, 1) both; font-size: 0.9rem; line-height: 1.35; }
.nt-toast-green { border-left-color: var(--credit); }
.nt-toast-red { border-left-color: var(--debit); }
.nt-toast-blue { border-left-color: var(--accent); }
.nt-toast-ico { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; font-size: 0.9rem; margin-top: 1px; }
.nt-toast-text { flex: 1 1 auto; min-width: 0; padding-top: 0.25rem; }
.nt-toast-close { flex: 0 0 auto; border: 0; background: transparent; color: color-mix(in srgb, var(--ink) 45%, transparent); font-size: 0.75rem; padding: 0.35rem; margin: -0.1rem -0.2rem 0 0; border-radius: 6px; }
.nt-toast-close:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 6%, transparent); }
.nt-toast-leaving { opacity: 0; transform: translateX(12px); transition: opacity 240ms ease, transform 240ms ease; }
@keyframes nt-toast-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
body.nt-marketing .nt-toasts, .nt-auth .nt-toasts { top: 1rem; }
@media (max-width: 575.98px) { .nt-toasts { right: 0.75rem; left: 0.75rem; width: auto; } }
@media (prefers-reduced-motion: reduce) { .nt-toast { animation: none; } .nt-toast-leaving { transition: none; } }
[data-bs-theme="dark"] .nt-toast { box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45); }

/* ===== Template column editor ===== */
.nt-template-layout { display: grid; grid-template-columns: minmax(0, 760px) minmax(260px, 320px); gap: 1.5rem; align-items: start; }
@media (max-width: 1199.98px) { .nt-template-layout { grid-template-columns: minmax(0, 1fr); } }
.nt-col-table-wrap { border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); border-radius: 10px; overflow-x: auto; }
.nt-col-table { min-width: 640px; }
.nt-col-table thead th { position: static; font-weight: 600; padding: 0.5rem 0.5rem; background: color-mix(in srgb, var(--ink) 3%, var(--surface)); }
.nt-col-table td { padding: 0.35rem 0.5rem; vertical-align: middle; }
.nt-col-move { width: 34px; white-space: nowrap; }
.nt-col-move .nt-col-btn { display: block; padding: 0 0.15rem; line-height: 1; font-size: 0.7rem; }
.nt-col-n { width: 34px; color: color-mix(in srgb, var(--ink) 50%, transparent); font-size: 0.8rem; }
.nt-col-btn { border: 0; background: transparent; color: color-mix(in srgb, var(--ink) 45%, transparent); border-radius: 6px; padding: 0.25rem 0.4rem; }
.nt-col-btn:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 6%, transparent); }
.nt-col-remove:hover { color: var(--debit); background: color-mix(in srgb, var(--debit) 8%, transparent); }
.nt-col-type { display: inline-block; padding: 0.3rem 0.5rem; font-family: var(--font-mono); font-size: 0.75rem; }
.nt-col-empty { padding: 1rem 0.75rem; }
.nt-paste { padding: 0.85rem 1rem; border-radius: 10px; background: color-mix(in srgb, var(--accent) 5%, var(--surface)); border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent); }
.nt-header-strip { display: flex; gap: 2px; overflow-x: auto; padding-bottom: 0.25rem; }
.nt-header-cell { flex: 0 0 auto; font-family: var(--font-mono); font-size: 0.7rem; font-weight: 600; padding: 0.3rem 0.5rem; background: color-mix(in srgb, var(--ink) 6%, transparent); border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); white-space: nowrap; max-width: 140px; overflow: hidden; text-overflow: ellipsis; }
.nt-header-cell-empty { color: color-mix(in srgb, var(--ink) 40%, transparent); }

/* ===== Binder rules as tiles: grey until filled, blue once a rule is set ===== */
.nt-rule-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
@media (max-width: 575.98px) { .nt-rule-grid { grid-template-columns: 1fr; } }
.nt-rule-tile { display: flex; gap: 0.75rem; align-items: flex-start; padding: 0.85rem; border-radius: 12px; border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); background: color-mix(in srgb, var(--ink) 2%, var(--surface)); transition: border-color 160ms ease, background-color 160ms ease; }
.nt-rule-tile-wide { grid-column: 1 / -1; }
.nt-rule-ico { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; font-size: 0.95rem; color: color-mix(in srgb, var(--ink) 50%, transparent); background: color-mix(in srgb, var(--ink) 7%, transparent); transition: color 160ms ease, background-color 160ms ease; }
.nt-rule-body { flex: 1 1 auto; min-width: 0; }
.nt-rule-body .form-label { margin-bottom: 0.25rem; }
.nt-rule-filled { border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: color-mix(in srgb, var(--accent) 4%, var(--surface)); }
.nt-rule-filled .nt-rule-ico { color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }

/* ===== Lists: links read as names, not as hyperlinks ===== */
.card table a:not(.btn):not(.nt-ref):not(.nt-fstep-link) { text-decoration: none; font-weight: 500; color: var(--ink); }
.card table a:not(.btn):not(.nt-ref):not(.nt-fstep-link):hover { color: var(--accent); text-decoration: underline; }
.card table td.small a:not(.btn):not(.nt-ref) { font-weight: 400; }
/* Page header lines sit level with the icon tile. */
.nt-page-sub { padding-left: calc(44px + 1rem); }
@media (max-width: 575.98px) { .nt-page-sub { padding-left: 0; } }
/* Template editor: room for the carrier's header text. */
.nt-col-table th:nth-child(3), .nt-col-table td:nth-child(3) { min-width: 240px; }
.nt-col-table { min-width: 760px; }

/* ===== Help page and activity log ===== */
.nt-help { max-width: 760px; }
.nt-help-steps { padding-left: 1.25rem; display: flex; flex-direction: column; gap: 0.6rem; font-size: 0.92rem; margin: 0; }
.nt-help-list { padding-left: 1.1rem; display: flex; flex-direction: column; gap: 0.5rem; font-size: 0.92rem; margin: 0; }
.nt-activity-list { list-style: none; margin: 0; padding: 0; }
.nt-activity-row { display: flex; gap: 1.25rem; padding: 0.75rem 1.25rem; border-top: 1px solid color-mix(in srgb, var(--ink) 7%, transparent); }
.nt-activity-row:first-child { border-top: 0; }
.nt-activity-when { flex: 0 0 110px; font-size: 0.82rem; line-height: 1.3; }
.nt-activity-what { flex: 1 1 auto; min-width: 0; font-size: 0.92rem; }
.nt-close-account > summary { list-style: none; cursor: pointer; }
.nt-close-account > summary::-webkit-details-marker { display: none; }

/* ===== Phones: nothing clipped, nothing squeezed =====
   Tables inside cards scroll sideways within the card instead of being
   cut off; the marketing grid keeps its gutters inside the viewport;
   the editor's quick picks stack. */
.card:has(> table), .card:has(> .table) { overflow-x: auto; }
.nt-col-table-wrap { overflow-x: auto; }
@media (max-width: 575.98px) {
  .nt-marketing .row.g-5 { --bs-gutter-x: 1.25rem; --bs-gutter-y: 1.25rem; }
  .nt-quickpicks { flex-direction: column; align-items: flex-start; gap: 0.35rem; }
  .nt-quickpicks .nt-sep { display: none; }
  .nt-binder-preview { position: static; }
}
@media (max-width: 575.98px) { .nt-mapping { min-width: 640px; } .nt-mapping-wrap { overflow-x: auto; } }
/* Phones: list tables keep their columns and scroll sideways inside the
   card, instead of breaking file names into five lines. */
@media (max-width: 575.98px) {
  body:not(.nt-marketing) .card > .table { min-width: 640px; }
  body:not(.nt-marketing) .card > .table td, body:not(.nt-marketing) .card > .table th { white-space: nowrap; }
}

/* ===== Uploads queue: choose binders in the list, process all at once ===== */
.nt-queue { min-width: 240px; }
.nt-clash { padding: 0.75rem 0.9rem; border-radius: 10px; background: color-mix(in srgb, var(--amber) 12%, var(--surface)); border: 1px solid color-mix(in srgb, var(--amber) 45%, transparent); margin: 0.25rem 0; }
.nt-routes { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.88rem; }
.nt-routes-miss { color: var(--debit); }

/* ===== Dashboard assistant ===== */
/* A fixed window that scrolls inside itself: the page never grows with the conversation. */
.nt-chat-thread { display: flex; flex-direction: column; gap: 0.6rem; height: 360px; overflow-y: auto; overscroll-behavior: contain; margin-bottom: 0.75rem; padding-right: 0.25rem; border-top: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); border-bottom: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); padding-top: 0.6rem; padding-bottom: 0.6rem; }
.nt-chat-thread:empty { display: none; }
.nt-chat-thread > :first-child { margin-top: auto; }
@media (max-width: 575.98px) { .nt-chat-thread { height: 300px; } }
.nt-chat-msg { display: flex; gap: 0.6rem; align-items: flex-start; }
.nt-chat-user { justify-content: flex-end; }
.nt-chat-bubble { max-width: 78%; padding: 0.6rem 0.85rem; border-radius: 14px; font-size: 0.92rem; line-height: 1.45; background: color-mix(in srgb, var(--ink) 4%, var(--surface)); }
.nt-chat-user .nt-chat-bubble { background: color-mix(in srgb, var(--accent) 10%, var(--surface)); border-bottom-right-radius: 4px; }
.nt-chat-bot .nt-chat-bubble { border-bottom-left-radius: 4px; }
.nt-chat-bubble p { margin: 0 0 0.5rem; } .nt-chat-bubble p:last-child { margin-bottom: 0; }
.nt-chat-bubble ul { margin: 0 0 0.5rem 1.1rem; padding: 0; } .nt-chat-bubble ul:last-child { margin-bottom: 0; }
.nt-chat-bubble a { color: var(--accent); font-weight: 500; }
.nt-chat-avatar { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; font-size: 0.8rem; color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); margin-top: 2px; }
.nt-chat-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.nt-chip { border: 1px solid color-mix(in srgb, var(--ink) 14%, transparent); background: transparent; color: color-mix(in srgb, var(--ink) 75%, transparent); border-radius: 999px; padding: 0.25rem 0.7rem; font-size: 0.8rem; }
.nt-chip:hover { border-color: var(--accent); color: var(--accent); }
.nt-chat-dots { display: inline-flex; gap: 4px; padding: 0.2rem 0; }
.nt-chat-dots i { width: 6px; height: 6px; border-radius: 50%; background: color-mix(in srgb, var(--ink) 40%, transparent); animation: nt-dot 1s infinite ease-in-out; }
.nt-chat-dots i:nth-child(2) { animation-delay: 0.15s; } .nt-chat-dots i:nth-child(3) { animation-delay: 0.3s; }
@keyframes nt-dot { 0%, 80%, 100% { opacity: 0.3; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-3px); } }
@media (prefers-reduced-motion: reduce) { .nt-chat-dots i { animation: none; } }

/* ===== Assistant proposals and corrections ===== */
.nt-proposal { margin-top: 0.6rem; padding: 0.6rem 0.75rem; border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); border-radius: 10px; background: var(--surface); }
.nt-proposal + .nt-proposal { margin-top: 0.5rem; }
.nt-proposal-ico { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.nt-proposal-fold summary { cursor: pointer; color: var(--accent); list-style: none; }
.nt-proposal-fold summary::-webkit-details-marker { display: none; }
.nt-proposal table td { padding: 0.2rem 0.4rem; border-color: color-mix(in srgb, var(--ink) 8%, transparent); }
.nt-proposal form { display: inline; }
.nt-corrections .nt-issue-body { padding-top: 0.75rem; }

/* ===== Template editor: per-type format controls and value maps ===== */
.nt-col-format { min-width: 140px; }
.nt-col-format .form-select-sm { font-size: 0.8rem; }
.nt-col-values textarea { font-family: var(--font-mono); font-size: 0.78rem; }
.nt-col-values-btn { display: block; font-size: 0.78rem; text-decoration: none; }
/* Narrower name and source cells so the required tick stays in view without a scroll. */
.nt-col-table { min-width: 700px; }
.nt-col-table th:nth-child(3), .nt-col-table td:nth-child(3) { min-width: 190px; }
.nt-col-table th:nth-child(4), .nt-col-table td:nth-child(4) { min-width: 190px; }
.nt-template-layout { grid-template-columns: minmax(0, 800px) minmax(240px, 300px); }

/* ===== Assistant page ===== */
.nt-chat-page .nt-chat-thread { height: calc(100vh - 420px); min-height: 320px; max-height: 720px; border-top: 0; padding-top: 0; }
.nt-chat-page .nt-chat-thread:empty + .nt-chat-form { margin-top: 0; }
.nt-plain-list { padding-left: 1.1rem; margin: 0; }
.nt-plain-list li + li { margin-top: 0.3rem; }
.nt-tile-ico-lg { width: 48px; height: 48px; font-size: 1.3rem; border-radius: 12px; }
@media (max-width: 575.98px) { .nt-chat-page .nt-chat-thread { height: 320px; } }

/* ===== Assistant page: full width, text area, saved chats ===== */
.nt-chat-page .nt-chat-thread { height: calc(100vh - 460px); min-height: 280px; max-height: 640px; }
.nt-chat-thread-open { height: auto !important; max-height: none !important; overflow: visible; }
.nt-chat-textarea { resize: none; min-height: 84px; line-height: 1.45; }
.nt-chat-who { font-size: 0.72rem; color: color-mix(in srgb, var(--ink) 55%, transparent); margin-bottom: 0.2rem; }
.nt-chat-event { text-align: center; padding: 0.2rem 0; }
.nt-chat-bubble > div > p:last-child { margin-bottom: 0; }
.nt-access-form { margin-left: 0.75rem; }
.nt-access-form .form-select-sm { font-size: 0.78rem; padding-top: 0.15rem; padding-bottom: 0.15rem; }
.nt-page-head-actions { flex-wrap: nowrap; }
@media (max-width: 767.98px) { .nt-page-head-actions { flex-wrap: wrap; } }
.nt-chat-send { align-self: stretch; padding-left: 1.4rem; padding-right: 1.4rem; }
.nt-chat-drop { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; border: 2px dashed var(--accent); border-radius: 12px; background: color-mix(in srgb, var(--accent) 6%, var(--surface)); color: var(--accent); font-weight: 600; z-index: 3; pointer-events: none; }
.nt-chat-page { position: relative; }
.nt-chat-attach { font-size: 0.85rem; text-decoration: none; }

/* ===== Assistant: the box at work. The border becomes a slow, breathing gradient with a faint glow. ===== */
.nt-chat-box { position: relative; border-radius: 12px; isolation: isolate; }
.nt-composer { position: relative; z-index: 1; }
.nt-chat-thinking .nt-composer { border-color: transparent; }
.nt-chat-thinking::before, .nt-chat-thinking::after {
  content: ""; position: absolute; inset: -2px; border-radius: 14px; pointer-events: none;
  background: linear-gradient(115deg, #1F4FD8 0%, #7C5CFF 30%, #22C3E6 55%, #7C5CFF 78%, #1F4FD8 100%);
  background-size: 260% 260%;
  animation: nt-drift 4.5s ease-in-out infinite;
}
/* The ring: the gradient masked to a two-pixel edge. */
.nt-chat-thinking::before {
  padding: 2px; z-index: 2;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude;
}
/* The glow: the same gradient, blurred and breathing behind the box. */
.nt-chat-thinking::after { z-index: -1; filter: blur(14px); opacity: 0.35; animation: nt-drift 4.5s ease-in-out infinite, nt-breathe 2.4s ease-in-out infinite; }
@keyframes nt-drift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
@keyframes nt-breathe { 0%, 100% { opacity: 0.22; } 50% { opacity: 0.45; } }
@media (prefers-reduced-motion: reduce) { .nt-chat-thinking::before, .nt-chat-thinking::after { animation: none; } }
.nt-chat-send { align-self: auto; padding-left: 1.4rem; padding-right: 1.4rem; }

/* Assistant bubbles: room to read. Short paragraphs, spaced bullets, links that say what they open. */
.nt-chat-bubble { font-size: 0.95rem; line-height: 1.6; padding: 0.8rem 1rem; max-width: 82%; }
.nt-chat-bubble p { margin: 0 0 0.75rem; }
.nt-chat-bubble ul { margin: 0.25rem 0 0.85rem 1.2rem; }
.nt-chat-bubble li + li { margin-top: 0.4rem; }
.nt-chat-bubble strong { font-weight: 600; }
.nt-chat-bubble a { text-underline-offset: 3px; }

/* A quiet focus on the question box: no halo, a faint accent edge. */
.nt-chat .nt-chat-box .nt-chat-textarea:focus, .nt-chat .nt-chat-box .nt-chat-textarea:focus-visible {
  outline: none !important; box-shadow: none !important; border-width: 1px; border-color: color-mix(in srgb, var(--accent) 40%, transparent) !important;
}

/* ===== Plan limit modal: the paywall before the form ===== */
.nt-plan-options { display: grid; gap: 0.5rem; }
.nt-plan-option { display: flex; align-items: center; gap: 0.75rem; width: 100%; text-align: left; padding: 0.65rem 0.9rem; border: 1px solid color-mix(in srgb, var(--ink) 14%, transparent); border-radius: 10px; background: var(--surface); color: var(--ink); }
.nt-plan-option:hover { border-color: var(--accent); color: var(--ink); }

/* Uploads queue: the binder chooser gets the room it needs, once there is room. */
@media (min-width: 768px) { .nt-queue-col { min-width: 280px; } }

/* ===== Assistant composer: one bordered box, tools along its foot ===== */
.nt-composer { border: 1px solid color-mix(in srgb, var(--ink) 16%, transparent); border-radius: 12px; background: var(--surface); }
.nt-composer:focus-within { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.nt-composer .nt-chat-textarea, .nt-chat .nt-chat-box .nt-composer .nt-chat-textarea:focus { border: 0 !important; box-shadow: none !important; background: var(--surface); position: relative; z-index: 1; border-radius: 12px 12px 0 0; min-height: 76px; padding: 0.8rem 0.9rem 0.4rem; }
.nt-composer-bar { display: flex; align-items: center; justify-content: space-between; padding: 0.35rem 0.5rem 0.5rem 0.5rem; background: var(--surface); position: relative; z-index: 1; border-radius: 0 0 12px 12px; }
.nt-composer-attach { border: 0; background: transparent; color: color-mix(in srgb, var(--ink) 55%, transparent); width: 34px; height: 34px; border-radius: 8px; font-size: 1.15rem; display: inline-flex; align-items: center; justify-content: center; }
.nt-composer-attach:hover { color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.nt-chat-send { padding-left: 1.1rem; padding-right: 1.1rem; }
.nt-chat-thinking.nt-composer { border-color: color-mix(in srgb, var(--accent) 18%, transparent); }

/* Empty chat: the welcome fills the thread until the first message. */
.nt-chat-empty { margin: auto; text-align: center; max-width: 440px; padding: 1rem; }
.nt-chat-empty .nt-tile-ico-lg { width: 56px; height: 56px; font-size: 1.5rem; border-radius: 14px; }
.nt-chat-thread:has(.nt-chat-empty) { justify-content: center; }

/* Thinking bubble: a shimmering line and three dots until the answer lands. */
.nt-chat-pending .nt-chat-bubble { display: inline-flex; align-items: center; gap: 0.6rem; }
.nt-chat-thinking-label { font-size: 0.9rem; background: linear-gradient(90deg, color-mix(in srgb, var(--ink) 55%, transparent) 0%, var(--accent) 45%, #7C5CFF 55%, color-mix(in srgb, var(--ink) 55%, transparent) 100%); background-size: 220% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; animation: nt-shimmer 2.2s linear infinite; }
@keyframes nt-shimmer { from { background-position: 120% 0; } to { background-position: -120% 0; } }
.nt-chat-placeholder.nt-chat-user .nt-chat-bubble { opacity: 0.85; }
@media (prefers-reduced-motion: reduce) { .nt-chat-thinking-label { animation: none; color: var(--accent); background: none; } }

/* Figure tiles: the number sizes itself to the tile, so it never runs past the edge. */
.nt-figure-card .card-body { container-type: inline-size; }
.nt-figure-card .nt-figure { font-size: clamp(0.95rem, 7.5cqw, 1.3rem); }

/* ===== Dashboard: the month's stages as one quiet row of figures ===== */
.nt-stage-row { display: flex; flex-wrap: wrap; max-width: 520px; }
.nt-stage { padding: 0 1.25rem 0 0; margin-right: 1.25rem; border-right: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); }
.nt-stage:last-child { border-right: 0; margin-right: 0; padding-right: 0; }
.nt-stage-n { font-size: 1.3rem; font-weight: 650; letter-spacing: -0.02em; line-height: 1.1; display: flex; align-items: baseline; gap: 0.3rem; }
.nt-stage-of { font-size: 0.75rem; font-weight: 500; color: color-mix(in srgb, var(--ink) 50%, transparent); letter-spacing: 0; }
.nt-stage-label { font-size: 0.8rem; color: color-mix(in srgb, var(--ink) 62%, transparent); margin-top: 0.1rem; white-space: nowrap; }
.nt-stage-zero .nt-stage-n { color: color-mix(in srgb, var(--ink) 45%, transparent); }
@media (max-width: 575.98px) { .nt-stage { padding-right: 0.9rem; margin-right: 0.9rem; } .nt-stage-n { font-size: 1.15rem; } }

/* ===== Missing required fields, by row ===== */
.nt-missing-row { padding: 0.75rem 0; border-top: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); }
.nt-missing-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.15rem; }
.nt-missing-fields { display: grid; gap: 0.4rem; margin-top: 0.4rem; }
.nt-missing-field { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.nt-missing-label { flex: 0 0 150px; font-size: 0.85rem; color: color-mix(in srgb, var(--ink) 70%, transparent); }
.nt-missing-field form { display: flex; }
@media (max-width: 575.98px) { .nt-missing-label { flex-basis: 100%; } }
