@font-face {
  font-family: 'Geist';
  src: url("Geist-VariableFont_wght.74d893c71d5d.ttf") format('truetype');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* Triple Point — Private Credit origination theme.
   Maps the brand palette (docs/colour_palette.md) onto the Bootstrap 5.3
   components the app uses. Loaded after the Bootstrap CDN stylesheet, so these
   rules win. Utility classes (.bg-*, .btn-*) are set with !important because the
   Bootstrap utilities they override are themselves !important. */

:root {
  /* ── Brand palette — canonical tokens, verbatim from docs/colour_palette.md.
     Everything else in this file references these (or the semantic aliases
     below), so the palette has one source of truth. ──────────────────────── */
  --night-100: #005C80;
  --night-200: #004966;
  --night-300: #00374D;
  --night-400: #002432;
  --night-500: #001A24;

  --turquoise-100: #45C2D8;
  --turquoise-200: #45C2D8;
  --turquoise-300: #208698;
  --turquoise-400: #17616E;

  --grey-blue-100: #D2DDE0;
  --grey-blue-200: #B4C6CB;
  --grey-blue-300: #96AFB6;
  --grey-blue-400: #7697A0;

  --aqua-100: #E9F8F8;
  --aqua-200: #BDEDEA;
  --aqua-300: #93E3DC;
  --aqua-400: #68D8CD;
  --aqua-500: #29C7B8;
  --aqua-600: #209C91;
  --aqua-700: #18726A;
  --aqua-800: #0F4842;
  --aqua-900: #061E1B;

  --orange-100: #FFF0E1;
  --orange-200: #FED6AE;
  --orange-300: #FEBC7C;
  --orange-400: #FDA349;
  --orange-500: #FD8916;
  --orange-600: #DE7002;
  --orange-700: #AC5601;
  --orange-800: #793D01;
  --orange-900: #472401;

  --pure-100: #FFFDFA;
  --pure-200: #FFF8F0;
  --pure-300: #FFF4E5;
  --pure-400: #FFF0DB;
  --pure-500: #FFEBD0;

  --dust-100: #FCFCFC;
  --dust-200: #F7F7F7;
  --dust-300: #F0F0F0;

  /* ── Semantic aliases — the names used across this file, each pointing at a
     palette token (so existing rules are unchanged but now palette-sourced). */
  --tp-dark-teal: var(--night-400);
  --tp-mid-teal: var(--turquoise-400);
  --tp-light-teal: var(--aqua-500);
  --tp-orange: var(--orange-500);
  --tp-light-orange: var(--pure-400);
  --tp-blue-grey: var(--grey-blue-400);

  /* Runtime-honoured Bootstrap variables (links, focus rings, incidental uses). */
  --bs-primary: var(--tp-mid-teal);
  --bs-primary-rgb: 23, 97, 110;
  --bs-link-color: var(--tp-mid-teal);
  --bs-link-color-rgb: 23, 97, 110;
  --bs-link-hover-color: var(--tp-dark-teal);
  --bs-link-hover-color-rgb: 0, 36, 50;
  --bs-focus-ring-color: rgba(23, 97, 110, 0.25);
}

body {
  background-color: #f3f6f7;  /* a faint teal-grey wash, in place of plain bg-light */
}

/* ── Brand header bar (templates/base.html) ────────────────────────────────── */
.tp-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  background-color: var(--tp-dark-teal);
  padding: 0.5rem 1.5rem;
  min-height: 64px;
}
.tp-header__brand { display: flex; align-items: center; gap: 0.75rem; }
.tp-header__logo { display: inline-flex; align-items: center; }
.tp-header__logo img { height: 40px; width: auto; display: block; }
.tp-header__right { display: flex; align-items: center; gap: 0.75rem; }
.tp-header__app-name {
  font-family: 'Geist', sans-serif;
  color: var(--tp-light-teal);
  font-size: 1.9rem;
  font-weight: 400;
  letter-spacing: 0.03em;
}
.tp-header__user {
  color: var(--tp-orange);
  font-weight: 600;
  white-space: nowrap;
}
/* Release/build tag (placename, e.g. "Vienna-1.1") — orange, just after the app name.
   align-self overrides the brand bar's center alignment so the small tag sits at the
   bottom; padding-bottom nudges it up to line up with the app name's baseline rather
   than its descender. */
.tp-header__build {
  color: var(--tp-orange);
  font-weight: 600;
  font-size: 0.95rem;
  white-space: nowrap;
  align-self: flex-end;
  padding-bottom: 0.3rem;
}
/* Environment flag — bold "TEST" box shown on the test endpoint only (absent in
   prod). A high-contrast box so it's unmistakable which endpoint is in use. */
.tp-header__env {
  align-self: center;
  background: #d32f2f;
  color: #fff;
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  line-height: 1;
  padding: 0.25rem 0.5rem;
  border-radius: 0.25rem;
  text-transform: uppercase;
}
/* Scoped under .tp-header so it beats Bootstrap's link colour in every state. */
.tp-header .tp-header__bell,
.tp-header .tp-header__bell:link,
.tp-header .tp-header__bell:visited,
.tp-header .tp-header__bell:hover,
.tp-header .tp-header__bell:focus {
  color: #fff;
  font-size: 1.1rem;
  line-height: 1;
  text-decoration: none;
}
.tp-header .tp-header__bell .bi { color: #fff; }

/* ── App shell: left sidebar + main content (templates/base.html) ──────────── */
.tp-shell { display: flex; align-items: stretch; min-height: calc(100vh - 64px); }
.tp-sidebar {
  flex: 0 0 220px;
  background: #fff;
  border-right: 1px solid #dde6e8;
  padding: 1rem 0.5rem;
}
.tp-main { flex: 1 1 auto; min-width: 0; }
.tp-sidebar__group { margin-bottom: 1.25rem; }
.tp-sidebar__title {
  font-weight: 700;
  color: var(--tp-dark-teal);
  padding: 0.25rem 0.75rem;
  margin-bottom: 0.25rem;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.tp-sidebar .nav-link {
  color: var(--tp-dark-teal);
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.25rem;
  /* Flex + gap owns the icon↔label spacing, so collapsing to the icon rail leaves no
     stray margin behind (and every entry spaces identically, which the per-link
     `me-1` classes did not). */
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.tp-sidebar .nav-link:hover:not(.disabled) { background: var(--tp-light-orange); }
.tp-sidebar .nav-link.active { background: var(--tp-mid-teal); color: #fff; }
.tp-sidebar .nav-link.disabled { color: var(--tp-blue-grey); }
/* Icons keep one column whatever the label length, so the rail's icons line up with
   the expanded nav's — nothing shifts sideways as the pane opens and closes. */
.tp-sidebar .nav-link .bi { flex: 0 0 1rem; text-align: center; }

/* ── Collapsible nav ───────────────────────────────────────────────────────────
   Collapsed is an ICON RAIL, not a hidden pane: every workflow stays one click away
   (with its name as a native tooltip), which a hidden pane would not.

   The state lives as a class on <html>, set from localStorage by an inline script in
   the <head> — before first paint, so a user who collapsed the nav doesn't see it
   flash open on every page load. The width transition is suppressed until the body
   carries .tp-nav-ready for the same reason: no animation on load, only on click. */
.tp-sidebar__toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-bottom: 0.75rem;
  padding: 0.35rem;
  border: 1px solid #dde6e8;
  border-radius: 6px;
  background: #fff;
  color: var(--tp-dark-teal);
  line-height: 1;
}
.tp-sidebar__toggle:hover { background: var(--tp-light-orange); }
.tp-sidebar__toggle .bi { transition: transform 0.2s ease; }
.tp-nav-ready .tp-sidebar { transition: flex-basis 0.2s ease; }

.tp-nav-collapsed .tp-sidebar { flex-basis: 3.5rem; }
/* The labels and group headings go; the icons and the toggle stay. `display: none`
   rather than a width transition on the text — a squeezed label reflows to two lines
   mid-animation, which reads as a glitch. */
.tp-nav-collapsed .tp-sidebar__label,
.tp-nav-collapsed .tp-sidebar__title { display: none; }
.tp-nav-collapsed .tp-sidebar .nav-link { justify-content: center; padding: 0.5rem 0; }
/* Point the chevrons the way they now act: outward = expand. */
.tp-nav-collapsed .tp-sidebar__toggle .bi { transform: rotate(180deg); }

/* Page title in brand dark teal. */
h1 { color: var(--tp-dark-teal); }

/* ── Links ───────────────────────────────────────────────────────────────── */
a { color: var(--tp-mid-teal); }
a:hover { color: var(--tp-dark-teal); }

/* ── Primary buttons ─────────────────────────────────────────────────────── */
.btn-primary {
  --bs-btn-bg: var(--tp-mid-teal);
  --bs-btn-border-color: var(--tp-mid-teal);
  --bs-btn-hover-bg: var(--tp-dark-teal);
  --bs-btn-hover-border-color: var(--tp-dark-teal);
  --bs-btn-active-bg: var(--tp-dark-teal);
  --bs-btn-active-border-color: var(--tp-dark-teal);
  --bs-btn-disabled-bg: var(--tp-mid-teal);
  --bs-btn-disabled-border-color: var(--tp-mid-teal);
}
.btn-outline-primary {
  --bs-btn-color: var(--tp-mid-teal);
  --bs-btn-border-color: var(--tp-mid-teal);
  --bs-btn-hover-bg: var(--tp-mid-teal);
  --bs-btn-hover-border-color: var(--tp-mid-teal);
  --bs-btn-active-bg: var(--tp-mid-teal);
  --bs-btn-active-border-color: var(--tp-mid-teal);
}
.btn-outline-secondary {
  --bs-btn-color: var(--tp-blue-grey);
  --bs-btn-border-color: var(--tp-blue-grey);
  --bs-btn-hover-bg: var(--tp-blue-grey);
  --bs-btn-hover-border-color: var(--tp-blue-grey);
  --bs-btn-active-bg: var(--tp-blue-grey);
  --bs-btn-active-border-color: var(--tp-blue-grey);
}
.btn-link { --bs-btn-color: var(--tp-mid-teal); --bs-btn-hover-color: var(--tp-dark-teal); }

/* Decision buttons (Stage 2): Approve = light teal, Return = orange.
   Reject keeps Bootstrap's red — the palette has no red, and a terminal reject
   reads best in a distinct alarm colour. */
.btn-success {
  /* Approve — base Aqua/500, hover/active step down the aqua ramp (600 → 700). */
  --bs-btn-bg: var(--aqua-500);
  --bs-btn-border-color: var(--aqua-500);
  --bs-btn-color: var(--tp-dark-teal);
  --bs-btn-hover-bg: var(--aqua-600);
  --bs-btn-hover-border-color: var(--aqua-600);
  --bs-btn-hover-color: var(--tp-dark-teal);
  --bs-btn-active-bg: var(--aqua-700);
  --bs-btn-active-border-color: var(--aqua-700);
  --bs-btn-active-color: #fff;
}
.btn-warning {
  /* Return — base Orange/500, hover/active step down the orange ramp (600 → 700). */
  --bs-btn-bg: var(--orange-500);
  --bs-btn-border-color: var(--orange-500);
  --bs-btn-color: #fff;
  --bs-btn-hover-bg: var(--orange-600);
  --bs-btn-hover-border-color: var(--orange-600);
  --bs-btn-hover-color: #fff;
  --bs-btn-active-bg: var(--orange-700);
  --bs-btn-active-border-color: var(--orange-700);
  --bs-btn-active-color: #fff;
}

/* ── Status badges (DrawdownRequest.status_badge) ───────────────────────────
   One unique colour per workflow status, from docs/colour_palette.md. The
   progression warms through the turquoise/aqua range to orange at the final
   stage; rejected is red (a terminal/error state, outside the brand ramp). */
.badge.tp-badge-draft    { background-color: var(--grey-blue-400) !important; color: #fff; }
.badge.tp-badge-manager  { background-color: var(--turquoise-100) !important; color: var(--tp-dark-teal); }
.badge.tp-badge-legal    { background-color: var(--aqua-500) !important; color: var(--tp-dark-teal); }
.badge.tp-badge-date     { background-color: var(--aqua-600) !important; color: #fff; }
.badge.tp-badge-ops      { background-color: var(--turquoise-400) !important; color: #fff; }
.badge.tp-badge-aspire   { background-color: var(--orange-400) !important; color: var(--tp-dark-teal); }
.badge.tp-badge-opsmgr   { background-color: var(--orange-600) !important; color: #fff; }
.badge.tp-badge-bankline { background-color: var(--orange-800) !important; color: #fff; }
.badge.tp-badge-payment  { background-color: var(--night-100) !important; color: #fff; } /* Stage 9 leaves the ops orange ramp — the money stage reads as its own thing */
.badge.tp-badge-complete { background-color: var(--aqua-800) !important; color: #fff; } /* terminal/done — the settled end of the aqua ramp */
.badge.tp-badge-rejected { background-color: #C5283D !important; color: #fff; } /* terminal/error red — outside the brand ramp */

/* ── Provenance badge: a supporting file carried forward from an earlier
   drawdown (drwdn.evidence), NOT a workflow status. Deliberately outlined rather
   than filled: it sits inline beside a filename in a dense table, where a solid
   status-weight chip would read as the row's own state. Light orange draws the
   eye (a reviewer must not mistake carried-over evidence for evidence gathered
   here) without claiming a stage colour. */
.badge.tp-badge-carried {
  background-color: var(--tp-light-orange) !important;
  color: var(--tp-dark-teal);
  border: 1px solid var(--orange-400);
  font-weight: 600;
  font-size: 0.7rem;
  vertical-align: baseline;
}

/* ── Read-only checklist tables (drwdn/_checklist_readonly.html) ───────────────
   Every stage's checklist has the same five columns, and several stack on one
   detail page. Auto layout sizes each table to its own content, so identical
   columns land in different places table to table. A fixed layout takes the
   widths from the <colgroup> alone, so they line up. The Check column takes the
   remainder. min-width lets .table-responsive scroll on a phone rather than
   crush the Check text into a sliver. */
.tp-checklist-table { table-layout: fixed; min-width: 48rem; }
.tp-checklist-table .tp-col-num    { width: 2.5rem; }
.tp-checklist-table .tp-col-result { width: 5.5rem; }
.tp-checklist-table .tp-col-notes  { width: 28%; }
.tp-checklist-table .tp-col-files  { width: 24%; }

/* ── Dashboard summary tiles ──────────────────────────────────────────────────
   A flat strip of one-number boxes across the top of a list page, in labelled
   groups (in_life/_summary_cards.html). Deliberately NOT Bootstrap cards: these
   sit above a dense table and are read at a glance, so a border is enough —
   stacked shadowed cards would compete with the real cards below them.

   The groups sit side by side while there is room and wrap as whole groups, so a
   narrow window never splits "Last 30 days" across two lines with "Current"
   stranded between them. Each tile grows to share its group's width, so the boxes
   in a group are one size whatever their labels say. */
.tp-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  margin-bottom: 1rem;
}
.tp-stats__group { flex: 1 1 22rem; min-width: 0; }
.tp-stats__title {
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--tp-dark-teal);
  margin-bottom: .375rem;
}
/* The basis of the figures ("by submission date"), carried on the group heading
   rather than under a tile: it qualifies all four of them. */
.tp-stats__basis {
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--tp-blue-grey);
  margin-left: .5rem;
}
.tp-stats__row { display: flex; flex-wrap: wrap; gap: .5rem; }
.tp-stat {
  flex: 1 1 0;
  min-width: 7rem;
  padding: .5rem .75rem;
  background: #fff;
  border: 1px solid var(--grey-blue-100);
  border-radius: .375rem;
}
.tp-stat--alert { border-color: var(--orange-300); }
.tp-stat__value {
  display: block;
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.15;
  color: var(--tp-dark-teal);
}
.tp-stat__value--ok { color: var(--tp-mid-teal); }
/* The late tile reuses .tp-overdue, so "past the SLA" has one colour wherever it
   appears. Restated at two-class specificity rather than relying on .tp-overdue
   being declared later in this file, which a reordering would silently undo. */
.tp-stat__value.tp-overdue { color: var(--orange-600); }
.tp-stat__label {
  display: block;
  font-size: .75rem;
  line-height: 1.2;
  color: var(--tp-blue-grey);
}

/* ── Past the SLA ─────────────────────────────────────────────────────────────
   The In-Life dashboard's "Outstanding for" cell, and the late-work summary card,
   when a request has been with Operations longer than its 48 hours.

   ⛔ Orange is spent ONLY on work that is both breached AND still outstanding — a
   completed request that ran over renders in muted grey. A warning colour on rows
   nobody can act on is how a warning colour stops being read.

   orange-600 rather than the brighter orange-500: this is body text in a dense
   table, where the mid-ramp orange on white is too light to read comfortably. Not
   Bootstrap's .text-warning, which on this palette is a yellow that reads as a
   note rather than as a breach. */
.tp-overdue { color: var(--orange-600); font-weight: 600; }

/* ── Nav tabs ────────────────────────────────────────────────────────────── */
.nav-tabs { --bs-nav-tabs-link-active-color: var(--tp-dark-teal); }
.nav-tabs .nav-link { color: var(--tp-mid-teal); }
.nav-tabs .nav-link:hover:not(.disabled) { color: var(--tp-dark-teal); }
.nav-tabs .nav-link.active {
  color: var(--tp-dark-teal);
  border-top: 2px solid var(--tp-light-teal);
}

/* ── Table headers ───────────────────────────────────────────────────────── */
.table-light, .table > thead.table-light > tr > th {
  --bs-table-bg: #e4eef0;
  color: var(--tp-dark-teal);
}

/* Unread notification rows — a faint brand-teal wash (pairs with the teal
   "New" badge), in place of Bootstrap's neutral-grey .table-active. */
.tp-unread > td { background-color: rgba(41, 199, 184, 0.12); }

/* ── Cards ───────────────────────────────────────────────────────────────── */
.card { border-color: #dde6e8; }
.border-info { border-color: var(--tp-light-teal) !important; }

/* ── Alerts (tinted to the palette; danger stays red) ──────────────────────── */
.alert-primary, .alert-info {
  --bs-alert-bg: #e4f5f3;
  --bs-alert-border-color: var(--tp-light-teal);
  --bs-alert-color: var(--tp-dark-teal);
}
.alert-success {
  --bs-alert-bg: #e1f4f1;
  --bs-alert-border-color: var(--tp-mid-teal);
  --bs-alert-color: var(--tp-dark-teal);
}
.alert-warning {
  --bs-alert-bg: var(--tp-light-orange);
  --bs-alert-border-color: var(--tp-orange);
  --bs-alert-color: var(--orange-800);
}

/* ── Flash messages (the `messages` block in templates/base.html) ──────────────
   A notification is sized by its text, not by the page. Bootstrap's `.alert` is a
   block, so "Successfully signed in as Charles Fox." used to stretch the full width
   of the container — which reads as a banner rather than a notice, and looks worst on
   the sign-in pages, where a full-bleed bar sits over the splash image above a 420px
   card.

   `width: fit-content` with a lower bound, so a two-word message ("Saved.") still
   gets a box big enough to read as one, and a long validation summary still wraps
   inside the container instead of overflowing it. The column + `gap` is what keeps
   several messages stacked once the alerts stop being full-width block siblings.

   It floats over the page rather than sitting in flow: an in-flow alert pushed the
   whole page down when it arrived and pulled it back up when dismissed, so what the
   user was about to click moved under the pointer. Absolute within `.tp-main`, so it
   takes no layout space; the container ignores clicks and only the alerts take them,
   so the page underneath stays usable around a notice. */
.tp-main { position: relative; }
.tp-messages {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1030;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  align-items: center;      /* centred at the top of the page, not off to the right */
  gap: 0.5rem;
}
.tp-messages .alert {
  pointer-events: auto;
  width: fit-content;
  min-width: min(20rem, 100%);
  max-width: 100%;
  margin-bottom: 0;
  box-shadow: 0 0.25rem 0.75rem rgba(0, 36, 50, 0.15);
}
/* On the sign-in pages the alert stays in flow, centred on the card below it: the
   pair is centred as a group (see `.tp-login .tp-main`), and there is nothing
   underneath for an arriving notice to shift. */
.tp-login .tp-messages {
  position: static;
  pointer-events: auto;
  align-items: stretch;
}
.tp-login .tp-messages .alert {
  margin-inline: auto;
  box-shadow: none;
}

/* ── Stage intro copy ────────────────────────────────────────────────────────
   The standing paragraph under a stage heading that says what the stage is for and
   who may act — read once by someone meeting the stage for the first time, then
   skipped. It is muted rather than boxed (an alert would compete with the stage's
   own controls), but Bootstrap's .small (87.5%) drops it to the size of the table
   fine print underneath, where it stops reading as prose. This sits between the two.
   Use in place of .small on those paragraphs, not alongside it. */
.stage-intro { font-size: .9375rem; }

/* ── Key choice callout (Stage A "Loan or Lease?") ──────────────────────────
   The pivotal decision that shapes the rest of the form — given an emphasised
   tinted box (left accent border) so it stands out without oversized text. */
.tp-keychoice {
  background: var(--aqua-100);
  border: 1px solid var(--turquoise-400);
  border-left: 5px solid var(--turquoise-400);
  border-radius: 8px;
  padding: 1rem 1.25rem;
}
.tp-keychoice__q {
  font-size: 1rem;
  font-weight: 600;
  color: var(--tp-dark-teal);
  margin-bottom: 0.55rem;
}
.tp-keychoice__opts { display: flex; gap: 1.5rem; }
.tp-keychoice__opts .form-check { margin: 0; padding-left: 1.75em; }
.tp-keychoice__opts .form-check-input {
  width: 1.15em; height: 1.15em; margin-top: 0.15em; margin-left: -1.75em;
}
.tp-keychoice__opts .form-check-label {
  font-size: 1rem; font-weight: 500; color: var(--tp-dark-teal); cursor: pointer;
}

/* ── Form focus ring in brand teal ─────────────────────────────────────────── */
.form-control:focus, .form-select:focus {
  border-color: var(--tp-light-teal);
  box-shadow: 0 0 0 0.25rem var(--bs-focus-ring-color);
}

/* Mandatory-field markers — a red asterisk on required form labels and table
   column headers. Shared by the origination form and the Stage 2 / Stage 4
   review checklists so every stage flags required fields the same way. */
label.required::after, th.required::after { content: "\00a0*"; color: #dc3545; }

/* Field validation messages ("This field is required", etc.) in red — shared by
   the origination form and the Stage 2 / Stage 4 review checklists. The asterisk
   marks a field as required; this text appears on a failed submit. No red row
   background — the asterisk + message is the whole treatment. */
.errorlist {
  color: #dc3545;
  list-style: none;
  padding-left: 0;
  margin: 0.25rem 0 0;
  font-size: 0.875rem;
}

/* Checked radios & checkboxes in brand orange (Bootstrap hard-codes its blue,
   so --bs-primary alone doesn't reach these). */
.form-check-input:checked {
  background-color: var(--tp-orange);
  border-color: var(--tp-orange);
}
.form-check-input:focus {
  border-color: var(--tp-orange);
  box-shadow: 0 0 0 0.25rem rgba(253, 137, 22, 0.25);
}

/* select2 single-select container: match Bootstrap's .form-select height so a
   select2 typeahead (Facility ID / Borrower) lines up with the plain Team /
   Stage dropdowns next to it. !important throughout because select2's own CSS
   has the same selector specificity and loads after theme.css (via form.media),
   so it would otherwise win — same reason the colour rules below use it.
   38px container − 0.75rem vertical padding − 2px border = 24px content, which
   matches the 1.5 line-height so the text is centred and never clips. */
.select2-container--default .select2-selection--single {
  height: calc(1.5em + 0.75rem + 2px) !important;  /* Bootstrap .form-select default */
  padding: 0.375rem 0.75rem;
  /* Same border as the native .form-select beside it (select2's own #aaa border
     loads after theme.css, so !important is needed to win). */
  border: 1px solid var(--bs-border-color) !important;
  border-radius: 0.375rem;
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
  line-height: 1.5 !important;
  padding: 0;
  color: #212529;
}
/* select2's placeholder defaults to light grey (#999); match the native select's
   default-option text colour so "Any facility…" reads like "All teams". */
.select2-container--default .select2-selection--single .select2-selection__placeholder {
  color: #212529 !important;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
  height: 100% !important;
  top: 0 !important;
  right: 0.5rem !important;
}

/* select2 dropdown (borrower/facility typeaheads): highlighted option in brand
   orange, the already-selected option in light orange. (Native <select> option
   highlighting is drawn by the OS and can't be themed via CSS.) */
.select2-container--default .select2-results__option--highlighted[aria-selected] {
  /* !important: select2's own rule has the same selector/specificity and loads
     after theme.css, so it would otherwise win with its default blue. */
  background-color: var(--tp-orange) !important;
  color: #fff !important;
}
.select2-container--default .select2-results__option--selected,
.select2-container--default .select2-results__option[aria-selected="true"] {
  background-color: var(--tp-light-orange);
  color: var(--tp-dark-teal);
}

/* Routing-role badge — [LOR] / [Facility Agent] beside a lender's name on the
   Participations grid and the payment chain (see components/role_tags.html). Reads
   as an annotation on the name, not a status: outlined in brand teal rather than
   filled, so it can't be mistaken for one of the status badges on the same pages. */
.badge.tp-role-tag {
  background-color: transparent;
  color: var(--tp-dark-teal);
  border: 1px solid var(--tp-mid-teal);
  font-weight: 600;
  font-size: .7rem;
  padding: .15em .4em;
  vertical-align: middle;
  white-space: nowrap;
}

/* ── The derived payment chain ─────────────────────────────────────────────────
   Project-level, not per-page, because the SAME chain is rendered in three places
   and they all have to read as one screen:
     • the Draft Submission form's Payment Details tab (editable: account + reference)
     • the detail page's Stage F block (read-only, with the account details)
     • the detail page's Stage 5 panel (read-only: what will reach RBS. Ops no longer
       types an internal reference — it is derived as `<contract id>.PX`)
   Each renders one <table> per leg type, headed by a tinted caption. Independent
   <table>s auto-size to their own content, so every shared column is pinned to a
   percentage — that is the only thing keeping the columns of the tables above and
   below each other in line. Add a column to one of the three and give it a
   pay-col-* width here, or the alignment goes. */
.payments-table { margin-bottom: 0; }
/* A caption (not a <tr>) so the leg heading can't be mistaken for a data row and
   doesn't have to span a column count that differs between the three renderings. */
.payments-table .pay-leg-caption {
  caption-side: top; color: var(--tp-dark-teal);
  font-size: .78rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  padding: .4rem .6rem; border-radius: .375rem .375rem 0 0;
}
/* Internal legs (money moving inside the lender group) take the teal/grey end of the
   palette; the two external ones — the payments that actually leave Triple Point —
   take the warmer end, so they stand out as the rows needing an account. */
.pay-leg-fund_payout        { background-color: var(--aqua-200); }
.pay-leg-fund_costs         { background-color: var(--aqua-100); }
.pay-leg-agent_payout       { background-color: var(--grey-blue-200); }
.pay-leg-agent_costs        { background-color: var(--grey-blue-100); }
.pay-leg-customer_payout    { background-color: var(--pure-500); }
.pay-leg-beneficiary_payout { background-color: var(--pure-400); }
.pay-leg-third_party_payout { background-color: var(--orange-200); }
/* Not a payment and not a transfer: payout attributed to no payee yet (a money row
   naming no contract, or a contract naming no customer). It is a draft-only fault the
   submit gate refuses, so it is deliberately NOT on either end of the palette above —
   a neutral grey says "this is not a leg like the others" rather than implying it is
   money going somewhere. Without a rule here it rendered with no caption background
   at all, which read as a styling bug rather than as the problem it is. */
.pay-leg-unattributed_payout { background-color: var(--grey-blue-100); }
/* The derived figures (Payer / Recipient / Value) are separated from what a user
   fills in (account, reference) by a whitespace gutter, which keeps the right-aligned
   Value off the account cell. Unlike the Participations one this is pure width — no
   transparent background, no cleared border — because the caption, header and totals
   rows are solid across the table. */
.payments-table .pay-gutter { width: 2.5rem; min-width: 2.5rem; padding: 0; }
.payments-table .pay-col-party { width: 16%; }
.payments-table .pay-col-value { width: 11%; }
.payments-table .pay-col-ref   { width: 18%; }
/* Read-only Stage F only: the chosen account, broken out into its own columns. */
.payments-table .pay-col-loc       { width: 8%; }
.payments-table .pay-col-acct-name { width: 12%; }
.payments-table .pay-col-acct-no   { width: 12%; }
.payments-table .pay-col-sort      { width: 7%; }
/* Stage 9 renders the same read-only rows with the account name / number / sort code and
   the per-leg reference dropped (see `compact` in _payment_row_readonly.html). The four
   columns it still shares with Stage F keep their pinned widths, so the two tables read
   as the same chain; Account Location, now the last column, takes the width those
   dropped columns used to hold rather than staying pinned at 8% and being squeezed
   against the right edge of a full-width table. */
.payments-table-compact .pay-col-loc { width: auto; }

/* ── Page width ────────────────────────────────────────────────────────────────
   The workflow pages (a form and the detail page that reviews it) are WIDE by
   nature — the payment chain is nine columns, the participations grid twelve — so
   they get the screen rather than Bootstrap's .container, whose responsive
   max-width (1140px on lg/xl) squeezed the detail page's tables while the form tab
   showing the same table ran full width.

   Not `container-fluid` either: a table row spanning a 4K monitor edge to edge is
   hard to track across, so there is a ceiling. 1760px is above the usable width of
   a 1920px screen once the nav is out (1920 − 220), so nothing changes at 1080p and
   below — it only stops the sprawl on the very large monitors. Centred, so the
   leftover space is symmetric.

   Single-column forms (Bank Callback, login) keep their own narrower caps: a column
   of one-line inputs stretched wide is worse to fill in, not better. */
.tp-page {
  width: 100%;
  max-width: 1760px;
  margin-inline: auto;
  padding: 1.5rem;
}

/* ── Sign-in pages (templates/account/login.html, login_local.html) ────────────
   `PC Portal_Image 3.jpg` behind the sign-in card, in place of the body's grey-teal
   wash.

   Painted on `.tp-main`, not on `body`: `.tp-main` is the flex child that fills the
   height beside the nav, so the image covers exactly the area the card floats in and
   stops cleanly at the header and the sidebar rather than running under them.

   The relative url() resolves against this stylesheet, which sits beside the image in
   static/ — same as the Geist font file at the top of this file. So it survives
   collectstatic without needing {% static %}.

   `cover` upscales a 600×350 source, which is only tolerable because the image is
   already a soft, low-contrast wash: it reads as atmosphere, not as a photograph with
   detail to lose. Dropping in a larger file needs no change here.

   The card is near-opaque white rather than a light tint, because the image's own
   contrast varies across it — pale sky top-right, dark trees down the left — so text
   laid straight onto it would be legible at some viewport sizes and not others. */
.tp-login .tp-main {
  background-image: url("PC Portal_Image 3.da5b1dc956d2.jpg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  /* Column, so a `messages` alert stacks above the card and the pair is centred as a
     group. Padding rather than bare centring: with `justify-content: center` a block
     taller than the viewport would otherwise have its top clipped past the scroll
     origin (the local-login form carrying an error alert is the tall case). */
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: 2rem;
}
.tp-login-card {
  width: 100%;
  max-width: 420px;
  margin-inline: auto;
  padding: 1.75rem;
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid #dde6e8;
  border-radius: 0.5rem;
  box-shadow: 0 0.5rem 1.5rem rgba(0, 36, 50, 0.18);
}

/* ── The 500 page ──────────────────────────────────────────────────────────────
   Same background image and the same card treatment as the sign-in pages, for the same
   reason: it is the other screen a user meets with no application chrome around it,
   and it should look like the same product rather than like the server's own output.

   Its own classes rather than reusing `.tp-login`'s, because the two differ in one
   structural way — templates/500.html is a STANDALONE document (it cannot extend
   base.html; see the comment there), so there is no `.tp-main` for `.tp-login .tp-main`
   to match. Sharing the rules would have meant the error page carrying a class named
   for a page it is not.

   Everything here is layout over the shared tokens; nothing is a new colour. */
.tp-error {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  margin: 0;
}
.tp-error__main {
  flex: 1 1 auto;
  background-image: url("PC Portal_Image 3.da5b1dc956d2.jpg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* Padding rather than bare centring, as on the sign-in pages: a card taller than the
     viewport would otherwise have its top clipped past the scroll origin. */
  padding: 2rem 1rem;
}
.tp-error-card {
  width: 100%;
  max-width: 480px;
  margin-inline: auto;
  padding: 1.75rem;
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid #dde6e8;
  border-radius: 0.5rem;
  box-shadow: 0 0.5rem 1.5rem rgba(0, 36, 50, 0.18);
}
