/* "App Light" look (Task 7.13a, DECISIONS F81), on top of the vendored
   Bootstrap 5.3. Our colors are tokens (--nw-*), mapped onto Bootstrap's own
   variables, so bootstrap.min.css stays byte-for-byte as shipped.

   Light is the default; static/js/theme.js switches <html data-bs-theme> to
   dark when the device is set to dark. tests/test_theme.py reads the two
   token blocks below and checks WCAG AA contrast, so keep each token on its
   own line as `--nw-name: #rrggbb;`.

   The given accent (#0a7cff light, #0a84ff dark) is used for marks that
   aren't text (chart line, focus ring, active tab icon). Text and filled
   buttons in light mode use --nw-link, a deeper blue, because #0a7cff is only
   3.9:1 on white and AA needs 4.5:1. Field borders use --nw-field-line, 3:1
   against the card and the page, so a box or checkbox shows where to tap. */

:root,
[data-bs-theme=light] {
  --nw-bg: #f2f2f7;
  --nw-card: #ffffff;
  --nw-ink: #111114;
  --nw-ink-2: #6e6e76;
  --nw-pill: #e5e5ea;
  --nw-line: #d8d8de;
  --nw-field-line: #86868e;
  --nw-accent: #0a7cff;
  --nw-link: #0066d6;
  --nw-btn: #0066d6;
  --nw-btn-hover: #0056b8;
  --nw-on-btn: #ffffff;
  --nw-gain: #176f31;
  --nw-gain-bg: #e3f3e7;
  --nw-loss: #c0261d;
  --nw-loss-bg: #fde8e7;
  --nw-tabbar: #ffffff;
  --nw-chart-asset: #2a78d6;
  --nw-chart-liability: #eb6834;
  --nw-chart-available: #279a7e;
  --nw-chart-grid: #e5e5ea;
  --nw-chart-stale: #8a5a00;
  --nw-chart-missing: #b02a37;
  --nw-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
  --nw-area-alpha: 0.22;

  --bs-body-bg: var(--nw-bg);
  --bs-body-bg-rgb: 242, 242, 247;
  --bs-body-color: var(--nw-ink);
  --bs-body-color-rgb: 17, 17, 20;
  --bs-emphasis-color: var(--nw-ink);
  --bs-emphasis-color-rgb: 17, 17, 20;
  --bs-secondary-color: var(--nw-ink-2);
  --bs-secondary-color-rgb: 110, 110, 118;
  --bs-secondary-bg: var(--nw-pill);
  --bs-tertiary-bg: var(--nw-pill);
  --bs-border-color: var(--nw-line);
  --bs-link-color: var(--nw-link);
  --bs-link-color-rgb: 0, 102, 214;
  --bs-link-hover-color: var(--nw-btn-hover);
  --bs-link-hover-color-rgb: 0, 86, 184;
  --bs-primary: var(--nw-link);
  --bs-primary-rgb: 0, 102, 214;
  --bs-focus-ring-color: rgba(10, 124, 255, 0.35);
}

[data-bs-theme=dark] {
  --nw-bg: #000000;
  --nw-card: #1c1c1e;
  --nw-ink: #f2f2f7;
  --nw-ink-2: #98989f;
  --nw-pill: #2c2c2e;
  --nw-line: #38383a;
  --nw-field-line: #7a7a82;
  --nw-accent: #0a84ff;
  --nw-link: #0a84ff;
  --nw-btn: #0071e3;
  --nw-btn-hover: #0062c4;
  --nw-on-btn: #ffffff;
  --nw-gain: #30d158;
  --nw-gain-bg: #0f2e17;
  --nw-loss: #ff6961;
  --nw-loss-bg: #3b1513;
  --nw-tabbar: #1c1c1e;
  --nw-chart-asset: #4a90e2;
  --nw-chart-liability: #eb6834;
  --nw-chart-available: #279a7e;
  --nw-chart-grid: #38383a;
  --nw-chart-stale: #ffda6a;
  --nw-chart-missing: #ea868f;
  --nw-shadow: none;
  --nw-area-alpha: 0.32;

  --bs-body-bg: var(--nw-bg);
  --bs-body-bg-rgb: 0, 0, 0;
  --bs-body-color: var(--nw-ink);
  --bs-body-color-rgb: 242, 242, 247;
  --bs-emphasis-color: var(--nw-ink);
  --bs-emphasis-color-rgb: 242, 242, 247;
  --bs-secondary-color: var(--nw-ink-2);
  --bs-secondary-color-rgb: 152, 152, 159;
  --bs-secondary-bg: var(--nw-pill);
  --bs-tertiary-bg: var(--nw-pill);
  --bs-border-color: var(--nw-line);
  --bs-link-color: var(--nw-link);
  --bs-link-color-rgb: 10, 132, 255;
  --bs-link-hover-color: #409cff;
  --bs-link-hover-color-rgb: 64, 156, 255;
  --bs-primary: var(--nw-link);
  --bs-primary-rgb: 10, 132, 255;
  --bs-focus-ring-color: rgba(10, 132, 255, 0.45);
}

/* --- Type ---------------------------------------------------------------- */
:root {
  --bs-body-font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, system-ui, sans-serif;
  --bs-border-radius: 10px;
  --bs-border-radius-sm: 8px;
  --bs-border-radius-lg: 14px;
  --nw-radius-card: 18px;
}
body { -webkit-font-smoothing: antialiased; }
/* Money lines up in columns: digits all the same width. */
.table, .nw-num, .nw-headline-figure, .nw-pill { font-variant-numeric: tabular-nums; }

/* --- Cards, tables ------------------------------------------------------- */
.card {
  --bs-card-bg: var(--nw-card);
  --bs-card-border-width: 0;
  --bs-card-border-radius: var(--nw-radius-card);
  --bs-card-inner-border-radius: var(--nw-radius-card);
  --bs-card-spacer-x: 1.125rem;
  --bs-card-spacer-y: 1.125rem;
  box-shadow: var(--nw-shadow);
}
.table { --bs-table-bg: transparent; }
.table > :not(caption) > * > * { border-bottom-color: var(--nw-line); }

/* --- Buttons and fields -------------------------------------------------- */
.btn-primary {
  --bs-btn-color: var(--nw-on-btn);
  --bs-btn-bg: var(--nw-btn);
  --bs-btn-border-color: var(--nw-btn);
  --bs-btn-hover-color: var(--nw-on-btn);
  --bs-btn-hover-bg: var(--nw-btn-hover);
  --bs-btn-hover-border-color: var(--nw-btn-hover);
  --bs-btn-active-color: var(--nw-on-btn);
  --bs-btn-active-bg: var(--nw-btn-hover);
  --bs-btn-active-border-color: var(--nw-btn-hover);
  --bs-btn-disabled-bg: var(--nw-btn);
  --bs-btn-disabled-border-color: var(--nw-btn);
}
.btn-outline-primary {
  --bs-btn-color: var(--nw-link);
  --bs-btn-border-color: var(--nw-link);
  --bs-btn-hover-color: var(--nw-on-btn);
  --bs-btn-hover-bg: var(--nw-btn);
  --bs-btn-hover-border-color: var(--nw-btn);
  --bs-btn-active-color: var(--nw-on-btn);
  --bs-btn-active-bg: var(--nw-btn);
  --bs-btn-active-border-color: var(--nw-btn);
}
/* A picked choice in a row of choices (Money out / Money in, a kind of repair)
   is a dark outline, not the blue of the page's one next step (review 3 UX6). */
.btn-check:checked + .btn-outline-primary {
  color: var(--nw-ink);
  background: var(--nw-card);
  border-color: var(--nw-ink);
  box-shadow: inset 0 0 0 1px var(--nw-ink);
  font-weight: 600;
}
.btn-outline-secondary {
  --bs-btn-color: var(--nw-ink);
  --bs-btn-border-color: var(--nw-line);
  --bs-btn-hover-color: var(--nw-ink);
  --bs-btn-hover-bg: var(--nw-pill);
  --bs-btn-hover-border-color: var(--nw-line);
  --bs-btn-active-color: var(--nw-ink);
  --bs-btn-active-bg: var(--nw-pill);
  --bs-btn-active-border-color: var(--nw-line);
}
.form-control, .form-select { background-color: var(--nw-card); border-color: var(--nw-field-line); }
.form-check-input { --bs-form-check-bg: var(--nw-card); border-color: var(--nw-field-line); }
/* Bootstrap's red and green text are under 4.5:1 (#dc3545 is 4.06 on white);
   ours pass in both themes (tests/test_theme.py). Over budget, past due. */
.text-danger { color: var(--nw-loss) !important; }
.text-success { color: var(--nw-gain) !important; }
/* A photo or file button is a label for a hidden file input just after it:
   a keyboard user's focus lands on the input, so the label shows the ring. */
label.btn:has(+ input.visually-hidden:focus-visible) { outline: 2px solid var(--nw-accent); outline-offset: 2px; }
/* "Skip to content" (review A6): hidden until a keyboard user's first Tab,
   then a button in the top corner that jumps past the menu to <main>. */
.nw-skip-link:focus { position: fixed; top: .5rem; left: .5rem; z-index: 1090; padding: .5rem 1rem; border-radius: .5rem; color: var(--nw-on-btn); background: var(--nw-btn); }
#nw-main:focus { outline: none; }
/* Phones and small tablets: every button (small ones were about 31 px, the
   rest 38) is at least 44 by 44 px, a thumb, so a short word ("Go") or a bare
   arrow is as wide as it is tall (review PHN2). A text button inside a
   sentence (align-baseline) stays a word in the line. */
@media (max-width: 991.98px) {
  .btn:not(.align-baseline) {
    min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; justify-content: center;
  }
  /* Tabs (What I own and owe, a report's parts) are taps too (review PHN2). */
  .nav-pills .nav-link { min-height: 44px; display: inline-flex; align-items: center; }
  /* Fold-outs in cards (the rehab's Change, Add a work item, Show N more) and
     small links standing alone (.nw-tap: Start one, Change stage) are 44 px
     tall too (review 3 PHN1). :where() keeps the rule weaker than a fold-out
     with its own look (the header's More and filter). */
  :where(.card) details > summary { min-height: 44px; padding-block: 0.625rem; }
  .nw-tap { min-height: 44px; display: inline-flex; align-items: center; }
  /* The page header's More items (Change stage, downloads) are taps too (F-page-header). */
  .nw-head-more .dropdown-item { min-height: 44px; display: flex; align-items: center; }
  .nw-head-tab { min-height: 44px; display: inline-flex; align-items: center; }
}
/* Phones: small fields get 16 px text, so the iPhone doesn't zoom in when
   one is tapped, and every field is 44 px tall. */
@media (max-width: 767.98px) {
  .form-control-sm, .form-select-sm { font-size: 1rem; }
  .form-control:not(textarea), .form-select { min-height: 44px; }
}

/* --- Alerts: borderless tinted cards ------------------------------------- */
.alert {
  --bs-alert-border-color: transparent;
  --bs-alert-border-radius: 14px;
}

/* --- Pills and the segmented control ------------------------------------- */
.nw-pill {
  display: inline-flex; align-items: center; gap: 0.25rem;
  padding: 0.2rem 0.6rem; border-radius: 999px;
  background: var(--nw-pill); color: var(--nw-ink);
  font-size: 0.8125rem; line-height: 1.3;
}
.nw-pill-gain { background: var(--nw-gain-bg); color: var(--nw-gain); }
.nw-pill-loss { background: var(--nw-loss-bg); color: var(--nw-loss); }
.nw-segment {
  display: flex; width: 100%; padding: 2px; gap: 2px;
  background: var(--nw-pill); border-radius: 10px;
}
.nw-segment > .btn {
  flex: 1 1 0; border: 0; border-radius: 8px !important;
  color: var(--nw-ink); background: transparent; font-weight: 500;
}
.nw-segment > .btn:hover { background: transparent; color: var(--nw-ink); }
.nw-segment > .btn.active { background: var(--nw-card); color: var(--nw-ink); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12); }

/* --- Page title and the date pill (dashboard) ---------------------------- */
.nw-page-title { font-size: 2rem; font-weight: 700; letter-spacing: -0.02em; }
.nw-date-pill > summary {
  list-style: none; cursor: pointer;
  padding: 0.3rem 0.8rem; border-radius: 999px;
  background: var(--nw-pill); color: var(--nw-ink); font-size: 0.875rem; font-weight: 500;
}
.nw-date-pill > summary::-webkit-details-marker { display: none; }
.nw-date-pill[open] > summary { margin-bottom: 0.5rem; }
.nw-headline-figure { font-size: 2.25rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.1; }
@media (min-width: 768px) { .nw-headline-figure { font-size: 2.5rem; } }

/* --- Top bar of the logged-out pages --------------------------------------- */
.nw-topbar {
  background: var(--nw-card);
  --bs-navbar-color: var(--nw-ink-2);
  --bs-navbar-hover-color: var(--nw-ink);
  --bs-navbar-active-color: var(--nw-link);
  --bs-navbar-brand-color: var(--nw-ink);
  --bs-navbar-brand-hover-color: var(--nw-ink);
  box-shadow: 0 1px 0 var(--nw-line);
}
.nw-topbar .navbar-brand { font-weight: 700; }

.nw-demo-strip { background: var(--bs-warning-bg-subtle); color: var(--bs-warning-text-emphasis); font-size: 0.8125rem; text-align: center; padding: 0.25rem 1rem; }
/* A ribbon with its X on the right (F-ribbon-close); the X keeps a 44 px tap area. */
.nw-ribbon { display: flex; align-items: center; gap: 0.5rem; }
.nw-ribbon-text { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.nw-ribbon-x { flex: none; margin: -0.5rem -0.75rem -0.5rem 0; }
.nw-ribbon-x .btn-close { box-sizing: content-box; padding: 0.875rem; background-size: 0.75em; }
.nw-demo-strip .nw-ribbon-x { margin: -0.25rem -0.75rem -0.25rem 0; }
/* The strip's smaller text made its X 41 by 33 px (review PHN2): padded to a
   44 px square whatever the font size. */
.nw-demo-strip .nw-ribbon-x .btn-close { padding: calc((44px - 1em) / 2); }

/* --- Other pages (Task 7.13b) -------------------------------------------- */
/* Page header (templates/_page_title.html) and section headings. */
.nw-page-head { min-width: 0; }
.nw-page-sub { color: var(--nw-ink-2); font-size: 0.9375rem; }

/* --- The page header (F-page-header, templates/_page_header.html) ---------
   Back line, title and grey line, one blue button with More, tabs in one
   sliding row, filters folded behind one line. On a phone the buttons sit
   under the title (blue left, More right); from 768 px they sit beside it. */
.nw-head { margin-bottom: 1rem; }
.nw-head-back { font-size: 0.875rem; margin-bottom: 0.125rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nw-head-back a { text-decoration: none; }
.nw-head-back a + a::before { content: "\203A"; color: var(--nw-ink-2); margin: 0 0.375rem; display: inline-block; }
.nw-head-back::before { content: "\2039"; color: var(--nw-link); margin-right: 0.25rem; }
.nw-head-top { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem 1rem; }
.nw-head-titles { flex: 1 1 100%; min-width: 0; }
.nw-head .nw-page-title { margin: 0; line-height: 1.15; }
.nw-head-actions { flex: 1 1 100%; display: flex; align-items: center; gap: 0.5rem; }
.nw-head-actions > .btn { white-space: nowrap; }
.nw-head-more { margin-left: auto; position: relative; }
.nw-head-more > summary { list-style: none; white-space: nowrap; }
.nw-head-more > summary::-webkit-details-marker { display: none; }
.nw-head-more:not([open]) > .dropdown-menu { display: none; }
.nw-head-more > .dropdown-menu { right: 0; left: auto; top: calc(100% + 0.25rem); min-width: 14rem; max-width: calc(100vw - 2rem); }
@media (min-width: 768px) {
  .nw-head-titles { flex: 1 1 auto; }
  .nw-head-actions { flex: 0 0 auto; }
  .nw-head-more { margin-left: 0; }
}
.nw-head-tabs {
  display: flex; gap: 1.25rem; overflow-x: auto; margin-top: 0.75rem;
  border-bottom: 1px solid var(--nw-line); scrollbar-width: none;
}
.nw-head-tabs::-webkit-scrollbar { display: none; }
.nw-head-tab {
  flex: none; white-space: nowrap; padding: 0.5rem 0 0.5625rem; color: var(--nw-ink-2);
  text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.nw-head-tab:hover { color: var(--nw-ink); }
.nw-head-tab[aria-current="page"] { color: var(--nw-ink); font-weight: 600; border-bottom-color: var(--nw-btn); }
.nw-head-filter { margin-top: 0.5rem; }
.nw-head-filter > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 0.5rem;
  padding: 0.5rem 0; min-height: 44px; font-size: 0.9375rem;
}
.nw-head-filter > summary::-webkit-details-marker { display: none; }
.nw-head-filter > summary svg { flex: none; color: var(--nw-ink-2); }
.nw-head-filter-sum { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nw-head-filter-go { flex: none; color: var(--nw-link); font-weight: 500; }
.nw-head-filter[open] .nw-head-filter-go { visibility: hidden; }
.nw-head-filter-body { background: var(--nw-card); border-radius: 14px; padding: 0.75rem 1rem; box-shadow: var(--nw-shadow); }
.nw-head-filter-body > form + form { margin-top: 0.5rem; }
@media print { .nw-head-actions, .nw-head-tabs, .nw-head-filter > summary .nw-head-filter-go { display: none !important; } }
.nw-section-title { font-size: 1.125rem; font-weight: 600; margin: 1.5rem 0 0.5rem; }
.nw-search-form { max-width: 30rem; }

/* Lists in cards. Wide screens keep a light table: small grey headers, thin
   row lines, no line under the last row. */
.nw-list-card { padding-top: 0.25rem; padding-bottom: 0.25rem; }
.nw-rowlist thead th { font-size: 0.75rem; font-weight: 600; color: var(--nw-ink-2); }
.nw-rowlist > tbody > tr:last-child > *,
.nw-rowlist > tfoot > tr:last-child > * { border-bottom-width: 0; }
.nw-rowlist > tfoot { border-top: 1px solid var(--nw-line); }

/* Chart of accounts: the code never breaks, and a sub-account sits a step in
   under its heading. */
.nw-cell-code { white-space: nowrap; }
.nw-cell-indent > .nw-row-link { margin-left: 1rem; }

/* A figure with a badge beside it ("estimated", "stale", "replaced"): the
   figure keeps to one line but the badge may drop under it, so a narrow phone
   never scrolls sideways (Eric, 2026-10-26). Covers every cell or value that
   is marked text-nowrap and holds a badge, so a new page needs nothing extra. */
.text-nowrap:has(.badge) { white-space: normal !important; }
.text-nowrap:has(.badge) > :not(.badge, :has(.badge)) { white-space: nowrap; }
/* A badge's reason beside it ("Based on the selling price estimate; final once
   the collateral sells") wraps like any sentence, even in a value kept to one
   line, so a loan page fits a phone (review REG2). */
.nw-badge-why,
.text-nowrap:has(.badge) > .nw-badge-why { white-space: normal; overflow-wrap: anywhere; }

/* Search results and other plain lists: one row per item, the whole row a link. */
.nw-list > li { position: relative; padding: 0.625rem 0; border-bottom: 1px solid var(--nw-line); }
.nw-list > li:last-child { border-bottom: 0; }
.nw-list .nw-row-link::after { content: ""; position: absolute; inset: 0; }

/* Phones (under 768 px): each table row becomes a settings-style row. The name
   cell sits left with its grey line under it and the amount sits right; every
   other cell becomes a small grey "Label: value" line under them, from its
   data-label, so nothing that shows on a wide screen is lost and nothing
   scrolls sideways. Same markup at every width: CSS only. */
@media (max-width: 767.98px) {
  .nw-rowlist, .nw-rowlist > tbody, .nw-rowlist > tfoot { display: block; }
  .nw-rowlist > thead { display: none; }
  .nw-rowlist > tbody > tr, .nw-rowlist > tfoot > tr {
    position: relative;
    /* The right column (an amount) never takes more than half the row, so a
       cell left without a place can't squeeze the name to a letter a line. */
    display: grid; grid-template-columns: minmax(0, 1fr) fit-content(50%);
    column-gap: 0.75rem; align-items: start;
    padding: 0.625rem 0;
    border-bottom: 1px solid var(--nw-line);
  }
  .nw-rowlist > tbody > tr:last-child { border-bottom: 0; }
  .nw-rowlist > tfoot { border-top: 0; }
  .nw-rowlist > tfoot > tr { border-top: 1px solid var(--nw-line); border-bottom: 0; }
  .table.nw-rowlist > :not(caption) > * > * { display: block; padding: 0; border-bottom-width: 0; }
  .table.nw-rowlist > :not(caption) > * > :empty { display: none; }
  .nw-rowlist .nw-cell-name,
  .nw-rowlist > tbody > tr > th[scope="row"] { grid-column: 1; grid-row: 1; min-width: 0; overflow-wrap: anywhere; }
  .nw-rowlist .nw-cell-amount { grid-column: 2; grid-row: 1; text-align: right; font-weight: 600; }
  /* An account code (chart of accounts) sits right of the name, like an amount. */
  .nw-rowlist .nw-cell-code { grid-column: 2; grid-row: 1; text-align: right; color: var(--nw-ink-2); }
  .nw-rowlist .nw-cell-sub,
  .nw-rowlist [data-label] {
    grid-column: 1 / -1; text-align: left !important;
    font-size: 0.8125rem; color: var(--nw-ink-2);
  }
  .nw-rowlist [data-label]::before { content: attr(data-label) ": "; }
  .table.nw-rowlist .nw-cell-badges:not(:has(*)) { display: none; }
  /* Bootstrap's d-none (the 100% columns) still wins: it is !important. */
  .nw-rowlist .nw-row-link::after { content: ""; position: absolute; inset: 0; }
  /* A date that names the row (History, Household member) keeps its label but
     stays in the name's place, left of the amount. */
  .nw-rowlist .nw-cell-name[data-label] { grid-column: 1; font-size: inherit; color: inherit; }
  /* Buttons in a row (Change %, Void, Delete) sit above the row's link. */
  .nw-rowlist .btn { position: relative; z-index: 1; }
}

/* A row list with tick boxes (Transactions, 2026-10-30): the box sits in its
   own narrow column left of the name, the amount right, and every other line
   under the name. A row that can't be ticked keeps the empty column, so the
   names line up. Placed by class, so no cell falls into the amount's column. */
@media (max-width: 767.98px) {
  .nw-rowlist > tbody > tr:has(> .nw-cell-tick) { grid-template-columns: 1.75rem minmax(0, 1fr) fit-content(50%); }
  .nw-rowlist > tbody > tr:has(> .nw-cell-tick) > * { grid-column: 2 / -1; }
  .table.nw-rowlist > tbody > tr > .nw-cell-tick { display: block; grid-column: 1; grid-row: 1; }
  .nw-rowlist > tbody > tr:has(> .nw-cell-tick) > .nw-cell-name { grid-column: 2; grid-row: 1; }
  .nw-rowlist > tbody > tr:has(> .nw-cell-tick) > .nw-cell-amount { grid-column: 3; grid-row: 1; }
  .nw-rowlist .nw-cell-tick .form-check-input { margin-top: 0.125rem; position: relative; z-index: 1; }
}

/* A receipt's lines (Eric's first ten minutes walk, 2026-10-28), and a
   transaction's parts, which have the same columns. Wide screens
   keep the table. Phones (under 768 px): each line becomes its own small card,
   "Line 1" on top, Amount and Category side by side and the rest full width,
   each with its label above it from data-label, so nothing scrolls sideways.
   Vendor sits full width with Date and Total under it. Fields are 44 px tall
   and 16 px text (the phone rule under Buttons and fields), so the phone
   doesn't zoom in when one is tapped. Same markup at every width: CSS only. */
.nw-line-rows .nw-line-amount { min-width: 7rem; }
.nw-line-head .nw-line-total input { max-width: 9rem; }
@media (max-width: 767.98px) {
  .nw-line-head > * { flex: 1 1 calc(50% - 0.5rem); min-width: 0; }
  .nw-line-head > .nw-line-wide { flex-basis: 100%; }
  .nw-line-head .nw-line-total input { max-width: none; }
  .nw-line-rows, .nw-line-rows > tbody { display: block; }
  .nw-line-rows > thead { display: none; }
  .nw-line-rows > tbody { counter-reset: nw-line; }
  .nw-line-rows > tbody > tr {
    counter-increment: nw-line;
    display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    gap: 0.5rem 0.75rem;
    padding: 0.75rem; margin-bottom: 0.75rem;
    border: 1px solid var(--nw-line); border-radius: 8px;
  }
  .nw-line-rows > tbody > tr::before {
    content: "Line " counter(nw-line); grid-column: 1 / -1; font-weight: 600;
  }
  /* A transaction's parts ("What it was for"): "Part 1", "Part 2"; one part
     alone (the usual case) is just its fields, with no card around them. */
  .nw-line-parts > tbody > tr::before { content: "Part " counter(nw-line); }
  .nw-line-parts > tbody > tr:only-child { padding: 0; border: 0; }
  .nw-line-parts > tbody > tr:only-child::before { content: none; }
  .table.nw-line-rows > :not(caption) > * > * { display: block; padding: 0; border-bottom-width: 0; min-width: 0; }
  .nw-line-rows > tbody > tr > td:not(.nw-line-half) { grid-column: 1 / -1; }
  .nw-line-rows [data-label]::before {
    content: attr(data-label); display: block; margin-bottom: 0.125rem;
    font-size: 0.8125rem; color: var(--nw-ink-2);
  }
  .nw-line-rows .nw-line-amount { min-width: 0; }
}

/* The categories page (review UX22): each name is text with a small Rename
   that opens its box, so the page isn't a column of open text boxes. */
.nw-cat-rename > summary { list-style: none; cursor: pointer; }
.nw-cat-rename > summary::-webkit-details-marker { display: none; }

/* A typed journal entry's lines and the opening balances take the same phone
   cards as a receipt's lines (.nw-line-rows), with Debit and Credit side by
   side at equal width. An opening balance with nothing to say about where it
   comes from has no empty row on its card; one to check stays tinted. */
@media (max-width: 767.98px) {
  .nw-line-rows.nw-line-even > tbody > tr { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .table.nw-line-rows td.nw-line-blank { display: none; }
  .nw-line-rows > tbody > tr.table-warning { background-color: var(--bs-warning-bg-subtle); }
}

/* More tables as phone row lists (.nw-rowlist): the journal, a journal
   entry, rental listings, a rehab draw and Net worth's "By entity". A journal
   line's debit or credit sits right of its account with a small grey "Debit"
   or "Credit" before it, since the column headings are hidden there. */
@media (max-width: 767.98px) {
  .nw-rowlist .nw-cell-amount[data-side]::before {
    content: attr(data-side) " "; font-size: 0.8125rem; font-weight: 400; color: var(--nw-ink-2);
  }
  /* A row marked to look at (a draw line over its budget) is tinted edge to edge. */
  .nw-rowlist > tbody > tr.table-warning { background-color: var(--bs-warning-bg-subtle); }
}

/* Books on phones (2026-10-28): a line form whose lines each have a name (a
   property's depreciation items) has the item's name heading its card instead
   of "Line 1". The closed-months history, depreciation and reconcile tables
   are .nw-rowlist row lists. */
@media (max-width: 767.98px) {
  .nw-line-named > tbody > tr::before { content: none; }
  .nw-line-rows .nw-line-title { font-weight: 600; }
  /* A figure shown on a card (a cost) sits left under its label. */
  .nw-line-rows > tbody > tr > td.text-end { text-align: left !important; }
}

/* More phone row lists (2026-10-28): the deal track record, People and the
   plan chooser. A unit's buttons (For rent, Lease, Repair, Edit, Retire,
   Delete) wrap under its name on a phone instead of running off the edge;
   Bootstrap's text-nowrap is !important, so this is too. */
@media (max-width: 767.98px) {
  .nw-rowlist .nw-unit-actions { white-space: normal !important; }
  .nw-rowlist .nw-unit-actions .btn { margin-bottom: 0.25rem; }
  .table.nw-rowlist.w-auto { width: 100% !important; }
}

/* Item and entity pages (Task 7.13b part 2). "I made a mistake" is a quiet
   settings-style list under the event buttons; Void is a small text button. */
.nw-fix-list .list-group-item { background: transparent; min-height: 2.75rem; display: flex; align-items: center; }
.nw-void-link { font-size: 0.8125rem; }

/* Bank and login pages (Task 7.13b part 4). Login, two-factor and allauth's
   own pages: <main> itself is one centred card with the app's name on top
   (allauth/layouts/base.html), so allauth's pages, which fill the content
   block themselves, get it too. Map accounts: the "What to do" column keeps
   room for its selects on wide screens only. */
.container.nw-auth {
  max-width: 28rem;
  background: var(--nw-card);
  border-radius: var(--nw-radius-card);
  box-shadow: var(--nw-shadow);
  padding: 1.5rem 1.25rem;
  /* Logged in, <main> also has pt-3 pt-md-0 (Bootstrap utilities, !important). */
  padding-top: 1.5rem !important;
  margin-bottom: 1.5rem;
}
.nw-auth-brand { font-weight: 700; color: var(--nw-accent); margin-bottom: 0.75rem; }
/* A login's own pages inside the app's menus (usability review UX1): a reading
   width, and the link one level up above the title. */
.container.nw-account > * { max-width: 40rem; }
.nw-back-link { display: inline-flex; align-items: center; min-height: 44px; text-decoration: none; }
.nw-auth .nw-page-title, .nw-auth h1 { font-size: 1.625rem; font-weight: 700; letter-spacing: -0.02em; }
@media (min-width: 768px) {
  .nw-map-action { min-width: 18rem; }
}
@media (max-width: 767.98px) {
  /* A 16 px gutter each side of the card on a phone. */
  .container.nw-auth { width: calc(100% - 2rem); margin-top: 1rem; }
  .nw-rowlist .nw-map-action { margin-top: 0.5rem; }
}

/* Forms and review screens (Task 7.13b part 3). A narrow column on wide
   screens; labels sit above their inputs (Bootstrap's form-label). */
.nw-narrow { max-width: 40rem; }
.nw-effect-line { font-size: 1.0625rem; font-weight: 500; }
.nw-fields-card:not(:has(> .card-body > *)) { display: none; }
.nw-update-row + .nw-update-row { border-top: 1px solid var(--nw-line); }
.nw-form-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
/* Phones: fields and buttons at least 44 px tall (a thumb-sized target); the
   main button full width on top, Back / Cancel full width under it. Review
   pages keep Back first in the markup, the button Enter presses. */
@media (max-width: 767.98px) {
  .nw-form .form-control, .nw-form .form-select, .nw-form .input-group-text { min-height: 44px; }
  .nw-form .btn { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
  .nw-form-actions { flex-direction: column; }
  .nw-form-actions-back-first { flex-direction: column-reverse; }
  .nw-form-actions > .btn { width: 100%; min-height: 44px; }
}


/* Tenant repairs (F-tenant-repairs): the status bar a tenant sees under each
   repair (Sent, Seen, Booked, Done), and the form's kind tiles. */
.nw-repair-steps { display: flex; list-style: none; padding: 0; margin: 0 0 0.25rem; gap: 0.25rem; }
.nw-repair-steps li {
  flex: 1 1 0; text-align: center; font-size: 0.8125rem; padding-top: 0.375rem;
  border-top: 4px solid var(--nw-line); color: var(--nw-ink-2);
}
.nw-repair-steps li.nw-step-done { border-top-color: var(--nw-link); color: var(--nw-ink); }
.nw-repair-steps li.nw-step-now { font-weight: 600; }
.nw-kind-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); gap: 0.5rem; }
.nw-kind-tiles .btn { min-height: 44px; width: 100%; }
