/* ── RenewCounts ledger theme tokens ─────────────────────────────
   Brand ramp for Fluent components is seeded by data-theme-color on
   <body> (App.razor). These app tokens cover everything Fluent doesn't:
   page surfaces, money typography, and the accent palette.
   Dark values key off body[data-theme="dark"], which Fluent UI sets. */
:root {
    --rc-brand: #0F6E56;
    --rc-brand-soft: rgba(15, 110, 86, 0.10);
    /* Selected/edited data-grid row: a stronger tint than brand-soft so it's
       unmistakable and distinct from the subtotal-row's identical soft fill. */
    --rc-selection: rgba(15, 110, 86, 0.16);
    --rc-income: #0B7D5E;   /* chart marks only - chroma-validated variant */
    --rc-coral: #D85A30;
    --rc-coral-soft: rgba(216, 90, 48, 0.12);
    --rc-amber: #B26B0A;
    --rc-blue: #185FA5;

    --rc-bg-page: #F7F7F4;
    --rc-bg-card: #FFFFFF;
    --rc-bg-sidebar: #FCFCFA;
    --rc-rule: #E4E5DF;
    --rc-rule-strong: #C9CBC3;
    --rc-text-primary: #1F2421;
    --rc-text-secondary: #6B6F6C;
    --rc-text-muted: #9A9E99;

    --rc-font-ui: "Segoe UI Variable Text", "Segoe UI", system-ui, sans-serif;
    --rc-font-money: "Cascadia Mono", Consolas, monospace;
    --rc-radius: 8px;

    /* ── Density tokens ──────────────────────────────────────────
       Phone density here is spacing only. Fluent's own reboot.css sets body
       font-size/line-height (--fontSizeBase300 = 14px, --lineHeightBase300 = 20px)
       and its bundle loads AFTER app.css at equal specificity, so type belongs to
       Fluent - we don't fight it. These tokens drive only margins/gaps on elements
       this app owns. Shift them at the breakpoint and the layout tightens together. */
    --rc-card-pad: 16px;
    --rc-stack-gap: 16px;
    --rc-section-gap: 1rem;
}

/* Phones: tighter rhythm, type untouched. */
@media (max-width: 640.98px) {
    :root {
        --rc-card-pad: 12px;
        --rc-stack-gap: 10px;
        --rc-section-gap: 0.6rem;
    }
}

/* Tablets: more room than a phone, less than a desktop - a modest tightening. (Tablets
   share the phone's hamburger nav, but not its spacing: they have the width to breathe.) */
@media (min-width: 641px) and (max-width: 1024.98px) {
    :root {
        --rc-card-pad: 14px;
        --rc-stack-gap: 12px;
        --rc-section-gap: 0.8rem;
    }
}

body[data-theme="dark"] {
    --rc-brand: #3FA98A;
    --rc-brand-soft: rgba(63, 169, 138, 0.14);
    --rc-selection: rgba(63, 169, 138, 0.24);
    --rc-income: #35A282;
    --rc-coral: #E5744D;
    --rc-coral-soft: rgba(229, 116, 77, 0.16);
    --rc-amber: #E8A33D;
    --rc-blue: #6BA6DD;

    --rc-bg-page: #161917;
    --rc-bg-card: #1C201E;
    --rc-bg-sidebar: #191D1B;
    --rc-rule: #2C312E;
    --rc-rule-strong: #3E443F;
    --rc-text-primary: #E8EAE7;
    --rc-text-secondary: #9AA09B;
    --rc-text-muted: #6E746F;
}

html, body {
    font-family: var(--rc-font-ui);
    background-color: var(--rc-bg-page);
    color: var(--rc-text-primary);
}

/* Card padding is Fluent's (--spacingVerticalM/--spacingHorizontalM, set by its JS
   token system); overriding it from here loses to their later-loading bundle. What
   we do own is the gap BETWEEN cards, which is most of the wasted vertical space on
   a phone anyway. */
fluent-card {
    margin-bottom: var(--rc-section-gap);
}

fluent-card:last-child {
    margin-bottom: 0;
}

/* Every FluentAutocomplete's suggestion list - the category and payee pickers on the register,
   the import review screen, payee rules, the bridge mapping screens.

   Fluent's own bundle caps the OUTER wrapper at 400px but leaves its overflow visible, and gives
   the INNER list overflow-y: auto with no height to overflow. The result is a list that stops
   dead: it draws as many rows as fit, the rest are unreachable, and no scrollbar ever appears.
   On a chart of accounts that is 50 suggestions deep, everything past the ninth row might as well
   not exist - which is how an equity account below a screenful of expenses became untypeable.

   Bounding the inner list is the whole fix: its own overflow-y then has something to do. Kept
   under the outer wrapper's 400px so the two can't disagree, and under half the viewport so the
   list can't outgrow a phone. Specificity, not !important: `.class[attr] > tag` outranks Fluent's
   `.fluent-listbox fluent-listbox`, which matters because their bundle loads after this file. */
.fluent-listbox[auto-complete] > fluent-listbox {
    max-height: min(400px, 50vh);
    overflow-y: auto;
}

/* One option in an account picker.

   pointer-events is the load-bearing half: an option's own click handler lives on the option, so
   anything rendered inside it swallows the click and the option cannot be chosen at all. Fluent's
   own OptionTemplate sample carries the same declaration for the same reason. Without it these
   pickers would look right and select nothing.

   The colour marks the equity accounts that hold the company's structure - retained earnings,
   opening balance equity, the owner's capital and draw headers - so they read as different in kind
   from the expense categories they sit among. See StructuralEquityAccounts for which and why. */
.rc-account-option {
    pointer-events: none;
}

/* The same accounts, in a picker option and anywhere else they are listed. The second class exists
   because a table cell must not carry the pointer-events rule above: a row is selectable text, and a
   cell that ignores the pointer cannot be selected or right-clicked. */
.rc-account-option-structural,
.rc-account-structural {
    color: var(--rc-coral);
}

/* h1 is 40px at every width (Fluent's hero scale) - on a 390px phone that eats the
   fold before any content shows. This is a plain element we own, so a direct rule
   works; the type inside Fluent components is left alone. */
h1 {
    line-height: 1.25;
}

@media (max-width: 640.98px) {
    h1 {
        font-size: 1.75rem;
        margin-bottom: 0.4rem;
    }

    .content {
        padding-top: 0.6rem;
    }
}

/* Money: monospaced tabular figures so columns rule up like a ledger. */
.money {
    font-family: var(--rc-font-money);
    font-variant-numeric: tabular-nums;
    font-size: 0.93em;
}

/* Ledger-style type-group subtotal rows in the Chart of Accounts grid. */
tr.subtotal-row {
    background-color: var(--rc-brand-soft);
    font-weight: 600;
    border-top: 1px solid var(--rc-rule-strong);
}

/* The row currently open for inline editing/viewing in a data grid. A left accent bar
   plus a brand tint marks it without competing with the subtotal-row's top rule. */
tr.row-selected,
tr.row-selected td {
    background-color: var(--rc-selection);
}

/* The accent bar rides on the row; !important defeats Fluent's own row box-shadow. */
tr.row-selected {
    box-shadow: inset 4px 0 0 0 var(--rc-brand) !important;
}

/* ── Dashboard ─────────────────────────────────────────────── */
.kpi-row {
    display: grid;
    /* auto-fit + minmax already reflows to a single column on a phone; the min just
       needs to be under the narrowest viewport (390px minus page padding). */
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--rc-stack-gap);
    margin-bottom: var(--rc-section-gap);
}

.kpi-tile {
    padding: var(--rc-card-pad);
}

.kpi-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--rc-text-secondary);
}

.kpi-value {
    font-size: 22px;
    margin-top: 4px;
}

.kpi-net {
    color: var(--rc-blue);
}

.chart-card {
    padding: 14px 16px;
    max-width: 900px;
}

.chart-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 8px;
}

.chart-legend {
    display: flex;
    gap: 14px;
    font-size: 12px;
    color: var(--rc-text-secondary);
}

.chart-legend span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.legend-swatch {
    width: 9px;
    height: 9px;
    border-radius: 2px;
    display: inline-block;
}

.swatch-income { background: var(--rc-income); }
.swatch-expense { background: var(--rc-coral); }

.ive-chart {
    display: block;
    width: 100%;
    height: auto;
}

.ive-chart .bar-income { fill: var(--rc-income); }
.ive-chart .bar-expense { fill: var(--rc-coral); }

/* Personal books: this month's spending, ranked. Grid rather than flex so every bar starts at the
   same x - with per-row flex the longest category name would shift its own bar and the lengths
   would stop being comparable, which is the whole point of drawing them. */
.spend-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 2fr auto;
    align-items: center;
    gap: 10px;
    padding: 3px 0;
}

.spend-name {
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.spend-bar-track {
    background: var(--rc-surface-alt, rgba(127, 127, 127, 0.15));
    border-radius: 3px;
    height: 10px;
}

.spend-bar {
    background: var(--rc-coral);
    border-radius: 3px;
    height: 100%;
    min-width: 2px;
}

.spend-amount {
    font-size: 13px;
    text-align: right;
    min-width: 80px;
}

/* On a phone the bar has no room to say anything, so the name and amount take the row. */
@media (max-width: 600px) {
    .spend-row {
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .spend-bar-track {
        display: none;
    }
}
.ive-chart .chart-gridline { stroke: var(--rc-rule); stroke-width: 1; }

.ive-chart .chart-tick,
.ive-chart .chart-axis-label {
    fill: var(--rc-text-muted);
    font-size: 10px;
}

.ive-chart .chart-tick {
    font-family: var(--rc-font-money);
    font-variant-numeric: tabular-nums;
}

/* ── Reports ─────────────────────────────────────────────────
   Reports render as a paper-like sheet that is also the exact print layout.
   The sheet stays white/dark-text in both themes - it is a document. */
.report-toolbar {
    display: flex;
    align-items: center;
    gap: var(--rc-stack-gap);
    flex-wrap: wrap;
    margin-bottom: var(--rc-section-gap);
}

/* On screen the sheet scrolls inside its own region so the toolbar (and Print button)
   stay visible; on paper the region is unwrapped (see the print rules below). Horizontal
   overflow is allowed here too so a wide report (e.g. General Ledger) scrolls sideways
   within the region instead of blowing out the page layout.

   Sized by the .content flex column (see MainLayout.razor.css) rather than a viewport
   calculation, so it stays correct under the taller chrome on tablets and phones. */
.report-scroll {
    flex: 1;
    min-height: 0;
    overflow: auto;
    padding-bottom: 8px;
}

/* Reports with more/wider columns than a printed 8.5in page comfortably fits (General
   Ledger's Date/Ref/Memo/Debit/Credit/Balance) - let the sheet grow to its content width
   and scroll horizontally inside .report-scroll rather than compressing columns unreadably. */
.report-sheet-wide {
    max-width: none;
    width: max-content;
    min-width: 100%;
}

.report-sheet {
    background: #FFFFFF;
    color: #1F2421;
    max-width: 8.5in;
    margin: 0 auto;
    padding: 0.6in 0.7in;
    border-radius: var(--rc-radius);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
}

/* The sheet's inch-based padding is correct on paper but wastes a third of a 390px
   screen. Screen-only override - the @media print block below restores the sheet. */
@media screen and (max-width: 640.98px) {
    .report-sheet {
        padding: 16px 12px;
    }
}

.report-header {
    text-align: center;
    margin-bottom: 22px;
}

.report-company {
    font-size: 20px;
    font-weight: 600;
}

.report-title {
    font-size: 14px;
    text-transform: uppercase;
    letter-spacing: 0.10em;
    margin-top: 2px;
}

.report-dateline {
    font-size: 13px;
    color: #555;
    margin-top: 2px;
}

.report-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.report-table th,
.report-table td {
    padding: 4px 8px;
    text-align: left;
    vertical-align: top;
}

.report-table thead th {
    border-bottom: 1px solid #444;
    font-weight: 600;
}

.report-table .num {
    text-align: right;
    white-space: nowrap;
}

.report-table .col-code { width: 70px; }
.report-table .col-date { width: 90px; }
.report-table .col-ref { width: 70px; }
.report-table .col-name { width: 130px; }
/* Wide enough for "code - account name" on one line; without it the tax detail wraps every row to
   four lines and the printed report triples in length. */
.report-table .col-account { width: 210px; }

.report-section-row td {
    font-weight: 600;
    padding-top: 14px;
    border-bottom: 1px solid #999;
}

/* Detail-mode sub-rows: the individual transactions listed under an account, indented and muted. */
.report-detail-row td {
    font-size: 12px;
    color: #555;
    padding-top: 1px;
    padding-bottom: 1px;
}

.report-detail-row td:nth-child(2) {
    padding-left: 24px;
}

.report-total-row td {
    border-top: 1px solid #444;
    font-weight: 600;
}

/* Tax reports: section (bold, above) > tax line > transactions. Separate from the income statement's
   detail rows because this table is six columns wide, so its indent lands on a different cell. */
.report-subsection-row td {
    font-weight: 600;
    padding-top: 8px;
    padding-left: 16px;
}

.tax-detail-row td {
    font-size: 12px;
    color: #555;
    padding-top: 1px;
    padding-bottom: 1px;
}

.tax-detail-row td:first-child {
    padding-left: 32px;
}

.report-grand-total-row td {
    border-top: 1px solid #444;
    border-bottom: 3px double #444;
    font-weight: 700;
    padding-top: 6px;
}

.gl-account {
    margin-top: 18px;
}

.gl-account-header {
    font-weight: 600;
    font-size: 14px;
    margin-bottom: 2px;
}

.gl-opening-row td {
    color: #555;
    font-style: italic;
}

.report-empty {
    font-size: 13px;
    color: #555;
}

.report-warning {
    font-size: 13px;
    font-weight: 600;
    color: var(--rc-coral);
    margin-top: 8px;
}

.report-printed {
    margin-top: 24px;
    font-size: 10px;
    color: #888;
    text-align: right;
}

/* Standard letter paper; @page margins frame the sheet so its own print padding is removed.
   0.75in gives printed reports a comfortable border past the 0.5in minimum. */
@page {
    size: letter;
    margin: 0.75in;
}

@media print {
    html, body, .page, main, .content {
        background: #FFFFFF !important;
    }

    /* Hide the app shell - only the report sheet goes to paper. */
    .sidebar,
    main .top-row,
    .report-toolbar,
    .no-print,
    #blazor-error-ui {
        display: none !important;
    }

    main {
        margin: 0 !important;
    }

    .content {
        padding: 0 !important;
        margin: 0 !important;
    }

    /* The scroll region would clip everything after page one - let the sheet flow naturally.
       flex: none releases the height .content's flex column would otherwise impose. */
    .report-scroll {
        flex: none;
        height: auto;
        overflow: visible;
        padding: 0;
    }

    /* The shell's flex column and viewport height would constrain the printed sheet to a
       single screen's worth of space; let content dictate height on paper. */
    .page, main, .content {
        display: block !important;
        height: auto !important;
        overflow: visible !important;
    }

    .report-sheet {
        max-width: none;
        margin: 0;
        padding: 0;
        border-radius: 0;
        box-shadow: none;
    }

    /* Repeat column headers on every page and keep rows whole across page breaks. */
    .report-table thead {
        display: table-header-group;
    }

    .report-table tr {
        page-break-inside: avoid;
    }

    .gl-account-header {
        page-break-after: avoid;
    }
}

a, .btn-link {
    color: var(--rc-blue);
}

.btn-primary {
    color: #fff;
    background-color: var(--rc-brand);
    border-color: var(--rc-brand);
}

.btn-primary:hover, .btn-primary:focus, .btn-primary:active {
    background-color: #0B5340;
    border-color: #0B5340;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

/* A floating label sits ON TOP of its own input until the field is focused or filled, so a visible
   placeholder is drawn over it - "Password" and "Please enter your password." in the same few pixels,
   both unreadable. Bootstrap avoids this by making the placeholder transparent at rest; this file used
   to override that with a right-aligned visible one, which only stays clear of the label when the
   placeholder is short AND the field is wide. Neither holds here: these inputs are about 200px, so
   even "name@example.com" collided with "Email".

   So: nothing at rest, and the hint appears on focus - by which point the label has floated up out of
   the way and the placeholder has the box to itself. A filled field shows no placeholder anyway, which
   is why only the focus state needs a colour. */
.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: transparent;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    color: var(--bs-secondary-color);
    text-align: start;
}

/* Minimal chrome for unauthenticated account pages (AccountLayout.razor) - a centered card instead of
   the full app shell, so the login/register forms don't render the signed-in nav behind them. */
.account-shell {
    min-height: 100dvh;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 2rem 1rem;
}

.account-card {
    width: 100%;
    max-width: 640px;
}

.account-brand {
    display: inline-block;
    margin-bottom: 1.5rem;
    font-size: 1.25rem;
    font-weight: 600;
    text-decoration: none;
    color: var(--rc-text, #0F6E56);
}
/* ---- Operator tables -------------------------------------------------------------------------
   Shared by the admin billing screens. Global rather than scoped per page because there are now
   several of these and they must look like one product; the two older AI screens keep their own
   scoped copies until there's a reason to touch them. */
.admin-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.admin-table th,
.admin-table td {
    padding: 8px 12px;
    text-align: left;
    border-bottom: 1px solid var(--neutral-stroke-divider-rest, rgba(128, 128, 128, 0.25));
    vertical-align: middle;
}

.admin-table th {
    font-weight: 600;
    white-space: nowrap;
}

/* Figures line up on the decimal point, which is the only way a column of money is scannable. */
.admin-table .numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.admin-table td.actions {
    white-space: nowrap;
    text-align: right;
}

/* A balance owing should be findable without reading every row. */
.admin-table .owing {
    font-weight: 600;
    color: var(--warning, #b45309);
}

.admin-table .note {
    display: inline-block;
    margin-left: 6px;
    font-size: 0.75rem;
    opacity: 0.7;
}

.admin-table .pill {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 10px;
    font-size: 0.75rem;
    background: var(--neutral-fill-secondary-rest, rgba(128, 128, 128, 0.15));
}

.admin-table .pill.active,
.admin-table .pill.paid {
    background: var(--success, #15803d);
    color: white;
}

.admin-table .pill.pastdue,
.admin-table .pill.open {
    background: var(--warning, #b45309);
    color: white;
}

.admin-table .pill.canceled,
.admin-table .pill.void {
    opacity: 0.6;
}

/* Phones: the table scrolls inside itself rather than pushing the page sideways. */
@media (max-width: 640px) {
    .admin-table {
        display: block;
        overflow-x: auto;
    }
}

/* ---------------------------------------------------------------------------
   Legal documents (/terms, /privacy)

   Global rather than scoped because both pages share it. Type is set explicitly
   here: Fluent's bundle sets body to 14px and loads after this file, but a class
   selector still beats `body` on specificity - and a document somebody is being
   asked to agree to should be comfortable to read, not chrome-sized.
   --------------------------------------------------------------------------- */
.legal-doc {
    max-width: 46rem;
    font-size: 1rem;
    line-height: 1.6;
}

.legal-doc h2 {
    margin: 0 0 4px;
}

.legal-doc h3 {
    margin: 32px 0 8px;
    font-size: 1.1rem;
}

.legal-doc p,
.legal-doc li {
    font-size: 1rem;
    line-height: 1.6;
}

.legal-doc ul {
    padding-left: 22px;
}

.legal-doc li {
    margin-bottom: 6px;
}

.legal-doc .updated {
    opacity: 0.7;
    font-size: 0.9rem;
}

/* The promises worth not skimming past: what we won't do for non-payment, the
   read-and-export guarantee, and "we don't sell your data". */
.legal-doc .commitment {
    border-left: 3px solid var(--accent-fill-rest, #0f6cbd);
    padding: 8px 0 8px 14px;
    margin-left: 0;
}

.legal-doc ul.commitment {
    padding-left: 36px;
}

.legal-doc .summary {
    border: 1px solid var(--neutral-stroke-rest, #d1d1d1);
    border-radius: 6px;
    padding: 4px 20px 16px;
    margin-top: 16px;
}

.legal-doc .summary h3 {
    margin-top: 20px;
}

.legal-doc table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.95rem;
}

.legal-doc th,
.legal-doc td {
    text-align: left;
    vertical-align: top;
    padding: 8px 12px 8px 0;
    border-bottom: 1px solid var(--neutral-stroke-rest, #d1d1d1);
}

/* Wide tables scroll inside themselves rather than pushing the page sideways. */
.legal-doc .table-scroll {
    overflow-x: auto;
}

.site-footer {
    margin-top: 40px;
    padding: 16px 0;
    border-top: 1px solid var(--neutral-stroke-rest, #d1d1d1);
    font-size: 0.85rem;
    opacity: 0.8;
}

.site-footer a {
    margin-right: 16px;
}

/* ── Landing page ────────────────────────────────────────────
   The logged-out home page (Home.razor, the NotAuthorized branch). Global rather than scoped
   because Home.razor has no scoped stylesheet, and for the same reason the dashboard rules above
   are global: its markup is raw HTML sitting beside Fluent components, and a bare class on a
   Fluent component would not match a scoped rule anyway.

   Everything here is prefixed .lp- so a class name can never collide with the app proper, which
   the same visitor sees the moment they log in. */

.lp {
    max-width: 1040px;
    /* The hero paragraphs are the only long-form prose in the app, so they get a reading measure
       rather than the app's usual full width. */
    font-size: 1rem;
    line-height: 1.6;
}

/* Referenced by <use> from every card. Hidden rather than sized to zero: a 0x0 SVG still takes part
   in layout in some browsers, which would push the hero down by a line for no visible reason. */
.lp-sprite {
    display: none;
}

.lp-hero {
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    align-items: center;
    gap: 32px;
    padding: 8px 0 28px;
}

.lp-eyebrow {
    margin: 0 0 6px;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--rc-brand);
}

.lp h1 {
    margin: 0 0 10px;
    font-size: 2.1rem;
    line-height: 1.15;
    letter-spacing: -0.015em;
}

.lp-lead {
    margin: 0 0 12px;
    font-size: 1.12rem;
    color: var(--rc-text-secondary);
}

.lp-hero p {
    margin: 0 0 12px;
    max-width: 62ch;
}

.lp-cta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin: 18px 0 12px;
}

.lp-textlink {
    color: var(--rc-brand);
    font-size: 0.92rem;
}

.lp-fineprint {
    font-size: 0.88rem;
    color: var(--rc-text-secondary);
}

/* A caveat that has to be read, not skimmed past: amber rule, card ground, full width of the
   section it closes. Quieter than an error bar, louder than fine print. */
.lp-notice {
    margin: 16px 0 0;
    padding: 12px 14px;
    border-left: 3px solid var(--rc-amber);
    border-radius: var(--rc-radius);
    background: var(--rc-bg-card);
    color: var(--rc-text-primary);
    font-size: 0.92rem;
}

.lp-notice a {
    color: var(--rc-brand);
}

/* The illustration carries no information the text does not, so it is the first thing to go when
   the screen gets narrow (see the media query at the end). */
.lp-hero-art svg {
    display: block;
    width: 100%;
    height: auto;
}

.lp-art-panel {
    fill: none;
    stroke: var(--rc-rule-strong);
    stroke-width: 2;
    stroke-linecap: round;
}

.lp-art-panel rect {
    fill: var(--rc-bg-card);
}

.lp-art-arrow {
    fill: none;
    stroke: var(--rc-text-muted);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* The balanced entry and the check mark: the point of the picture, so they carry the brand color
   while everything around them stays neutral. */
.lp-art-accent {
    fill: none;
    stroke: var(--rc-brand);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.lp-art-bars rect {
    fill: var(--rc-brand);
}

.lp-art-bars rect:nth-child(3) {
    fill: var(--rc-coral);
}

.lp-section {
    padding: 26px 0 6px;
    border-top: 1px solid var(--rc-rule);
}

.lp-section > h2 {
    margin: 0 0 4px;
    font-size: 1.45rem;
    letter-spacing: -0.01em;
}

.lp-group {
    margin: 22px 0 10px;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--rc-text-secondary);
}

.lp-why {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 16px;
    margin-top: 14px;
}

.lp-why-card {
    background: var(--rc-bg-card);
    border: 1px solid var(--rc-rule);
    border-left: 3px solid var(--rc-brand);
    border-radius: var(--rc-radius);
    padding: 14px 16px;
}

.lp-why-card h3 {
    margin: 0 0 6px;
    font-size: 1.02rem;
    line-height: 1.3;
}

.lp-why-card p {
    margin: 0;
    font-size: 0.92rem;
    color: var(--rc-text-secondary);
}

/* A card that carries more than one paragraph needs them separated; the base rule zeroes the
   margin because most cards hold exactly one. */
.lp-why-card p + p,
.lp-card p + p {
    margin-top: 8px;
}

/* The feature summary and the pricing notes: statements, not sentences, so they are marked as a list
   rather than run together as prose. */
.lp-points {
    margin: 0;
    padding-left: 20px;
    font-size: 0.92rem;
    color: var(--rc-text-secondary);
}

.lp-points li + li {
    margin-top: 6px;
}

.lp-price-notes {
    max-width: 72ch;
    margin-top: 14px;
    padding-left: 18px;
}

/* Big enough to be the thing the eye lands on in the card, with the period alongside at body size so
   the two read as one figure rather than as a headline and a footnote. */
/* Qualified by the card, because .lp-why-card p sets a body size at equal specificity and wins on
   order otherwise - the price would render as another line of prose. */
.lp-why-card p.lp-price {
    margin: 0 0 6px;
    font-size: 1.6rem;
    font-weight: 600;
    line-height: 1.2;
    color: var(--rc-text-primary);
}

.lp-why-card p.lp-price span {
    font-size: 0.92rem;
    font-weight: 400;
    color: var(--rc-text-secondary);
}

/* A prose card sitting alone in the grid: keep the icon beside the text rather than above it,
   and hold the measure to something readable across the full width. */
.lp-why-wide {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}

.lp-why-wide > div {
    max-width: 78ch;
}

.lp-why-wide h4 {
    margin: 0 0 6px;
    font-size: 1.02rem;
    line-height: 1.3;
}

/* auto-fill rather than auto-fit: a group with three cards should leave the fourth column empty
   rather than stretching three cards across the full width, so the groups stay aligned with each
   other down the page. */
.lp-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 12px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.lp-card {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    background: var(--rc-bg-card);
    border: 1px solid var(--rc-rule);
    border-radius: var(--rc-radius);
    padding: 14px 16px;
}

.lp-card h4 {
    margin: 0 0 4px;
    font-size: 0.97rem;
    line-height: 1.3;
}

.lp-card p {
    margin: 0;
    font-size: 0.89rem;
    color: var(--rc-text-secondary);
}

.lp-ic {
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    margin-top: 2px;
    fill: none;
    stroke: var(--rc-brand);
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* The only long prose on the page that is not in the hero, and the section is full width, so it
   needs a reading measure of its own or the lines run to 1040px. Body colour and size, unlike the
   closing section: this is the part meant to be read, not skimmed. */
.lp-story p {
    max-width: 72ch;
    margin: 12px 0 0;
}

.lp-closing p {
    max-width: 72ch;
    font-size: 0.92rem;
    color: var(--rc-text-secondary);
}

@media (max-width: 860px) {
    .lp-hero {
        grid-template-columns: minmax(0, 1fr);
        gap: 18px;
    }

    /* Decoration, and on a phone it would cost a screen of scrolling before the first feature. */
    .lp-hero-art {
        display: none;
    }

    .lp h1 {
        font-size: 1.7rem;
    }

    .lp-lead {
        font-size: 1.02rem;
    }
}
