/* ── 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);
}

/* The placeholder App.razor shows while the interactive runtime starts. Hidden by CSS rather than
   removed by script: MainLayout's .page landing in <body> is the signal, so there is nothing to
   forget to call. The fade-in delay keeps a fast start from blinking a spinner at all. */
#app-loading {
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    color: var(--rc-text-secondary);
    opacity: 0;
    animation: app-loading-fade-in 150ms ease-out 250ms forwards;
}

body:has(> .page) #app-loading {
    display: none;
}

.app-loading-spinner {
    width: 28px;
    height: 28px;
    border: 3px solid var(--rc-rule);
    border-top-color: var(--rc-brand);
    border-radius: 50%;
    animation: app-loading-spin 800ms linear infinite;
}

@keyframes app-loading-fade-in {
    to { opacity: 1; }
}

@keyframes app-loading-spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .app-loading-spinner {
        animation-duration: 2400ms;
    }
}

/* 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;
}

/* ── Tabbed pages ────────────────────────────────────────────
   Every FluentTabs in the app looks the same: the tabs on a grey, bordered strip across the top, and
   the open tab's content on a card below it (Settings → Security set the look; Payroll settings, the
   employee record and Plans follow it). Global rather than per page, so a new tabbed page gets it
   without asking.

   The element names in the selectors are for specificity, not decoration: Fluent's bundle loads after
   this file, and its own .fluent-tab-panel rule would win a tie. A panel's own content should not add
   a card of its own inside this one. */
div.fluent-tabs > fluent-tablist {
    background: var(--colorNeutralBackground3);
    border: 1px solid var(--colorNeutralStroke2);
    border-radius: 6px;
    padding: 2px 8px;
    /* Fluent's tabs have no overflow handling; on a phone the strip scrolls sideways instead of
       pushing the page wider than the screen. */
    overflow-x: auto;
    max-width: 100%;
    box-sizing: border-box;
}

div.fluent-tabs > fluent-tablist > fluent-tab {
    white-space: nowrap;
}

div.fluent-tabs > div.fluent-tab-panel[role="tabpanel"] {
    margin-top: 12px;
    padding: 20px;
    background: var(--colorNeutralBackground1);
    border: 1px solid var(--colorNeutralStroke1);
    border-radius: var(--borderRadiusMedium);
    box-shadow: var(--shadow4);
}

@media (max-width: 600px) {
    div.fluent-tabs > div.fluent-tab-panel[role="tabpanel"] {
        padding: 12px;
    }
}

/* ── 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. */
/* The report group's tab strip (ReportTabs) above the toolbar. Screen only: RouteTabs marks itself
   no-print, and this wrapper goes with it so its margin doesn't print as a gap either. */
.report-tabs {
    margin-bottom: 12px;
    flex: none;
}

@media print {
    .report-tabs {
        display: none;
    }
}

.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;
}

/* A quiet note after a name in a report cell - "custom amount", "retired in Square". */
.report-flag {
    margin-left: 8px;
    font-size: 0.75rem;
    font-style: italic;
    color: var(--rc-text-secondary, #6B6F6C);
}

.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; }

/* Mapping screens: each row holds a name, a hint line and one or two pickers, so without a rule between
   rows the eye can't tell which picker belongs to which account. Reports stay unruled. */
.report-table.ruled tbody td {
    border-bottom: 1px solid var(--colorNeutralStroke2, #e0e0e0);
    padding-top: 8px;
    padding-bottom: 8px;
}

.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;
}

/* The plans table carries ten columns where the other operator tables carry six or seven, and inside
   a tab panel there is about 200px less room than it wants. It overflowed its container with nothing
   scrollable around it, so Edit sat half off the right edge of the window and Delete sat entirely
   past it - a plan with no subscribers could not be deleted at all. The headers are what set these
   columns' width rather than the figures under them ("Assistant included" over "$3.00"), so letting
   them wrap buys back more than the padding does; both are needed to fit. */
.admin-table.wide th,
.admin-table.wide td {
    padding: 8px 7px;
}

.admin-table.wide th {
    white-space: normal;
}

/* Insurance, not the fix: the columns above fit at the widths we support, and a table that outgrows
   its container again should scroll inside the page rather than off the side of it, where a button
   cannot be reached at all. */
.table-scroll {
    width: 100%;
    overflow-x: auto;
}

/* The Start Here banner sits in .content, which is a flex column, so it is a flex item and shrinks to
   fit whatever height the page leaves over. Squashed, its button row overflows the bar's own box and
   the page's first element paints on top of it: the buttons are visible and unclickable, which is the
   worst of both. It is a fixed-height row, so it says so. */
.guide-banner {
    flex: 0 0 auto;
}

/* Same reason, for every page's own message bars. A page's top-level bar is a direct child of
   .content, so it is a flex item too, and a long one was being floored at a single line with the rest
   of its sentence clipped - the tax lines page's "No tax return set for this company" ended mid-word.
   A squashed message bar is never what was wanted. */
.content > fluent-message-bar {
    flex: 0 0 auto;
}

/* A link inside a message bar could not be clicked. Chrome's hit test stopped at the content span
   the bar wraps its slot in, so a click on the link's own words landed on the span and went nowhere -
   no error, the text simply was not a link. Found on the employee header's "needs attention" links;
   every <a> in a FluentMessageBar had it. Giving the link its own positioned box is enough for the
   hit test to reach it. */
fluent-message-bar a {
    position: relative;
}

/* The three answers on the tax lines page are short phrases in a narrow column, so "Not on a return"
   broke over three lines and drove every row to about 150px - eighteen accounts that scrolled like a
   hundred, and the reason the page read as unfinished quite apart from its missing rules. The table
   already scrolls horizontally, which is the better trade. Global rather than scoped because the label
   is rendered inside the Fluent component, where the page's scoped CSS cannot reach it. */
.imported-tax-lines fluent-radio-group label {
    white-space: nowrap;
}

/* 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;
}

/* The terms/privacy line on the Identity pages. Those pages are Bootstrap-scaffolded rather than
   Fluent, so this keeps to the same plain type as the links already on them. */
.account-legal {
    margin-top: 16px;
    font-size: 0.88rem;
    color: var(--rc-text-secondary);
}

.account-legal span {
    margin: 0 6px;
}

/* One option in the tax-line picker. Two lines: what the line is, and under it the reference number
   and the part of the return it sits in - both of which the box is searched by, so both have to be
   visible or the reader cannot tell which of two similarly named lines they just found.

   pointer-events for the same reason as .rc-account-option above: the click handler is on the option,
   and content inside it swallows the click. */
.rc-tax-line-option {
    pointer-events: none;
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

/* Clipped to one line, not wrapped. The suggestion popup is not sized from the input: Fluent clamps
   it to the room between the input's left edge and the right edge of the window, and this input sits
   at the right-hand end of a wide table, so on a narrower window the list arrives about 220px wide
   however much the field asked for. Every option then broke over three or four lines at different
   heights and the list read as though the rows were running into each other. Two lines each, always,
   is legible at any width the popup happens to get; the full text is on the title. */
.rc-tax-line-meta {
    font-size: 0.85em;
    opacity: 0.7;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Bank import: the QIF/CSV escape hatch sits low in the upload row, down against the card's bottom
   edge, so it reads as a footnote to Upload rather than a second action beside it. */
.import-format-escape {
    align-self: flex-end;
    margin-bottom: -10px;
}
