/* MaxOS (MaxiMoney's CRM) — one stylesheet, tokens first.
   Palette read from the approved dashboard design. Every colour in the
   application comes from a token below; no screen invents its own. */

:root {
  /* core */
  --ink:          #0F1C2E;
  --ink-2:        #31435A;
  --muted:        #64748B;
  --faint:        #94A3B8;
  --ground:       #F4F7FA;
  --surface:      #FFFFFF;
  --surface-2:    #F8FAFC;
  --line:         #E1E8F0;
  --line-2:       #EDF1F6;

  /* brand */
  --emerald:      #0EA472;
  --emerald-ink:  #0B8F63;
  --emerald-soft: #DCFCE7;
  --mint:         #2DD4A7;

  /* sidebar */
  --rail:         #0F1C2E;
  --rail-ink:     #C3D2E2;
  --rail-dim:     #64748B;
  --rail-active:  #1B2E45;

  /* semantic */
  --ok:        #10B981;  --ok-soft:     #DCFCE7;
  --info:      #2563EB;  --info-soft:   #DBEAFE;
  --warn:      #B45309;  --warn-soft:   #FEF3C7;
  --danger:    #DC2626;  --danger-soft: #FEE2E2;
  --violet:    #7C3AED;  --violet-soft: #EDE9FE;
  --slate:     #475569;  --slate-soft:  #E2E8F0;

  --radius:    8px;
  --radius-lg: 12px;
  --shadow:    0 1px 2px rgba(15, 28, 46, .05);
  --shadow-lg: 0 10px 34px -12px rgba(15, 28, 46, .26);
  --rail-w:    238px;

  --font: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink-2);
  font: 400 13.5px/1.55 var(--font);
  -webkit-font-smoothing: antialiased;
}

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

.ic { flex: none; vertical-align: -.18em; }
.muted { color: var(--muted); }
.mono { font: 500 12px/1.5 var(--mono); color: var(--ink); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 4px; padding: 1px 5px; }
.num { font-variant-numeric: tabular-nums; }
.hide { display: none !important; }

/* ── shell ──────────────────────────────────────────────────────────── */
.shell { display: grid; grid-template-columns: var(--rail-w) minmax(0, 1fr); min-height: 100vh; }

.rail {
  background: var(--rail);
  color: var(--rail-ink);
  position: sticky; top: 0; height: 100vh;
  display: flex; flex-direction: column;
  padding: 20px 0 16px;
}

.rail__brand { display: flex; align-items: center; gap: 10px; padding: 0 20px 22px; }
.rail__mark {
  width: 36px; height: 36px; border-radius: 10px; flex: none;
  background: linear-gradient(145deg, var(--mint), var(--emerald-ink));
  display: grid; place-items: center; color: #06281E; font-weight: 700; font-size: 18px;
}
.rail__name { color: #fff; font-weight: 600; font-size: 16px; letter-spacing: -.01em; line-height: 1.1; }
.rail__name em { color: var(--mint); font-style: normal; }
.rail__tag { display: block; font: 500 9.5px/1 var(--mono); letter-spacing: .16em; color: var(--rail-dim); margin-top: 4px; }

.rail__nav { flex: 1; overflow-y: auto; padding: 0 12px; }
.rail__group { font: 600 9.5px/1 var(--font); letter-spacing: .14em; text-transform: uppercase;
  color: var(--rail-dim); padding: 0 10px; margin: 18px 0 8px; }
.rail__group:first-child { margin-top: 0; }

.rail__link {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px; margin-bottom: 2px; border-radius: 8px;
  color: var(--rail-ink); font-size: 13.5px; font-weight: 500;
  border-left: 2px solid transparent;
}
.rail__link:hover { background: var(--rail-active); text-decoration: none; }
.rail__link.is-active {
  background: var(--rail-active); color: #fff; border-left-color: var(--mint);
}
.rail__link.is-active .ic { color: var(--mint); }

.rail__me {
  display: flex; align-items: center; gap: 10px;
  margin: 12px 12px 0; padding: 12px 11px 0; border-top: 1px solid rgba(255, 255, 255, .08);
  color: var(--rail-ink);
}
.rail__me b { display: block; color: #fff; font-size: 13px; font-weight: 600; }
.rail__me span { display: block; font-size: 11.5px; color: var(--rail-dim); }

/* ── topbar ─────────────────────────────────────────────────────────── */
.top {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 18px;
  padding: 14px 32px; background: var(--surface); border-bottom: 1px solid var(--line);
}
.search { position: relative; flex: 1; max-width: 620px; }
.search .ic { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--faint); }
.search input {
  width: 100%; padding: 10px 14px 10px 40px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface-2); font: inherit; color: var(--ink);
}
.search input::placeholder { color: var(--faint); }
.search input:focus { outline: none; border-color: var(--emerald); background: var(--surface); }

.top__right { margin-left: auto; display: flex; align-items: center; gap: 8px; }

.menu { position: relative; }
.menu__btn {
  display: flex; align-items: center; gap: 10px; padding: 5px 8px 5px 5px;
  background: none; border: 1px solid transparent; border-radius: var(--radius);
  cursor: pointer; font: inherit; color: var(--ink);
}
.menu__btn:hover { background: var(--surface-2); border-color: var(--line); }
.menu__btn b { display: block; font-size: 13px; font-weight: 600; line-height: 1.25; }
.menu__btn span { display: block; font-size: 11.5px; color: var(--muted); }
.menu__list {
  position: absolute; right: 0; top: calc(100% + 6px); min-width: 210px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); padding: 6px; display: none; z-index: 40;
}
.menu.is-open .menu__list { display: block; }
.menu__list a, .menu__list button {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 11px; border-radius: var(--radius); color: var(--ink-2);
  background: none; border: 0; font: inherit; text-align: left; cursor: pointer;
}
.menu__list a:hover, .menu__list button:hover { background: var(--surface-2); text-decoration: none; }
.menu__sep { height: 1px; background: var(--line); margin: 5px 0; }

/* ── page ───────────────────────────────────────────────────────────── */
main { min-width: 0; }
.page { padding: 26px 32px 64px; }
.page__head { display: flex; align-items: flex-start; gap: 20px; flex-wrap: wrap; margin-bottom: 22px; }
.page__head h1 { margin: 0 0 5px; font-size: 27px; font-weight: 600; letter-spacing: -.022em; color: var(--ink); }
.page__head p { margin: 0; color: var(--muted); font-size: 14px; }
.page__actions { margin-left: auto; display: flex; gap: 9px; flex-wrap: wrap; }

.crumb { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--muted); margin-bottom: 12px; }
.crumb a { color: var(--muted); }

/* ── buttons ────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 9px 16px; border-radius: var(--radius); border: 1px solid transparent;
  font: 500 13.5px/1.2 var(--font); cursor: pointer; white-space: nowrap;
  background: var(--surface); color: var(--ink); border-color: var(--line);
}
.btn:hover { text-decoration: none; background: var(--surface-2); }
.btn--primary { background: var(--emerald); color: #fff; border-color: var(--emerald); }
.btn--primary:hover { background: var(--emerald-ink); border-color: var(--emerald-ink); }
.btn--danger { background: var(--danger); color: #fff; border-color: var(--danger); }
.btn--danger:hover { background: #B91C1C; border-color: #B91C1C; }
.btn--ghost { background: none; border-color: transparent; color: var(--muted); }
.btn--ghost:hover { background: var(--surface-2); color: var(--ink); }
.btn[disabled] { opacity: .55; cursor: not-allowed; }
.btn--sm { padding: 6px 11px; font-size: 12.5px; }

.btn-icon {
  display: inline-grid; place-items: center; width: 30px; height: 30px;
  border-radius: 7px; border: 1px solid var(--line); background: var(--surface);
  color: var(--muted); cursor: pointer; padding: 0;
}
.btn-icon:hover { color: var(--ink); background: var(--surface-2); text-decoration: none; }
.btn-icon--danger:hover { color: var(--danger); border-color: #FCA5A5; background: var(--danger-soft); }
.btn-icon--warn:hover { color: var(--warn); border-color: #FCD34D; background: var(--warn-soft); }
.btn-icon--ok:hover { color: var(--ok); border-color: #6EE7B7; background: var(--ok-soft); }
.row-actions { display: flex; gap: 6px; justify-content: flex-end; }
/* Loan details' row controls, drawn as the old All Loans screen drew them: plain icons, with a box only under the
   pointer. Only this list; the others keep their boxed buttons. */
#loans-table .row-actions { gap: 2px; }
#loans-table .btn-icon { border-color: transparent; background: none; color: var(--ink-2); }
#loans-table .btn-icon:hover { border-color: var(--line); background: var(--surface-2); color: var(--ink); }
#loans-table .btn-icon--max { color: var(--violet); }
/* Pinned to the right edge while the other columns scroll beneath (founder, 1 October 2026: "keep action fixed and
   other scrollable"), each cell painted with its row's colour so nothing shows through. An empty table's single cell
   is left alone. */
#loans-table > thead > tr > th:last-child,
#loans-table > tbody > tr > td:last-child:not(.dt-empty) {
  position: sticky; right: 0; z-index: 1; box-shadow: -8px 0 8px -8px rgba(15, 28, 46, .2); }
#loans-table > thead > tr > th:last-child { background: var(--surface-2); }
#loans-table > tbody > tr > td:last-child:not(.dt-empty) { background: var(--surface); }
#loans-table > tbody > tr:hover > td:last-child:not(.dt-empty) { background: var(--surface-2); }

/* ── cards & tiles ──────────────────────────────────────────────────── */
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow);
}
.card__head {
  display: flex; align-items: center; gap: 12px;
  padding: 15px 20px; border-bottom: 1px solid var(--line);
}
.card__head h2 { margin: 0; font-size: 15px; font-weight: 600; color: var(--ink); display: flex; align-items: center; gap: 9px; }
.card__head .ic { color: var(--emerald); }
.card__head .card__link { margin-left: auto; font-size: 13px; }
.card__body { padding: 20px; }

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(212px, 1fr)); gap: 14px; margin-bottom: 18px; }
.tile {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 17px 18px; display: flex; gap: 14px; align-items: flex-start; box-shadow: var(--shadow);
}
.tile__icon { width: 40px; height: 40px; border-radius: 10px; display: grid; place-items: center; flex: none; }
.tile__label { font-size: 12.5px; color: var(--muted); margin-bottom: 3px; }
.tile__value { font-size: 25px; font-weight: 600; color: var(--ink); letter-spacing: -.02em; line-height: 1.1;
  font-variant-numeric: tabular-nums; }
.tile__value small { font-size: 15px; color: var(--faint); font-weight: 500; }
.tile__foot { font-size: 12px; color: var(--muted); margin-top: 4px; }
/* A tile whose value is words, not a figure: a name, sized to sit beside the figures. */
.tile__value--words { font-size: 17px; letter-spacing: 0; line-height: 1.3; padding-top: 3px; }
/* The state an RM records in the panel's grid, where the tax return gives none. */
.state-pick { font: inherit; font-size: 12.5px; padding: 3px 6px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--surface); color: var(--ink); max-width: 100%; }
/* The Loan details list's multi-pick of loan types: a closed summary, a list of boxes when opened. */
.multi { position: relative; }
.multi > summary { list-style: none; cursor: pointer; font-size: 12.5px; padding: 5px 26px 5px 9px; height: 30px;
  border: 1px solid var(--line); border-radius: 7px; background: var(--surface); color: var(--ink); white-space: nowrap;
  min-width: 150px; display: flex; align-items: center; }
.multi > summary::-webkit-details-marker { display: none; }
.multi > summary::after { content: "▾"; position: absolute; right: 9px; color: var(--muted); font-size: 11px; }
.multi__menu { position: absolute; z-index: 20; top: calc(100% + 4px); left: 0; min-width: 210px; padding: 6px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 9px; box-shadow: var(--shadow);
  display: grid; gap: 2px; }
.multi__menu label { display: flex; align-items: center; gap: 8px; padding: 5px 7px; border-radius: 6px;
  font-size: 12.5px; color: var(--ink); cursor: pointer; white-space: nowrap; }
.multi__menu label:hover { background: var(--surface-2); }
/* Click-to-copy cells on the Loan details list: the masked number and "On file", copied in full. */
.copy-cell { font: inherit; border: 0; background: none; padding: 0; cursor: copy; color: inherit; }
.copy-cell:hover { text-decoration: underline dotted; text-underline-offset: 3px; }
/* A whole row opens the customer's loans panel. */
#loans-table tbody tr { cursor: pointer; }
/* A loans panel scrolled into view clears the top bar, so its title and buttons show. */
#loan-profile { scroll-margin-top: 84px; }
/* A tile whose body is a control, not a number. `min-width: 0` is the part
   that matters: without it the flex child refuses to shrink below its content
   and the buttons push out past the card, scrolling the whole page sideways. */
.tile__body { flex: 1; min-width: 0; }
.assign { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.assign select {
  flex: 1 1 120px; min-width: 0; padding: 7px 9px; font: inherit; font-size: 13px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink);
}
.assign .btn { flex: 0 0 auto; }

.t-ok     { background: var(--ok-soft);     color: var(--ok); }
.t-info   { background: var(--info-soft);   color: var(--info); }
.t-warn   { background: var(--warn-soft);   color: var(--warn); }
.t-danger { background: var(--danger-soft); color: var(--danger); }
.t-violet { background: var(--violet-soft); color: var(--violet); }
.t-slate  { background: var(--slate-soft);  color: var(--slate); }

/* ── badges, avatars, person cells ──────────────────────────────────── */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 20px; font-size: 11.5px; font-weight: 500; white-space: nowrap;
  background: var(--slate-soft); color: var(--slate);
}
/* A badge that is a button. It has to keep looking like the badge beside it —
   the row reads as data, not as a toolbar — while still inviting a click, so
   the affordance is a cursor, a hover lift and a focus ring rather than a
   border that would make every row look busy. */
.badge--action {
  border: 1px solid transparent; font: inherit; font-size: 11.5px; font-weight: 500;
  cursor: pointer; transition: .12s;
}
.badge--action:hover { filter: brightness(.96); border-color: currentColor; }
.badge--action:focus-visible { outline: 2px solid var(--emerald); outline-offset: 2px; }

.badge--ok     { background: var(--ok-soft);     color: #047857; }
.badge--info   { background: var(--info-soft);   color: #1D4ED8; }
.badge--warn   { background: var(--warn-soft);   color: var(--warn); }
.badge--danger { background: var(--danger-soft); color: #B91C1C; }
.badge--violet { background: var(--violet-soft); color: #6D28D9; }
.badge--muted  { background: var(--slate-soft);  color: var(--slate); }

.avatar {
  width: 32px; height: 32px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-size: 11.5px; font-weight: 600;
  background: var(--slate-soft); color: var(--slate);
}
.avatar--emerald { background: var(--emerald-soft); color: #047857; }
.avatar--azure   { background: var(--info-soft);    color: #1D4ED8; }
.avatar--amber   { background: var(--warn-soft);    color: var(--warn); }
.avatar--violet  { background: var(--violet-soft);  color: #6D28D9; }
.avatar--rose    { background: var(--danger-soft);  color: #B91C1C; }
.avatar--slate   { background: var(--slate-soft);   color: var(--slate); }
.avatar--lg { width: 56px; height: 56px; font-size: 18px; }

.person { display: flex; align-items: center; gap: 10px; }
.person__name { display: block; font-weight: 500; color: var(--ink); }
.person__sub  { display: block; font-size: 12px; color: var(--muted); }
.link { color: var(--emerald-ink); font-weight: 500; }
/* A link that is a button (it opens something on the page rather than a new one) reads as a link. */
button.link { appearance: none; border: 0; background: none; padding: 0; font: inherit; font-weight: 500; cursor: pointer; }
button.link:hover { text-decoration: underline; text-underline-offset: 2px; }

.stack__title { display: block; font-weight: 500; color: var(--ink); }
.stack__sub   { display: block; font-size: 12px; color: var(--muted); }

/* ── tables (DataTables) ────────────────────────────────────────────── */
.tablewrap { overflow-x: auto; }
table.dataTable { width: 100% !important; border-collapse: collapse; margin: 0 !important; }
table.dataTable thead th {
  font: 600 10px/1 var(--font); letter-spacing: .09em; text-transform: uppercase; color: var(--muted);
  text-align: left; padding: 13px 20px; background: var(--surface-2);
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
table.dataTable tbody td {
  padding: 13px 20px; border-bottom: 1px solid var(--line-2); vertical-align: middle; color: var(--ink-2);
}
table.dataTable tbody tr:last-child td { border-bottom: 0; }
table.dataTable tbody tr:hover { background: var(--surface-2); }
table.dataTable th.dt-right, table.dataTable td.dt-right { text-align: right; }
table.dataTable thead th.sorting,
table.dataTable thead th.sorting_asc,
table.dataTable thead th.sorting_desc { cursor: pointer; position: relative; padding-right: 30px; }
table.dataTable thead th.sorting::after,
table.dataTable thead th.sorting_asc::after,
table.dataTable thead th.sorting_desc::after {
  content: "↕"; position: absolute; right: 14px; opacity: .4; font-size: 11px;
}
table.dataTable thead th.sorting_asc::after  { content: "↑"; opacity: 1; color: var(--emerald); }
table.dataTable thead th.sorting_desc::after { content: "↓"; opacity: 1; color: var(--emerald); }

/* DataTables wraps the table in the SAME .dt-layout-row structure it uses for
   the page-length / search / info / paging bars. These rules are for those
   control bars only — applied to the table's row they make the cell shrink to
   its content and `margin-left: auto` shoves the whole table to the right.
   `.dt-layout-table` is how DataTables marks the table's own row. */
.dt-layout-row:not(.dt-layout-table) {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 13px 20px;
}
.dt-layout-row:not(.dt-layout-table):first-child { border-bottom: 1px solid var(--line); }
.dt-layout-row:not(.dt-layout-table):last-child { border-top: 1px solid var(--line); }
.dt-layout-row:not(.dt-layout-table) .dt-layout-cell:last-child { margin-left: auto; }

.dt-layout-table { display: block; }
.dt-layout-table .dt-layout-cell { width: 100%; margin: 0; }
.dt-info { font-size: 12.5px; color: var(--muted); }
.dt-length select, .dt-search input {
  padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--radius);
  font: inherit; font-size: 13px; color: var(--ink); background: var(--surface);
}
.dt-paging { display: flex; gap: 4px; }
.dt-paging .dt-paging-button {
  min-width: 32px; height: 32px; padding: 0 9px; border: 1px solid var(--line);
  background: var(--surface); border-radius: 7px; color: var(--ink-2);
  font: 500 12.5px/30px var(--font); cursor: pointer;
}
.dt-paging .dt-paging-button:hover:not(.disabled):not(.current) { background: var(--surface-2); }
.dt-paging .dt-paging-button.current { background: var(--emerald); border-color: var(--emerald); color: #fff; }
.dt-paging .dt-paging-button.disabled { opacity: .4; cursor: default; }
.dt-empty { padding: 44px 20px !important; text-align: center; color: var(--muted); }

/* ── filter bar ─────────────────────────────────────────────────────── */
.filters { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 13px 20px;
  border-bottom: 1px solid var(--line); background: var(--surface); border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
.filters label { font-size: 12px; color: var(--muted); font-weight: 500; }
/* A label and its control wrap as one, so a narrow screen never leaves a label at a line's end. */
.filter-pair { display: inline-flex; align-items: center; gap: 8px; }
/* Help Requests: how long a request has waited, red after a day; what came of a call, kept readable. */
.wait { font-size: 12px; color: var(--muted); }
.wait--late { color: var(--danger); font-weight: 600; }
.call-note { max-width: 360px; white-space: pre-line; font-size: 13px; color: var(--ink-2); }
/* The dialogs' longer answers (what came of a call) in the page's own type, not the browser's fixed-width default. */
.swal2-textarea { font: inherit; font-size: 14px; line-height: 1.5; }
.filters__search { font: inherit; font-size: 12.5px; padding: 5px 9px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--surface); color: var(--ink); height: 30px; width: 210px; max-width: 100%; }
/* A filter row that is a whole card (the dashboard's date range), and its date boxes. */
.filters--alone { border-bottom: 0; border-radius: var(--radius-lg); }
.filters input[type="date"] { font: inherit; font-size: 12.5px; padding: 5px 8px; border: 1px solid var(--line);
  border-radius: 7px; background: var(--surface); color: var(--ink); height: 30px; width: 138px; }
.filters select {
  padding: 7px 11px; border: 1px solid var(--line); border-radius: var(--radius);
  font: inherit; font-size: 13px; background: var(--surface); color: var(--ink); min-width: 140px;
}

/* ── forms ──────────────────────────────────────────────────────────── */
.field { margin-bottom: 16px; }
.field > label { display: block; font-size: 12.5px; font-weight: 500; color: var(--ink); margin-bottom: 6px; }
.field .req { color: var(--danger); }
.field input, .field select, .field textarea {
  width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius);
  font: inherit; font-size: 13.5px; color: var(--ink); background: var(--surface);
}
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--emerald); }
.field input[readonly] { background: var(--surface-2); color: var(--muted); }
.field__hint { display: block; font-size: 12px; color: var(--muted); margin-top: 5px; }
.field__error { display: none; font-size: 12px; color: var(--danger); margin-top: 5px; }
.field.has-error input, .field.has-error select { border-color: var(--danger); background: #FFFBFB; }
.field.has-error .field__error { display: block; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }

.switch { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.switch input { width: auto; }

.alert { display: flex; gap: 11px; padding: 13px 15px; border-radius: var(--radius);
  font-size: 13px; margin-bottom: 18px; align-items: flex-start; }
.alert--info   { background: var(--info-soft);   color: #1D4ED8; }
.alert--warn   { background: var(--warn-soft);   color: var(--warn); }
.alert--danger { background: var(--danger-soft); color: #B91C1C; }
.alert--ok     { background: var(--ok-soft);     color: #047857; }
.alert b { display: block; margin-bottom: 2px; }
/* An alert's first <b> is its heading, so `b` is a block there. Bold used
   mid-sentence needs opting back out, or it breaks the line. */
.alert b.inline { display: inline; margin: 0; }

/* ── drawer (slide-in form) ─────────────────────────────────────────── */
.drawer-backdrop {
  position: fixed; inset: 0; background: rgba(15, 28, 46, .38); z-index: 60;
  opacity: 0; pointer-events: none; transition: opacity .18s ease;
}
.drawer-backdrop.is-open { opacity: 1; pointer-events: auto; }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(520px, 100%);
  background: var(--surface); z-index: 61; box-shadow: var(--shadow-lg);
  transform: translateX(100%); transition: transform .22s ease;
  display: flex; flex-direction: column;
}
.drawer.is-open { transform: none; }

/* The panel's content is wrapped in .drawer__inner and then a <form>, so the
   column layout has to continue through both — otherwise `flex: 1` on the body
   applies to a child of a non-flex parent, nothing scrolls, and the footer
   (with the save button) is pushed below the viewport. `min-height: 0` lets the
   scrolling body actually shrink instead of growing to fit its content. */
.drawer__inner,
.drawer__inner > form {
  flex: 1; min-height: 0; display: flex; flex-direction: column;
}

.drawer__head { display: flex; align-items: center; gap: 12px; padding: 18px 22px;
  border-bottom: 1px solid var(--line); flex: none; }
.drawer__head h2 { margin: 0; font-size: 16px; font-weight: 600; color: var(--ink); }
.drawer__head p { margin: 3px 0 0; font-size: 12.5px; color: var(--muted); }
.drawer__close { margin-left: auto; }
.drawer__body { padding: 22px; overflow-y: auto; flex: 1; }
.drawer__foot { display: flex; gap: 10px; justify-content: flex-end; padding: 15px 22px;
  border-top: 1px solid var(--line); background: var(--surface-2); flex: none; }

@media (prefers-reduced-motion: reduce) {
  .drawer, .drawer-backdrop { transition: none; }
}

/* A header a screen reader reads and a sighted reader does not need: the
   column holds one icon button whose own aria-label names the customer. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.nowrap { white-space: nowrap; }

/* ── modal ──────────────────────────────────────────────────────────── */
/* Centred, beside the side drawer rather than instead of it: a drawer is for a
   form filled top to bottom, a modal for a short exchange you come back from. */
.modal-backdrop { position: fixed; inset: 0; background: rgba(15, 28, 46, .38); z-index: 70;
  opacity: 0; pointer-events: none; transition: opacity .16s ease; }
.modal-backdrop.is-open { opacity: 1; pointer-events: auto; }
.modal { position: fixed; z-index: 71; left: 50%; top: 50%;
  transform: translate(-50%, -48%) scale(.98); opacity: 0; pointer-events: none;
  width: min(520px, calc(100vw - 32px)); max-height: min(720px, calc(100vh - 48px));
  background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column; transition: opacity .16s ease, transform .16s ease; }
.modal.is-open { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%) scale(1); }
/* Nothing may paint outside the rounded box. A child that outgrows max-height
   used to spill down the page, unclipped, and read as content that had escaped
   the dialog — which is exactly what it was. */
.modal { overflow: hidden; }
.modal__inner { display: flex; flex-direction: column; min-height: 0; flex: 1; }

/* A dialog whose body and footer are wrapped in a <form> — the Enrich Profile
   one — puts a plain block between .modal__inner and .modal__body, and a block
   is not a flex container. `.modal__body { flex: 1; min-height: 0 }` then
   addressed a parent that had no main axis, so the body never got a height to
   scroll inside: it grew to its content, pushed the form past the modal's
   max-height, and the last two cards rendered below the white box.
   Making the form the flex column restores the chain the head/body dialogs
   already had. */
.modal__inner > form { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.modal__head { display: flex; align-items: flex-start; gap: 12px; padding: 18px 20px 14px; flex: none; }
.modal__head h2 { margin: 0; font-size: 16px; font-weight: 600; color: var(--ink); }
.modal__head p { margin: 3px 0 0; font-size: 12px; color: var(--muted); }
.modal__close { margin-left: auto; flex: none; }
.modal__body { padding: 0 20px 20px; overflow-y: auto; flex: 1; min-height: 0; }

@media (prefers-reduced-motion: reduce) { .modal, .modal-backdrop { transition: none; } }

/* ── the Notes dialog ───────────────────────────────────────────────── */
.note-form__row { display: flex; align-items: flex-end; gap: 10px; margin-top: 10px; }
.note-form__row .field-lite { flex: 1; }
.note-form__row input[type="date"] { font-size: 12.5px; padding: 6px 9px; border: 1px solid var(--line);
  border-radius: 7px; background: var(--surface); color: var(--ink); width: 100%; }
.note-form__row .btn { flex: none; }
.note-form__hint { margin: 8px 0 0; font-size: 11.5px; color: var(--muted); line-height: 1.5; }
.note-history__h { margin: 22px 0 8px; font-size: 12.5px; font-weight: 600; color: var(--ink); }
.note-history { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.note-history li { border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px;
  background: var(--surface-2); }
.note-history__top { display: flex; align-items: flex-start; gap: 10px; }
.note-history__body { font-size: 13px; font-weight: 600; color: var(--ink); line-height: 1.45;
  white-space: pre-wrap; flex: 1; }
.note-history__edit { appearance: none; border: 0; background: none; cursor: pointer; font: inherit;
  font-size: 12px; flex: none; padding: 0; }
.note-history__meta { margin-top: 4px; font-size: 11.5px; color: var(--muted); }
.note-history__form { margin-top: 10px; }
.note-history__form .field { margin: 0; }

/* ── filter bars (the Notes and Enrich dialogs) ─────────────────────── */
/* Two rows: every segmented control on one line with the search, then every
   input on the next with its label above it. Both are flex rows that wrap, so
   a narrow screen folds them rather than needing a breakpoint per control. */
.filterbar { display: flex; flex-direction: column; gap: 13px; padding: 15px 16px;
  border-bottom: 1px solid var(--line); }
.filterbar__row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.filterbar__row--fields { align-items: flex-end; gap: 12px; }
.filterbar__search { flex: 0 1 260px; min-width: 180px; position: relative; }
.filterbar__inline { display: flex; align-items: center; gap: 7px; }
.filterbar__label { font-size: 12.5px; color: var(--muted); white-space: nowrap; }

/* A labelled control: the label sits above, small and grey, the way the brief
   has it — not beside, which is what made the bar three rows longer. */
.field-lite { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field-lite > span { font-size: 11.5px; color: var(--muted); white-space: nowrap; line-height: 1.3; }
.field-lite--wide { flex: 0 1 auto; max-width: 360px; }

.filterbar input[type="number"], .filterbar input[type="date"], .filterbar select {
  font-size: 12px; padding: 5px 8px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--surface); color: var(--ink); min-width: 0; height: 30px; }
.filterbar input[type="number"] { width: 108px; }
.filterbar input[type="date"] { width: 128px; }
.filterbar select { min-width: 96px; }
.filterbar .is-pending { color: var(--faint); background: var(--surface-2); }
.filterbar .is-pending::placeholder { color: var(--faint); }

/* A segmented control. The chosen one is filled in the brand green, which is
   what makes the row readable at a glance across five groups. `is-on` is put
   on the button by the handler, so the styling cannot drift from the value. */
.seg { display: inline-flex; background: var(--surface); border: 1px solid var(--line);
  border-radius: 8px; padding: 2px; gap: 2px; }
.seg button, .seg a { appearance: none; border: 0; background: transparent; cursor: pointer;
  font: inherit; font-size: 12px; color: var(--ink-2); padding: 4px 10px; border-radius: 6px;
  white-space: nowrap; text-decoration: none; line-height: 1.2; }
.seg button:hover, .seg a:hover { background: var(--surface-2); }
.seg button.is-on, .seg a.is-on { background: var(--emerald); color: #fff; font-weight: 600; }
.seg button.is-on:hover, .seg a.is-on:hover { background: var(--emerald-ink); }
.seg button:focus-visible, .seg a:focus-visible { outline: 2px solid var(--emerald); outline-offset: 1px; }
.seg button[disabled] { color: var(--faint); cursor: not-allowed; }
.seg button[disabled]:hover { background: transparent; }
.seg button[disabled].is-on { background: var(--emerald); color: #fff; }

/* The loan-category chips. Multi-select, so they toggle rather than replace. */
.chips { display: flex; flex-wrap: wrap; gap: 4px; }
.chip { appearance: none; cursor: pointer; font: inherit; font-size: 11px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-2);
  border-radius: 6px; padding: 2px 7px; white-space: nowrap; line-height: 1.5; }
.chip:hover { background: var(--surface-2); }
.chip.is-on { background: var(--emerald-soft); border-color: #6EE7B7; color: var(--emerald-ink);
  font-weight: 600; }
.chip:focus-visible { outline: 2px solid var(--emerald); outline-offset: 1px; }
.chip[disabled] { color: var(--faint); background: var(--surface-2); cursor: not-allowed; }
.chip[disabled]:hover { background: var(--surface-2); }

/* The star column. A button that does not look like one. */
.star { appearance: none; border: 0; background: transparent; cursor: pointer; padding: 0;
  font-size: 15px; line-height: 1; color: var(--faint); }
.star:hover { color: var(--warn); }
.star.is-on { color: #F59E0B; }
.star:focus-visible { outline: 2px solid var(--emerald); outline-offset: 2px; border-radius: 3px; }
span.star { cursor: default; }

/* The profile panel the eye opens, above the table. Its own card rather than a
   drawer: it is wide, it has three tables in it, and the reader is comparing it
   against the rows underneath. */
/* A card of its own between the filter card and the table, so it sits in the
   page's rhythm rather than inside somebody else's border. */
.profile-card { border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface); padding: 16px 18px 20px; box-shadow: var(--shadow); }
.profile-card--loading { color: var(--muted); font-size: 13px; padding: 26px 18px; text-align: center; }

/* The Loans page stacks three blocks: filters, the profile panel when one is
   open, and the table. One grid gap rather than a margin on each, and the slot
   collapses when it holds nothing — otherwise a closed panel leaves an empty
   grid row and doubles the space between the two cards. */
.page-stack { display: grid; gap: 16px; }
.page-stack > #loan-profile:empty { display: none; }
/* A grid item's default `min-width: auto` refuses to shrink below its content,
   and the table inside carries `min-width: 1560px` — so the card grew past the
   page and scrolled the whole layout sideways instead of scrolling the table
   inside its own wrapper. This is what makes the wrapper do its job. */
.page-stack > * { min-width: 0; }
/* Title on the left, the whole action row on the right, on ONE line. It wrapped
   to two rows before and sat under the title, which read as two separate
   things rather than one header. Scrolls sideways on a narrow screen rather
   than wrapping, so the row stays a row. */
.profile-card__head { display: flex; align-items: center; gap: 10px;
  padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.profile-card__head h2 { margin: 0; font-size: 15px; font-weight: 600; color: var(--ink);
  white-space: nowrap; }
.profile-card__head > .mono { flex: none; }
.profile-card__actions { display: flex; align-items: center; gap: 5px; margin-left: auto;
  overflow-x: auto; padding-bottom: 2px; }
.profile-card__actions .btn { font-size: 11px; padding: 4px 8px; gap: 4px; white-space: nowrap;
  flex: none; }
.profile-card__actions .btn .ic { width: 13px; height: 13px; }
/* The row scrolls rather than wrapping, so it needs an edge that says so —
   otherwise the last button just looks cut off, which is how it read before. */
.profile-card__actions { scrollbar-width: thin; }
.profile-card__actions::after { content: ''; flex: none; width: 2px; }
.profile-card__h { margin: 20px 0 6px; font-size: 12.5px; font-weight: 600; color: var(--ink);
  display: flex; align-items: baseline; gap: 6px; }
.profile-card__h .muted { font-weight: 500; }
.profile-card__right { margin-left: auto; font-weight: 500; font-size: 11.5px; color: var(--muted); }
.profile-card__note { margin: 0 0 8px; font-size: 11.5px; color: var(--muted); }

/* An empty section says so in one line inside the table, rather than a centred
   block with an icon — which took more vertical room than the rows it stands
   in for, and made a panel of four empty sections unreadable. */
.profile-empty { padding: 14px 10px; font-size: 12px; color: var(--muted); }

/* The applicant band: who is borrowing, what they earn, what they owe. */
/* Green, as the live panel draws it. What needs attention inside it — a loan
   with no EMI, FOIR understated — carries its own amber, so the band itself
   does not have to shout. */
.applicant { display: flex; align-items: center; gap: 16px; margin: 14px 0 4px;
  padding: 11px 14px; border: 1px solid #BBF7D0; background: #F0FDF4; border-radius: 8px; }
.applicant__who { min-width: 0; }
.applicant__who b { font-size: 12.5px; color: var(--ink); }
.applicant__who span { font-size: 12.5px; color: var(--ink-2); margin-left: 8px; }
.applicant__pay { font-variant-numeric: tabular-nums; }
.applicant__who p { margin: 3px 0 0; font-size: 11.5px; color: var(--muted); }
/* Two FOIRs side by side (founder, 1 October 2026): a personal loan's, on the applicant alone; a home loan's, with
   co-applicants. */
.applicant__foirs { margin-left: auto; flex: none; display: flex; gap: 8px; }
.applicant__foirs .applicant__foir { margin-left: 0; min-width: 118px; }
.applicant__foir { margin-left: auto; flex: none; text-align: center; border: 1px solid var(--line);
  background: var(--surface); border-radius: 7px; padding: 6px 14px; }
.applicant__foir span { display: block; font-size: 10px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); }
.applicant__foir b { display: block; font-size: 15px; color: var(--ink); line-height: 1.3; }
.applicant__foir small { display: block; font-size: 10px; color: var(--faint); }

/* The asset entry row — a kind, a figure, Add — and the lines above it. */
.asset-row { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
/* The paid-pull dialog: what is on file, then the cost, then the four digits. */
.bureau { display: grid; gap: 14px; }
.bureau p { margin: 0; }
.bureau__onfile { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius); }
.bureau__pull { display: grid; gap: 10px; }
.bureau__pull form { display: grid; gap: 10px; }
.bureau__cost { padding: 10px 12px; border-radius: var(--radius); background: var(--warn-soft); color: #78350F; }
.bureau__wait { display: flex; gap: 8px; align-items: flex-start; padding: 10px 12px;
  border-radius: var(--radius); background: var(--surface-2); }
.bureau__code { display: grid; gap: 6px; font-size: 12.5px; }
.bureau__code input { width: 120px; padding: 7px 10px; border: 1px solid var(--line); border-radius: 7px;
  font: inherit; letter-spacing: .3em; }
.bureau__code input:focus { outline: none; border-color: var(--emerald); }
.bureau__last { font-size: 12px; }
.profile-table--assets { margin-bottom: 10px; }
.profile-table--assets td { white-space: nowrap; }
.asset-row select, .asset-row input { font-size: 12px; padding: 5px 9px; border: 1px solid var(--line);
  border-radius: 7px; background: var(--surface); color: var(--ink); height: 30px; }
.asset-row select:focus, .asset-row input:focus { outline: none; border-color: var(--emerald); }
.asset-row select { min-width: 120px; }
.asset-row input { width: 140px; }

/* Exactly four across, as the brief has it — `auto-fit` spread them to seven on
   a wide screen, which broke the row-of-four reading the labels depend on.
   Folded by breakpoint instead, which is the only way to hold a fixed count. */
.profile-grid { display: grid; gap: 11px 20px; padding: 13px 0 3px;
  grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) { .profile-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px)  { .profile-grid { grid-template-columns: 1fr; } }
.profile-grid--tight { padding-top: 4px; }
.profile-grid > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.profile-grid span { font-size: 11px; color: var(--muted); line-height: 1.3; }
.profile-grid b { font-size: 13px; font-weight: 600; color: var(--ink); overflow-wrap: anywhere;
  line-height: 1.35; }
.profile-grid b small { font-weight: 500; }
/* A monospace VALUE, not a chip. `.mono` carries a border and a fill, which in
   a field grid reads as an editable input — which is what the masked number
   looked like. */
.profile-grid b.mono { font-family: var(--mono); font-size: 12.5px; background: none;
  border: 0; padding: 0; border-radius: 0; }

/* These tables are read, not sorted or paged — they carry no DataTables chrome,
   so they need the borders and padding it would otherwise supply. */
.profile-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.profile-table th { text-align: left; font-size: 10.5px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
  padding: 8px 10px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.profile-table td { padding: 9px 10px; border-bottom: 1px solid var(--line-2); color: var(--ink-2); }
.profile-table .dt-right { text-align: right; }

/* Nineteen columns do not fit a laptop, so the table scrolls inside its card.
   Tighter rows than the other screens: this one is scanned across, and a row
   that wraps anywhere makes every row taller. */
/* Nineteen columns do not fit a laptop, so the TABLE scrolls sideways — but
   only the table. The scroll was on the whole wrapper, which put the page-length
   select, the search box, the row count and the paging inside the scrolling
   strip: they were laid out against the card's width while the table ran 400px
   past them, so the search ended up floating in the middle of the header and
   the paging in the middle of the foot.
   `.dt-layout-table` is the row DataTables puts the table in, and it is the
   only row that should move. */
.tablewrap--wide { overflow: visible; }
.tablewrap--wide .dt-layout-table { overflow-x: auto; }
/* Without this the cell refuses to shrink below the table's min-width and the
   scroll never engages — the same `min-width: auto` trap as the page stack. */
.tablewrap--wide .dt-layout-table .dt-layout-cell { min-width: 0; }
.tablewrap--wide table { min-width: 1560px; }
.tablewrap--wide td { padding-top: 9px; padding-bottom: 9px; white-space: nowrap; }
.tablewrap--wide th { white-space: nowrap; }

/* ── Ask Max chat ───────────────────────────────────────────────────── */
/* The drawer is wider for a conversation than for a form: a two-line answer
   wrapped at 520px becomes five, and a chat is judged on how much of it you
   can see at once. */
.drawer--chat { width: min(600px, 100%); }

/* The scope sits between .drawer__inner and the body/foot, so the column
   layout has to continue through it — the same reason .drawer__inner > form
   above does. Without this the transcript does not scroll and the composer
   leaves the bottom of the screen. */
.maxchat { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.maxchat__body { padding: 18px 20px; display: flex; flex-direction: column; gap: 10px; }
.maxchat__foot { flex-direction: column; align-items: stretch; gap: 8px; justify-content: flex-start; }
.maxchat__foot .field { margin: 0; }
.maxchat__foot textarea { resize: none; }
.maxchat__actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.maxchat__usage { font-size: 12px; margin-left: auto; }
.maxchat__note { margin: 0; font-size: 11.5px; color: var(--muted); }

/* Something has to happen between pressing Ask and the answer arriving: a
   model takes seconds, and a button that only greys out reads as a page that
   has stopped working. */
.max-thinking {
  align-self: flex-start; font-size: 12.5px; color: var(--muted);
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 10px; padding: 9px 13px;
}
.max-thinking::after {
  content: '…'; display: inline-block; width: 1em; text-align: left;
  animation: max-dots 1.1s steps(4, end) infinite;
}
@keyframes max-dots { 0% { content: ''; } 25% { content: '.'; } 50% { content: '..'; } 75% { content: '...'; } }
@media (prefers-reduced-motion: reduce) { .max-thinking::after { animation: none; } }

/* One row's worth of Ask Max: an icon button that reads as the assistant. */
.btn-icon--max { color: var(--violet); }
.btn-icon--max:hover { background: var(--violet-soft); border-color: #C4B5FD; color: var(--violet); }


/* ── permission matrix ──────────────────────────────────────────────── */
.matrix { width: 100%; border-collapse: collapse; }
.matrix th { font: 600 10px/1 var(--font); letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted); padding: 12px 14px; border-bottom: 1px solid var(--line); text-align: center; background: var(--surface-2); }
.matrix th:first-child { text-align: left; width: 40%; }
.matrix td { padding: 11px 14px; border-bottom: 1px solid var(--line-2); text-align: center; }
.matrix td:first-child { text-align: left; }
.matrix tr:hover td { background: var(--surface-2); }
.matrix__group td {
  background: var(--ink) !important; color: #fff; font: 600 10px/1 var(--font);
  letter-spacing: .14em; text-transform: uppercase; padding: 9px 14px; text-align: left;
}
.matrix__module { font-weight: 500; color: var(--ink); }
.matrix__module small { display: block; font-weight: 400; font-size: 11.5px; color: var(--muted); font-family: var(--mono); }
.matrix__na { color: var(--faint); }

.check { display: inline-grid; place-items: center; cursor: pointer; }
.check input { position: absolute; opacity: 0; width: 0; height: 0; }
.check span {
  width: 19px; height: 19px; border: 1.5px solid var(--line); border-radius: 5px;
  display: grid; place-items: center; background: var(--surface); transition: .12s;
}
.check input:checked + span { background: var(--emerald); border-color: var(--emerald); }
.check input:checked + span::after { content: ""; width: 5px; height: 9px; border: solid #fff;
  border-width: 0 2px 2px 0; transform: rotate(42deg) translate(-1px, -1px); }
.check input:focus-visible + span { outline: 2px solid var(--emerald); outline-offset: 2px; }
/* A box with its word beside it (Menu Management's actions): the word outside .check, so it keeps its own width. */
.check-label { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ink); cursor: pointer; }
/* What each action allows, under the boxes in Menu Management and beside an item on the permission screens. */
.action-help { display: grid; grid-template-columns: max-content 1fr; gap: 4px 10px; margin: 8px 0 0; font-size: 12px; }
.action-help dt { font-family: var(--mono); color: var(--ink-2); }
.action-help dd { margin: 0; color: var(--muted); }
.matrix__help { display: block; font-size: 11px; color: var(--muted); font-weight: 400; margin-top: 2px; max-width: 320px; white-space: normal; }

/* A permission checkbox that also says "this differs from the role".
   The tick is the answer to "can they do it"; the ring is the answer to "did
   someone change it for this person", which only an admin auditing the account
   needs — so it is a quiet outline, not a second colour competing with the
   tick. An unticked-but-changed box still shows the ring, which is the case a
   plain checkbox cannot express on its own. */
.check--perm span { position: relative; }
.check--perm.is-changed span {
  border-color: var(--warn);
  box-shadow: 0 0 0 2px var(--warn-soft);
}
.check--perm.is-changed::after {
  content: ""; position: absolute; top: -3px; right: -3px; width: 7px; height: 7px;
  border-radius: 50%; background: var(--warn);
}
.check--perm { position: relative; }

/* the inline "Changed" chip used in the explainer */
.pill-changed {
  display: inline-block; padding: 1px 7px; border-radius: 20px; font-size: 11px; font-weight: 600;
  background: var(--warn-soft); color: var(--warn); border: 1px solid #FDE68A;
}

/* score cell: the number leads, the band qualifies it */
.score { display: inline-flex; align-items: center; gap: 9px; }
.score b { font-size: 15px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }

/* ── misc layout helpers ────────────────────────────────────────────── */
.cols { display: grid; gap: 16px; }
.cols--2 { grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); }
.cols--sidebar { grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); }

.deflist { display: grid; grid-template-columns: auto 1fr; gap: 12px 22px; font-size: 13.5px; }
.deflist dt { color: var(--muted); font-size: 12.5px; }
.deflist dd { margin: 0; color: var(--ink); font-weight: 500; }

.empty { padding: 48px 20px; text-align: center; color: var(--muted); }
.empty .ic { color: var(--faint); margin-bottom: 10px; }
.empty b { display: block; color: var(--ink); font-size: 14px; margin-bottom: 4px; }

.list { list-style: none; margin: 0; padding: 0; }
.list li { display: flex; gap: 12px; padding: 12px 20px; border-bottom: 1px solid var(--line-2); align-items: center; }
.list li:last-child { border-bottom: 0; }
.list__text { flex: 1; min-width: 0; }
.list__text b { display: block; font-weight: 500; color: var(--ink); font-size: 13px; }
.list__text span { display: block; font-size: 12px; color: var(--muted); }
.list__when { font-size: 12px; color: var(--faint); white-space: nowrap; }

/* ── auth page ──────────────────────────────────────────────────────── */
.auth { min-height: 100vh; display: grid; grid-template-columns: 1fr 1fr; }
.auth__aside { background: var(--rail); color: #fff; padding: 52px; display: flex; flex-direction: column; }
.auth__aside .rail__brand { padding: 0 0 48px; }
.auth__art { margin: auto 0; display: grid; place-items: center; }
.auth__art svg { width: 100%; max-width: 520px; height: auto; display: block; }
.auth__caption { color: var(--rail-ink); font-size: 14.5px; max-width: 42ch; margin: 22px 0 0; text-align: center; }
.auth__points { list-style: none; padding: 0; margin: 40px 0 0; display: grid; gap: 13px; }
.auth__points li { display: flex; gap: 11px; align-items: flex-start; color: var(--rail-ink); font-size: 13px; }
.auth__points .ic { color: var(--mint); margin-top: 1px; }
.auth__main { display: grid; place-items: center; padding: 40px; }
.auth__form { width: 100%; max-width: 384px; }
.auth__form h1 { font-size: 25px; font-weight: 600; color: var(--ink); margin: 0 0 6px; letter-spacing: -.02em; }
.auth__form > p { color: var(--muted); margin: 0 0 26px; }
.auth__form .btn { width: 100%; padding: 11px; }

@media (max-width: 900px) {
  .auth { grid-template-columns: 1fr; }
  .auth__aside { display: none; }
}

@media (max-width: 1080px) {
  .shell { grid-template-columns: 1fr; }
  .rail {
    position: fixed; left: 0; top: 0; width: var(--rail-w); z-index: 70;
    transform: translateX(-100%); transition: transform .2s ease;
  }
  .rail.is-open { transform: none; }
  .page, .top { padding-left: 20px; padding-right: 20px; }
  .cols--sidebar { grid-template-columns: 1fr; }
  .grid-2 { grid-template-columns: 1fr; }
}
@media (min-width: 1081px) { .rail__toggle { display: none; } }

/* Narrow screens: stack each filter under its own label.
   The filter bar is a flat row — icon, label, select, label, select — held
   together by `flex-wrap`, which is fine until it wraps: a label lands at the
   end of one line and the select it names starts the next, so "Band" appears
   to belong to the Stage dropdown. One column fixes it without touching the
   markup, because the source order is already label-then-select. The funnel
   icon is decorative and would sit on a row of its own, so it goes. */
@media (max-width: 640px) {
  .filters { display: grid; grid-template-columns: 1fr; gap: 4px; padding: 14px 16px; }
  .filters > svg { display: none; }
  .filters label { margin-top: 8px; }
  .filters label:first-of-type { margin-top: 0; }
  .filters select { width: 100%; min-width: 0; }

  /* The permission matrix's "N changed from the role" counter squeezes to one
     word per line beside its button. The amber rings on the grid already say
     which cells differ, so the sentence is the part that can go. */
  [data-changed-count] { display: none; }
}

/* ── toastr & sweetalert, tuned to the palette ──────────────────────── */
/* Toastr ships each variant as `#toast-container > .toast-success` with an
   !important background-image. That out-specifies `> div`, so the icon must be
   cleared on the variant selectors themselves or it tiles behind the text.
   Opacity is left alone — toastr animates it inline. */
#toast-container > div {
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  padding: 14px 18px; font: 500 13.5px/1.45 var(--font); width: auto; max-width: 340px;
}
#toast-container > .toast-success,
#toast-container > .toast-error,
#toast-container > .toast-info,
#toast-container > .toast-warning {
  background-image: none !important;
  background-color: var(--ink);
  color: #fff;
}
#toast-container > .toast-success { border-left: 3px solid var(--mint); }
#toast-container > .toast-error   { border-left: 3px solid #F87171; }
#toast-container > .toast-info    { border-left: 3px solid #60A5FA; }
#toast-container > .toast-warning { border-left: 3px solid #FBBF24; }

.swal2-popup { border-radius: var(--radius-lg) !important; font-family: var(--font) !important; padding: 26px !important; }
.swal2-title { font-size: 18px !important; font-weight: 600 !important; color: var(--ink) !important; }
.swal2-html-container { font-size: 13.5px !important; color: var(--ink-2) !important; margin: 8px 0 0 !important; }
.swal2-actions { gap: 9px !important; margin-top: 22px !important; }
.swal2-confirm, .swal2-cancel {
  border-radius: var(--radius) !important; padding: 9px 18px !important;
  font: 500 13.5px/1.2 var(--font) !important; box-shadow: none !important;
}
.swal2-cancel { background: var(--surface) !important; color: var(--ink) !important; border: 1px solid var(--line) !important; }
.swal2-icon { margin: 0 auto 14px !important; }
/* SweetAlert2's own select is too narrow to hold "Neha Kulkarni · rm-neha" on
   a phone, and stretched edge to edge it reads as a text field rather than a
   choice. A capped width, centred, gives one control that is comfortable at
   both ends: it shrinks to the dialog on a narrow screen and stays a compact,
   centred dropdown on a wide one. */
.swal2-select {
  /* No `display` here, deliberately. SweetAlert2 hides the inputs a dialog is
     not using with an inline style, and `display: block !important` overrode
     that — so an empty dropdown appeared in EVERY confirm dialog in the app,
     not just the one this rule was written for. Style the appearance; let the
     library decide what is on screen. */
  width: 100% !important; max-width: 300px !important;
  margin: 6px auto 0 !important;
  padding: 9px 12px !important; border: 1px solid var(--line) !important;
  border-radius: var(--radius) !important; background: var(--surface) !important;
  font: inherit !important; font-size: 13.5px !important; color: var(--ink) !important;
}
.swal2-select:focus {
  outline: none !important;
  border-color: var(--emerald) !important;
  box-shadow: 0 0 0 3px var(--emerald-soft) !important;
}
.swal2-close {
  color: var(--faint) !important; font-size: 26px !important; width: 34px !important; height: 34px !important;
  border-radius: 8px !important; top: 8px !important; right: 8px !important; box-shadow: none !important;
}
.swal2-close:hover { color: var(--ink) !important; background: var(--surface-2) !important; }
.swal2-close:focus-visible { outline: 2px solid var(--emerald) !important; outline-offset: 2px; }

/* ── the Enrich Profile dialog ──────────────────────────────────────── */
/* Wider than the default modal because its fields are paired: two columns of
   income figures read as a form, one column reads as a queue. The width is a
   modifier rather than a new component — everything else about the modal,
   including how it opens and closes, is the same dialog. */
.modal--wide { width: min(700px, calc(100vw - 32px)); }

/* A footer outside the scrolling body, so Save is reachable without scrolling
   to the end of a long form. `flex: none` keeps it out of the body's scroll. */
.modal__foot { display: flex; align-items: center; justify-content: flex-end; gap: 14px;
  padding: 14px 20px; border-top: 1px solid var(--line); flex: none;
  background: var(--surface); border-radius: 0 0 var(--radius-lg) var(--radius-lg); }

.enrich-card { border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px 2px; margin-bottom: 14px; background: var(--surface); }
.enrich-card h3 { margin: 0 0 12px; font-size: 13px; font-weight: 600; color: var(--ink); }
.enrich-card__head { display: flex; align-items: baseline; gap: 10px; }
.enrich-card__head h3 { flex: 1; }
.enrich-card__remove { font-size: 12px; color: var(--danger); flex: none; }
/* Its own grid, not the page's .grid-2.
   .grid-2 collapses to one column under a 1080px WINDOW, which is right for a
   drawer that shares the page's width and wrong for this dialog: the modal is
   min(700px, 100vw - 32px), so on a 1000px laptop window it is still 700px wide
   with room for both columns — and it was stacking them anyway. What this grid
   collapses on is its own width, which only falls below two columns when the
   viewport does. */
.enrich-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
/* The last row of a card is a single field in the left column, so the card's
   own bottom padding does the spacing and the field's margin would double it. */
.enrich-grid > .field:last-child { margin-bottom: 12px; }
.enrich-hint { margin: 0 0 12px; font-size: 11.5px; color: var(--muted); line-height: 1.5; }
.enrich-add { margin: 0 0 14px; }
.enrich-note { margin: 4px 0 0; font-size: 11.5px; color: var(--muted); line-height: 1.5; }

@media (max-width: 620px) {
  /* The modal is 100vw - 32px here, so this is the point where its own columns
     genuinely stop fitting — not the point where the page's would. */
  .enrich-grid { grid-template-columns: 1fr; }
}

/* ── the loan book on the profile panel ─────────────────────────────────── */
/* A delinquent account is tinted for the whole row, as the admin panel tints
   it: DPD is the one thing on this table somebody is scanning for. */
.profile-table tr.is-dpd > td { background: var(--danger-soft); }
.profile-table .is-overdue { color: var(--danger); font-weight: 600; }
/* A figure a person typed, as opposed to one the credit report gave. The tint
   is the whole point — it is how a reader tells the two apart at a glance. */
.profile-table .is-typed { background: var(--ok-soft); }
.profile-table__total > td { border-top: 1px solid var(--line); font-weight: 600;
  background: var(--surface-2); }
.loan-edited { display: block; font-size: 10px; font-weight: 400; color: var(--emerald-ink); }

.cell-edit { display: inline-flex; align-items: center; gap: 2px; justify-content: flex-end; }
.cell-edit input { width: 70px; text-align: right; padding: 3px 5px; font: inherit; font-size: 12px;
  border: 1px solid var(--line); border-radius: 5px; background: var(--surface); color: var(--ink);
  font-variant-numeric: tabular-nums; }
.cell-edit input.is-narrow { width: 48px; }
.cell-edit input:focus { outline: none; border-color: var(--emerald); }

/* The three provenances, per cell, and they win over a delinquent row's tint —
   in a red row a reader still has to tell a typed figure from a reported one.
   Yellow is the figure NOBODY reported or confirmed: worked out from the rest
   of the loan, as the admin panel shows it, and saved only if somebody takes it. */
.profile-table tr > td.is-typed { background: var(--ok-soft); }
.profile-table tr > td.is-calc { background: #FEF9E7; }
.profile-table .is-saving { color: var(--emerald-ink); font-weight: 600; }
.profile-table tr.is-closed > td { color: var(--muted); }
.profile-table .tick-cell { width: 30px; padding-right: 0; }
.profile-table .tick-cell input { margin: 0; vertical-align: middle; }

/* The three account tables — loans, guaranteed, cards — set the way the admin
   panel sets them: 12px, 5px cells, headers in plain case. Sixteen columns are
   scanned ACROSS, and the uppercase, letter-spaced headers the rest of the
   profile uses were a third of this table's width on their own. A header wider
   than its figures ("Could get %") takes a second line, so the loans table fits
   a 1440px screen whole (founder, 30 September 2026). */
/* Prefixed with table.dataTable because the shared DataTables header rule is,
   and it would otherwise out-rank these. */
table.dataTable.profile-table--accounts { font-size: 12px; }
table.dataTable.profile-table--accounts > thead > tr > th { padding: 7px 5px;
  font: 500 12px/1.3 var(--font); letter-spacing: 0; text-transform: none; white-space: normal; vertical-align: bottom; }
table.dataTable.profile-table--accounts > tbody > tr > td,
table.dataTable.profile-table--accounts > tfoot > tr > td { padding: 7px 5px; }
/* One line per account, as the panel shows it. A narrower window scrolls the
   table sideways rather than folding a lender's name into three lines and a
   date in half. */
table.dataTable.profile-table--accounts > tbody > tr[data-loan] > td { white-space: nowrap; }
/* ...and Save stays in reach while it does: the controls column is pinned to
   the right edge, header to totals, each cell painted with its own row's colour
   so nothing passing beneath shows through. */
table.dataTable.profile-table--controls > thead > tr > th:last-child,
table.dataTable.profile-table--controls > tbody > tr[data-loan] > td.loan-actions,
table.dataTable.profile-table--controls > tfoot > tr > td.loan-actions {
  position: sticky; right: 0; z-index: 1; box-shadow: -8px 0 8px -8px rgba(15, 28, 46, .2); }
table.dataTable.profile-table--controls > thead > tr > th:last-child { background: var(--surface-2); }
table.dataTable.profile-table--controls > tbody > tr[data-loan] > td.loan-actions { background: var(--surface); }
table.dataTable.profile-table--controls > tbody > tr[data-loan]:hover > td.loan-actions { background: var(--surface-2); }
table.dataTable.profile-table--controls > tbody > tr.is-dpd > td.loan-actions { background: var(--danger-soft); }
table.dataTable.profile-table--controls > tfoot > tr > td.loan-actions { background: var(--surface-2); }
/* Save and four icons as one set, the same on every row, so they line up down the column. */
.loan-actions__set { display: inline-flex; align-items: center; gap: 0; vertical-align: middle; }
.profile-table--accounts .dpd-open { padding: 0; border: 0; background: none; font: inherit;
  color: inherit; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.profile-table--accounts .cell-edit input.is-invalid { border-color: var(--danger);
  box-shadow: 0 0 0 2px var(--danger-soft); }
.profile-table--accounts .loan-actions { white-space: nowrap; }
.profile-table--accounts .btn-icon { width: 24px; height: 24px; border-radius: 6px;
  border-color: transparent; background: none; vertical-align: middle; }
.profile-table--accounts .btn-icon:hover { border-color: var(--line); background: var(--surface-2); }
.profile-table--accounts .cell-edit input { width: 64px; }
.profile-table--accounts .cell-edit input.is-narrow { width: 46px; }
.profile-table--accounts .cell-edit input[name="market_value"] { width: 80px; }

/* The row's Save — a word, as both MaxOS screens have it, not an icon. */
.btn-save { height: 24px; padding: 0 11px; margin-right: 4px; vertical-align: middle;
  font: inherit; font-size: 11px; font-weight: 500; color: var(--ink);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 999px; cursor: pointer; }
.btn-save:hover:not(:disabled) { border-color: var(--emerald); color: var(--emerald-ink); }
.btn-save:focus-visible { outline: 2px solid var(--emerald); outline-offset: 1px; }
.btn-save:disabled { opacity: .45; cursor: not-allowed; }

/* An older staff figure on a cell the bureau has since reported, and the
   control that takes it off. */
.stale-fill { display: block; margin-left: auto; padding: 0; border: 0; background: none;
  font: inherit; font-size: 10px; color: var(--warn); cursor: pointer;
  text-decoration: underline dotted; }
.stale-fill:disabled { opacity: .5; cursor: default; }

.btn-icon--danger:hover { color: var(--danger); }

/* A menu item that has been switched off. It was styled inline until the
   attribute turned out never to have been applied — the expression built it
   inside an escaped EJS tag, so the row rendered style=&quot;…&quot; and kept
   its full opacity. A class cannot fail that way. */
.dataTable tr.is-off > td { opacity: .55; }

/* ── the EMI calculator ─────────────────────────────────────────────────── */
.emc { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.emc__side { border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 15px 2px; }
.emc__side h3 { margin: 0 0 12px; font-size: 13px; font-weight: 600; color: var(--ink); }
.emc__side .field { margin-bottom: 13px; }
.emc__auto { font-size: 11px; font-weight: 400; color: var(--muted); margin-left: 5px; }
.emc__help { margin: 10px 0 0; font-size: 11.5px; color: var(--muted); line-height: 1.55; }
/* A derived box reads as an answer, not as something somebody typed. */
.emc input[data-derived] { color: var(--emerald-ink); background: var(--surface-2); }
.emc__summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
  margin-top: 14px; padding: 12px 14px; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: var(--radius); }
.emc__summary span { display: block; font-size: 11px; color: var(--muted); }
.emc__summary b { font-size: 14px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.emc__summary b.is-good { color: var(--emerald-ink); }
.emc__summary b.is-bad { color: var(--danger); }
.emc__foot { justify-content: stretch; }
.emc__send { width: 100%; }

@media (max-width: 620px) {
  .emc { grid-template-columns: 1fr; }
  .emc__summary { grid-template-columns: 1fr 1fr; }
}
.applicant__warn { color: var(--warn); }
.applicant__foir.is-stretched b { color: var(--warn); }
.applicant__foir.is-high b { color: var(--danger); }
.applicant__co { margin: 4px 0 0; font-size: 12px; color: var(--ink-2); display: flex; gap: 8px; flex-wrap: wrap; }
.applicant__co b { font-weight: 600; }
.applicant__co span { color: var(--muted); }

/* ── assign property ────────────────────────────────────────────────────── */
.prop-current { border: 1px solid var(--ok); background: var(--ok-soft); border-radius: var(--radius);
  padding: 11px 13px; margin-bottom: 14px; }
.prop-current__top { display: flex; align-items: flex-start; gap: 8px; }
.prop-current__h { margin: 0; flex: 1; font-size: 12px; font-weight: 600; color: #047857; }
.prop-current__addr { margin: 4px 0 0; font-size: 13px; font-weight: 600; color: var(--ink); }
.prop-current p.muted { margin: 2px 0 0; font-size: 12px; }
.prop-lead { margin: 0 0 8px; font-size: 12px; color: var(--muted); }
.prop-none { margin: 0 0 14px; padding: 16px 0; text-align: center; font-size: 12px; color: var(--muted); }
.prop-list { list-style: none; margin: 0 0 16px; padding: 0; display: flex; flex-direction: column; gap: 7px; }
/* Each row is the address plus its copy button. The address itself is the
   control — clicking it assigns — so it is a <button>, not a label. */
.prop-list li { display: flex; align-items: stretch; gap: 7px; }
.prop-option { flex: 1; min-width: 0; text-align: left; padding: 10px 12px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
  font: inherit; color: var(--ink); }
.prop-option:hover:not(:disabled) { border-color: var(--emerald); background: var(--surface-2); }
.prop-option.is-on { border-color: var(--emerald); background: var(--ok-soft); }
.prop-option:disabled { cursor: default; opacity: .7; }
.prop-option b { display: block; font-size: 12.5px; font-weight: 600; line-height: 1.4; }
.prop-option small { display: block; margin-top: 2px; font-size: 11.5px; }
.prop-copy { flex: none; align-self: stretch; border: 1px solid var(--line); border-radius: var(--radius); }
.prop-assign { width: 100%; margin-top: 2px; }
.prop-clear { width: 100%; margin-top: 8px; color: var(--danger); }
.btn-icon--has-notes { color: var(--info); }
.btn-icon--has-property { color: var(--emerald-ink); }
/* A field that belongs to one employment type only. The client shows the set
   that matches and hides the other, so a salaried applicant is never asked for
   a turnover. */
[data-person][data-kind="salaried"] [data-when="business"],
[data-person][data-kind="business"] [data-when="salaried"] { display: none; }
.applicant__line { margin: 0 0 3px; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--ink-2); }
.applicant__line b { font-weight: 600; color: var(--ink); }
.applicant__line > span { color: var(--muted); }
.applicant__line .applicant__pay { margin-left: auto; font-weight: 600; color: var(--ink); white-space: nowrap; }
.applicant__emi { color: var(--warn) !important; }
.applicant__sum { margin: 7px 0 0; padding-top: 7px; border-top: 1px solid rgba(22,163,74,.16);
  font-size: 12.5px; color: var(--ink-2); }

/* ── the twelve-month payment strip ─────────────────────────────────────── */
.dpd-strip { list-style: none; margin: 0 0 12px; padding: 0;
  display: grid; grid-template-columns: repeat(12, 1fr); gap: 4px; }
.dpd-month { text-align: center; border-radius: 6px; padding: 8px 2px 6px;
  border: 1px solid var(--line); background: var(--surface); }
.dpd-month b { display: block; font-size: 12px; font-weight: 600; line-height: 1.2; }
.dpd-month small { display: block; margin-top: 3px; font-size: 9px; color: var(--muted);
  white-space: nowrap; }
.dpd-month.is-ok { border-color: var(--ok); background: var(--ok-soft); }
.dpd-month.is-ok b { color: #047857; }
.dpd-month.is-late { border-color: var(--danger); background: var(--danger-soft); }
.dpd-month.is-late b { color: var(--danger); }
/* A month nobody reported is not a clean month. Neutral, and visibly not green. */
.dpd-month.is-unreported { background: var(--surface-2); }
.dpd-month.is-unreported b { color: var(--faint); }
.acct-status { display: block; font-size: 10px; }
@media (max-width: 620px) { .dpd-strip { grid-template-columns: repeat(6, 1fr); } }

/* ── the application-details sub-row ────────────────────────────────────── */
.appdetail-row > td { padding: 0 8px 10px; background: var(--surface-2); }
.appdetail { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px;
  background: var(--surface); }
.appdetail__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px 16px; }
.appdetail__grid span { display: block; font-size: 10.5px; color: var(--muted); }
.appdetail__grid b { font-size: 12.5px; font-weight: 600; color: var(--ink); }
.appdetail__block { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line-2); }
.appdetail__block h4 { margin: 0 0 7px; font-size: 12px; font-weight: 600; color: var(--ink);
  display: flex; align-items: baseline; gap: 10px; }
.appdetail__facts { margin: 0; display: flex; gap: 14px; flex-wrap: wrap; font-size: 12.5px; }
.appdetail__facts b { font-weight: 600; color: var(--muted); font-size: 11px; }
.appdetail__none { margin: 0; font-size: 11.5px; color: var(--muted); line-height: 1.5; }

/* CERSAI. Three positions, and the muted one is the important one: it means
   nobody has looked, which is not the same as no charge. */
.cersai { margin: 0; padding: 9px 11px; border-radius: var(--radius); font-size: 12px;
  border: 1px solid var(--line); }
.cersai b { display: block; margin-bottom: 2px; }
.cersai span { color: var(--muted); line-height: 1.5; }
.cersai--muted { background: var(--surface-2); }
.cersai--ok { background: var(--ok-soft); border-color: var(--ok); }
.cersai--ok b { color: #047857; }
.cersai--warn { background: var(--warn-soft); border-color: var(--warn); }
.cersai--warn b { color: var(--warn); }
.cersai-list { list-style: none; margin: 8px 0 0; padding: 0; display: flex;
  flex-direction: column; gap: 6px; }
.cersai-list li { border: 1px solid var(--line); border-radius: 7px; padding: 8px 10px;
  background: var(--surface); font-size: 12px; }
.cersai-list li.is-satisfied { opacity: .6; }
.cersai-list b { display: block; }
.cersai-list small { display: block; margin-top: 2px; }

/* Sortable column headings. */
.profile-table th.is-sortable { cursor: pointer; user-select: none; }
.profile-table th.is-sortable:hover { color: var(--ink); }
.sort-mark { display: inline-block; width: 10px; font-size: 9px; color: var(--emerald-ink); }
/* On the account tables the headers may take two lines, so the arrow takes no width of its own: a header never wraps
   just to make room for it, and it draws into the cell's padding once a column is sorted. */
.profile-table--accounts .sort-mark { width: 0; }

@media (max-width: 900px) { .appdetail__grid { grid-template-columns: repeat(2, 1fr); } }

/* ── the consolidation tick bar ─────────────────────────────────────────── */
.consol-bar { display: flex; align-items: center; gap: 12px; padding: 10px 14px; margin-bottom: 14px;
  border: 1px solid var(--emerald); border-radius: var(--radius); background: var(--ok-soft); }
.consol-bar span { font-size: 12.5px; font-weight: 600; color: #047857; flex: 1; }
.consol-tick { margin-right: 5px; }

/* ── the consolidation panel ────────────────────────────────────────────── */
.consol { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.consol__side { border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 15px; }
.consol__side h3 { margin: 0 0 11px; font-size: 13px; font-weight: 600; color: var(--ink); }
.consol__h4 { margin: 14px 0 8px; font-size: 12px; font-weight: 600; color: var(--ink); }
.consol__h4:first-of-type { margin-top: 0; }
.consol__types { list-style: none; margin: 0 0 12px; padding: 0; display: flex;
  flex-direction: column; gap: 5px; }
.consol__types li { display: flex; align-items: baseline; gap: 6px; font-size: 12.5px; }
.consol__types b { font-weight: 600; color: var(--ink); }
.consol__types em { margin-left: auto; font-style: normal; font-weight: 600;
  font-variant-numeric: tabular-nums; }
.consol__figs { margin: 0; padding: 10px 0 0; border-top: 1px solid var(--line-2);
  display: flex; flex-direction: column; gap: 6px; }
.consol__figs > div { display: flex; align-items: baseline; gap: 10px; }
.consol__figs dt { font-size: 12px; color: var(--muted); flex: 1; }
.consol__figs dd { margin: 0; font-size: 13px; font-weight: 600; color: var(--ink);
  font-variant-numeric: tabular-nums; }
.consol__figs--out { margin-top: 14px; padding-top: 12px; }
.consol__figs--out dd { font-size: 15px; }
.consol__figs dd.is-good { color: var(--emerald-ink); }
.consol__figs dd.is-bad { color: var(--danger); }
/* A blend built from part of the inputs is not the blend, and the panel says so
   where the figures are rather than in a banner nobody reads. */
.consol__warn { margin: 10px 0 0; padding: 8px 10px; border-radius: var(--radius);
  background: var(--warn-soft); color: var(--warn); font-size: 11.5px; line-height: 1.5; }
.consol__included { list-style: none; margin: 0; padding: 0; display: flex;
  flex-direction: column; gap: 4px; }
.consol__included li { display: flex; gap: 10px; font-size: 12px; }
.consol__included span { flex: 1; color: var(--ink-2); }
.consol__included em { font-style: normal; font-variant-numeric: tabular-nums; color: var(--ink); }
.consol__note { margin: 8px 0 0; font-size: 11.5px; color: var(--muted); line-height: 1.5; }
.consol__side .field { margin-bottom: 11px; }
@media (max-width: 720px) { .consol { grid-template-columns: 1fr; } }

/* ── the complete file (contract v1.19): everything the application fetched, shown in full ──────────────────────── */
/* Where each consent stands, under the name: green while live, red once withdrawn, grey once its term ended. */
.access-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 7px; }
.access-tags .badge { white-space: normal; text-align: left; }
.file__h { font-size: 12.5px; font-weight: 600; color: var(--ink); margin: 18px 0 8px; }
.file__h:first-child { margin-top: 0; }
.deflist--file { font-size: 13px; }
.deflist--file dd { overflow-wrap: anywhere; }
/* A monospace value in a cell, not a chip (`.mono` carries a border and a fill). */
.mono-val { font-family: var(--mono); font-size: 12.5px; }
.profile-table--file td { vertical-align: top; }
.profile-table--file tr.is-failed > td { background: var(--danger-soft); }
/* The month grid, or a call's request and answer, opened under its row. */
.file-grid > td { background: var(--surface-2); padding: 10px 12px; }
/* Under 30 days late: amber, between the green of on time and the red of 30 and more. */
.dpd-month.is-warn { border-color: var(--warn); background: var(--warn-soft); }
.dpd-month.is-warn b { color: var(--warn); }
/* A paper as received, or an area of the paid report: closed to its title, open to what is inside. */
.fold { border: 1px solid var(--line); border-radius: 8px; margin-bottom: 10px; background: var(--surface); }
.fold > summary { cursor: pointer; padding: 9px 12px; font-size: 13px; font-weight: 600; color: var(--ink);
  list-style: none; display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::before { content: "▸"; color: var(--muted); font-size: 11px; }
.fold[open] > summary::before { content: "▾"; }
.fold > summary .muted { font-weight: 500; font-size: 12px; }
.fold > .jtree, .fold > p { margin: 0 12px 10px; }
.fold__body { padding: 0 12px 10px; }
.fold__body > .card__note { margin-bottom: 6px; }
.fold__body .tablewrap { margin-top: 8px; }
/* The JSON tree (lib/json-view.js): folds per object and array, a line per value. */
.jtree { font: 12px/1.6 var(--mono); color: var(--ink-2); overflow: auto; max-height: 560px;
  padding: 8px 10px; background: var(--surface-2); border-radius: 6px; }
.jtree__node > summary { cursor: pointer; list-style: none; }
.jtree__node > summary::-webkit-details-marker { display: none; }
.jtree__node > summary::before { content: "▸ "; color: var(--muted); }
.jtree__node[open] > summary::before { content: "▾ "; }
.jtree__kids { padding-left: 18px; margin-left: 4px; border-left: 1px dotted var(--line); }
.jtree__key { color: var(--ink); font-weight: 600; }
.jtree__str { color: #047857; white-space: pre-wrap; overflow-wrap: anywhere; }
.jtree__num { color: #1D4ED8; }
.jtree__bool { color: #B45309; }
.jtree__null { color: var(--faint); }
.jtree__kind { color: var(--muted); }
/* A partner's call: what was sent beside what came back. */
.call-io { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.call-io h4 { margin: 0 0 6px; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
@media (max-width: 900px) { .call-io { grid-template-columns: 1fr; } }

/* ── the customer page, fitted (founder, 3 October 2026): one card grammar, one rhythm ─────────────────────────── */
/* Every block on the page is a child of a stack: one gap between them, no margins of their own, and a grid child that
   may shrink (`min-width: 0`), so a wide table scrolls inside its card instead of widening the page. */
.stack { display: grid; gap: 16px; }
.stack > * { min-width: 0; }
.stack > .tiles { margin-bottom: 0; }
.stack > .alert { margin: 0; }
.stack > #loan-profile:empty { display: none; }
.stack--side { align-self: start; }
.cols > * { min-width: 0; }
.card { min-width: 0; }
/* The card's head: the title left, the meta right; on a narrow card the meta drops under the title, still on the
   right, rather than pushing out of the card. */
/* Scoped to the customer page: the only page whose card heads carry a right-side meta that must wrap under the
   title on a narrow card; the other pages' heads keep their one-line layout. */
.page--customer .card__head { flex-wrap: wrap; row-gap: 8px; }
.page--customer .card__head h2 { min-width: 0; }
.card__meta { margin-left: auto; display: flex; align-items: center; justify-content: flex-end; gap: 6px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--muted); text-align: right; }
.card__meta b { color: var(--ink); font-weight: 600; }
.card__meta .btn { white-space: nowrap; }
/* One empty state everywhere: a muted line in the card's own padding; no borders, no icon. */
.card__empty { margin: 0; padding: 16px 20px; font-size: 12.5px; color: var(--muted); }
/* A line of explanation inside a card; `--ink` where it is the thing itself (a recommendation), not a note on it. */
.card__note { margin: 0; font-size: 12.5px; color: var(--muted); line-height: 1.5; }
.card__note--ink { color: var(--ink-2); }
.card__intro { margin: 0; padding: 14px 20px 0; font-size: 12.5px; color: var(--muted); line-height: 1.5; }
.card__intro + .thread { margin-top: 12px; }
.card__body--form { padding-bottom: 0; }
.card__body--form .btn { margin-bottom: 18px; }
.card__figure { font-size: 30px; font-weight: 600; color: var(--ink); letter-spacing: -.02em; line-height: 1.1;
  font-variant-numeric: tabular-nums; }
/* The head of the page: the avatar, then a column that may shrink, so the consent tags wrap inside it. */
.who { display: flex; gap: 16px; align-items: center; min-width: 0; flex: 1; }
.who > div { min-width: 0; flex: 1; }
.who h1 { margin-bottom: 4px; }
.who__row { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin: 7px 0 0; }
.who__note { font-size: 12.5px; color: var(--muted); }
/* The sidebar's label/value cards share one label column, so Identity and Profile line up; a long value wraps. */
.deflist--side { grid-template-columns: minmax(104px, 128px) minmax(0, 1fr); gap: 10px 16px; align-items: baseline;
  font-size: 13px; }
.deflist--side dt { font-size: 12.5px; }
.deflist--side dd { min-width: 0; overflow-wrap: anywhere; }
.list__figure { font-size: 13px; font-weight: 600; color: var(--ink); white-space: nowrap; }
/* Tables of the file: cells on one line, so a wide table scrolls in its own wrapper rather than growing tall; a column
   of words (`.wrap`) is the exception. The 36-month grid keeps a readable width at 1280 and 1440. */
.profile-table--file th, .profile-table--file td { white-space: nowrap; }
.profile-table--file td.wrap { white-space: normal; min-width: 200px; max-width: 460px; overflow-wrap: anywhere; }
.profile-table--file .dpd-strip { min-width: 600px; }
/* A table that is the whole card body, flush with its edges. */
.profile-table--flush tr > :first-child { padding-left: 20px; }
.profile-table--flush tr > :last-child { padding-right: 20px; }
.profile-table--flush tbody tr:last-child td { border-bottom: 0; }
/* The paid report. */
.report__headline { margin: 0 0 4px; font-size: 15px; font-weight: 600; color: var(--ink); line-height: 1.4; }
.report__conclusion { margin: 0 0 14px; font-size: 13px; color: var(--ink-2); }
.report__steps { margin: 6px 0 0; padding-left: 18px; font-size: 12.5px; color: var(--ink-2); line-height: 1.5; }
.report__steps li { margin: 2px 0; }
.finding__title { display: block; font-weight: 600; color: var(--ink); }
.finding__detail { display: block; font-size: 12px; color: var(--muted); white-space: normal; font-weight: 400; }
/* The customer's own chat with Max: a thread that scrolls inside the card, theirs on the right, Max's on the left. */
.thread { max-height: 420px; overflow-y: auto; padding: 14px 20px 18px; display: grid; gap: 10px;
  background: var(--surface-2); border-top: 1px solid var(--line-2); border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
.msg { max-width: 78%; padding: 9px 12px; border-radius: 12px; font-size: 13px; line-height: 1.45; color: var(--ink);
  white-space: pre-wrap; overflow-wrap: anywhere; background: var(--surface); border: 1px solid var(--line); }
.msg--user { justify-self: end; background: var(--emerald-soft); border-color: #BBF7D0; border-bottom-right-radius: 4px; }
.msg--max { justify-self: start; border-bottom-left-radius: 4px; }
.msg small { display: block; margin-top: 4px; font-size: 10.5px; color: var(--muted); }
.msg--user small { text-align: right; }
/* The state an RM records, in the loans panel's grid: a dropdown the width of its words, never a stretched box. */
.state-pick { width: auto; height: 28px; font-weight: 500; vertical-align: middle; }
@media (max-width: 1080px) { .deflist--side { grid-template-columns: minmax(104px, 160px) minmax(0, 1fr); } }
.list--tight { margin-top: 6px; }
.enrich-hint--flush { margin: 0; }
/* An asset's own details, under its name: an insurance cover's type and premium, a loan answer's rate. */
.asset-detail { display: block; font-size: 11.5px; color: var(--muted); white-space: normal; font-weight: 400; }
/* The loans panel's Documents section: the bureau report's line, then the income-tax documents year by year. */
.docs { display: grid; gap: 8px; }
.docs__row { display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; font-size: 12.5px; color: var(--ink-2); }
.docs__row b { color: var(--ink); }
.docs__row .link { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; }
.docs__row--head { margin-top: 6px; }
.profile-table--docs td, .profile-table--docs th { white-space: nowrap; }
.profile-table--docs .link { display: inline-flex; align-items: center; gap: 4px; }
/* A card anchored to from the loans panel clears the top bar when scrolled to. */
#credit-report { scroll-margin-top: 84px; }
/* Enrich Profile, pre-filled from the return (founder, 3 October 2026): the line that says so, and a light tint on
   every value that is ours until the RM touches it. */
.enrich-hint--source { display: flex; align-items: center; gap: 6px; margin: -4px 0 12px; color: #1D4ED8; }
.enrich-card input[data-prefilled], .enrich-card select[data-prefilled] { background: var(--info-soft); }
