/* The browser's own `[hidden] { display: none }` loses to any author rule that
   sets a display — same specificity, author sheet wins — so `.btn { display:
   inline-flex }` silently shows every `<button class="btn" hidden>`. Stating it
   once here, with the weight to hold, means the attribute always means what it
   says. */
[hidden] { display: none !important; }

/* ============================================================================
   Lendmax Capital — one stylesheet, no build step, no framework.

   The shell is light: a white rail on a cool neutral ground, navy kept as an
   accent for the mark and for text rather than used as a wall. Every colour is
   a token defined three times — bare :root for light, a prefers-color-scheme
   block for the un-stamped default, and a [data-theme] block so the toggle
   wins in both directions. Nothing sets a colour outside the token set.

   Every foreground/background pair was measured for WCAG 2.1 AA.
   ========================================================================= */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

:root {
  color-scheme: light;

  /* Neutrals, biased slightly toward the accent so they read as chosen. */
  --ground:      #F5F7FA;
  --surface:     #FFFFFF;
  --surface-2:   #FAFBFD;
  --sunk:        #EFF2F7;
  --line:        #E4E8EF;
  --line-2:      #CFD6E2;
  --control:     #8892A6;   /* 3.1 on white — WCAG 1.4.11 */

  --ink:         #0E1626;
  --ink-2:       #4A5A72;   /* 6.4 on white */
  --ink-3:       #5F6D85;   /* 5.2 on white, 5.1 on --surface-2 */

  /* Brand. Navy is the mark and the deepest ink; blue is the action colour. */
  --navy:        #101B31;
  --accent:      #1657C8;   /* 6.3 on white */
  --accent-2:    #0F47A8;
  --accent-soft: #E8F0FD;
  --accent-ink:  #0E4394;
  --accent-line: #C4D8F8;
  --ring:        rgba(22, 87, 200, .22);
  --on-accent:   #FFFFFF;   /* text and icons that sit on --accent */

  /* Semantic. These mean something; they are never decoration. */
  --good:        #0B6B47;  --good-soft: #E3F4EC;  --good-ink: #08553A;  --good-line: #BEE3D0;
  --warn:        #7A5300;  --warn-soft: #FBF1DC;  --warn-ink: #6A4700;  --warn-line: #EEDCB4;
  --bad:         #C4180D;  --bad-soft:  #FCE8E6;  --bad-ink:  #A2170D;  --bad-line:  #F3CCC7;
  --violet:      #5B3FD1;  --violet-soft: #ECE8FB; --violet-ink: #43309C; --violet-line: #D6CDF6;
  --teal:        #00707C;  --teal-soft: #DFF2F4;  --teal-ink: #005A64;  --teal-line: #B8DFE3;

  --sans:    'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --display: 'Newsreader', Georgia, 'Times New Roman', serif;
  --mono:    'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --r-sm: 6px;
  --r:    10px;
  --r-lg: 14px;

  /* Shadow is for things that float, not for everything. */
  --lift:  0 1px 2px rgba(14, 22, 38, .05), 0 2px 8px rgba(14, 22, 38, .04);
  --float: 0 4px 12px rgba(14, 22, 38, .08), 0 16px 40px rgba(14, 22, 38, .12);

  --rail: 246px;
  --topbar: 56px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --ground:      #0B111C;
    --surface:     #121A28;
    --surface-2:   #172032;
    --sunk:        #1C2536;
    --line:        #253048;
    --line-2:      #35435F;
    --control:     #5B6E93;   /* 3.0 on --surface-2, 3.3 on --surface */

    --ink:         #E8EDF6;
    --ink-2:       #A9B7CD;   /* 7.4 on --surface */
    --ink-3:       #8494AE;   /* 5.1 on --surface */

    --navy:        #E8EDF6;
    --accent:      #74A9F7;   /* 6.8 on --surface */
    --accent-2:    #9BC2FA;
    --accent-soft: #16263F;
    --accent-ink:  #A8C9F9;
    --accent-line: #23395C;
    --ring:        rgba(116, 169, 247, .30);
    --on-accent:   #0B111C;

    --good:        #4FCB96;  --good-soft: #10281F;  --good-ink: #6DDCAC;  --good-line: #1D4536;
    --warn:        #E0B155;  --warn-soft: #2A2113;  --warn-ink: #EFC978;  --warn-line: #4A3A1B;
    --bad:         #F2837A;  --bad-soft:  #2E1614;  --bad-ink:  #FBA49C;  --bad-line:  #55231F;
    --violet:      #A38CF5;  --violet-soft: #1E1938; --violet-ink: #BCA9FA; --violet-line: #342A5C;
    --teal:        #48B7C4;  --teal-soft: #10262A;  --teal-ink: #6CD0DC;  --teal-line: #1C4249;

    --lift:  0 1px 2px rgba(0, 0, 0, .3), 0 2px 8px rgba(0, 0, 0, .24);
    --float: 0 4px 12px rgba(0, 0, 0, .4), 0 16px 40px rgba(0, 0, 0, .5);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --ground:      #0B111C;
  --surface:     #121A28;
  --surface-2:   #172032;
  --sunk:        #1C2536;
  --line:        #253048;
  --line-2:      #35435F;
  --control:     #5B6E93;

  --ink:         #E8EDF6;
  --ink-2:       #A9B7CD;
  --ink-3:       #8494AE;

  --navy:        #E8EDF6;
  --accent:      #74A9F7;
  --accent-2:    #9BC2FA;
  --accent-soft: #16263F;
  --accent-ink:  #A8C9F9;
  --accent-line: #23395C;
  --ring:        rgba(116, 169, 247, .30);
  --on-accent:   #0B111C;

  --good:        #4FCB96;  --good-soft: #10281F;  --good-ink: #6DDCAC;  --good-line: #1D4536;
  --warn:        #E0B155;  --warn-soft: #2A2113;  --warn-ink: #EFC978;  --warn-line: #4A3A1B;
  --bad:         #F2837A;  --bad-soft:  #2E1614;  --bad-ink:  #FBA49C;  --bad-line:  #55231F;
  --violet:      #A38CF5;  --violet-soft: #1E1938; --violet-ink: #BCA9FA; --violet-line: #342A5C;
  --teal:        #48B7C4;  --teal-soft: #10262A;  --teal-ink: #6CD0DC;  --teal-line: #1C4249;

  --lift:  0 1px 2px rgba(0, 0, 0, .3), 0 2px 8px rgba(0, 0, 0, .24);
  --float: 0 4px 12px rgba(0, 0, 0, .4), 0 16px 40px rgba(0, 0, 0, .5);
}

/* ------------------------------------------------------------------- base */

html { -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--ground);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1 {
  font-family: var(--display);
  font-size: 30px; font-weight: 600; letter-spacing: -.018em; line-height: 1.15;
  text-wrap: balance;
}
h2 { font-size: 14.5px; font-weight: 600; letter-spacing: -.005em; }
h3 { font-size: 13px; font-weight: 600; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-sm); }

svg { flex: none; }
.mono, code { font-family: var(--mono); font-size: .88em; letter-spacing: -.01em; }
.subtle { color: var(--ink-3); }
.num, table td.num, table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap; }

/* ----------------------------------------------------------------- layout */

body.has-side { display: grid; grid-template-columns: var(--rail) minmax(0, 1fr); min-height: 100vh; }
body.plain { min-height: 100vh; }
/* The collapse class sits on <html>, not <body>: it is applied by the
   pre-paint script, before <body> exists, so the rail never jumps. */
:root.rail-tight { --rail: 68px; }

/* ------------------------------------------------------------------- rail */

.rail {
  background: var(--surface);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
  min-width: 0;
}

.rail__brand {
  display: flex; align-items: center; gap: 10px;
  height: var(--topbar); flex: none;
  padding: 0 16px;
  border-bottom: 1px solid var(--line);
  color: var(--ink); font-weight: 600; font-size: 14.5px; letter-spacing: -.015em;
  text-decoration: none; white-space: nowrap; overflow: hidden;
}
.rail__brand:hover { text-decoration: none; }
.rail__brand img { width: 24px; height: 24px; flex: none; }
.rail__brand img.on-dark, .top__mark img.on-dark { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .rail__brand img.on-light { display: none; }
  :root:not([data-theme="light"]) .rail__brand img.on-dark { display: block; }
}
:root[data-theme="dark"] .rail__brand img.on-light { display: none; }
:root[data-theme="dark"] .rail__brand img.on-dark { display: block; }
:root[data-theme="light"] .rail__brand img.on-light { display: block; }
:root[data-theme="light"] .rail__brand img.on-dark, .top__mark img.on-dark { display: none; }
.rail__brand em { font-style: normal; color: var(--ink-3); font-weight: 400; }

.rail__scroll { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 12px 10px 8px; }
.rail__scroll::-webkit-scrollbar { width: 8px; }
.rail__scroll::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }

.rail__group + .rail__group { margin-top: 14px; }
.rail__group h3 { margin: 0; }

/* The group header is a control, so it is a button and it looks like one on
   hover. The chevron points down when the group is open and right when it is
   folded — the direction says which way the content went.

   Quiet, deliberately: the rail is furniture and the page is the work. The
   section being worked in is marked by the blue label rather than by a bar,
   which is the same information at a fraction of the ink. */
.rail__grouphead {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 3px 8px 5px; margin-bottom: 1px;
  border: 0; border-radius: var(--r-sm); background: none;
  font: inherit; font-size: 10.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .09em;
  color: var(--ink-3); cursor: pointer; text-align: left;
}
.rail__grouphead:hover { background: var(--sunk); color: var(--ink-2); }
.rail__grouphead:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.rail__grouphead svg {
  width: 13px; height: 13px; flex: none; color: var(--control);
  transform: rotate(90deg); transition: transform .16s ease;
}
.rail__group.is-shut .rail__grouphead svg { transform: rotate(0deg); }

/* In use: the section that is open, which — the rail being an accordion — is
   also the section holding the page you are on. */
.rail__group:not(.is-shut) > h3 > .rail__grouphead,
.rail__group[data-here] > h3 > .rail__grouphead { color: var(--accent); font-weight: 700; }
.rail__group:not(.is-shut) > h3 > .rail__grouphead svg,
.rail__group[data-here] > h3 > .rail__grouphead svg { color: var(--accent); }
.rail__groupname { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* What is waiting inside a folded group. Without it, folding Lending hides the
   one number that says a file needs attention — so the count comes up to the
   header and is only shown when the group is shut. */
.rail__groupn {
  flex: none; background: var(--accent); color: var(--on-accent);
  font-size: 9.5px; font-weight: 700; letter-spacing: 0;
  padding: 1px 5px; border-radius: 999px;
  font-variant-numeric: tabular-nums; display: none;
}
.rail__group.is-shut .rail__groupn { display: inline-block; }

.rail__group ul { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.rail__group.is-shut > ul { display: none; }

/* A drawer inside a group. Settings is fifteen rows and was read from the top
   every time; grouped by the question that brings somebody there, it is one
   loose row and five drawers. The header is a nav row that folds rather than
   navigates, so it reads as a sibling of the links under it — indented one
   step, because the indent is what says these belong to it. */
.rail__subhead {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 7px 8px; border: 0; border-radius: var(--r-sm); background: none;
  font: inherit; font-size: 13.2px; font-weight: 500; color: var(--ink-2);
  cursor: pointer; text-align: left;
}
.rail__subhead:hover { background: var(--sunk); color: var(--ink); }
.rail__subhead:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.rail__subhead svg {
  width: 14px; height: 14px; flex: none; color: var(--ink-3);
  transform: rotate(90deg); transition: transform .16s ease;
}
.rail__sub.is-shut .rail__subhead svg { transform: rotate(0deg); }
.rail__sub > ul { padding-left: 14px; margin-left: 8px; border-left: 1px solid var(--line); }
.rail__sub.is-shut > ul { display: none; }
.rail__sub .nav__n { margin-left: auto; }

.rail a.nav {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 8px; border-radius: var(--r-sm);
  color: var(--ink-2); font-size: 13.2px; font-weight: 500;
  text-decoration: none; white-space: nowrap; overflow: hidden;
  position: relative;
}
.rail a.nav svg { width: 16px; height: 16px; color: var(--ink-3); }
.rail a.nav:hover { background: var(--sunk); color: var(--ink); text-decoration: none; }
.rail a.nav:hover svg { color: var(--ink-2); }
.rail a.nav[aria-current="page"] {
  background: var(--accent-soft); color: var(--accent-ink); font-weight: 600;
}
.rail a.nav[aria-current="page"] svg { color: var(--accent); }

.nav__n {
  margin-left: auto; background: var(--sunk); color: var(--ink-2);
  font-size: 10.5px; font-weight: 600; padding: 1px 6px; border-radius: 999px;
  font-variant-numeric: tabular-nums; min-width: 20px; text-align: center;
}
.rail a.nav[aria-current="page"] .nav__n { background: var(--accent); color: var(--on-accent); }

.rail__foot { flex: none; border-top: 1px solid var(--line); padding: 8px 10px; }
/* Which release is actually running. Small, quiet, and always there —
   the first question when a deployment looks wrong. */
.rail__build {
  margin: 6px 2px 0; font-size: 11px; line-height: 1.3; color: var(--ink-3);
  font-variant-numeric: tabular-nums; letter-spacing: .01em;
}
.rail__build em { font-style: normal; opacity: .72; }

.iconbtn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-width: 32px; height: 32px; padding: 0 8px;
  border: 1px solid transparent; border-radius: var(--r-sm);
  background: none; color: var(--ink-2); font: inherit; font-size: 12.5px;
  cursor: pointer; text-decoration: none;
}
.iconbtn:hover { background: var(--sunk); color: var(--ink); text-decoration: none; }
.iconbtn svg { width: 16px; height: 16px; }

/* Collapsed rail: icons only, labels tucked away, tooltip on hover. */
.rail-tight .rail__brand { padding: 0; justify-content: center; }
.rail-tight .rail__brand span { display: none; }
.rail-tight .rail__group h3 { display: none; }
/* At 68 pixels there are no labels to fold away, so a folded group would hide
   its icons behind a header showing nothing. Every group is open here, and the
   click handler declines to fold — the stored choice is kept for when the rail
   is expanded again rather than being discarded. */
.rail-tight .rail__group.is-shut > ul { display: flex; }
/* Same reasoning one level down: no labels, so nothing to fold, and a folded
   drawer would hide its icons behind a header showing nothing. */
.rail-tight .rail__subhead { display: none; }
.rail-tight .rail__sub.is-shut > ul { display: flex; }
.rail-tight .rail__sub > ul { padding-left: 0; margin-left: 0; border-left: 0; }
.rail-tight .rail__group + .rail__group {
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line);
}
.rail-tight .rail a.nav { justify-content: center; padding: 8px 0; }
.rail-tight .rail a.nav span.nav__label, .rail-tight .nav__n { display: none; }
.rail-tight .rail a.nav::after {
  content: attr(data-label);
  position: absolute; left: calc(100% + 8px); top: 50%; transform: translateY(-50%);
  background: var(--ink); color: var(--surface);
  padding: 4px 9px; border-radius: var(--r-sm); font-size: 12px; font-weight: 500;
  white-space: nowrap; opacity: 0; pointer-events: none; z-index: 60;
  box-shadow: var(--float);
}
.rail-tight .rail a.nav:hover::after, .rail-tight .rail a.nav:focus-visible::after { opacity: 1; }
.rail-tight .rail__foot .iconbtn span { display: none; }
.rail-tight .rail__build em { display: none; }
.rail-tight .rail__build { font-size: 10px; }
.rail-tight .rail__foot { display: flex; flex-direction: column; gap: 4px; align-items: center; }

/* ----------------------------------------------------------------- topbar */

.main { display: flex; flex-direction: column; min-width: 0; }

.top {
  display: flex; align-items: center; gap: 12px;
  height: var(--topbar); flex: none; padding: 0 20px 0 24px;
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 30;
}
@supports not (backdrop-filter: blur(1px)) { .top { background: var(--surface); } }

.crumbs { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink-3); min-width: 0; }
.crumbs a { color: var(--ink-2); }
.crumbs a:hover { color: var(--accent); }
.crumbs span { color: var(--ink); font-weight: 500; }
.crumbs i { font-style: normal; color: var(--line-2); }

.top__spacer { flex: 1; }

/* The search button that opens the palette. */
.searchbtn {
  display: flex; align-items: center; gap: 8px;
  height: 32px; min-width: 210px; padding: 0 8px 0 10px;
  border: 1px solid var(--control); border-radius: var(--r-sm);
  background: var(--surface-2); color: var(--ink-3);
  font: inherit; font-size: 13px; cursor: pointer; text-align: left;
}
.searchbtn:hover { border-color: var(--ink-2); color: var(--ink-2); }
.searchbtn svg { width: 15px; height: 15px; }
.searchbtn kbd {
  margin-left: auto; font-family: var(--sans); font-size: 10.5px; font-weight: 600;
  color: var(--ink-3); background: var(--sunk); border: 1px solid var(--line);
  border-radius: 4px; padding: 1px 5px; line-height: 1.5;
}

.top__who { display: flex; align-items: center; gap: 8px; }
.top__role { font-size: 12.5px; color: var(--ink-3); text-transform: capitalize; }
.avatar {
  width: 28px; height: 28px; border-radius: 50%; flex: none;
  background: var(--accent); color: var(--on-accent);
  display: grid; place-items: center; font-size: 10.5px; font-weight: 700; letter-spacing: .02em;
}

.linkbtn { background: none; border: 0; padding: 0; font: inherit; color: var(--accent); cursor: pointer; }
.linkbtn:hover { text-decoration: underline; }

.railtoggle, .drawertoggle, .top__mark { display: none; }
.top__mark { align-items: center; }
.top__mark img { width: 22px; height: 22px; }
.railtoggle { display: inline-flex; }

/* ------------------------------------------------------------------- page */

.page { padding: 28px 24px 72px; max-width: 1200px; width: 100%; }
.page--wide { max-width: 1560px; }

.page__head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 20px;
  margin-bottom: 22px; flex-wrap: wrap;
}
.page__headmain { min-width: 0; }
.page__act { display: flex; gap: 8px; flex-wrap: wrap; }
.eyebrow {
  font-size: 11px; text-transform: uppercase; letter-spacing: .09em;
  color: var(--ink-3); font-weight: 600; margin-bottom: 6px;
}
.lede { color: var(--ink-2); font-size: 14.5px; margin-top: 8px; max-width: 68ch; text-wrap: pretty; }

/* ------------------------------------------------------------------ cards */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  margin-bottom: 18px;
  overflow: hidden;
}
.card__head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 18px 12px;
}
.card__head + .card__body { padding-top: 0; }
.card__act { display: flex; gap: 6px; align-items: center; }
.card__body { padding: 4px 18px 18px; }
.card__body > :last-child { margin-bottom: 0; }
.card__foot {
  padding: 11px 18px; border-top: 1px solid var(--line); background: var(--surface-2);
  font-size: 12.5px; color: var(--ink-3);
}
/* A table fills its card edge to edge — the card border is the table's frame. */
.card__body > .tablewrap:only-child { margin: 0 -18px -18px; }
.card__head + .card__body > .tablewrap:only-child { margin-top: 0; }

.split { display: grid; grid-template-columns: minmax(0, 1.85fr) minmax(0, 1fr); gap: 18px; align-items: start; }
@media (max-width: 1040px) { .split { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------------ tiles */
/* One bordered strip rather than six floating boxes. Colour appears only
   where the number has a state worth naming. */

/* The figures are what the eye scans across, so they have to sit on one line
   even when one label wraps to two and another tile has no note. Subgrid does
   that properly: the strip owns the three rows and each tile borrows them, so
   label, figure and note align across the whole row. */
.tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
  grid-auto-rows: auto auto auto;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  overflow: hidden; margin-bottom: 18px;
}
.tile {
  padding: 14px 18px 15px;
  display: grid; grid-row: span 3; grid-template-rows: subgrid; row-gap: 3px;
  align-content: start;
  border-right: 1px solid var(--line);
  text-decoration: none; color: inherit; min-width: 0;
}
@supports not (grid-template-rows: subgrid) {
  .tile { display: flex; flex-direction: column; gap: 3px; }
  .tile__value { margin-top: auto; }
}
.tile:last-child { border-right: 0; }
a.tile:hover { background: var(--surface-2); text-decoration: none; }
.tile__label {
  font-size: 11px; color: var(--ink-3); font-weight: 600;
  text-transform: uppercase; letter-spacing: .05em; line-height: 1.35;
  display: flex; align-items: baseline; gap: 6px;
}
.tile__value {
  font-size: 24px; font-weight: 600; letter-spacing: -.025em; line-height: 1.15;
  font-variant-numeric: tabular-nums; padding-top: 4px;
}
.tile__value--sm { font-size: 16px; letter-spacing: -.01em; }
.tile__note { font-size: 11.5px; color: var(--ink-3); min-height: 1.35em; }
.tile__dot { width: 6px; height: 6px; position: relative; top: -1px; border-radius: 50%; background: var(--line-2); flex: none; }
.tile.good .tile__dot { background: var(--good); }
.tile.warn .tile__dot { background: var(--warn); }
.tile.bad  .tile__dot { background: var(--bad); }
.tile.blue .tile__dot { background: var(--accent); }
.tile.violet .tile__dot { background: var(--violet); }
.tile.teal .tile__dot { background: var(--teal); }
.tile.bad  .tile__value { color: var(--bad); }
.tile.good .tile__value { color: var(--good); }

/* ----------------------------------------------------------------- tables */

.tablewrap { overflow-x: auto; }
table.data { width: 100%; border-collapse: collapse; font-size: 13px; }
table.data th {
  text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-3); font-weight: 600; padding: 9px 12px;
  border-bottom: 1px solid var(--line); background: var(--surface-2);
  white-space: nowrap;
}
/* Sticky is opt-in and only for a table that owns a scroll box of its own. A
   sticky header inside a card sticks to the viewport rather than to the card,
   and paints itself over the rows halfway down the page. */
.tablewrap--tall { max-height: 70vh; overflow: auto; }
.tablewrap--tall table.data th { position: sticky; top: 0; z-index: 1; }
table.data thead th:first-child { padding-left: 18px; }
table.data thead th:last-child { padding-right: 18px; }
table.data th[data-dir]::after {
  content: '↑'; margin-left: 5px; color: var(--accent); font-size: 10px;
}
table.data th[data-dir="desc"]::after { content: '↓'; }
table.data td { padding: 10px 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
table.data td:first-child { padding-left: 18px; }
table.data td:last-child { padding-right: 18px; }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: var(--surface-2); }
table.data--compact td { padding: 6px 12px; font-size: 12.5px; }
table.data--compact th { padding: 7px 12px; }
table.data tfoot td {
  font-weight: 600; border-top: 1px solid var(--line-2); border-bottom: 0;
  background: var(--surface-2);
}
.right { text-align: right; }

/* ------------------------------------------------------------ pills & bars */

.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 600;
  background: var(--sunk); color: var(--ink-2); white-space: nowrap;
  border: 1px solid transparent;
}
.pill--good   { background: var(--good-soft);   color: var(--good-ink);   border-color: var(--good-line); }
.pill--warn   { background: var(--warn-soft);   color: var(--warn-ink);   border-color: var(--warn-line); }
.pill--bad    { background: var(--bad-soft);    color: var(--bad-ink);    border-color: var(--bad-line); }
.pill--blue   { background: var(--accent-soft); color: var(--accent-ink); border-color: var(--accent-line); }
.pill--violet { background: var(--violet-soft); color: var(--violet-ink); border-color: var(--violet-line); }
.pill--teal   { background: var(--teal-soft);   color: var(--teal-ink);   border-color: var(--teal-line); }

.bar { display: block; height: 6px; background: var(--sunk); border-radius: 999px; overflow: hidden; min-width: 60px; }
.bar > span { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.bar--good > span { background: var(--good); }
.bar--warn > span { background: var(--warn); }
.bar--bad  > span { background: var(--bad); }

.notice {
  padding: 12px 15px; border-radius: var(--r); font-size: 13px; margin-bottom: 16px;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--ink-2);
}
.notice--good { background: var(--good-soft);   border-color: var(--good-line);   color: var(--good-ink); }
.notice--warn { background: var(--warn-soft);   border-color: var(--warn-line);   color: var(--warn-ink); }
.notice--bad  { background: var(--bad-soft);    border-color: var(--bad-line);    color: var(--bad-ink); }
.notice--info { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-ink); }
.notice strong { font-weight: 600; }
.notice a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* A toast, not a line at the top of the document.
   A save returns you to where you were working, so a confirmation printed at
   the top of a page you are not looking at is a confirmation nobody reads —
   and a refusal nobody reads is a save somebody believes happened. */
.flash {
  position: fixed; z-index: 60; left: 50%; transform: translateX(-50%);
  top: 14px; max-width: min(680px, calc(100vw - 32px));
  display: flex; align-items: flex-start; gap: 12px;
  padding: 11px 15px; border-radius: var(--r); font-size: 13px;
  font-weight: 500; border: 1px solid var(--line); background: var(--surface);
  box-shadow: var(--lift);
}
.flash__x {
  flex: none; border: 0; background: none; padding: 0 2px; margin-left: auto;
  font-size: 17px; line-height: 1; color: inherit; opacity: .6; cursor: pointer;
}
.flash__x:hover { opacity: 1; }
.flash.is-going { opacity: 0; transition: opacity .4s ease; }
@media (prefers-reduced-motion: reduce) { .flash.is-going { transition: none; } }
.flash--good { background: var(--good-soft); border-color: var(--good-line); color: var(--good-ink); }
.flash--bad  { background: var(--bad-soft);  border-color: var(--bad-line);  color: var(--bad-ink); }
.flash--warn { background: var(--warn-soft); border-color: var(--warn-line); color: var(--warn-ink); }

.empty { padding: 40px 18px; text-align: center; color: var(--ink-3); font-size: 13px; }
.empty p { margin-bottom: 12px; }
.empty p:last-child { margin-bottom: 0; }

/* ------------------------------------------------------------------ forms */

.field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 14px; }
.field label { font-size: 12.5px; font-weight: 500; color: var(--ink-2); }
.field .hint { font-size: 12px; color: var(--ink-3); }

/* `input[type=text]` does not match `<input>` with no type attribute — the
   attribute has to be present for the selector to fire. Half the forms in the
   application omit it, so every one of those inputs was falling back to the
   browser's 20-character default width. */
input:not([type]), input[type=text], input[type=email], input[type=password],
input[type=number], input[type=date], input[type=tel], input[type=search],
select, textarea {
  font: inherit; font-size: 13.5px; padding: 8px 11px;
  border: 1px solid var(--control); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink); width: 100%;
}
input::placeholder, textarea::placeholder { color: var(--ink-3); }
input:not([type]):hover, input:hover, select:hover, textarea:hover { border-color: var(--ink-2); }
input:focus, select:focus, textarea:focus {
  border-color: var(--accent); outline: 3px solid var(--ring); outline-offset: 0;
}
select {
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%235F6D85' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");
  background-position: right 9px center;
  background-size: 15px 15px;
  background-repeat: no-repeat;
  padding-right: 30px;
}
:root[data-theme="dark"] select,
:root:not([data-theme="light"]) select {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%238494AE' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) select {
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%235F6D85' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");
  }
}
textarea { min-height: 82px; resize: vertical; font-family: var(--sans); }
.row { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 0 14px; }
/* Settings fields carry a line of explanation each, so they need more room
   than a form row and have to stay aligned when one of them wraps. */
.row--settings { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 4px 24px; }
.row--settings .field { margin-bottom: 18px; }
.field--full { grid-column: 1 / -1; }

/* Radio and checkbox groups on the intake forms. The desk had no vocabulary
   for these because nothing on it asked a multiple-choice question until the
   New Investor and New Borrower screens rendered the public applications. */
.optset { display: flex; flex-direction: column; gap: 6px; padding: 2px 0; }
.optset--row { flex-direction: row; flex-wrap: wrap; gap: 6px 18px; }
.optset__one {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 13px; font-weight: 400; color: var(--ink); cursor: pointer;
}
.optset__one input { margin: 0; flex: 0 0 auto; }
.optset__one span { line-height: 1.4; }
.field--wide { grid-column: span 2; }
@media (max-width: 760px) { .field--wide { grid-column: 1 / -1; } }

/* The unit belongs beside the number, not in the label: "90" and "90 days"
   are different amounts of confusion. */
.unit { position: relative; display: flex; align-items: center; }
.unit input { padding-right: 4.5em; }
.unit__tag {
  position: absolute; right: 10px; font-size: 11.5px; color: var(--ink-3);
  pointer-events: none; white-space: nowrap; font-variant-numeric: tabular-nums;
}
/* A unit that reads before the figure rather than after it. A dollar sign is
   a prefix everywhere else in the language, and `$` sitting to the right of
   the box reads as a currency code, not as money. */
.unit--lead input { padding-right: 10px; padding-left: 2em; text-align: right; }
.unit--lead .unit__tag { right: auto; left: 10px; }

.btnrow { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.btnrow--end { justify-content: flex-end; }

.btn {
  display: inline-flex; align-items: center; gap: 7px; justify-content: center;
  padding: 8px 15px; border-radius: var(--r-sm);
  border: 1px solid var(--accent); background: var(--accent); color: var(--on-accent);
  font: inherit; font-size: 13px; font-weight: 600; letter-spacing: -.005em;
  cursor: pointer; text-decoration: none; min-height: 36px; white-space: nowrap;
}
.btn:hover { background: var(--accent-2); border-color: var(--accent-2); text-decoration: none; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn svg { width: 15px; height: 15px; }
.btn.secondary { background: var(--surface); color: var(--ink); border-color: var(--control); }
.btn.secondary:hover { background: var(--sunk); border-color: var(--ink-2); }
.btn.ghost { background: transparent; color: var(--ink-2); border-color: transparent; }
.btn.ghost:hover { background: var(--sunk); color: var(--ink); }
.btn.danger { background: var(--bad); border-color: var(--bad); color: var(--on-accent); }
/* The button that moves money. Green because it is the end of a sequence
   rather than one more step in it, and because on a page of blue buttons the
   irreversible one should not look like the rest. */
.btn.good { background: var(--good); border-color: var(--good); color: var(--on-accent); }
.btn.good:hover { background: var(--good-ink); border-color: var(--good-ink); }
.btn.sm { padding: 4px 11px; font-size: 12px; min-height: 28px; border-radius: var(--r-sm); }
.btn--wide { width: 100%; }
/* A second solid button, for the case where two primary actions sit side by
   side and are different jobs — New investor and New borrower on the
   dashboard. Two buttons in the same colour read as one choice made twice. */
.btn--violet { background: var(--violet); border-color: var(--violet); color: var(--on-accent); }
.btn--violet:hover { background: var(--violet-ink); border-color: var(--violet-ink); }

/* A search box that sits above the table it narrows. Full width, because a
   260px box above a nine-column table looks like it belongs to something
   else. */
/* A collapsible section. Used where a record is long enough that opening all
   of it at once is a wall rather than a document — the investor's application
   is a hundred answers under eight headings. */
.fold { border: 1px solid var(--line); border-radius: var(--r-sm); margin-bottom: 8px;
  background: var(--surface); }
.fold > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 14px; cursor: pointer; list-style: none;
  font-size: 13.5px; font-weight: 600; color: var(--ink);
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::before {
  content: '›'; flex: none; width: 12px; margin-right: 2px;
  color: var(--ink-3); font-size: 15px; line-height: 1;
  transition: transform .12s ease;
}
.fold[open] > summary::before { transform: rotate(90deg); }
.fold > summary > span:first-of-type { flex: 1 1 auto; }
.fold__n {
  flex: none; padding: 1px 8px; border-radius: 999px; background: var(--sunk);
  color: var(--ink-3); font-size: 11.5px; font-weight: 500; font-variant-numeric: tabular-nums;
}
.fold > summary:hover { background: var(--sunk); }
.fold__body { padding: 2px 14px 12px; border-top: 1px solid var(--line); }
@media (prefers-reduced-motion: reduce) { .fold > summary::before { transition: none; } }

/* The period control. One row: what to show, the choice within it, and Apply. */
.periodbar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px;
  padding: 10px 12px; margin-bottom: 14px;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface);
}
.periodbar__set { display: flex; align-items: center; gap: 6px; }
.periodbar__set select, .periodbar__set input { min-height: 32px; padding: 4px 9px; font-size: 13px; }
.periodbar__lab { font-size: 12.5px; color: var(--ink-3); white-space: nowrap; }
.periodbar__now {
  margin-left: auto; font-size: 12.5px; font-weight: 600; color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

/* ─────────────────────────────────────────────── the campaign builder */

.studio { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 18px; }
@media (max-width: 900px) { .studio { grid-template-columns: 1fr; } }

.pal h3 {
  margin: 0 0 8px; font-size: 11.5px; font-weight: 600; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-3);
}
.pal h3 + * { margin-bottom: 18px; }
.pal__grid { display: grid; gap: 6px; }
.pal__item {
  display: block; width: 100%; text-align: left; padding: 8px 11px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); font: inherit; color: var(--ink);
}
.pal__item:hover { border-color: var(--accent); background: var(--accent-soft); }
.pal__item span { display: block; font-size: 13px; font-weight: 600; }
.pal__item em { display: block; font-size: 11.5px; font-style: normal; color: var(--ink-3); }
.pal__theme { display: grid; gap: 6px; }
.pal__theme label {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 12.5px; color: var(--ink-2);
}
.pal__theme input { width: 44px; height: 26px; padding: 0; border: 1px solid var(--line); }
/* `.pal h3 + *` gives the element straight after a heading its bottom margin,
   which the note under the merge-field picker is not — so "Look" sat flush
   against the sentence above it. */
.pal .hint { margin: 6px 0 18px; }

/* A switch over one view: the builder's desktop/mobile preview.
   Not navigation, so buttons rather than the chip links used for filters — and
   the chosen one has to look chosen. It was two ghost buttons and an `is-on`
   class nothing styled, which renders as two words of plain text. */
.seg {
  display: inline-flex; gap: 2px; padding: 2px;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--sunk);
}
.seg > button {
  font: inherit; font-size: 12.5px; font-weight: 600; line-height: 1;
  min-height: 30px; padding: 7px 13px; cursor: pointer;
  border: 0; border-radius: calc(var(--r-sm) - 2px);
  background: transparent; color: var(--ink-3);
}
.seg > button:hover { color: var(--ink); }
.seg > button.is-on { background: var(--surface); color: var(--ink); box-shadow: var(--lift); }

.stage { min-width: 0; }
.stage__bar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-bottom: 8px;
}
.stage__scroll {
  padding: 20px 12px; border: 1px solid var(--line); border-radius: var(--r);
  background: #EEF2F7; overflow-x: auto;
}
/* The stage is the real width. 600px is what the email is; 375px is a phone,
   and the same breakpoint the sent message carries takes over below 620. */
.canvas {
  width: 600px; max-width: 100%; margin: 0 auto; border-radius: 10px;
  background: #fff; color: #1A1F2B; overflow: hidden;
}
.stage__scroll[data-mode="mobile"] .canvas { width: 375px; }

.canvas__empty { padding: 44px 28px; text-align: center; color: var(--ink-3); }
.canvas__empty p { margin: 0 0 6px; }

.blk { position: relative; border-top: 1px dashed transparent; }
.blk:hover { border-top-color: #C9D6EA; }
.blk__bar {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 3px 10px; background: #F3F6FB; border-bottom: 1px solid #E4EAF4;
  opacity: 0; transition: opacity .12s ease;
}
.blk:hover .blk__bar, .blk:focus-within .blk__bar { opacity: 1; }
.blk__name { font: 600 11px/1.4 var(--sans); letter-spacing: .04em;
  text-transform: uppercase; color: #5F6D85; }
.blk__acts { display: flex; gap: 2px; }
.blk__acts button {
  min-width: 22px; height: 22px; padding: 0 5px; cursor: pointer;
  border: 1px solid transparent; border-radius: 4px; background: transparent;
  font: 12px/1 var(--sans); color: #5F6D85;
}
.blk__acts button:hover:not(:disabled) { background: #fff; border-color: #D5DEEC; color: #101B31; }
.blk__acts button:disabled { opacity: .3; cursor: default; }
.blk__body { padding: 4px 32px 10px; }
.blk__row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin: 6px 0 8px; }
.blk__lab { font-size: 11.5px; color: #5F6D85; }
/* `background-color`, not the `background` shorthand: the shorthand resets the
   chevron the base `select` rule paints, and a select with a repeating or
   missing arrow is the tell that a control was styled without looking at it. */
.blk__mini {
  min-height: 26px; padding: 3px 8px; border: 1px solid #D5DEEC; border-radius: 4px;
  background-color: #fff; background-repeat: no-repeat;
  font: 12px/1.4 var(--sans); color: #101B31;
}
select.blk__mini { width: auto; min-width: 62px; padding-right: 26px;
  background-position: right 6px center; background-size: 13px 13px; }
.blk__mini--wide { flex: 1 1 180px; min-width: 0; }
.blk__align { display: inline-flex; gap: 2px; }
.blk__align button {
  min-width: 24px; height: 24px; cursor: pointer; border: 1px solid #D5DEEC;
  border-radius: 4px; background-color: #fff; font: 11px/1 var(--sans); color: #5F6D85;
}
.blk__align button.is-on { background: #101B31; border-color: #101B31; color: #fff; }

/* What the blocks look like — deliberately close to what the email renders,
   because this is the preview as well as the editor. */
.em-h { margin: 14px 0 8px; font: 700 22px/1.25 var(--sans); }
.em-h1 { font-size: 28px; } .em-h2 { font-size: 22px; } .em-h3 { font-size: 18px; }
.em-t { font: 15px/1.6 var(--sans); margin: 4px 0 12px; }
.em-t p { margin: 0 0 .85em; }
.em-t ul, .em-t ol { margin: 0 0 .85em; padding-left: 1.4em; }
.em-t:focus, .em-h:focus, .em-btn:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
.em-btn {
  display: inline-block; padding: 12px 26px; border-radius: 10px;
  font: 600 15px/1 var(--sans); color: #fff; margin: 4px 0 16px;
}
.em-img { display: block; width: 100%; height: auto; margin: 6px 0 12px; }
.em-ph {
  padding: 28px; margin: 6px 0 12px; text-align: center; border: 1px dashed #C9D6EA;
  border-radius: 6px; color: #5F6D85; font-size: 13px;
}
.em-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.stage__scroll[data-mode="mobile"] .em-cols { grid-template-columns: 1fr; gap: 0; }
.em-rule { height: 1px; background: #E2E8F2; margin: 10px 0; }
.em-space { background: repeating-linear-gradient(45deg,
  #F3F6FB, #F3F6FB 6px, #E9EEF7 6px, #E9EEF7 12px); border-radius: 4px; }
.em-code {
  width: 100%; padding: 10px 12px; border: 1px solid #D5DEEC; border-radius: 6px;
  background: #F8FAFD; font: 12.5px/1.6 var(--mono); color: #101B31; resize: vertical;
}

/* The sent message, framed on its own page. */
.mailframe {
  margin-top: 12px; border: 1px solid var(--line); border-radius: var(--r); overflow: hidden;
  background: #EEF2F7;
}
.mailframe iframe { display: block; width: 100%; height: 640px; border: 0; }

/* ───────────────────────────────────────────────────────────── charts */

.chart { margin: 0 0 6px; }
.chart figcaption {
  margin-bottom: 8px; font-size: 12px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-3);
}
/* The viewBox is 0–100 in both directions and the SVG is stretched to fit, so
   a bar's height is a percentage and nothing has to be measured in pixels. The
   cost is that strokes would stretch too — hence vector-effect on every one. */
.chart__svg { display: block; width: 100%; overflow: visible; }
.chart__col rect { fill: var(--accent); }
.chart__col--good rect { fill: var(--good); }
.chart__col--warn rect { fill: var(--warn); }
.chart__col--bad rect  { fill: var(--bad); }
.chart__col--violet rect { fill: var(--violet); }
.chart__col--muted rect { fill: var(--line-2); }
.chart__col:hover rect { fill: var(--accent-2); }
.chart__zero { stroke: var(--line-2); stroke-width: 1; }
/* A line chart has to let its stroke hang over the edge of the box; a column
   chart's bars sit inside it. */
.chart__svg--line { padding: 2px 0; }
.chart__line { fill: none; stroke: var(--accent); stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round; }
.chart__area { fill: var(--accent-soft); opacity: .8; }
.chart__axis {
  display: flex; margin-top: 8px; border-top: 1px solid var(--line); padding-top: 8px;
}
.chart__tick {
  flex: 1 1 0; min-width: 0; text-align: center; padding: 0 2px;
  font-variant-numeric: tabular-nums;
}
.chart__tick b { display: block; font-size: 12.5px; font-weight: 600; color: var(--ink); }
.chart__tick span {
  display: block; font-size: 11px; color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (max-width: 700px) { .chart__tick span { font-size: 10px; } }

/* ──────────────────────────────────────────────── the settings screen */

/* Dense. Nineteen settings under five headings has to be one screen, or
   somebody configuring the fund is scrolling between the question and the
   answer. 180px is the narrowest a labelled input reads at. */
/* `auto-fill`, not `auto-fit`. With auto-fit a section holding two fields
   stretches them to half the page each, so "Money, decimal places" gets 600px
   for a single digit and the page stops reading as a grid. auto-fill keeps the
   column count and leaves the empty tracks empty. */
.row--set {
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 0 14px;
  margin-bottom: 4px;
}
.row--set .field { margin-bottom: 12px; gap: 3px; }
.row--set .field label { font-size: 12px; }
.row--set .field .hint { font-size: 11.5px; line-height: 1.4; }
.row--set input, .row--set select, .row--set textarea {
  min-height: 32px; padding: 5px 10px; font-size: 13px;
}
.row--set .unit input { padding-right: 4.5em; }

/* The section heading. A rule that runs to the edge, so the groups read as
   bands rather than as a list of bold words. */
/* A section label inside a card or a form: small caps with a hairline running
   out to the edge. `.rule` is the same thing outside the settings pages —
   one look for "this is where the next group of fields starts". */
.setsec, h3.rule {
  display: flex; align-items: center; gap: 10px;
  margin: 16px 0 10px; font-size: 11.5px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-3);
}
.setsec::after, h3.rule::after {
  content: ''; flex: 1 1 auto; height: 1px; background: var(--line);
}
.setform > .setsec:first-of-type { margin-top: 4px; }
.setblurb {
  margin: 0 0 4px; max-width: 78ch; font-size: 13px; line-height: 1.55; color: var(--ink-2);
}
.setform__save {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line);
}
.card--set .card__body { padding-top: 14px; }

/* ─────────────────────────────────────────────────────────────── the bell */

.bellwrap { position: relative; display: flex; }
.bellbtn { position: relative; }
.bellbtn__n {
  position: absolute; top: 1px; right: 0; min-width: 16px; height: 16px; padding: 0 4px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 999px; background: var(--bad); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.bell {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  width: min(400px, calc(100vw - 24px));
  border: 1px solid var(--line); border-radius: var(--r); background: var(--surface);
  box-shadow: var(--float); overflow: hidden;
}
.bell__head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 14px; border-bottom: 1px solid var(--line); font-size: 13.5px;
}
.bell__list { list-style: none; margin: 0; padding: 0; max-height: 52vh; overflow-y: auto; }
.bell__item {
  display: flex; align-items: flex-start; gap: 4px;
  border-bottom: 1px solid var(--line);
}
.bell__item:last-child { border-bottom: 0; }
.bell__item.is-new { background: var(--accent-soft); }
.bell__link {
  flex: 1 1 auto; min-width: 0; display: flex; gap: 9px; align-items: flex-start;
  padding: 10px 4px 10px 14px; color: inherit; text-decoration: none;
}
a.bell__link:hover { background: var(--sunk); text-decoration: none; }
.bell__dot {
  flex: none; width: 7px; height: 7px; margin-top: 6px; border-radius: 999px;
  background: var(--accent);
}
.bell__dot--good { background: var(--good); }
.bell__dot--warn { background: var(--warn); }
.bell__dot--bad  { background: var(--bad); }
.bell__text { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.bell__text strong { font-size: 13px; font-weight: 600; line-height: 1.35; }
.bell__body { font-size: 12px; color: var(--ink-2); line-height: 1.4; }
.bell__when { font-size: 11.5px; color: var(--ink-3); }
.bell__acts { flex: none; display: flex; align-items: center; gap: 2px; padding: 8px 8px 0 0; }
.bell__act {
  padding: 3px 7px; border: 1px solid transparent; border-radius: 5px; background: transparent;
  font: 500 11.5px/1.4 var(--sans); color: var(--ink-3); cursor: pointer; white-space: nowrap;
}
.bell__act:hover { background: var(--sunk); border-color: var(--line); color: var(--ink); }
.bell__empty { margin: 0; padding: 26px 16px; text-align: center;
  font-size: 13px; color: var(--ink-3); }
.bell__foot { padding: 9px 14px; border-top: 1px solid var(--line); font-size: 12.5px; }

/* ───────────────────────────────────────────────────────── the dashboard */

/* Wide left, fixed rail. The left holds tables — a pipeline in a 300px column
   is a list of truncated words — and the rail holds things addressed to the
   person reading, which are all one line each. */
.deck { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 18px; align-items: start; }
.deck__main { min-width: 0; display: flex; flex-direction: column; gap: 18px; }
.deck__rail { display: flex; flex-direction: column; gap: 14px; position: sticky; top: 68px; }
@media (max-width: 1180px) {
  .deck { grid-template-columns: 1fr; }
  .deck__rail { position: static; }
}
/* `align-items: start`, or the shorter card stretches to match the taller one
   and the balance sheet grows a foot of empty white below its own footer. */
.split2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 18px; align-items: start; }
.split2 > * { min-width: 0; }

/* The week's target. The one number the desk is managed by, so it is the one
   thing above the tiles. */
.target {
  display: grid; grid-template-columns: minmax(180px, 220px) minmax(0, 1fr) minmax(220px, 300px);
  gap: 22px; align-items: center;
  padding: 18px 22px; margin-bottom: 18px;
  border: 1px solid var(--line); border-left: 4px solid var(--accent);
  border-radius: var(--r); background: var(--surface);
}
.target--good { border-left-color: var(--good); }
.target--warn { border-left-color: var(--warn); }
.target--bad  { border-left-color: var(--bad); }
@media (max-width: 900px) { .target { grid-template-columns: 1fr; gap: 14px; } }
.target__fig { min-width: 0; }
.target__bar { min-width: 0; }
.target__eyebrow {
  margin: 0 0 2px; font-size: 11px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-3);
}
.target__big {
  margin: 0; font-size: 30px; font-weight: 700; letter-spacing: -.02em; line-height: 1.1;
  font-variant-numeric: tabular-nums; color: var(--ink);
}
.target__of { margin: 2px 0 0; font-size: 12.5px; color: var(--ink-2); }
.target__track {
  position: relative; height: 12px; border-radius: 999px; background: var(--sunk);
  overflow: visible;
}
.target__fill {
  height: 100%; border-radius: 999px; background: var(--accent);
  transition: width .3s ease;
}
.target--good .target__fill { background: var(--good); }
.target--warn .target__fill { background: var(--warn); }
.target--bad  .target__fill { background: var(--bad); }
/* Where the week should be by today. A bar measured only against the whole
   week cannot tell "behind on Tuesday" from "behind on Friday". */
.target__pace {
  position: absolute; top: -3px; width: 2px; height: 18px; background: var(--ink-2);
  border-radius: 1px; transform: translateX(-1px);
}
.target__note { margin: 8px 0 0; font-size: 12.5px; color: var(--ink-2); }
.target__list { display: flex; flex-direction: column; gap: 2px; max-height: 108px; overflow-y: auto; }
.target__row {
  display: grid; grid-template-columns: 92px minmax(0, 1fr) auto; gap: 8px; align-items: baseline;
  padding: 3px 6px; border-radius: 5px; font-size: 12px; color: var(--ink-2);
  text-decoration: none;
}
.target__row:hover { background: var(--sunk); text-decoration: none; }
.target__row span:nth-child(2) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.target__row b { color: var(--ink); font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) { .target__fill { transition: none; } }

/* This week, module by module. */
.modrow { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: var(--r-sm);
  overflow: hidden; }
.mod {
  display: flex; flex-direction: column; gap: 2px; padding: 11px 13px;
  background: var(--surface); color: inherit; text-decoration: none;
  border-left: 3px solid transparent;
}
.mod:hover { background: var(--sunk); text-decoration: none; }
.mod--good { border-left-color: var(--good); }
.mod--warn { border-left-color: var(--warn); }
.mod--bad  { border-left-color: var(--bad); }
.mod__label { font-size: 11px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-3); }
.mod__value { font-size: 19px; font-weight: 700; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums; color: var(--ink); }
.mod__note { font-size: 11.5px; color: var(--ink-3); }

/* A rail widget. Tighter than a card, and always a list of links. */
.wid { border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); }
.wid__head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 13px; border-bottom: 1px solid var(--line);
}
.wid__head h2 { margin: 0; font-size: 12.5px; font-weight: 700; letter-spacing: .01em; }
.wid__body { padding: 2px 0; }
.wid__foot { padding: 8px 13px; border-top: 1px solid var(--line); font-size: 12px; }
.wid__list { list-style: none; margin: 0; padding: 0; max-height: 320px; overflow-y: auto; }
.wid__list > li { display: flex; align-items: flex-start; gap: 2px;
  border-bottom: 1px solid var(--line); }
.wid__list > li:last-child { border-bottom: 0; }
.wid__item.is-new { background: var(--accent-soft); }
.wid__item.is-late { background: var(--bad-soft); }
.wid__row {
  flex: 1 1 auto; min-width: 0; display: flex; gap: 8px; align-items: flex-start;
  padding: 9px 4px 9px 13px; color: inherit; text-decoration: none;
}
a.wid__row:hover { background: var(--sunk); text-decoration: none; }
.wid__empty { margin: 0; padding: 18px 13px; font-size: 12.5px; color: var(--ink-3); }
.wid__add {
  display: grid; grid-template-columns: minmax(0, 1fr) 132px auto; gap: 6px;
  padding: 10px 13px; border-top: 1px solid var(--line);
}
.wid__add input { min-height: 30px; padding: 4px 9px; font-size: 12.5px; }
.bell__act--do { border-color: var(--good-line); color: var(--good-ink);
  background: var(--good-soft); }
.bell__act--do:hover { background: var(--good); border-color: var(--good); color: #fff; }

/* Four numbers on one line, for a widget that is a summary rather than a list. */
.statrow { display: flex; gap: 2px; padding: 10px 13px; border-bottom: 1px solid var(--line); }
.statrow span { flex: 1 1 0; display: flex; flex-direction: column; min-width: 0;
  font-size: 11px; color: var(--ink-3); }
.statrow b { font-size: 17px; font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums; }

/* The annual roll. A banner rather than a card, because it is one action and
   it should read as a prompt, not as a section of the page. */
.rollbar {
  display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap;
  padding: 14px 18px; margin-bottom: 16px;
  border: 1px solid var(--line); border-left: 4px solid var(--control);
  border-radius: var(--r); background: var(--surface);
}
.rollbar--due { border-left-color: var(--warn); background: var(--warn-soft); }
.rollbar strong { display: block; font-size: 14px; }
.rollbar p { margin: 4px 0 0; max-width: 72ch; font-size: 12.5px; line-height: 1.5;
  color: var(--ink-2); }

/* ──────────────────────────────────────────── the PDF mapping review */

.mapscore { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 22px;
  align-items: center; }
@media (max-width: 700px) { .mapscore { grid-template-columns: 1fr; } }
.mapscore__fig { text-align: center; }
.mapscore__fig strong {
  display: block; font-size: 34px; font-weight: 700; letter-spacing: -.02em; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--ink);
}
.mapscore__fig strong span { font-size: 19px; font-weight: 600; color: var(--ink-3); }
.mapscore__fig > span { display: block; margin-top: 4px; font-size: 11.5px;
  letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); }
.mapscore__bar { min-width: 0; }
.mapscore__bar .target__track { margin-bottom: 8px; }
.mapscore__bar .hint { max-width: 84ch; }

/* What did not map. Red, at the bottom, and not dressed up — this is the list
   somebody has to work through and it should look like one. */
.card--miss { border-color: var(--bad-line); }
.card--miss .card__head h2 { color: var(--bad-ink); }
.mapmiss__lede { margin: 0 0 12px; font-size: 13px; line-height: 1.55; color: var(--bad-ink); }
.mapmiss {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 2px 16px;
}
.mapmiss li {
  display: flex; align-items: baseline; gap: 6px; padding: 3px 0;
  font-size: 12.5px; color: var(--bad-ink);
}
.mapmiss li.is-required { font-weight: 600; }
.mapmiss li em { font-style: normal; font-size: 10.5px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--bad); }
.mapmiss li span { margin-left: auto; font-size: 11px; color: var(--ink-3); }

.findbar { margin-bottom: 14px; }
.field--find { max-width: 480px; }

.chips { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 16px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: 999px; border: 1px solid var(--control);
  background: var(--surface); font-size: 12.5px; font-weight: 500;
  color: var(--ink-2); text-decoration: none;
}
.chip:hover { border-color: var(--ink-2); color: var(--ink); text-decoration: none; }
.chip.is-on {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 600;
}
.chip__n { opacity: .7; font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------ label/value */

.facts, .kv { display: grid; gap: 0; }
.facts > div, .kv > div {
  display: grid; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--line);
  align-items: baseline;
}
.facts > div { grid-template-columns: minmax(0, 40%) minmax(0, 1fr); }
.kv > div { grid-template-columns: minmax(0, 32%) minmax(0, 1fr); }
.facts > div:last-child, .kv > div:last-child { border-bottom: 0; padding-bottom: 0; }
.facts > div:first-child, .kv > div:first-child { padding-top: 0; }
.facts dt, .kv dt { font-size: 12.5px; color: var(--ink-3); }
.facts dd, .kv dd { font-size: 13px; min-width: 0; overflow-wrap: anywhere; }

/* Two label/value columns where a card is wide enough to hold them. */
.facts--two, .kv--two { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 40px; }
.kv--two > div { grid-template-columns: minmax(0, 42%) minmax(0, 1fr); }
/* In one column the first row loses its top padding and the last its rule.
   In two columns those exceptions land on one item of a pair and knock the
   two halves of the row out of line, so every row here is treated alike. */
.facts--two > div, .kv--two > div { padding: 9px 0; border-bottom: 1px solid var(--line); }

/* The bottom line of a list of figures. This used to be attempted by putting
   `<strong>` in the label, which `kv` escapes — so the tags appeared on the
   screen. It is a state of the row, so the row carries it. */
.kv__lead dt { color: var(--ink); font-weight: 600; }
.kv__lead dd { font-weight: 600; }
/* Across the full width, because two columns are read row by row and a total
   that sits in one of them sits in the middle of its own list. */
.kv--two > .kv__lead {
  grid-column: 1 / -1; border-bottom: 0; border-top: 1px solid var(--line-2);
  margin-top: 4px; padding-top: 12px;
  grid-template-columns: minmax(0, 20%) minmax(0, 1fr);
}
@media (max-width: 900px) { .kv--two > .kv__lead { grid-template-columns: minmax(0, 42%) minmax(0, 1fr); } }
@media (max-width: 900px) {
  .facts--two, .kv--two { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------------ track */

.track { list-style: none; display: flex; padding: 0; margin: 0 0 22px; overflow-x: auto; }
.track__step { flex: 1 1 0; min-width: 100px; position: relative; padding: 0 4px; text-align: center; }
.track__step::before,
.track__step::after {
  content: ''; position: absolute; top: 6px; height: 2px; background: var(--line);
}
.track__step::before { left: 0; right: 50%; }
.track__step::after { left: 50%; right: 0; }
.track__step:first-child::before, .track__step:last-child::after { display: none; }
.track__step.is-done::before, .track__step.is-done::after,
.track__step.is-now::before { background: var(--good); }
.track__dot {
  position: relative; z-index: 1; display: block; width: 14px; height: 14px; margin: 0 auto 8px;
  border-radius: 50%; background: var(--surface); border: 2px solid var(--line-2);
}
.track__step.is-done .track__dot { background: var(--good); border-color: var(--good); }
.track__step.is-now .track__dot {
  background: var(--surface); border-color: var(--good);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--good) 18%, transparent);
}
.track__label { display: block; font-size: 11.5px; font-weight: 500; color: var(--ink-3); }
.track__step.is-now .track__label { color: var(--ink); font-weight: 600; }
.track__when { display: block; font-size: 10.5px; color: var(--ink-3); }

/* ------------------------------------------------------------------ board */
/* The pipeline as lanes. It scrolls sideways on purpose: seven stages will not
   fit on a laptop at a readable card width, and squeezing them makes every
   card unreadable rather than making the last two visible. */

.board {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(196px, 1fr);
  gap: 10px; overflow-x: auto; padding-bottom: 10px; margin-bottom: 18px;
  scroll-snap-type: x proximity;
  align-items: start;
}

/* Content that runs off the side says so. The classes are set from the actual
   scroll position, so the fade appears only while there really is more that
   way and disappears at the end — a permanent gradient is a lie half the
   time, and a board with a hidden eighth lane is how a file goes unseen. */
.xscroll { position: relative; }
.xscroll::before, .xscroll::after {
  content: ''; position: absolute; top: 0; bottom: 10px; width: 40px;
  pointer-events: none; opacity: 0; transition: opacity .15s ease; z-index: 2;
}
.xscroll::before {
  left: 0; background: linear-gradient(90deg, var(--ground), transparent);
}
.xscroll::after {
  right: 0; background: linear-gradient(270deg, var(--ground), transparent);
}
.xscroll.can-left::before, .xscroll.can-right::after { opacity: 1; }
.card .xscroll::before { background: linear-gradient(90deg, var(--surface), transparent); }
.card .xscroll::after { background: linear-gradient(270deg, var(--surface), transparent); }
@media (prefers-reduced-motion: reduce) {
  .xscroll::before, .xscroll::after { transition: none; }
}
.board__col {
  background: var(--sunk); border-radius: var(--r-lg); padding: 11px;
  display: flex; flex-direction: column; gap: 8px; min-width: 0;
  min-height: 116px; scroll-snap-align: start;
}
.board__col > h3 {
  display: flex; align-items: center; gap: 7px;
  font-size: 11px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-2); font-weight: 600;
}
.board__col > h3 span {
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
  padding: 0 7px; font-size: 10.5px; color: var(--ink-2);
  font-variant-numeric: tabular-nums; letter-spacing: 0;
}
.board__sum {
  font-size: 15px; font-weight: 600; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; margin-top: -4px;
}
.board__none { color: var(--ink-3); font-size: 12.5px; padding: 6px 2px; }

.deal {
  display: flex; flex-direction: column; gap: 2px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  padding: 10px 12px; text-decoration: none; color: inherit; min-width: 0;
}
.deal:hover { border-color: var(--line-2); box-shadow: var(--lift); text-decoration: none; }
.deal strong { font-size: 13.5px; font-weight: 600; letter-spacing: -.01em; }
.deal__ref { font-size: 10.5px; color: var(--ink-3); letter-spacing: .01em; }
.deal__meta {
  font-size: 12px; color: var(--ink-2); font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.deal__flag {
  align-self: flex-start; margin-top: 5px; white-space: nowrap;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  background: var(--warn-soft); color: var(--warn-ink); border: 1px solid var(--warn-line);
  border-radius: 999px; padding: 1px 8px; font-size: 10.5px; font-weight: 600;
}

/* ------------------------------------------------------------------- feed */

.feed { list-style: none; padding: 0; display: flex; flex-direction: column; }
.feed li {
  padding: 9px 0 9px 16px; border-bottom: 1px solid var(--line);
  font-size: 13px; position: relative;
}
.feed li::before {
  content: ''; position: absolute; left: 2px; top: 15px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--line-2);
}
.feed li:first-child::before { background: var(--accent); }
.feed li:last-child { border-bottom: 0; padding-bottom: 0; }
.feed li:first-child { padding-top: 0; }
.feed li:first-child::before { top: 6px; }
.feed strong { font-weight: 600; }

/* ------------------------------------------------------------------- tabs */

/* Tabs wrap rather than scroll sideways.
   Settings runs to twelve of them and the twelfth sat off the right edge
   behind a scrollbar the page never showed — a settings tab nobody can see is
   a setting nobody finds. Every bar that already fits on one line is
   unaffected; only one that does not takes a second row. */
.tabs {
  display: flex; flex-wrap: wrap; gap: 2px 0; margin-bottom: 20px;
  border-bottom: 1px solid var(--line);
}
.tabs a, .tabs button {
  padding: 9px 14px; font: inherit; font-size: 13px; font-weight: 500;
  color: var(--ink-2); background: none; border: 0; cursor: pointer;
  border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap;
  text-decoration: none;
}
.tabs a:hover, .tabs button:hover { color: var(--ink); text-decoration: none; }
.tabs [aria-selected="true"], .tabs [aria-current="page"] {
  color: var(--accent-ink); border-bottom-color: var(--accent); font-weight: 600;
}

/* ------------------------------------------------------- command palette */

.palette {
  position: fixed; inset: 0; z-index: 100;
  background: color-mix(in srgb, #0B111C 52%, transparent);
  backdrop-filter: blur(2px);
  display: grid; align-items: start; justify-items: center;
  padding: 12vh 16px 16px;
}
.palette__box {
  width: 100%; max-width: 620px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--float); overflow: hidden;
  display: flex; flex-direction: column; max-height: 68vh;
}
.palette__in {
  display: flex; align-items: center; gap: 10px;
  padding: 0 16px; border-bottom: 1px solid var(--line); flex: none;
}
.palette__in svg { width: 17px; height: 17px; color: var(--ink-3); }
.palette__in input {
  border: 0; background: none; padding: 15px 0; font-size: 15px; width: 100%;
}
.palette__in input:focus { outline: 0; }
.palette__in .spin { width: 14px; height: 14px; color: var(--ink-3); animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spin { animation: none; } }

.palette__list { overflow-y: auto; padding: 6px; flex: 1; }
.palette__group {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--ink-3); font-weight: 600; padding: 10px 10px 5px;
}
.palette__hit {
  display: flex; align-items: center; gap: 11px;
  padding: 8px 10px; border-radius: var(--r-sm); cursor: pointer;
  color: var(--ink); text-decoration: none;
}
.palette__hit:hover, .palette__hit.is-on { background: var(--sunk); text-decoration: none; }
.palette__hit.is-on { background: var(--accent-soft); }
.palette__hit svg { width: 16px; height: 16px; color: var(--ink-3); }
.palette__hit.is-on svg { color: var(--accent); }
.palette__hit b { font-weight: 600; font-size: 13.5px; }
.palette__hit small { color: var(--ink-3); font-size: 12px; margin-left: auto; padding-left: 12px; white-space: nowrap; }
.palette__none { padding: 28px 16px; text-align: center; color: var(--ink-3); font-size: 13px; }
.palette__foot {
  flex: none; border-top: 1px solid var(--line); background: var(--surface-2);
  padding: 8px 14px; font-size: 11.5px; color: var(--ink-3);
  display: flex; gap: 14px; flex-wrap: wrap;
}
.palette__foot kbd {
  font-family: var(--sans); font-size: 10.5px; font-weight: 600;
  background: var(--sunk); border: 1px solid var(--line); border-radius: 4px; padding: 0 4px;
}

/* ------------------------------------------------------------------- auth */

.auth {
  min-height: 100vh; display: grid; place-items: center; padding: 24px;
  background: var(--ground);
}
.auth__card {
  width: 100%; max-width: 400px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 34px; box-shadow: var(--lift);
}
.auth__logo { display: block; margin-bottom: 24px; height: 34px; width: auto; }
.auth__logo.on-dark { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .auth__logo.on-light { display: none; }
  :root:not([data-theme="light"]) .auth__logo.on-dark { display: block; }
}
:root[data-theme="dark"] .auth__logo.on-light { display: none; }
:root[data-theme="dark"] .auth__logo.on-dark { display: block; }
:root[data-theme="light"] .auth__logo.on-light { display: block; }
:root[data-theme="light"] .auth__logo.on-dark { display: none; }

/* A page with no navigation has no header to hang a bar on: the theme control
   floats in the corner instead of sitting on an otherwise empty strip. */
body.plain .top {
  position: absolute; top: 0; right: 0; left: auto; width: auto;
  background: none; backdrop-filter: none; border: 0; padding: 10px 12px; height: auto;
}
body.plain .main { position: relative; }
body.plain .page { padding: 0; max-width: none; }

/* A portal page — the broker's and the borrower's document pages — has no rail
   but it does have a header, so the floating-corner rule above is wrong for it:
   the wordmark belongs on a real strip at the top left, with the name of the
   portal opposite, the same furniture on both. */
body.plain .top--portal {
  position: sticky; inset: 0 0 auto 0; width: 100%; height: auto;
  display: flex; align-items: center; gap: 14px;
  padding: 12px 24px;
  background: var(--surface); border-bottom: 1px solid var(--line);
  backdrop-filter: none;
}
body.plain .top--portal .auth__logo { margin-bottom: 0; height: 28px; }
body.plain .page--portal { padding: 26px 24px 72px; max-width: 1200px; margin: 0 auto; }

.auth__card h1 { font-size: 23px; margin-bottom: 18px; }
.auth__foot { margin-top: 18px; font-size: 12.5px; color: var(--ink-3); }

/* --------------------------------------------------------------- responsive */

.scrim { display: none; }

@media (max-width: 900px) {
  body.has-side { grid-template-columns: 1fr; }

  /* The rail becomes a drawer. It is off-canvas until the header button
     opens it — a wrapped row of eighteen links is not navigation. */
  .rail {
    position: fixed; inset: 0 auto 0 0; width: min(84vw, 300px); z-index: 50;
    transform: translateX(-100%); transition: transform .18s ease;
    box-shadow: var(--float);
  }
  body.drawer-open .rail { transform: none; }
  body.drawer-open .scrim {
    display: block; position: fixed; inset: 0; z-index: 45;
    background: color-mix(in srgb, #0B111C 52%, transparent);
  }
  .railtoggle { display: none; }
  .drawertoggle, .top__mark { display: inline-flex; }
  .top { padding-left: 14px; padding-right: 14px; }
  .page { padding: 22px 16px 64px; }
  .searchbtn { min-width: 0; }
  .searchbtn span, .searchbtn kbd { display: none; }
  .top__role { display: none; }
  h1 { font-size: 25px; }

  /* Tiles stack two-up and keep their dividers. */
  .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tile { border-bottom: 1px solid var(--line); }
  .tiles > .tile:nth-last-child(-n+2) { border-bottom: 0; }
  .tile:nth-child(2n) { border-right: 0; }

  .facts > div, .kv > div { grid-template-columns: 1fr; gap: 2px; }

  .board { grid-auto-flow: row; grid-auto-columns: auto; }

  /* Only the last crumb has room, and it is the one that says where you are. */
  .crumbs > *:not(:last-child) { display: none; }
  .crumbs { font-size: 13px; }
  .crumbs span { color: var(--ink); }
}

@media (max-width: 620px) {
  .tile__value { font-size: 20px; }
  .tile { padding: 12px 16px 13px; }
  .page__head { align-items: flex-start; }

  /* Tables reflow to stacked records. Each cell carries its own label, so a
     row reads as a small card rather than as a horizontal scroll. */
  table.data--stack thead { display: none; }
  table.data--stack, table.data--stack tbody, table.data--stack tr, table.data--stack td {
    display: block; width: 100%;
  }
  table.data--stack tr {
    border-bottom: 1px solid var(--line); padding: 10px 0;
  }
  table.data--stack tr:last-child { border-bottom: 0; }
  table.data--stack td {
    border: 0; padding: 3px 18px; display: flex; gap: 12px; align-items: baseline;
    text-align: left;
  }
  table.data--stack td::before {
    content: attr(data-label);
    font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em;
    color: var(--ink-3); font-weight: 600; min-width: 96px; flex: none;
  }
  table.data--stack td.num { text-align: left; justify-content: flex-start; }
  table.data--stack td:empty { display: none; }
}

/* Two figures still fit on a 390-wide phone; one per screen turns a summary
   into a scroll. Only go single-column when two genuinely will not fit. */
@media (max-width: 359px) {
  .tiles { grid-template-columns: 1fr; }
  .tile { border-right: 0; border-bottom: 1px solid var(--line); }
  .tiles > .tile:nth-last-child(-n+2) { border-bottom: 1px solid var(--line); }
  .tiles > .tile:last-child { border-bottom: 0; }
}

@media print {
  .rail, .top, .page__act, .btnrow, .chips, .palette, .scrim { display: none !important; }
  body { background: #fff; }
  body.has-side { display: block; }
  .card { box-shadow: none; border-color: #ccc; break-inside: avoid; }
  .tablewrap--tall table.data th { position: static; }
}

/* ─────────────────────────────────────────────── 3.0 · documents on screen

   A certificate, a statement and a payout are documents before they are
   screens: somebody prints them and sends them to a shareholder or a
   solicitor. They get a paper ground, a measure that reads, and a print
   stylesheet that drops everything around them. */

.paper {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 34px 38px;
  max-width: 46rem;
  margin: 0 0 18px;
}
.paper__head { text-align: center; margin-bottom: 22px; }
.paper__org {
  font-size: 11.5px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-2); margin-bottom: 8px;
}
.paper__head h2 {
  font-family: var(--display); font-weight: 600; font-size: 25px; letter-spacing: -.01em;
}
.paper__sub { color: var(--ink-2); font-size: 13px; margin-top: 4px; }
.paper__head::after {
  content: ""; display: block; height: 3px; width: 76px; margin: 16px auto 0;
  background: var(--accent); border-radius: 2px;
}
.paper__legend {
  margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line);
  font-size: 12px; line-height: 1.6; color: var(--ink-2); max-width: 40rem;
}
.paper__sigs {
  display: grid; grid-template-columns: 1fr 1fr; gap: 40px; margin: 40px 0 8px;
}
.paper__sigs .rule {
  display: block; border-bottom: 1px solid var(--control); height: 26px; margin-bottom: 6px;
}
.paper__sigs small { font-size: 11px; color: var(--ink-3); }
.paper__foot {
  margin-top: 18px; font-size: 11.5px; color: var(--ink-3); text-align: center;
}
/* A rendered template is monospaced because its alignment is part of it. */
.paper--plain {
  font: 12.5px/1.65 var(--mono); white-space: pre-wrap; padding: 26px 28px;
}

/* A block of source or a payload. Scrolls in its own box; the page never does. */
.code {
  font: 12px/1.6 var(--mono); background: var(--sunk); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 14px 16px; overflow-x: auto; max-height: 26rem;
  overflow-y: auto; white-space: pre;
}
.note {
  font: 12.5px/1.6 var(--sans); background: var(--sunk); border-left: 3px solid var(--line-2);
  border-radius: 0 var(--r-sm) var(--r-sm) 0; padding: 10px 14px; white-space: pre-wrap;
}

/* A heading inside a card, where one card carries several tables. */
.subhead {
  font-size: 12px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  color: var(--ink-2); margin: 20px 0 8px;
}
.card > .subhead:first-child, .card__body > .subhead:first-child,
.card__body > form > .subhead:first-child { margin-top: 0; }

/* The broker's condition list: not a data table, just what is outstanding. */
.conds { list-style: none; display: flex; flex-direction: column; gap: 10px; }
.conds li {
  padding: 10px 14px; background: var(--sunk); border-radius: var(--r-sm);
  border-left: 3px solid var(--warn); font-size: 13px;
}

/* Two forms side by side in a table cell — accept and reject, say. */
form.inline { display: inline-flex; gap: 6px; align-items: center; vertical-align: middle; }
form.inline + form.inline { margin-left: 6px; }
form.inline input { max-width: 15rem; }

.actions { display: flex; gap: 10px; flex-wrap: wrap; margin: 18px 0; }

@media print {
  .rail, .top, .scrim, .palette, .actions, .flash, .crumbs, .page__act { display: none !important; }
  .main, .page { margin: 0; padding: 0; }
  .paper { border: 0; padding: 0; max-width: none; }
  .card { border: 0; box-shadow: none; padding: 0; }
  a[href]::after { content: ""; }
}

/* A group folding is a small movement and it reads better with one, but not
   for anybody who has asked the system for less of it. */
@media (prefers-reduced-motion: reduce) {
  .rail__grouphead svg { transition: none; }
}

/* ── The underwriting file ─────────────────────────────────────────────────
   Eight sections read down one page, because underwriting is comparing section
   four against section two and a screen that shows one at a time makes that a
   memory exercise. */

/* A numbered section heading. The numbers are the order somebody underwrites
   in — who is borrowing, what they earn, what they owe, what secures it — so
   they carry information rather than decorating the page. */
.secthead {
  display: flex; align-items: center; gap: 11px;
  margin: 30px 0 12px; font-family: var(--display);
  font-size: 15px; font-weight: 600; letter-spacing: -.01em; color: var(--ink);
}
.secthead:first-child { margin-top: 4px; }
.secthead::after {
  content: ''; flex: 1; height: 1px; background: var(--line);
}
.secthead .secthead__n {
  flex: none; display: grid; place-items: center; width: 22px; height: 22px;
  border-radius: 50%; background: var(--accent-soft); color: var(--accent-ink);
  border: 1px solid var(--accent-line);
  font-family: var(--sans); font-size: 11px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* A section that opens. The heading is the button — a 20-pixel chevron is a
   needlessly small target for something the reader presses on every file —
   and the chevron is there because it is what says the section opens at all.
   The rule that used to be drawn by ::after is drawn by the button's own
   border-bottom instead, so the whole strip is one clickable row. */
.fold { margin: 26px 0 0; }
.fold:first-child { margin-top: 4px; }
.secthead:has(.secthead__btn) { margin: 0 0 0; gap: 0; }
.secthead:has(.secthead__btn)::after { content: none; }
.secthead__btn {
  flex: 1; display: flex; align-items: center; gap: 11px; min-width: 0;
  background: none; border: 0; border-bottom: 1px solid var(--line);
  padding: 9px 2px; margin: 0; font: inherit; color: inherit;
  text-align: left; cursor: pointer; border-radius: 6px 6px 0 0;
}
.secthead__btn:hover { background: var(--tint); }
.secthead__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.secthead__t { flex: none; }
/* The one line of the section worth reading while it is shut. Truncated
   rather than wrapped: a summary that pushes the heading onto two lines
   defeats the point of closing the section. */
.secthead__sum {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--sans); font-size: 12px; font-weight: 400; color: var(--ink-3);
  padding-left: 6px;
}
.secthead__chev {
  flex: none; width: 9px; height: 9px; margin-right: 6px;
  border-right: 1.8px solid var(--ink-3); border-bottom: 1.8px solid var(--ink-3);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .14s ease;
}
.fold.is-open .secthead__chev { transform: rotate(-135deg) translate(-2px, -2px); }
.secthead__act { flex: none; display: flex; gap: 6px; padding-left: 10px; }
.fold__body { padding-top: 12px; }
/* A closed section still shows the rule under its heading, so eight of them
   read as a list of what is on the file rather than as eight loose lines. */
.fold:not(.is-open) .secthead__btn { border-bottom-color: var(--line); }

/* The application tab, tightened.
   Every figure on a file is read by scanning down it for the one that is
   wrong, and the default rhythm — set for pages that are read a paragraph at
   a time — put about a third as much on a screen as an underwriter wants.
   Scoped to the fold rather than changed globally: a settings page with six
   fields on it is not improved by being squeezed. */
.fold .card { margin-bottom: 10px; }
.fold .card__head { padding: 10px 14px 8px; }
.fold .card__body { padding: 2px 14px 12px; }
.fold .card__foot { padding: 8px 14px; }
.fold .card__body > .tablewrap:only-child { margin: 0 -14px -12px; }
.fold .kv > div, .fold .facts > div { padding: 4px 0; gap: 10px; }
.fold .kv--two > div, .fold .facts--two > div { padding: 4px 0; }
.fold .kv--two, .fold .facts--two { column-gap: 28px; }
.fold .kv dt, .fold .facts dt { font-size: 12px; }
.fold .kv dd, .fold .facts dd { font-size: 12.5px; }
.fold .data th, .fold .data td { padding-top: 6px; padding-bottom: 6px; }
.fold .cardlede { margin: 0 0 8px; }
/* An input in a tightened row keeps the row's own height, so pressing Edit
   does not make the card twice as tall as the one being read. */
.fold .ed__i { padding: 2px 6px; font-size: 12.5px; }
.fold .ed { width: 100%; }

/* The confirmation that a save landed. It sits in the card's own header
   rather than at the top of the page, because that is where the person is
   looking — a banner four sections away is a banner nobody sees. */
.saved {
  font-family: var(--sans); font-size: 12px; font-weight: 500;
  color: var(--good-ink); background: var(--good-soft);
  border: 1px solid var(--good-line); border-radius: 999px; padding: 3px 10px;
  margin-right: 8px; white-space: nowrap;
}
.saved--bad {
  color: var(--bad-ink); background: var(--bad-soft); border-color: var(--bad-line);
  white-space: normal;
}

/* The intake form for one more row, folded away under the table it adds to. */
.addrow {
  margin: 10px -14px -12px; padding: 12px 14px 14px;
  background: var(--tint); border-top: 1px solid var(--line);
}
.addrow .field { margin-bottom: 0; }
.addrow .row { margin-bottom: 10px; }
.addrow .btn { margin-right: 6px; }

/* A value that can be corrected in place. The input takes the size of the
   text it replaces so the card does not jump when Edit is pressed. */
.ed { display: inline-block; max-width: 100%; }
.ed__v { display: inline; }
/* A small mask-drawn glyph inside a button. `currentColor` so it takes the
   button's own ink in both themes rather than being a second colour to keep
   in step. */
.ico { display: inline-block; }
.ed__i {
  width: 100%; min-width: 90px; box-sizing: border-box;
  padding: 4px 7px; border: 1px solid var(--line-2); border-radius: 6px;
  background-color: var(--paper); color: var(--ink); font: inherit; font-size: 13px;
}
/* A select keeps the chevron the rest of the app draws — the shorthand
   `background` above would wipe the image and leave the arrow drawn by the
   browser underneath the text. */
select.ed__i { padding-right: 28px; background-position: right 8px center; }
.ed__i:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); }
.card.is-editing { box-shadow: 0 0 0 1.5px var(--accent-line); }
.card.is-editing .card__head { background: var(--accent-soft); }
.ico--pencil {
  display: inline-block; width: 11px; height: 11px; vertical-align: -1px;
  background: currentColor;
  -webkit-mask: var(--pencil) center / contain no-repeat;
  mask: var(--pencil) center / contain no-repeat;
}
:root {
  --pencil: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M12.1 1.3a1.1 1.1 0 0 1 1.6 0l1 1a1.1 1.1 0 0 1 0 1.6l-8 8L3 13l1.1-3.7 8-8Z'/%3E%3C/svg%3E");
}

/* The choice of which numbers drive the ratios. A checkbox in the header of
   the two sections it chooses between: it reads as a property of the section
   because that is what the desk asked for, and it posts as one column because
   ratios computed from both at once are not ratios. */
.basis {
  display: inline-flex; align-items: center; gap: 8px;
  background: none; border: 1px solid var(--line); border-radius: 999px;
  padding: 5px 12px 5px 9px; font: inherit; font-size: 12px; color: var(--ink-2);
  cursor: pointer; text-align: left;
}
.basis:hover { border-color: var(--line-2); color: var(--ink); }
.basis__box {
  flex: none; width: 14px; height: 14px; border-radius: 4px;
  border: 1.5px solid var(--line-2); background: var(--surface);
}
.basis.is-on { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-ink); }
.basis.is-on .basis__box {
  border-color: var(--accent); background: var(--accent);
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.2 3.2L13 5'/%3E%3C/svg%3E");
  background-size: 12px; background-position: center; background-repeat: no-repeat;
}
.basis:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* GDS and TDS on a section, next to the numbers they were computed from. */
.ratioline {
  margin: 14px 0 0; padding: 10px 13px; border-radius: var(--r);
  background: var(--surface-2); border: 1px solid var(--line);
  font-size: 13px; color: var(--ink-2); font-variant-numeric: tabular-nums;
}
.ratioline.is-on { background: var(--accent-soft); border-color: var(--accent-line); }
.ratioline strong { color: var(--ink); font-weight: 600; }
.ratioline em { font-style: normal; color: var(--ink-3); font-size: 12px; }
.ratioline .ok { color: var(--good); font-weight: 600; }
.ratioline .over { color: var(--bad); font-weight: 600; }

/* ── The servicing desk ────────────────────────────────────────────────────
   Four screens over one table. The table is the desk's own; what is new here
   is the second line inside a cell, the days-to-maturity figure that has to
   read at a glance, and the dialog every action opens in. */

/* A second line under a cell's main value — an address under a borrower, a
   promise under an amount. Not a separate column: it is the same fact, and a
   column for it would be empty on most rows. */
.rowsub {
  display: block; font-size: 11.5px; color: var(--ink-3); line-height: 1.35;
  margin-top: 1px; overflow-wrap: anywhere;
}

/* Days to maturity, and the missed count. Both are read by scanning down a
   column, so they are tabular and the ones that matter carry their own ground
   rather than only a colour — a red number among black numbers is one contrast
   ratio away from invisible. */
.dtm {
  display: inline-block; min-width: 2.6em; padding: 1px 7px; border-radius: 999px;
  font-variant-numeric: tabular-nums; font-weight: 600; font-size: 12px;
}
.dtm--warn { background: var(--warn-soft); color: var(--warn-ink); }
.dtm--bad  { background: var(--bad-soft); color: var(--bad-ink); }

/* The servicing table runs wide. Its own cells stay on one line except the
   borrower, which carries the address underneath. */
.servicing td, .servicing th { white-space: nowrap; }
.servicing td:nth-child(2) { white-space: normal; min-width: 190px; }
/* The actions wrap rather than run off the side. Three of them at the labels
   the desk chose is wider than the cell on a laptop, and `nowrap` there pushed
   the last button past the edge of the card with no scrollbar to find it by. */
.servicing td.right {
  white-space: normal;
  display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; align-items: center;
}
/* A ghost button is borderless everywhere else, and rightly so — it sits beside
   a filled one and the contrast is the point. In a row of eight columns with
   three of them side by side there is no filled button to contrast with, and
   three borderless labels read as one run of text rather than as controls. */
.servicing td.right .btn.ghost {
  border-color: var(--line); background: var(--surface); color: var(--ink-2);
}
.servicing td.right .btn.ghost:hover { border-color: var(--line-2); color: var(--ink); }

/* A date is a date's width, wherever it appears on this desk. */
.servicing input[type=date], .data input[type=date] { max-width: 190px; }

/* A field that will be refused without an answer says so on the label, rather
   than only when the form comes back. */
.req {
  font-size: 10.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--warn-ink); background: var(--warn-soft); border-radius: var(--r-sm);
  padding: 1px 5px; margin-left: 6px; vertical-align: 1px;
}

/* The email box and its button, on one line. */
.emailrow { display: inline-flex; gap: 8px; align-items: center; }
.emailrow input { min-width: 240px; }

@media print {
  .noprint, .rail, .top, .chips, .tabs { display: none !important; }
  .page { padding: 0; }
  .card { border: 0; box-shadow: none; }
}

/* ── The action dialog ─────────────────────────────────────────────────────
   Native <dialog>. The trigger is a link to the same form on a page of its own,
   so nothing here is load-bearing: with the script blocked the link navigates
   and the action still works. */
.sheet {
  /* `margin: auto` is what centres a native dialog. Without it the panel pins
     to the top-left of the viewport, which is where the first cut put it. */
  margin: auto; padding: 0; border: 1px solid var(--line-2); border-radius: var(--r-lg);
  background: var(--surface); color: var(--ink); box-shadow: 0 24px 60px rgb(0 0 0 / 22%);
  width: min(680px, calc(100vw - 32px)); max-height: min(86vh, 900px);
}
.sheet::backdrop { background: rgb(11 17 28 / 46%); }
.sheet__form { display: flex; flex-direction: column; max-height: inherit; }
.sheet__head {
  display: grid; grid-template-columns: 1fr auto; align-items: start; gap: 4px 12px;
  padding: 16px 18px 12px; border-bottom: 1px solid var(--line);
}
.sheet__head h2 {
  margin: 0; font-family: var(--display); font-size: 17px; font-weight: 600;
  letter-spacing: -.01em;
}
/* Second column, explicitly. Auto-placement put the close button in the first
   cell and pushed the title across, so the dialog opened with an ✕ where its
   heading should be. */
.sheet__head .iconbtn { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
.sheet__file {
  grid-column: 1; margin: 0; font-size: 12px; color: var(--ink-3);
  font-family: var(--mono); font-variant-numeric: tabular-nums;
}
.sheet__file:empty { display: none; }
.sheet__body { padding: 16px 18px 4px; overflow: auto; }
.sheet__body .cardlede { margin-bottom: 16px; }
.sheet__foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 12px 18px 16px; border-top: 1px solid var(--line); background: var(--surface-2);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}
@media (max-width: 560px) {
  .sheet { width: calc(100vw - 16px); }
  .sheet__foot { flex-direction: column-reverse; }
  .sheet__foot .btn { width: 100%; justify-content: center; }
}

/* ── Deals ─────────────────────────────────────────────────────────────────
   Four patterns the rest of the desk did not already have. Everything else on
   these screens — the board, the deal card, the tiles, the tabs, the tables —
   is the shell's own, deliberately: a module with its own vocabulary is a
   module that stops looking like the same application after two releases. */

/* Choosing documents to ask for. Grouped, because twenty-eight in one list is
   a wall, and the grouping is the same one the catalogue defines. */
/* One box per group, wide enough that a document's name fits on one line —
   "Property tax bill Statement (NS)" wrapping to two turned a ten-item group
   into twenty lines and set the height of the whole block. A group of more
   than eight takes two cells and lays its own list out in two columns, so no
   box is twice the height of its neighbours, and `dense` lets the group after
   it fill the cell the wide one could not fit into.

   Flowed columns were tried first: a fieldset cannot be split across a column
   break, so the browser packs two short groups into one column and leaves the
   last column empty, which reads worse than a ragged bottom edge. */
.picksets {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
  gap: 14px; margin-bottom: 18px; grid-auto-flow: row dense;
  /* Without this the grid stretches every group to the height of the tallest,
     so four of the five boxes end in a hand's width of empty rule. */
  align-items: start;
}
.pickset {
  border: 1px solid var(--line); border-radius: var(--r); padding: 12px 14px 8px;
  background: var(--surface-2); min-width: 0;
}
.pickset--wide { grid-column: span 2; }
.pickset--wide .picks { columns: 2; column-gap: 18px; }
.pickset--wide .pick { break-inside: avoid; }
@media (max-width: 700px) {
  /* One cell wide is all there is, so spanning two is spanning off the page. */
  .pickset--wide { grid-column: auto; }
  .pickset--wide .picks { columns: 1; }
}
.pickset legend {
  padding: 0 6px; font-size: 11px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-3);
}
.pick {
  display: flex; align-items: flex-start; gap: 9px; padding: 6px 2px;
  font-size: 13px; line-height: 1.45; cursor: pointer; border-radius: var(--r-sm);
}
.pick:hover { color: var(--ink); }
.pick input { flex: 0 0 auto; margin: 2px 0 0; accent-color: var(--accent); }
.pick input:disabled + span { color: var(--ink-3); cursor: default; }
.pick em {
  font-style: normal; color: var(--ink-3); font-size: 11.5px;
  font-variant-numeric: tabular-nums;
}
.pick:has(input:disabled) { cursor: default; }
.pick:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

/* What a package contains: eight names, and nothing else to say about any of
   them. This was the condition list, which draws a full-width bar per item —
   eight bars each holding two words and most of a screen of nothing. Numbered
   because the documents are generated and filed in this order. */
.namelist {
  margin: 0 0 16px; padding: 0; list-style: none; counter-reset: doc;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 2px 24px;
}
.namelist li {
  counter-increment: doc; display: flex; align-items: baseline; gap: 10px;
  padding: 7px 0; font-size: 13px; border-bottom: 1px solid var(--line);
}
.namelist li::before {
  content: counter(doc, decimal-leading-zero);
  font-size: 11px; font-variant-numeric: tabular-nums; color: var(--ink-3);
  font-weight: 600; flex: none;
}

/* A card's own opening sentence. Not `.lede`, which is the page's and is set
   to a narrow reading measure — inside a card that measure leaves the sentence
   ending a third of the way across while the notice beneath it runs the full
   width, and the two read as belonging to different pages. */
.cardlede { margin: 0 0 14px; font-size: 13.5px; color: var(--ink-2); max-width: 78ch; }

/* An outbox message, shown exactly as it will be sent.
   The height is capped so a page of queued mail stays a page rather than a
   scroll of correspondence, and the cap needs a visible bottom: the first cut
   gave it none, so a clipped message ran straight into the attachment line
   under it and the two overlapped. */
.msg {
  white-space: pre-wrap; word-break: break-word; overflow: auto;
  margin: 0 0 4px; padding: 14px 16px; line-height: 1.65;
  overscroll-behavior: contain;
  /* A whole number of lines plus the padding. A cap in round `em` lands
     wherever it lands and slices the twenty-first line through the middle,
     which reads as a rendering fault rather than as more text below. */
  max-height: calc(20 * 1.65em + 28px);
}
.attached {
  margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
}

/* ── The fee schedule ──────────────────────────────────────────────────────
   A price list is read down the amount column, so the rows are tight, the
   boxes sit in the row rather than in a card of their own, and the figures are
   tabular. The desk's own table does the rest. */
.feetable td { padding-top: 5px; padding-bottom: 5px; vertical-align: middle; }
/* The switch sits on the name's line. `.pick` aligns to the top of a label
   that may wrap to three lines in a document chooser; in a table row of one
   line that puts the box a few pixels below the word it belongs to. */
.feetable .pick { padding: 0; font-size: 13px; align-items: center; }
.feetable .pick input { margin: 0; }
.feetable .amt { font-variant-numeric: tabular-nums; }
.feetable input, .feetable select { height: 32px; padding-top: 0; padding-bottom: 0; }
.feetable tbody tr:hover { background: var(--surface-2); }
.linkbtn.bad { color: var(--bad); }

/* Adding one: a name that needs room, and three narrow answers beside it. */
.row--addfee {
  grid-template-columns: minmax(0, 1fr) minmax(0, 140px) minmax(0, 170px) minmax(0, 130px);
}
@media (max-width: 760px) { .row--addfee { grid-template-columns: 1fr; } }

/* A strip carrying two or three figures rather than a full row of them.
   `auto-fit` fills the line, so two figures either stretch to four hundred
   pixels of white with a number in the corner or sit at their own width beside
   an empty cell that is still inside the border. Sizing the box to its
   contents is the honest answer: two figures, a box two figures wide. */
.tiles--few {
  grid-template-columns: none; grid-auto-flow: column;
  grid-auto-columns: minmax(148px, 190px);
  width: max-content; max-width: 100%;
}

/* The line a document request is asked on: a date is a date's width, and the
   note takes the rest. */
.row--askline { grid-template-columns: minmax(0, 190px) minmax(0, 1fr); }
@media (max-width: 640px) { .row--askline { grid-template-columns: 1fr; } }

/* Row actions in a table's last cell. Three verbs run together read as one
   word; the separators are drawn rather than typed so the markup stays a list
   of buttons. */
td.right .linkbtn + .inline::before,
td.right .inline + .inline::before {
  content: '·'; color: var(--line-2); margin: 0 7px 0 4px;
}
td.right .inline { display: inline; }


/* The lender lawyer form: four to a row, even widths, no ragged part-rows. */
.lawyerform .row--set { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) { .lawyerform .row--set { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .lawyerform .row--set { grid-template-columns: 1fr; } }

/* ── setting up a pre-authorised debit ───────────────────────────────── */

/* Two questions off two pieces of paper: the void cheque on the left, the
   mortgage on the right. Down one column the amount sat below the fold. */
.padform {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px 36px; align-items: start;
}
.padform__col { min-width: 0; }
.padform__col > .rule:first-child { margin-top: 0; }
.padform .row--set2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* The signature and the button sit under the schedule, not adrift under both
   columns — ticking the box is the last thing before the debit is created. */
.padform__sign {
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line);
}
.padform__sign .btnrow { margin-top: 12px; }
@media (max-width: 1000px) {
  .padform { grid-template-columns: 1fr; }
  .padform .row--set2 { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
}

/* ── a settings group in two columns ─────────────────────────────────── */

/* Four short sections read as one screen side by side and as three stacked.
   `align-items: start` so a two-field section does not stretch to match a
   four-field one and leave a hole under its last input. */
.setgrid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px 36px; align-items: start;
}
.setgrid__sec { min-width: 0; }
.setgrid .setsec { margin-top: 18px; }
.setgrid__sec:first-child .setsec, .setgrid__sec:nth-child(2) .setsec { margin-top: 4px; }
.row--set2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1000px) {
  .setgrid { grid-template-columns: 1fr; }
  .row--set2 { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
}

/* ── the deals board filter ──────────────────────────────────────────── */

/* One row: when on the left, who on the right. Both are in the address, so a
   filtered board is a link somebody can send. */
.dealfilter {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin: 0 0 14px;
}
.dealfilter__when, .dealfilter__who { display: flex; align-items: center; gap: 8px; }
.dealfilter__when select { min-width: 150px; }
.dealfilter__dates { display: inline-flex; gap: 6px; }
.dealfilter__who input { min-width: 260px; }
.dealfilter__said { margin: -8px 0 14px; }
@media (max-width: 720px) {
  .dealfilter { flex-direction: column; align-items: stretch; }
  .dealfilter__who input { min-width: 0; flex: 1; }
}

/* ── the second check, on the instruct tab ───────────────────────────── */

/* The verdict on top, the four verbs under it. Stacked rather than in a row
   because "Reject" carries a reason box, and a reason box in a table cell
   beside three buttons squeezes all four into nothing. */
.check2 { display: flex; flex-direction: column; gap: 8px; }
.check2__now { font-size: .82rem; }
.check2__do { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.check2__do .inline { display: inline-flex; gap: 6px; align-items: center; }
.check2__do .btn[disabled] { opacity: .45; cursor: default; }

/* Refusing is behind a disclosure. A reason box on every row makes seven
   documents four screens long, and refusal is not the common case. */
.refuse > summary {
  cursor: pointer; list-style: none; font-size: 12px; color: var(--bad);
  padding: 4px 11px; min-height: 28px; display: inline-flex; align-items: center;
  border: 1px solid transparent; border-radius: var(--r-sm);
}
.refuse > summary::-webkit-details-marker { display: none; }
.refuse > summary:hover { background: var(--sunk); border-color: var(--bad); }
.refuse[open] > summary { border-color: var(--bad); }
.refuse form { display: flex; gap: 6px; align-items: center; margin-top: 6px; flex-wrap: wrap; }
.refuse input { max-width: 260px; }

/* ── a recipient's documents, done as a set ──────────────────────────── */

/* The group buttons sit in the card's footer rather than its header, because
   they act on the rows above them and read as the end of that list. */
.groupdo { gap: 10px; align-items: center; flex-wrap: wrap; }
.groupdo .inline { display: inline-flex; }

/* ── the borrower's upload link, and the uploads it collects ─────────── */

/* The address sits on the same line as the button that makes it live, because
   the two are one thought: ask for documents, here is where they go. It is a
   real hyperlink rather than a read-only input — the thing anybody wants to do
   with it is open it and check it works. */
.askline__go { align-items: center; flex-wrap: wrap; gap: 12px; margin-top: 4px; }
.uploadlink {
  font-size: .82rem; word-break: break-all; min-width: 0;
  padding: 5px 9px; border: 1px solid var(--line-2); border-radius: 7px;
  background: var(--surface-2);
}
.uploadlink:hover { border-color: var(--accent); }

.btnrow--tight { gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.btnrow--tight input { max-width: 210px; }

/* The status verbs under a request. Separators are drawn, not typed. */
.linkrow { margin-top: 6px; }
.linkrow .inline { display: inline; }

/* ──────────────────────────────────────────────── conditions on a file */
/* One row per condition, one column, because a condition carries a file list,
   a reason and three decisions and none of that fits a table cell. The state
   is on the left edge as a stripe as well as in the pill: a column of thirty
   pills is read one at a time, a column of stripes is read at a glance. */
.condlist { display: flex; flex-direction: column; gap: 10px; }
.condrow {
  border: 1px solid var(--line); border-left: 3px solid var(--line-2);
  border-radius: var(--r); padding: 11px 14px; background: var(--surface);
}
.condrow--good { border-left-color: var(--good); }
.condrow--warn { border-left-color: var(--warn); }
.condrow--bad { border-left-color: var(--bad); }
.condrow--blue { border-left-color: var(--accent); }
.condrow--violet { border-left-color: var(--violet); }
.condrow__head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.condrow__head h4 { margin: 0; font-size: 13.5px; font-weight: 650; }
.condrow__head h4 em { font-style: normal; font-weight: 400; color: var(--ink-3); font-size: 11.5px; }
.condrow__open { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.condrow__open:hover { color: var(--accent); }
.condrow__meta { font-size: 11.5px; color: var(--ink-3); }
/* Pushed right so the three decisions sit in the same place on every row —
   a button that moves with the length of a document's name is a button that
   has to be looked for. */
.condrow__acts { margin-left: auto; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.condrow__acts .inline { display: inline-flex; }
.condrow__why {
  margin: 7px 0 0; font-size: 12.5px; color: var(--bad-ink);
  background: var(--bad-soft); border: 1px solid var(--bad-line);
  border-radius: var(--r-sm); padding: 6px 9px;
}
.condrow--good .condrow__why, .condrow--violet .condrow__why {
  color: var(--ink-2); background: var(--surface-2); border-color: var(--line);
}
.condrow__none { margin: 6px 0 0; font-size: 12px; color: var(--ink-3); }
.condfiles { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 4px; }
.condfile { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12.5px; }

/* How much of the file is answered. Green only at 100 — a bar that is green
   at ninety is a bar nobody looks at. */
/* Reject is red where it matters — in the dialog, on the button that actually
   sends the condition back. On the row it is one of three and a column of red
   is a column nobody reads. */
.btn.ghost.bad { color: var(--bad); }
.btn.ghost.bad:hover { border-color: var(--bad); background: var(--bad-soft); }

.compbar { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; font-size: 12.5px; }
.compbar__track {
  flex: 1; height: 7px; border-radius: 4px; background: var(--sunk); overflow: hidden;
}
.compbar__track span { display: block; height: 100%; background: var(--accent); border-radius: 4px; }
.compbar strong { font-variant-numeric: tabular-nums; min-width: 3.2em; text-align: right; }
.compbar.is-clear .compbar__track span { background: var(--good); }
.compbar.is-clear strong { color: var(--good); }

@media (max-width: 760px) {
  .condrow__acts { margin-left: 0; width: 100%; }
}

/* ─────────────────────────────────────────────────── the template editor */

/* Two columns: the page being written, and the fields that go on it. The
   field list is the whole reason this is not a textarea — somebody writing a
   commitment letter should not have to remember whether it is {{deal.ref}} or
   {{deal.reference}}. */
.compose {
  display: grid;
  gap: 18px;
  grid-template-columns: minmax(0, 1fr) 280px;
  align-items: start;
}
@media (max-width: 1000px) { .compose { grid-template-columns: minmax(0, 1fr); } }

.editor { border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); }

.editor__bar {
  display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
  padding: 8px; border-bottom: 1px solid var(--line);
  background: var(--sunk); border-radius: var(--r) var(--r) 0 0;
  position: sticky; top: 0; z-index: 2;
}
.editor__bar button {
  font: inherit; font-size: 12px; line-height: 1;
  min-height: 28px; padding: 6px 9px;
  border: 1px solid transparent; border-radius: var(--r-sm);
  background: transparent; color: var(--ink-2); cursor: pointer;
}
.editor__bar button:hover { background: var(--surface); color: var(--ink); border-color: var(--line); }
.editor__bar button b, .editor__bar button i { font-size: 13px; }
.editor__sep { width: 1px; align-self: stretch; margin: 2px 4px; background: var(--line); }

.editor__canvas {
  min-height: 420px; padding: 26px 30px;
  font-family: var(--display);
  font-size: 15px; line-height: 1.62; color: var(--ink);
  overflow-wrap: break-word;
}
.editor__canvas:focus { outline: 2px solid var(--accent); outline-offset: -2px; }
.editor__canvas > :first-child { margin-top: 0; }
.editor__canvas > :last-child { margin-bottom: 0; }
.editor__canvas p { margin: 0 0 0.85em; }
.editor__canvas h2, .editor__canvas h3, .editor__canvas h4 {
  font-family: var(--sans);
  margin: 1.4em 0 0.5em; line-height: 1.25;
}
.editor__canvas h3 { font-size: 15px; letter-spacing: 0.01em; }
.editor__canvas ul, .editor__canvas ol { margin: 0 0 0.85em; padding-left: 1.4em; }
.editor__canvas li { margin: 0.2em 0; }
.editor__canvas table { border-collapse: collapse; width: 100%; margin: 0 0 1em; font-size: 14px; }
.editor__canvas td, .editor__canvas th {
  border-bottom: 1px solid var(--line); padding: 6px 10px; text-align: left; vertical-align: top;
}
.editor__canvas td:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.editor__canvas hr { border: 0; border-top: 1px solid var(--line); margin: 1.4em 0; }

/* The code view. Same box, same padding as the canvas, so switching between
   them does not move the page under the person doing it. */
.editor__code {
  display: block; width: 100%; min-height: 320px; margin: 0; padding: 18px 20px;
  border: 0; border-radius: 0 0 var(--r) var(--r); background: var(--surface-2); color: var(--ink);
  font-family: var(--mono); font-size: 12.5px; line-height: 1.65;
  resize: vertical; white-space: pre; overflow-wrap: normal; tab-size: 2;
}
.editor__code:focus { outline: 2px solid var(--accent); outline-offset: -2px; }
.editor__note {
  margin: 0; padding: 10px 20px 14px; border-top: 1px solid var(--line);
  color: var(--ink-2); font-size: 12.5px; line-height: 1.5;
}

/* A merge field, wherever it appears: in the canvas, in a preview, in the
   list. It reads as a slot rather than as words somebody meant to type. */
.tokenlist { display: flex; flex-direction: column; gap: 2px; }
.fields {
  border: 1px solid var(--line); border-radius: var(--r); background: var(--surface);
  position: sticky; top: 12px; max-height: calc(100vh - 40px);
  display: flex; flex-direction: column; overflow: hidden;
}
.fields__head { padding: 10px; border-bottom: 1px solid var(--line); background: var(--sunk); }
.fields__head input { width: 100%; }
.fields__scroll { overflow-y: auto; padding: 6px; }
.fields__group { margin-bottom: 10px; }
.fields__group > p {
  margin: 6px 6px 4px; font-size: 10px; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--ink-3); font-weight: 600;
}
.fields button {
  display: block; width: 100%; text-align: left; font: inherit; font-size: 12px;
  padding: 5px 7px; border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--ink); cursor: pointer;
}
.fields button:hover { background: var(--accent-soft); color: var(--accent-ink); }
.fields button span { display: block; font-size: 10.5px; color: var(--ink-2); }
.fields button:hover span { color: var(--accent-ink); }
.fields__foot { padding: 8px 10px; border-top: 1px solid var(--line); font-size: 11px; color: var(--ink-2); }

/* The preview: the same letter with the sample behind it. Fixed width so it
   reads at the measure a printed page reads at, not the width of the screen. */
.proof {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  padding: 34px 40px; max-width: 46rem;
  font-family: var(--display); font-size: 15px; line-height: 1.62;
}
.proof > :first-child { margin-top: 0; }
/* A label/value table shrinks to its content.
   Stretched to the full width with the value right-aligned, "To" and the
   broker's name ended up a hand's width apart with nothing in between, and a
   long label ran under its own value. The label column is as wide as the
   longest label and the value starts one gutter after it — which is what the
   PDF does, so the preview and the document agree. */
.proof table { border-collapse: collapse; width: auto; max-width: 100%;
  margin: 0 0 1.1em; font-size: 14px; }
.proof td, .proof th {
  border-bottom: 1px solid var(--line); padding: 5px 0; vertical-align: top;
  text-align: left;
}
.proof td + td, .proof th + th { padding-left: 22px; }
.proof tr > td:first-child { color: var(--ink-2); }
.proof tr > td:last-child { font-weight: 600; font-variant-numeric: tabular-nums; }

/* A grid is a form, not a table of figures: ruled cells, a banded head and
   room to write in. The same thing the PDF draws for `<table class="grid">`. */
.proof table.grid { width: 100%; }
.proof table.grid th, .proof table.grid td {
  border: 1px solid var(--line-2); padding: 7px 9px; height: 24px;
}
.proof table.grid th { background: var(--surface-2); font-weight: 600; color: var(--ink); }
.proof table.grid tr > td { color: inherit; font-weight: 400; }
.proof h3 {
  font-family: var(--sans);
  font-size: 15px; margin: 1.4em 0 0.5em;
}
.proof ol, .proof ul { padding-left: 1.4em; }

/* ───────────────────────────────────────────── the underwriter's file page */

/* The stage buttons. Each one is the colour of the stage it moves to, so the
   row reads as a map of the pipeline rather than as five identical buttons
   whose labels have to be read one at a time. */
.stagerow {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin: 0 0 14px;
}
.stagebtn {
  font: inherit; font-size: 12.5px; font-weight: 600; line-height: 1;
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 34px; padding: 9px 14px; cursor: pointer;
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink);
}
.stagebtn:hover { border-color: var(--ink-2); }
.stagebtn::before {
  content: ''; width: 9px; height: 9px; border-radius: 50%;
  background: currentColor; opacity: 0.9;
}
.stagebtn--blue   { color: var(--accent-ink);  background: var(--accent-soft); border-color: var(--accent-line); }
.stagebtn--warn   { color: var(--warn-ink);    background: var(--warn-soft);   border-color: var(--warn-line); }
.stagebtn--violet { color: var(--violet-ink);  background: var(--violet-soft); border-color: var(--violet-line); }
.stagebtn--good   { color: var(--good-ink);    background: var(--good-soft);   border-color: var(--good-line); }
.stagebtn--bad    { color: var(--bad-ink);     background: var(--bad-soft);    border-color: var(--bad-line); }
.stagebtn--ghost  { color: var(--ink-2); background: transparent; border-style: dashed; }
.stagerow form { margin: 0; }
/* Forward and back are different kinds of action, and the row reads as one
   list of options without something between them. */
.stagerow__sep {
  width: 1px; align-self: stretch; min-height: 24px; margin: 0 4px;
  background: var(--line);
}

/* Two columns on the offer: the terms, and the money. They are read together —
   a rate means nothing without the fees beside it — so they sit side by side
   and stack only when there is genuinely no room. */
.offer2 { display: grid; gap: 20px; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
@media (max-width: 1080px) { .offer2 { grid-template-columns: minmax(0, 1fr); } }

/* A fee, as a line in a ledger: name, amount, and what share of the mortgage
   it is. The percentage is the point — $9,000 means nothing until you know it
   is 2% of the advance or 9% of it. */
.feeledger { display: flex; flex-direction: column; gap: 2px; }
.feeline {
  display: grid; gap: 10px; align-items: center;
  grid-template-columns: minmax(0, 1fr) 130px 62px 28px;
  padding: 5px 0; border-bottom: 1px solid var(--line);
}
.feeline:last-of-type { border-bottom: 0; }
.feeline label { margin: 0; font-size: 12.5px; color: var(--ink); font-weight: 500; }
.feeline label small { display: block; font-weight: 400; color: var(--ink-2); font-size: 11px; }
.feeline input { text-align: right; font-variant-numeric: tabular-nums; }
.feeline__pct {
  font-size: 11.5px; color: var(--ink-2); text-align: right;
  font-variant-numeric: tabular-nums;
}
.feeline__x { text-align: right; }
@media (max-width: 560px) {
  .feeline { grid-template-columns: minmax(0, 1fr) 110px; }
  .feeline__pct, .feeline__x { grid-column: 2; text-align: right; }
}

/* What it all comes to, under the ledger. The cost of borrowing is the line
   that decides whether the offer is defensible, so it is the one that carries
   a colour. */
.tally { margin-top: 14px; border-top: 2px solid var(--line-2); padding-top: 12px; }
.tally__row {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 4px 0; font-size: 13px;
}
.tally__row span:last-child { font-variant-numeric: tabular-nums; font-weight: 500; }
.tally__row--lead { font-size: 15px; font-weight: 600; padding-top: 10px; }
.tally__row--lead span:last-child { font-size: 17px; }

/* The correspondence preview. A dialog rather than a new tab, because the
   point is to glance at what was sent without losing the file. */
.viewer__bar {
  display: flex; gap: 8px; align-items: center; justify-content: space-between;
  padding: 10px 14px; border-bottom: 1px solid var(--line); background: var(--sunk);
}
.viewer__zoom { display: flex; gap: 4px; align-items: center; }
.viewer__body {
  overflow: auto; max-height: 70vh; padding: 24px; background: var(--sunk);
}
.hint.bad { color: var(--bad); }

.viewer__sheet {
  background: #fff; color: #111; margin: 0 auto; padding: 40px 46px; max-width: 46rem;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.14);
  transform-origin: top center;
  font-family: var(--display); font-size: 15px; line-height: 1.62;
  white-space: pre-wrap;
}

/* ─────────────────────────────────────────────────────── the settings section */

/* Where you are and the way out, one line, same place on every page. */
.subhead-bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 2px 0 16px; font-size: 12.5px; color: var(--ink-2);
}
.subhead-bar__spacer { flex: 1 1 auto; }
.subhead-bar strong { color: var(--ink); font-weight: 600; }
.subhead-bar__sep { color: var(--line-2); }
.backlink {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px 4px 8px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface);
  color: var(--ink-2); text-decoration: none; font-weight: 500;
}
.backlink:hover { color: var(--ink); border-color: var(--ink-2); text-decoration: none; }
.backlink span { font-size: 14px; line-height: 1; }

/* Tighter inside the section. A settings page is a dense reference screen, not
   an article: the same card vocabulary, with the air taken out of it so more
   than one thing fits above the fold. */
.settings .card { margin-bottom: 14px; }
.settings .card__head { padding: 11px 16px; }
.settings .card__body { padding: 14px 16px 16px; }
.settings .card__foot { padding: 9px 16px; font-size: 11.5px; }
.settings .cardlede { margin: 0 0 12px; font-size: 12.5px; }
.settings .row { gap: 12px 14px; }
.settings .field { margin-bottom: 0; }
.settings .field label { font-size: 12px; margin-bottom: 3px; }
.settings .hint { font-size: 11.5px; margin-top: 3px; }
.settings .tiles { margin-bottom: 14px; }
.settings .tile { padding: 12px 14px; }
.settings .tile__value { font-size: 20px; }
.settings .data td, .settings .data th { padding-top: 7px; padding-bottom: 7px; }
.settings .subhead {
  margin: 18px 0 10px; font-size: 10.5px; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-3); font-weight: 600;
}
.settings .subhead:first-child { margin-top: 0; }
.settings .tabs { margin-bottom: 14px; }

/* Two settings cards side by side where they are read together. */
.pair { display: grid; gap: 14px; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
@media (max-width: 1000px) { .pair { grid-template-columns: minmax(0, 1fr); } }
.pair > * { margin-bottom: 0 !important; }

/* One field and its button on a line, where the figure it corrects is read.
   A form that looks like a form is too much furniture for changing one date. */
.inlineset {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: -2px 0 14px; font-size: 12.5px;
}
.inlineset label { color: var(--ink-2); font-weight: 500; margin: 0; }
.inlineset input { max-width: 165px; }
.inlineset .hint { margin: 0; }

/* ─────────────────────────────────────────────────────────────── symmetry */

/* Tiles were `repeat(auto-fit, minmax(…))`, which fills the row and leaves the
   last one stretched to whatever is left — five tiles came out four wide and
   one enormous. Equal columns instead: whatever the count, every tile is the
   same width and the row is a row rather than a ragged shelf. */
.tiles { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); }
.tiles > * { min-width: 0; }
@media (max-width: 1180px) { .tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 780px)  { .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 440px)  { .tiles { grid-template-columns: minmax(0, 1fr); } }

/* Cards side by side line up at the top and share a baseline grid, so two
   forms of different lengths do not leave one card floating half a screen
   above the other's footer. */
.pair { align-items: stretch; }
.pair > .card { display: flex; flex-direction: column; height: 100%; }
.pair > .card > .card__body { flex: 1 1 auto; }

/* A field row that does not fill its last line leaves a hole on the right.
   Inside a section, fields sit on an even grid of equal columns and a field
   that needs more says so, rather than every row being measured by hand. */
.settings .row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  align-items: start;
}
.settings .row .field--wide { grid-column: span 2; }
.settings .row .field--full { grid-column: 1 / -1; }
@media (max-width: 700px) {
  .settings .row { grid-template-columns: minmax(0, 1fr); }
  .settings .row .field--wide { grid-column: span 1; }
}

/* Two facts lists beside each other keep the same label column, so the eye
   runs down one gutter rather than two that nearly line up. */
.settings .kv--two, .settings .facts--two { column-gap: 32px; }

/* Three cards read as a set: equal columns, so the third does not sit alone
   under a row of two. */
.trio { display: grid; gap: 14px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.trio > * { margin-bottom: 0 !important; }
@media (max-width: 1080px) { .trio { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px)  { .trio { grid-template-columns: minmax(0, 1fr); } }

/* ─────────────────────────────────────── a long form, one section at a time */
/* A hundred and thirty-one questions on one page is a wall. Taken a section at
   a time it is a conversation — and the bar is the thing a long form never
   tells you: how much of it is left. */

.wizard {
  position: sticky; top: 0; z-index: 20;
  padding: 12px 14px 14px; margin-bottom: 14px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); box-shadow: var(--lift);
}
.wizard__head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin-bottom: 8px;
}
.wizard__pct { font-size: 15px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.wizard__note { font-size: 12.5px; color: var(--ink-3); }

.step {
  border: 1px solid var(--line); border-radius: var(--r); background: var(--surface);
  margin-bottom: 12px;
}
.step > summary {
  display: flex; align-items: center; gap: 12px; padding: 14px 18px;
  cursor: pointer; list-style: none;
  font-size: 15px; font-weight: 600; color: var(--ink);
}
.step > summary::-webkit-details-marker { display: none; }
.step > summary:hover { background: var(--sunk); border-radius: var(--r); }
.step[open] > summary { border-bottom: 1px solid var(--line); border-radius: var(--r) var(--r) 0 0; }
.step__title { flex: 1 1 auto; min-width: 0; }
.step__n {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 999px;
  background: var(--sunk); color: var(--ink-3);
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.step__state { flex: none; font-size: 12px; font-weight: 500; color: var(--ink-3); }
.step__body { padding: 16px 18px 18px; }

/* Done, and the next one to do. Colour carries it before the words are read. */
.step.is-done > summary .step__n { background: var(--good-soft); color: var(--good-ink); }
.step.is-done > summary .step__state { color: var(--good-ink); }
.step.is-current { border-color: var(--accent-line); box-shadow: var(--lift); }
.step.is-current > summary .step__n { background: var(--accent); color: var(--on-accent); }

/* The fee picker that sits under each of the two fee lists. One row: what it
   is, what it costs, where it goes. It was a card of its own with four
   labelled boxes, which is a form for something that is one choice. */
.feeadd {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--line);
}
.feeadd select { min-width: 200px; flex: 1 1 200px; }
.feeadd .unit { max-width: 130px; }
.feeadd select[name="deducted"] { min-width: 0; flex: 0 0 auto; width: auto; }

/* The percentage beside a fee is an input now, not a caption. It is narrow
   because it holds at most "12.500", and right-aligned so the column of them
   reads as a column. */
.unit--pct { display: inline-flex; align-items: center; width: 78px; }
.unit--pct input { text-align: right; padding-right: 20px; }
.unit--pct .unit__tag {
  position: absolute; right: 7px; pointer-events: none; color: var(--ink-3); font-size: 12px;
}
.feeline__pct { position: relative; display: flex; justify-content: flex-end; }
.feeline__pct .unit { position: relative; }

/* The one number on the instruct page that moves money. On a page of figures
   the one being wired should not have to be picked out. */
.data td.netrow {
  background: var(--good-soft); border-top: 2px solid var(--good-line);
  border-bottom: 2px solid var(--good-line); color: var(--good-ink);
}
.data td.indent { padding-left: 22px; }

/* The fund bar: what is about to happen on the left, the button that does it
   on the right. It is the one act this tab exists for, so it gets a row of
   its own rather than a place in a list of six. */
.fundbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
}
.fundbar .lede { margin: 0 0 2px; }
.fundbar .hint { margin: 0; max-width: 62ch; }
.fundbar form { flex: none; }

/* ------------------------------------------------------------- drop zones */
/* One per condition on the broker and borrower portals. The file input stays
   inside the label so the thing works with no script at all — the drag and
   drop is laid over a working control, not substituted for one. */
.drop-form { flex: none; display: flex; flex-direction: column; gap: 8px; align-items: flex-end; }
.drop {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-width: 260px; padding: 12px 14px; cursor: pointer;
  border: 1px dashed var(--line-2, var(--line)); border-radius: 10px;
  background: var(--surface-2); color: var(--ink-3); font-size: 12.5px;
  transition: border-color .12s, background .12s, color .12s;
}
.drop:hover { border-color: var(--ink-3); color: var(--ink-2); }
.drop input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; }
.drop:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.drop.is-over { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-ink); }
.drop.has-file { border-style: solid; border-color: var(--good-line); background: var(--good-soft);
  color: var(--good-ink); }
.drop__text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 34ch; }
@media (max-width: 720px) {
  .drop-form { width: 100%; align-items: stretch; }
  .drop { min-width: 0; }
}
.portalsearch { display: flex; align-items: center; gap: 8px; margin: 0; flex: none; }
.portalsearch input[type="search"] { width: 240px; }
@media (max-width: 720px) {
  .portalsearch { width: 100%; }
  .portalsearch input[type="search"] { width: auto; flex: 1; }
}

/* --------------------------------------------- the stage's own action strip */
/* Four acts in the order they happen. A step that is not available yet stays
   on the strip, greyed, with the reason under it — hiding it would mean
   somebody closing their first file does not know the step exists. */
.acts { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; }
.act { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; margin: 0; }
.act .btn { width: 100%; justify-content: center; text-align: center; }
.act .hint { margin: 0; }
.act .btn[disabled] { opacity: .45; cursor: not-allowed; }

/* Select all sits above the rule, not in the list: it is a control over the
   group rather than one of the things being chosen. */
.pick--all {
  font-weight: 600; color: var(--ink-2);
  padding-bottom: 8px; margin-bottom: 6px; border-bottom: 1px solid var(--line);
}
.pick--all input:indeterminate { accent-color: var(--ink-3); }

/* A file that arrived. The tick is the whole message — "You have uploaded X"
   with a green mark beside it says received, read and nothing more to do far
   faster than a sentence does. */
.tick {
  color: var(--good); font-weight: 700; margin-right: 6px;
  font-size: 13px; line-height: 1;
}
.sentlist { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 4px; }
.sentlist li {
  display: flex; align-items: baseline; gap: 2px;
  font-size: 12.5px; color: var(--ink-2);
}
.drop.is-sending { border-style: solid; border-color: var(--accent); background: var(--accent-soft);
  color: var(--accent-ink); cursor: progress; }

/* The tick column on a table you act on in bulk. */
.tickcell { width: 40px; }
.tickcell input, th input[type="checkbox"] { accent-color: var(--accent); margin: 0; }

/* ─────────────────────────────────────────── dragging a file across the board */
/* The card being carried, the columns that will take it, and the ones that
   will not. A column that will refuse a drop says so while the card is still
   in the air — bouncing it back with a flash after the fact teaches nobody
   where the file may actually go. */
.deal[draggable="true"] { cursor: grab; }
.deal.is-dragging { opacity: .4; cursor: grabbing; }
.board__col { transition: background .12s, box-shadow .12s, opacity .12s; }
.board__col.is-open {
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-line);
  border-radius: var(--r);
}
.board__col.is-over { box-shadow: inset 0 0 0 2px var(--accent); }
.board__col.is-closed { opacity: .45; }
@media (prefers-reduced-motion: reduce) { .board__col { transition: none; } }

/* Find a file on the list you are standing on. Sits under the tiles and above
   the list, because it filters the list and not the book. */
.findbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 14px; }
.findbar input[type="search"] { width: 300px; max-width: 100%; }
@media (max-width: 720px) { .findbar input[type="search"] { width: auto; flex: 1; } }

/* The fee name, editable in place. The box only looks like a box on hover and
   focus: a column of fifteen framed inputs reads as a form to fill in, and
   this is a list to read with the occasional correction. */
.feename { display: flex; align-items: center; gap: 10px; }
.feename input[type="checkbox"] { flex: none; accent-color: var(--accent); }
.feename__in {
  flex: 1; min-width: 0; border-color: transparent; background: none;
  font: inherit; font-size: 13px; padding: 4px 6px;
}
.feename__in:hover { border-color: var(--control); background: var(--surface); }
.feename__in:focus { border-color: var(--accent); background: var(--surface); }

/* ─────────────────────────────────────────────── the fund's own marks */
/* Four slots, each showing what is actually being used right now — the point
   of the card is "is this the right logo", and a card that showed only file
   names could not answer it. */
.brandgrid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 16px;
  align-items: start;
}
.brandslot { display: flex; flex-direction: column; gap: 6px; }
.brandslot h4 { margin: 4px 0 0; font-size: 13px; font-weight: 650; }
.brandslot .hint { margin: 0; }
.brandslot__art {
  display: grid; place-items: center; min-height: 72px; padding: 12px;
  border: 1px solid var(--line); border-radius: var(--r); background: #FFFFFF;
}
/* The dark wordmark is drawn for a dark ground, so it is shown on one. */
.brandslot__art--dark { background: #10151F; }
.brandslot__art img { max-width: 100%; max-height: 48px; width: auto; height: auto; }
.brandslot .drop-form { align-items: stretch; width: 100%; margin-top: 4px; }
.brandslot .drop { min-width: 0; padding: 9px 10px; }

/* ───────────────────────────────────────────── the conditions of advance */
/* A tick, the sentence, and a way to take it off. The sentence is editable in
   place because it is printed on the commitment as typed, and the wording is
   the thing an underwriter actually adjusts. */
.condlines { list-style: none; margin: 0 0 4px; padding: 0; display: grid; gap: 4px; }
.cond { display: flex; align-items: center; gap: 10px; }
.cond__tick { display: flex; flex: none; }
.cond__tick input { margin: 0; accent-color: var(--accent); }
.cond__text {
  flex: 1; min-width: 0; font-size: 13px; padding: 5px 8px;
  border-color: transparent; background: none;
}
.cond__text:hover { border-color: var(--control); background: var(--surface); }
.cond__text:focus { border-color: var(--accent); background: var(--surface); }
.cond input:checked + .cond__text, .cond__tick input:checked ~ .cond__text { color: var(--ink-3); }
.condadd {
  display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap;
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line);
}
.condadd .field { margin: 0; }
.condadd .field--wide { flex: 1 1 260px; min-width: 0; }

/* Whether a fee is disclosed as part of what the money costs. A tick per line
   and one at the head that sets them all — five ticks to say "yes, all of it"
   is four more than the answer deserves. */
.feeline { grid-template-columns: minmax(0, 1fr) 130px 62px 92px 28px; }
.feeline__cob { text-align: right; }
.cobtick {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  font-size: 11px; color: var(--ink-3); white-space: nowrap;
}
.cobtick input { margin: 0; accent-color: var(--accent); }
.cobtick:hover { color: var(--ink-2); }
/* Prepaid interest has no choice: it is interest and is already counted. */
.cobtick.is-fixed { cursor: help; opacity: .7; }
.feeline--head .cobtick { font-weight: 600; color: var(--ink-2); }
/* A subtotal that only explains the two lines around it. */
.tally__row--sub { font-size: 12px; color: var(--ink-2); padding-left: 14px; }
.tally__row--sub span:last-child { font-weight: 400; }
@media (max-width: 560px) {
  .feeline { grid-template-columns: minmax(0, 1fr) 110px; }
  .feeline__pct, .feeline__x, .feeline__cob { grid-column: 2; text-align: right; }
}

/* Who satisfies a condition, on the row. Narrow: it is two words and the
   sentence beside it is the thing being read. */
.cond__owner { flex: none; width: 108px; font-size: 12px; padding: 4px 6px; }
.condadd select[multiple] { width: 100%; min-height: 190px; padding: 4px; }
.condadd select[multiple] option { padding: 3px 6px; border-radius: 4px; }
@media (max-width: 720px) { .cond__owner { width: 92px; } }
