/* /Components/Import/ImportFormatHelp.razor.rz.scp.css */
/*
    Scoped to ImportFormatHelp. Tokens only.
*/

/* Three short rules, tight, so the strip reads as a strip rather than as prose. */
.ctt-quickrules[b-0sdiho3hni] {
    margin: 0 0 var(--space-4) 0;
    padding-left: var(--space-4);
    color: var(--ink);
    font-size: var(--text-sm);
}

.ctt-quickrules li + li[b-0sdiho3hni] {
    margin-top: var(--space-1);
}

/*
    The example. A well inside the card, monospaced, with tabular figures so the dates line up under
    each other - a column of ragged dates is harder to copy correctly.
*/
.ctt-example[b-0sdiho3hni] {
    background-color: var(--sunken);
    border: 1px solid var(--rule);
    border-radius: var(--radius-sm);
    padding: var(--space-3);
    margin: 0 0 var(--space-3) 0;
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    font-variant-numeric: tabular-nums;
    overflow-x: auto;
}

.ctt-example--sm[b-0sdiho3hni] {
    font-size: var(--text-xs);
    padding: var(--space-2) var(--space-3);
}

.ctt-example:focus-visible[b-0sdiho3hni] {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}
/* /Components/Import/ImportPreview.razor.rz.scp.css */
/*
    Scoped to ImportPreview. Tokens only.

    The head row puts the crossing count and its chips beside the dates and the countries, so the whole
    of level 1 fits above the disclosures with no scroll.
*/

.ctt-preview-head[b-lz0vw44rgl] {
    display: grid;
    grid-template-columns: minmax(14rem, 20rem) 1fr;
    gap: var(--space-4);
    align-items: start;
    margin-bottom: var(--space-4);
}

@media (max-width: 48rem) {
    .ctt-preview-head[b-lz0vw44rgl] {
        grid-template-columns: 1fr;
    }
}

/*
    The one sentence that disqualifies the figure above it. Full contrast ink on a faint wash, not
    muted and not a filled red block: it has to be read, and a card filled red is a card the reader
    learns to close.
*/
.ctt-preview-head__alarm[b-lz0vw44rgl] {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    margin: var(--space-2) 0 0;
    padding: var(--space-2);
    border-left: 3px solid var(--crit);
    border-radius: var(--radius-sm);
    background: var(--crit-wash);
    color: var(--ink);
    font-size: var(--text-sm);
}

/* A short definition list: label on the left, value on the right, no table furniture. */
.ctt-facts[b-lz0vw44rgl] {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-1) var(--space-4);
    margin: 0;
}

.ctt-facts dt[b-lz0vw44rgl] {
    color: var(--muted);
    font-weight: var(--weight-regular);
    font-size: var(--text-sm);
    white-space: nowrap;
}

.ctt-facts dd[b-lz0vw44rgl] {
    color: var(--ink);
    margin: 0;
    font-size: var(--text-sm);
}

/* The crossings table can be long. It scrolls inside its own box, never the page. */
.ctt-preview-table[b-lz0vw44rgl] {
    max-height: 24rem;
    overflow-y: auto;
}
/* /Components/Import/ImportProblemList.razor.rz.scp.css */
/*
    Scoped to ImportProblemList. Tokens only.

    The washes are the faintest tint the palette has, on purpose. This list can be a hundred rows long
    and a saturated row colour repeated a hundred times is unreadable - and unreadable is the same as
    hidden for a list whose whole job is to be read.

    Colour is never the only signal here: every row carries its line number, the text as typed, and the
    reason in words.
*/

.ctt-problem-heading[b-bj7i2829dr] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
}

.ctt-problem-heading--crit[b-bj7i2829dr] {
    color: var(--crit);
}

.ctt-problem-heading--warn[b-bj7i2829dr] {
    color: var(--warn);
}

.ctt-problem--crit[b-bj7i2829dr] {
    --bs-table-bg: var(--crit-wash);
    --bs-table-accent-bg: var(--crit-wash);
    color: var(--ink);
}

.ctt-problem--warn[b-bj7i2829dr] {
    --bs-table-bg: var(--warn-wash);
    --bs-table-accent-bg: var(--warn-wash);
    color: var(--ink);
}
/* /Components/Import/LedgerExportPanel.razor.rz.scp.css */
/*
    Scoped to LedgerExportPanel. Tokens only.

    The layout puts the tile and the two buttons side by side on a laptop and stacked on a phone, so
    the count, the browser-promise chip and both save buttons are on the first screen with no scroll.
    That is the point: §5 calls this the escape hatch.
*/

.ctt-export[b-07ldyzyp0a] {
    display: grid;
    grid-template-columns: minmax(14rem, 20rem) 1fr;
    gap: var(--space-4);
    align-items: start;
}

@media (max-width: 48rem) {
    .ctt-export[b-07ldyzyp0a] {
        grid-template-columns: 1fr;
    }
}

.ctt-export__actions[b-07ldyzyp0a] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.ctt-export__action[b-07ldyzyp0a] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    align-items: flex-start;
}

.ctt-export__action p[b-07ldyzyp0a] {
    color: var(--ink);
    max-width: 52ch;
}
/* /Components/Ledger/LedgerCountryBand.razor.rz.scp.css */
/*
    LedgerCountryBand. Tokens only - see LedgerHeaderBar.razor.css for why.
*/

.ctt-lband[b-xd6e8ay9l3] {
    background-color: var(--surface);
    border: 1px solid var(--rule);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    margin-bottom: var(--space-4);
}

.ctt-lband__heading[b-xd6e8ay9l3] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0 0 var(--space-2) 0;
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.ctt-lband__heading-icon[b-xd6e8ay9l3] {
    color: var(--muted);
    line-height: 1;
}

.ctt-lband__list[b-xd6e8ay9l3] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

/*
    One row per country. It wraps rather than scrolls, because a country whose chips fell off the
    right edge of the band would be a warning nobody sees.
*/
.ctt-lband__item[b-xd6e8ay9l3] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    padding: var(--space-2) 0;
    border-top: 1px solid var(--rule);
}

.ctt-lband__item:first-child[b-xd6e8ay9l3] {
    border-top: 0;
}

.ctt-lband__name[b-xd6e8ay9l3] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    color: var(--ink);
    font-weight: var(--weight-medium);
    min-width: 11rem;
}

.ctt-lband__name-icon[b-xd6e8ay9l3] {
    color: var(--muted);
    font-size: var(--text-sm);
    line-height: 1;
}

.ctt-lband__nights[b-xd6e8ay9l3] {
    color: var(--muted);
    font-size: var(--text-sm);
    font-variant-numeric: tabular-nums;
    min-width: 5.5rem;
}

.ctt-lband__chips[b-xd6e8ay9l3] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}
/* /Components/Ledger/LedgerHeaderBar.razor.rz.scp.css */
/*
    LedgerHeaderBar.

    Every value is a token from wwwroot/css/tokens.css, which is generated from design/tokens.json.
    No raw hex, no raw pixel size: a colour written here is a colour that exists on web and nowhere
    else, and this app also has a MAUI head coming.
*/

.ctt-lhead[b-rqlij0ij2v] {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
}

.ctt-lhead__what[b-rqlij0ij2v] {
    margin: 0;
    color: var(--muted);
    font-size: var(--text-sm);
}

/* The §8 line. Quiet, but on a surface of its own so it is never mistaken for body prose. */
.ctt-lhead__disclaimer[b-rqlij0ij2v] {
    margin: 0;
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    background-color: var(--sunken);
    border-radius: var(--radius-sm);
    color: var(--ink);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
}

.ctt-lhead__disclaimer-icon[b-rqlij0ij2v] {
    color: var(--muted);
    line-height: 1;
}

/* One primary action, then the rest. */
.ctt-lhead__actions[b-rqlij0ij2v] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
}

.ctt-lhead__secondary[b-rqlij0ij2v] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.ctt-lhead__actions .btn[b-rqlij0ij2v] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.ctt-lhead__totals[b-rqlij0ij2v] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-4);
}

.ctt-lhead__stat[b-rqlij0ij2v] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    color: var(--muted);
    font-size: var(--text-sm);
    font-variant-numeric: tabular-nums;
}

/*
    The open-gap banner. Amber, not red: it is a state to act on, not a limit already passed, and the
    three semantic colours mean one thing each.
*/
.ctt-lbanner[b-rqlij0ij2v] {
    display: flex;
    gap: var(--space-3);
    align-items: flex-start;
    padding: var(--space-3);
    background-color: var(--warn-wash);
    border: 1px solid var(--warn);
    border-left-width: 3px;
    border-radius: var(--radius-md);
}

.ctt-lbanner__icon[b-rqlij0ij2v] {
    color: var(--warn);
    font-size: var(--text-md);
    line-height: var(--leading-snug);
}

.ctt-lbanner__body[b-rqlij0ij2v] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
}

.ctt-lbanner__line[b-rqlij0ij2v] {
    margin: 0;
    color: var(--ink);
    font-weight: var(--weight-medium);
}

.ctt-lbanner__body .btn[b-rqlij0ij2v] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}
/* /Components/Ledger/LedgerTable.razor.rz.scp.css */
/*
    LedgerTable. Tokens only - see LedgerHeaderBar.razor.css for why.

    The two rules this file exists to hold in CSS:
      1. A gap row is amber and unmistakable.
      2. A transit row is NOT amber. It is quiet grey, because it is known, and giving it the same
         colour as a gap would say the two are the same kind of fact.
*/

.ctt-lt[b-rjrv9izgrv] {
    margin-bottom: var(--space-3);
}

.ctt-lt__caption[b-rjrv9izgrv] {
    caption-side: top;
    padding: 0 0 var(--space-2) 0;
    color: var(--muted);
    font-size: var(--text-sm);
}

.ctt-lt thead th[b-rjrv9izgrv] {
    color: var(--muted);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    vertical-align: bottom;
    white-space: nowrap;
}

/* The nights heading, and the four words under it that keep the direction of the danger visible. */
.ctt-lt__nights-head[b-rjrv9izgrv] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
}

.ctt-lt__nights-sub[b-rjrv9izgrv] {
    display: block;
    text-transform: none;
    letter-spacing: 0;
    font-weight: var(--weight-regular);
    color: var(--warn);
    font-size: var(--text-xs);
}

.ctt-lt__type[b-rjrv9izgrv] {
    width: 1.75rem;
    text-align: center;
    padding-right: 0;
}

.ctt-lt__date[b-rjrv9izgrv],
.ctt-lt__nights[b-rjrv9izgrv] {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.ctt-lt__note[b-rjrv9izgrv] {
    color: var(--muted);
    font-size: var(--text-sm);
    max-width: 18rem;
}

.ctt-lt__actions[b-rjrv9izgrv],
.ctt-lt__actions-head[b-rjrv9izgrv] {
    width: 2.5rem;
    text-align: right;
}

/* ---------------------------------------------------------------- rows */

.ctt-lrow > td[b-rjrv9izgrv] {
    border-color: var(--rule);
}

.ctt-lrow__icon[b-rjrv9izgrv] {
    color: var(--muted);
    line-height: 1;
}

.ctt-lrow__entered[b-rjrv9izgrv] {
    color: var(--ink);
    font-weight: var(--weight-medium);
}

.ctt-lrow__chips[b-rjrv9izgrv] {
    display: inline-flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin-left: var(--space-2);
    vertical-align: middle;
}

.ctt-lrow__sub[b-rjrv9izgrv] {
    display: block;
    color: var(--muted);
    font-size: var(--text-xs);
}

/* ---- a gap. Amber, and the icon is amber too, so colour is never the only signal. ---- */
.ctt-lrow--gap > td[b-rjrv9izgrv] {
    background-color: var(--warn-wash);
    color: var(--ink);
}

.ctt-lrow--gap > td:first-child[b-rjrv9izgrv] {
    box-shadow: inset 3px 0 0 0 var(--warn);
}

.ctt-lrow--gap .ctt-lrow__icon[b-rjrv9izgrv] {
    color: var(--warn);
}

.ctt-lrow--gap .ctt-lrow__entered[b-rjrv9izgrv] {
    color: var(--ink);
}

/* ---- in transit. Deliberately different from a gap: grey, not amber. ---- */
.ctt-lrow--transit > td[b-rjrv9izgrv] {
    background-color: var(--sunken);
    color: var(--ink);
}

.ctt-lrow--transit > td:first-child[b-rjrv9izgrv] {
    box-shadow: inset 3px 0 0 0 var(--muted);
}

.ctt-lrow--transit .ctt-lrow__icon[b-rjrv9izgrv] {
    color: var(--muted);
}

/* ---- the header row for a date carrying more than one crossing ---- */
.ctt-lrow--group > td[b-rjrv9izgrv] {
    background-color: var(--sunken);
    color: var(--ink);
    font-size: var(--text-sm);
    border-top: 1px solid var(--rule);
}

.ctt-lrow__group-icon[b-rjrv9izgrv] {
    color: var(--muted);
    margin-right: var(--space-1);
    line-height: 1;
}

.ctt-lrow__route[b-rjrv9izgrv] {
    color: var(--muted);
    margin-left: var(--space-2);
}

.ctt-lrow__roundtrip[b-rjrv9izgrv] {
    color: var(--muted);
    margin-left: var(--space-2);
    font-style: italic;
}

/* ---- provenance. §2: it is on every row, and only the unconfirmed one is coloured. ---- */
.ctt-lrow__prov[b-rjrv9izgrv] {
    display: inline-block;
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    color: var(--ink);
    background-color: var(--sunken);
    border: 1px solid var(--rule);
    border-radius: var(--radius-pill);
    padding: 0.1rem var(--space-2);
    white-space: nowrap;
}

.ctt-lrow__prov--warn[b-rjrv9izgrv] {
    background-color: var(--warn-wash);
    border-color: var(--warn);
}

/* ---- the one row action ---- */
.ctt-lrow__delete[b-rjrv9izgrv] {
    appearance: none;
    -webkit-appearance: none;
    background: none;
    border: 0;
    padding: var(--space-1);
    color: var(--muted);
    line-height: 1;
    border-radius: var(--radius-sm);
    cursor: pointer;
}

.ctt-lrow__delete:hover[b-rjrv9izgrv] {
    color: var(--crit);
    background-color: var(--crit-wash);
}
/* /Components/Settings/DeviceList.razor.rz.scp.css */
/*
    One rule. The network address a session was last seen from is raw machine text the reader is
    comparing character by character against something they half remember, so it is monospace - the
    same treatment country codes and imported values get in this app.

    Nothing here redefines a shared kit class. The chip on a row with no address is the kit's
    StatusChip, styled once in wwwroot/css/app.css.
*/
.ctt-devices__where[b-5ix0dbl7wc] {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    overflow-wrap: anywhere;
}
/* /Components/Settings/ProfileSwitchRow.razor.rz.scp.css */
/*
    Scoped to ProfileSwitchRow.

    Deliberately NOT added to wwwroot/css/app.css. That file belongs to the shared UI kit and three
    other screens are being rebuilt against it at the same time; a class added there for one screen is
    a merge conflict and a class nobody else knows the rules for. Every value below is a token from
    css/tokens.css, so the switch still follows the theme.
*/

.ctt-switch[b-y7cn2cli6z] {
    padding: var(--space-3) 0 var(--space-3) 2.75rem;
    border-bottom: 1px solid var(--rule);
    margin: 0;
}

.ctt-switch:last-child[b-y7cn2cli6z] {
    border-bottom: none;
}

/* Bootstrap puts the switch track at the left edge; pull it into the padding we just added. */
.ctt-switch .form-check-input[b-y7cn2cli6z] {
    margin-left: -2.75rem;
    width: 2.25rem;
    height: 1.15rem;
    margin-top: 0.15rem;
    cursor: pointer;
}

.ctt-switch .form-check-input:checked[b-y7cn2cli6z] {
    background-color: var(--accent);
    border-color: var(--accent);
}

.ctt-switch .form-check-label[b-y7cn2cli6z] {
    cursor: pointer;
    display: block;
}

.ctt-switch__label[b-y7cn2cli6z] {
    display: block;
    color: var(--ink);
    font-weight: var(--weight-semibold);
}

/* ONE line. The consequence is the whole answer for a reader who never opens the popover, so it gets
   real contrast rather than the muted grey a caption would take. */
.ctt-switch__consequence[b-y7cn2cli6z] {
    display: block;
    color: var(--ink);
    font-size: var(--text-sm);
    margin-top: 0.15rem;
}
/* /Layout/MainLayout.razor.rz.scp.css */
/*
    The app frame: the title bar, the status bar, the drawer-or-sidebar, the main column, the footer.

    WHAT IS IN HERE, AND WHAT IS NOT
    Only the frame. The shared UI kit (StatusChip, StatTile, InfoHint, Disclosure, EmptyState) and the
    Bootstrap remap are in wwwroot/css/app.css, which is global and therefore the right place for an
    app-wide skin. This file once held a second copy of all of it, written when app.css was believed to
    be the untouched Blazor template; two owners of one rule meant two places for the app to disagree
    with itself about what amber is. Do not put a .ctt-* rule back in here.

    ::deep, AND WHEN IT IS REQUIRED
    Blazor stamps its scope attribute only on the elements a component renders ITSELF. MainLayout
    renders .shell, .shell-bar, .shell-body, .shell-drawer, .shell-scrim, .shell-main and .shell-foot,
    so those take a plain selector. ShellStatusBar renders .shell-status and its children, so those
    MUST be written ::deep - without it .shell-status compiles to .shell-status[b-xxx] and matches
    nothing at all, and the sticky bar carrying all three warnings renders unstyled and scrolls away.
    That bug has happened here once already. A test now asserts the ::deep prefix on those selectors.

    Everything here is presentation. No selector encodes a rule, a threshold or a country.
*/
/* =========================================================================================
   THE FRAME
   ========================================================================================= */

.shell[b-vimflvta5v] {
    /* Restated on the frame rather than left to inherit, so the app column reads correctly even
       if a host page ever supplies a different body font. app.css sets the same values on body. */
    font-family: var(--font-ui);
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    color: var(--ink);
    background: var(--ground);
    min-height: 100vh;
    display: flex;
    flex-direction: column;

    /* Digits line up in every column, table and figure in the app. */
    font-variant-numeric: tabular-nums;

    /* ---- Bootstrap, re-pointed at the design tokens ----
       Bootstrap 5.3 reads these at run time, so one block here makes its buttons, tables, forms,
       modals and popovers follow the skin - and follow it in dark theme too, because the tokens do.
       Custom properties inherit, so this reaches @Body as well. */
    --bs-body-font-family: var(--font-ui);
    --bs-body-font-size: var(--text-base);
    --bs-body-color: var(--ink);
    --bs-body-bg: var(--ground);
    --bs-emphasis-color: var(--ink);
    --bs-heading-color: var(--ink);
    --bs-secondary-color: var(--muted);
    --bs-tertiary-color: var(--muted);
    --bs-secondary-bg: var(--sunken);
    --bs-tertiary-bg: var(--sunken);
    --bs-border-color: var(--rule);
    --bs-border-radius: var(--radius-md);
    --bs-border-radius-sm: var(--radius-sm);
    --bs-border-radius-lg: var(--radius-lg);
    --bs-link-color: var(--accent);
    --bs-link-hover-color: var(--accent);
    --bs-code-color: var(--accent);
    --bs-primary: var(--accent);
}

/* ---- title bar ---- */

.shell-bar[b-vimflvta5v] {
    position: sticky;
    top: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    height: 3rem;
    padding: 0 var(--space-3);
    background: var(--accent);
    color: var(--accent-ink);
}

.shell-bar__brand[b-vimflvta5v] {
    color: var(--accent-ink);
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
    text-decoration: none;
    white-space: nowrap;

    display: inline-flex;
    align-items: center;
    gap: var(--space-2);

    /*
        NEVER shrink, and no ellipsis.

        The bar holds a menu button and this, nothing else - the mark plus "Country Time" is about
        130px, which fits the narrowest phone in use. The rules that used to be here did the opposite:
        min-width 0 removed the automatic minimum size a flex item gets from its own content, which let
        this collapse, and text-overflow then cut the name down to "Cou...". An app that cannot say its
        own name in its own title bar looks broken, so it is better for the bar to overflow visibly
        than to hide the name quietly.
    */
    flex: none;

    /*
        The bar is filled with the accent, and the mark's default deep half IS the accent - so left
        alone it would be a teal shape on a teal bar. Restated here: the deep half becomes the text
        colour, the soft half a wash of it, and the cut takes the bar's own colour so it still reads
        as a gap rather than as a third stripe.
    */
    --brand-deep: var(--accent-ink);
    --brand-soft: color-mix(in srgb, var(--accent-ink) 42%, transparent);
    --brand-cut: var(--accent);
}

/*
    ::deep is REQUIRED here, and its absence made the mark invisible once.

    MainLayout writes the class - <BrandGlyph Class="shell-bar__mark" /> - but BrandGlyph renders the
    <svg>. Blazor stamps the scope attribute only on elements a component renders ITSELF, so a plain
    selector compiled to .shell-bar__mark[b-xxx] and matched nothing. An <svg> carrying only a viewBox
    has no intrinsic size inside a flex row, so with no width it collapsed to zero and the logo simply
    was not there.

    Writing the class in this file is not the same as rendering the element. That is the trap.
*/
.shell-bar__brand[b-vimflvta5v]  .shell-bar__mark {
    width: 1.5rem;
    height: 1.5rem;
    flex: none;
}


.shell-bar__menu[b-vimflvta5v] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    /* Mixed out of the ink colour, not white: --accent is a light blue in dark theme, where a white
       border and white glyph would both disappear. rgba first as a fallback. */
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-color: color-mix(in srgb, var(--accent-ink) 40%, transparent);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--accent-ink);
    font-size: var(--text-md);
    cursor: pointer;
}

.shell-visually-hidden[b-vimflvta5v] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ---- body: drawer or sidebar, plus the screen ---- */

.shell-body[b-vimflvta5v] {
    display: flex;
    align-items: stretch;
    flex: 1;
    min-height: 0;
}

.shell-main[b-vimflvta5v] {
    flex: 1;
    /* Without this a wide table inside @Body stretches the flex item and the whole page scrolls
       sideways. Level 1 has to be readable without that. */
    min-width: 0;
    padding: var(--space-5) var(--space-4) var(--space-6);
}

/* The drawer, on a narrow screen. Below the title bar on purpose, so the button that opened it is
   still on screen and still closes it. */
.shell-drawer[b-vimflvta5v] {
    display: none;
    position: fixed;
    top: 3rem;
    left: 0;
    bottom: 0;
    z-index: 60;
    width: min(17rem, 80vw);
    overflow-y: auto;
    background: var(--accent);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15);
}

.shell--menu-open .shell-drawer[b-vimflvta5v] {
    display: block;
}

/* A button, not a div: a keyboard reader gets a real way out of the drawer. */
.shell-scrim[b-vimflvta5v] {
    position: fixed;
    top: 3rem;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 50;
    border: 0;
    padding: 0;
    background: rgba(0, 0, 0, 0.45);
    cursor: pointer;
}

/* ---- footer: the escape hatches ---- */

.shell-foot[b-vimflvta5v] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-4);
    padding: var(--space-3) var(--space-4);
    border-top: 1px solid var(--rule);
    background: var(--surface);
    color: var(--muted);
    font-size: var(--text-sm);
}

.shell-foot__name[b-vimflvta5v] {
    font-weight: var(--weight-medium);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

/* The footer sits on the page ground, so the mark keeps its own colours here.
   ::deep for the same reason as the bar's mark: BrandGlyph renders the svg, not MainLayout. */
.shell-foot__name[b-vimflvta5v]  .shell-foot__mark {
    width: 1.125rem;
    height: 1.125rem;
    flex: none;
}

.shell-foot a[b-vimflvta5v] {
    color: var(--accent);
}

/* ---- wide screen: the drawer becomes a sidebar ---- */

@media (min-width: 900px) {
    .shell-bar__menu[b-vimflvta5v] {
        display: none;
    }

    .shell-drawer[b-vimflvta5v] {
        display: block;
        position: static;
        top: auto;
        width: 14rem;
        flex: 0 0 14rem;
        box-shadow: none;
    }

    .shell-scrim[b-vimflvta5v] {
        display: none;
    }

    .shell-main[b-vimflvta5v] {
        padding: var(--space-5) var(--space-5) var(--space-7);
    }
}

/* =========================================================================================
   THE STATUS BAR

   Sticky, under the title bar, so the three facts that change what a number means cannot be
   scrolled away. Kept to one line on a laptop and two or three on a phone: the dashboard has to
   show its first figure without scrolling.

   ::deep on all three, because ShellStatusBar renders this markup, not MainLayout. Blazor stamps
   its scope attribute only on the elements a component renders itself, so a plain .shell-status
   selector here compiles to .shell-status[b-xxx] and matches nothing at all.
   ========================================================================================= */

[b-vimflvta5v] .shell-status {
    position: sticky;
    top: 3rem;
    z-index: 20;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2) var(--space-4);
    padding: var(--space-2) var(--space-4);
    border-bottom: 1px solid var(--rule);
    background: var(--surface);
}

/* The section 8 line. Quiet - muted, small, no icon shouting at anyone - but never absent. */
[b-vimflvta5v] .shell-status__note {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    margin: 0;
    color: var(--muted);
    font-size: var(--text-sm);
}

[b-vimflvta5v] .shell-status__chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

/* =========================================================================================
   THE FOCUS RING on the shell's own two controls.

   ::deep is not used and must not be: these two elements are rendered by MainLayout itself, so a
   ::deep selector would not match them. Everything else in the app takes its ring from app.css.
   ========================================================================================= */

.shell-bar__menu:focus-visible[b-vimflvta5v],
.shell-scrim:focus-visible[b-vimflvta5v] {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

/* =========================================================================================
   THE GATE'S WAITING LINE.

   Shown for the few milliseconds between the page loading and the stored session token being read.
   Quiet on purpose: it is not a warning and it is not an error, and a loud panel here would flash on
   every single load. MainLayout renders this element itself, so no ::deep.
   ========================================================================================= */

.shell-gate[b-vimflvta5v] {
    color: var(--muted);
    font-size: var(--text-sm);
    margin: var(--space-4) 0 0;
}
/* /Layout/NavMenu.razor.rz.scp.css */
/*
    The navigation, drawn once. MainLayout decides where it sits - a drawer below 900px, a sidebar
    above - so nothing here positions itself.

    The accent colour is the structure colour and means nothing else. A nav item is never green,
    amber or red: those three mean safe, watch and breach, and a menu has no verdict to give.

    THEME NOTE. The drawer is painted with --accent, which is a DEEP teal in light theme and a LIGHT
    blue in dark theme. So the text here must be --accent-ink, never white: white on the dark-theme
    accent is unreadable. The hover and active washes are mixed out of --accent-ink for the same
    reason, with a plain rgba fallback first for any engine without color-mix.
*/

.shell-nav[b-rhu0hvrpeu] {
    padding: var(--space-3) var(--space-2);
}

.shell-nav__list[b-rhu0hvrpeu] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

/* ::deep, because NavLink renders the anchor itself and Blazor's scope attribute lands on this
   component's own elements only. */
.shell-nav__item[b-rhu0hvrpeu]  .shell-nav__link {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    color: var(--accent-ink);
    font-size: var(--text-base);
    text-decoration: none;
    opacity: 0.86;

    /* Comfortable for a thumb on a phone. */
    min-height: 2.75rem;
}

.shell-nav__item[b-rhu0hvrpeu]  .shell-nav__link:hover {
    background: rgba(255, 255, 255, 0.14);
    background: color-mix(in srgb, var(--accent-ink) 16%, transparent);
    opacity: 1;
}

/* The screen the reader is on. A left bar as well as a wash, so the current item is still obvious to
   someone who cannot separate two close greys. */
.shell-nav__item[b-rhu0hvrpeu]  .shell-nav__link.active {
    background: rgba(255, 255, 255, 0.2);
    background: color-mix(in srgb, var(--accent-ink) 22%, transparent);
    box-shadow: inset 0.1875rem 0 0 0 var(--accent-ink);
    font-weight: var(--weight-medium);
    opacity: 1;
}

.shell-nav__item[b-rhu0hvrpeu]  .shell-nav__link:focus-visible {
    outline: 2px solid var(--accent-ink);
    outline-offset: -2px;
}

.shell-nav__icon[b-rhu0hvrpeu] {
    flex: 0 0 1.25rem;
    font-size: var(--text-md);
    text-align: center;
}
/* /Layout/SignInLayout.razor.rz.scp.css */
/*
    The sign-in frame. One narrow column, centred, on the app's own ground colour.

    EVERY COLOUR AND EVERY SIZE IS A TOKEN. No literal hex anywhere, so the dark theme follows for
    free - the same rule the app frame is held to by a test.

    ::deep, AND WHERE IT IS REQUIRED
    Blazor stamps its scope attribute only on the elements THIS component renders. .plain-bar__mark
    names the <svg> that BrandGlyph renders, so it must be written ::deep or it compiles to
    .plain-bar__mark[b-xxx], matches nothing, and the mark renders at whatever size an unstyled inline
    svg happens to be. That exact bug made the logo disappear from the app bar once.
*/
.plain[b-lem99d3smi] {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-5) var(--space-4) var(--space-6);
    background: var(--ground);
    color: var(--ink);
    font-family: var(--font-ui);
    font-size: var(--text-base);
    line-height: var(--leading-normal);
}

.plain-bar[b-lem99d3smi] {
    display: flex;
    align-items: center;
    justify-content: center;
}

.plain-bar__brand[b-lem99d3smi] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-lg);
    font-weight: var(--weight-semibold);
    line-height: var(--leading-snug);

    /* No min-width: 0 and no text-overflow. The app's name is the app's name; the bar holds nothing
       else, so there is never a shortage of room, and a rule that lets it collapse once printed
       "Cou..." in the app frame. */
    flex: none;
}

[b-lem99d3smi] .plain-bar__mark {
    width: 2rem;
    height: 2rem;
    flex: none;
}

.plain-note[b-lem99d3smi] {
    color: var(--muted);
    font-size: var(--text-sm);
    text-align: center;
    margin: 0;
    max-width: 46rem;
}

.plain-main[b-lem99d3smi] {
    /* Phone first: full width, and a ceiling so the form does not stretch across a laptop. */
    width: 100%;
    max-width: 34rem;

    /* Lets a wide child - a long error message, a pasted address - shrink instead of pushing the
       page sideways. */
    min-width: 0;
}

.plain-foot[b-lem99d3smi] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin-top: auto;
    padding-top: var(--space-5);
    font-size: var(--text-sm);
}

.plain-foot a[b-lem99d3smi] {
    color: var(--muted);
}
/* /Pages/Dashboard.razor.rz.scp.css */
/* =============================================================================================
   Dashboard styles.

   Scoped to this page (Blazor CSS isolation), and every rule that reaches a child component uses
   ::deep on purpose. Nothing here is global: the shared classes - .ctt-tile, .ctt-chip, .ctt-hint,
   .ctt-disclosure, .ctt-empty, .ctt-tile-grid, .ctt-chip-row, .ctt-scroll-x - belong to the kit in
   wwwroot/css/app.css and are not touched from here. Three other screens share them.

   Every colour is a token from css/tokens.css, so dark theme comes for free and cannot drift from
   the rest of the app. No colour is written as a literal.

   Corner radii and spacing are tokens too. Radii are in px on purpose - a corner is physical
   geometry and should not grow with the reader's font size.
   ============================================================================================= */

.ctt-dash[b-3x74o3te3n] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

/* ---------------------------------------------------------------------------------------------
   1. The page head. Title, and the one line of framing that section 8 requires on the page.
   --------------------------------------------------------------------------------------------- */
.ctt-dash__head[b-3x74o3te3n] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.ctt-dash__h1[b-3x74o3te3n] {
    margin: 0;
    font-size: var(--text-xl);
    font-weight: var(--weight-semibold);
    line-height: var(--leading-tight);
    color: var(--ink);
}

/* The disclaimer. Grey, but body size - it is not fine print. */
.ctt-dash__legal[b-3x74o3te3n] {
    margin: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-1);
    font-size: var(--text-sm);
    color: var(--muted);
}

/* ---------------------------------------------------------------------------------------------
   2. The header strip. One line of facts about the record the numbers came from.
   --------------------------------------------------------------------------------------------- */
.ctt-dash[b-3x74o3te3n]  .ctt-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-4);
    padding: var(--space-2) var(--space-3);
    background-color: var(--sunken);
    border: 1px solid var(--rule);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.ctt-dash[b-3x74o3te3n]  .ctt-strip__fact,
.ctt-dash[b-3x74o3te3n]  .ctt-strip__link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    white-space: nowrap;
}

.ctt-dash[b-3x74o3te3n]  .ctt-strip__link {
    margin-left: auto;
    color: var(--accent);
}

/* ---------------------------------------------------------------------------------------------
   3. One-line notices. A warning that changes a decision, with its explanation in a popover.
      Deliberately not Bootstrap's .alert: an alert is a block of prose, and a block of prose is
      what this page is removing.
   --------------------------------------------------------------------------------------------- */
.ctt-notice[b-3x74o3te3n] {
    margin: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-1);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--rule);
    border-left: 3px solid var(--rule);
    border-radius: var(--radius-md);
    background-color: var(--surface);
    font-size: var(--text-sm);
    color: var(--ink);
}

.ctt-notice--warn[b-3x74o3te3n] {
    border-left-color: var(--warn);
}

.ctt-notice--warn > i[b-3x74o3te3n] {
    color: var(--warn);
}

/* ---------------------------------------------------------------------------------------------
   4. The top row: Schengen wide, the US tiles beside it.

      Schengen gets the space because it is the only limit on this page with a border officer
      attached. Below 60rem the two stack, so the tile keeps its figure legible on a phone.
   --------------------------------------------------------------------------------------------- */
.ctt-dash__top[b-3x74o3te3n] {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: var(--space-3);
    align-items: start;
}

/* The two US tiles sit side by side where there is room and stack where there is not. Stacking them
   always would push the residency table a whole tile further down the page, which is exactly the
   scrolling this redesign removes. */
.ctt-dash__side[b-3x74o3te3n] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    align-content: start;
    gap: var(--space-3);
    min-width: 0;
}

@media (max-width: 60rem) {
    .ctt-dash__top[b-3x74o3te3n] {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ---------------------------------------------------------------------------------------------
   5. The Schengen tile. Same shape as the kit's StatTile - a status edge, not a fill - but with a
      bigger figure and room for the meter.
   --------------------------------------------------------------------------------------------- */
.ctt-dash[b-3x74o3te3n]  .ctt-big {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-4);
    background-color: var(--surface);
    border: 1px solid var(--rule);
    border-left: 3px solid var(--rule);
    border-radius: var(--radius-lg);
    min-width: 0;
}

.ctt-dash[b-3x74o3te3n]  .ctt-big--ok { border-left-color: var(--ok); }
.ctt-dash[b-3x74o3te3n]  .ctt-big--warn { border-left-color: var(--warn); }
.ctt-dash[b-3x74o3te3n]  .ctt-big--crit { border-left-color: var(--crit); }

.ctt-dash[b-3x74o3te3n]  .ctt-big__head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.ctt-dash[b-3x74o3te3n]  .ctt-big__title {
    margin: 0;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
    line-height: var(--leading-snug);
    color: var(--ink);
}

.ctt-dash[b-3x74o3te3n]  .ctt-big__title > i {
    color: var(--accent);
}

.ctt-dash[b-3x74o3te3n]  .ctt-big__head > .ctt-hint {
    margin-left: auto;
}

.ctt-dash[b-3x74o3te3n]  .ctt-big__lead {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.ctt-dash[b-3x74o3te3n]  .ctt-big__label {
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--muted);
}

.ctt-dash[b-3x74o3te3n]  .ctt-big__value {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.ctt-dash[b-3x74o3te3n]  .ctt-big__figure {
    font-size: var(--text-figure);
    font-weight: var(--weight-bold);
    line-height: var(--leading-tight);
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

.ctt-dash[b-3x74o3te3n]  .ctt-big__figure--ok { color: var(--ok); }
.ctt-dash[b-3x74o3te3n]  .ctt-big__figure--warn { color: var(--warn); }
.ctt-dash[b-3x74o3te3n]  .ctt-big__figure--crit { color: var(--crit); }

.ctt-dash[b-3x74o3te3n]  .ctt-big__unit {
    font-size: var(--text-base);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/* No answer is not a small number. It is a sentence, where the number would be, in muted type -
   never coloured, because there is no verdict to colour. */
.ctt-dash[b-3x74o3te3n]  .ctt-big__none {
    font-size: var(--text-lg);
    font-weight: var(--weight-semibold);
    line-height: var(--leading-snug);
    color: var(--muted);
}

/* The demoted figure. Small, but full contrast: it is not fine print and it is not hidden. */
.ctt-dash[b-3x74o3te3n]  .ctt-big__provisional {
    margin: 0;
    max-width: 60ch;
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}

.ctt-dash[b-3x74o3te3n]  .ctt-big__caption {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    font-size: var(--text-sm);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.ctt-dash[b-3x74o3te3n]  .ctt-big__sep {
    color: var(--rule);
}

/* ---------------------------------------------------------------------------------------------
   6. The meter.

      Two segments. Solid is what the record counts. Striped is how much further the count could
      reach if every date with no record turned out to be a day that counts - the gap made visible
      on the figure itself, not only in the words.

      The stripes are drawn with a gradient rather than an animation, so there is nothing to switch
      off under prefers-reduced-motion.
   --------------------------------------------------------------------------------------------- */
.ctt-dash[b-3x74o3te3n]  .ctt-meter {
    display: flex;
    height: 0.75rem;
    background-color: var(--sunken);
    border-radius: var(--radius-pill);
    overflow: hidden;
}

/* Inline, so the meter and the window it measures share one line inside a table cell. */
.ctt-dash[b-3x74o3te3n]  .ctt-meter--slim {
    display: inline-flex;
    width: 6rem;
    height: 0.4rem;
    margin-right: var(--space-2);
    vertical-align: middle;
}

.ctt-dash[b-3x74o3te3n]  .ctt-meter__solid {
    background-color: var(--accent);
    transition: none;
}

.ctt-dash[b-3x74o3te3n]  .ctt-meter__solid--ok { background-color: var(--ok); }
.ctt-dash[b-3x74o3te3n]  .ctt-meter__solid--warn { background-color: var(--warn); }
.ctt-dash[b-3x74o3te3n]  .ctt-meter__solid--crit { background-color: var(--crit); }

.ctt-dash[b-3x74o3te3n]  .ctt-meter__gap {
    background-image: repeating-linear-gradient(
        45deg,
        var(--muted) 0,
        var(--muted) 2px,
        transparent 2px,
        transparent 5px
    );
    opacity: 0.75;
}

/* No scale under the bar. The unit beside the figure already says "of 90", and a second copy of the
   ceiling costs a line of height on the one screen this page has to fit into. */

/* ---------------------------------------------------------------------------------------------
   7. Section heads, used by the residency table.
   --------------------------------------------------------------------------------------------- */
.ctt-dash[b-3x74o3te3n]  .ctt-section {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.ctt-dash[b-3x74o3te3n]  .ctt-section__head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.ctt-dash[b-3x74o3te3n]  .ctt-section__title {
    margin: 0;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
    color: var(--ink);
}

.ctt-dash[b-3x74o3te3n]  .ctt-section__title > i {
    color: var(--accent);
}

.ctt-dash[b-3x74o3te3n]  .ctt-section__head > .ctt-hint {
    margin-left: auto;
}

/* ---------------------------------------------------------------------------------------------
   8. The residency table. Thirteen countries, one row each.

      Rows are tight on purpose: the whole point of this screen is that thirteen countries fit on
      one laptop screen without scrolling. The table scrolls inside .ctt-scroll-x when the viewport
      is too narrow, so the page body never scrolls sideways.
   --------------------------------------------------------------------------------------------- */
.ctt-dash[b-3x74o3te3n]  .ctt-rows {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
}

.ctt-dash[b-3x74o3te3n]  .ctt-rows thead th {
    padding: var(--space-1) var(--space-2);
    text-align: left;
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted);
    border-bottom: 1px solid var(--rule);
    white-space: nowrap;
}

.ctt-dash[b-3x74o3te3n]  .ctt-rows__band th {
    padding: var(--space-2) var(--space-2) var(--space-1);
    text-align: left;
    font-weight: var(--weight-regular);
    border-bottom: 1px solid var(--rule);
}

.ctt-dash[b-3x74o3te3n]  .ctt-rows__bandname {
    display: inline-block;
    margin-right: var(--space-2);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--ink);
}

/* Tight rows on purpose. Thirteen countries have to fit beside a Schengen tile on one laptop screen,
   and every extra pixel per row costs thirteen of them. */
.ctt-dash[b-3x74o3te3n]  .ctt-rows tbody tr:not(.ctt-rows__band) > * {
    padding: var(--space-1) var(--space-2);
    border-bottom: 1px solid var(--rule);
    vertical-align: middle;
}

/* The two rows that carry a demoted figure need the room, and only those. */
.ctt-dash[b-3x74o3te3n]  .ctt-rows__row--thin > * {
    vertical-align: top;
    padding-top: var(--space-2);
    padding-bottom: var(--space-2);
}

/* The status colour is a left edge on the row, the same idea as the tiles. */
.ctt-dash[b-3x74o3te3n]  .ctt-rows__row > :first-child {
    border-left: 3px solid transparent;
}

.ctt-dash[b-3x74o3te3n]  .ctt-rows__row--ok > :first-child { border-left-color: var(--ok); }
.ctt-dash[b-3x74o3te3n]  .ctt-rows__row--warn > :first-child { border-left-color: var(--warn); }
.ctt-dash[b-3x74o3te3n]  .ctt-rows__row--crit > :first-child { border-left-color: var(--crit); }

.ctt-dash[b-3x74o3te3n]  .ctt-rows__country {
    font-weight: var(--weight-regular);
    text-align: left;
    min-width: 9rem;
}

.ctt-dash[b-3x74o3te3n]  .ctt-rows__code {
    display: inline-block;
    min-width: 2.2rem;
    font-weight: var(--weight-semibold);
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}

.ctt-dash[b-3x74o3te3n]  .ctt-rows__name {
    color: var(--muted);
}

.ctt-dash[b-3x74o3te3n]  .ctt-rows__num {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

.ctt-dash[b-3x74o3te3n]  .ctt-rows__figure {
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
    color: var(--ink);
}

.ctt-dash[b-3x74o3te3n]  .ctt-rows__figure--ok { color: var(--ok); }
.ctt-dash[b-3x74o3te3n]  .ctt-rows__figure--warn { color: var(--warn); }
.ctt-dash[b-3x74o3te3n]  .ctt-rows__figure--crit { color: var(--crit); }

/* On the same line as the figure. A stacked unit costs a line on every one of thirteen rows. */
.ctt-dash[b-3x74o3te3n]  .ctt-rows__unit {
    font-size: var(--text-xs);
    color: var(--muted);
}

/* Words where a figure would be. Left-aligned and wrapped: it is a phrase, not a number. */
.ctt-dash[b-3x74o3te3n]  .ctt-rows__none {
    display: block;
    text-align: left;
    max-width: 12rem;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--muted);
    white-space: normal;
}

/* The demoted figure on a row. Full contrast, small type, never hidden. */
.ctt-dash[b-3x74o3te3n]  .ctt-rows__prov {
    display: block;
    margin-top: var(--space-1);
    text-align: left;
    max-width: 26rem;
    font-size: var(--text-xs);
    line-height: var(--leading-normal);
    color: var(--ink);
    white-space: normal;
}

/* Beside the meter, not under it. Same reason: one line per row, thirteen rows. */
.ctt-dash[b-3x74o3te3n]  .ctt-rows__window {
    font-size: var(--text-xs);
    color: var(--muted);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    vertical-align: middle;
}

.ctt-dash[b-3x74o3te3n]  .ctt-rows__act {
    text-align: right;
    white-space: nowrap;
}

/* ---------------------------------------------------------------------------------------------
   9. The "more" button: opens a dialog, or reveals the rest of a tile. A quiet link, not a button
      that competes with the figure beside it.
   --------------------------------------------------------------------------------------------- */
.ctt-dash[b-3x74o3te3n]  .ctt-more {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    font-size: var(--text-sm);
    color: var(--accent);
    cursor: pointer;
    text-align: left;
}

.ctt-dash[b-3x74o3te3n]  .ctt-more:hover {
    text-decoration: underline;
}

/* ---------------------------------------------------------------------------------------------
   10. Level 2 and level 3 content: the definition rows inside a Disclosure, the gap panel, and the
       bare card that becomes a dialog body.
   --------------------------------------------------------------------------------------------- */
.ctt-dash[b-3x74o3te3n]  .ctt-defs {
    display: grid;
    grid-template-columns: minmax(8rem, max-content) minmax(0, 1fr);
    gap: var(--space-1) var(--space-3);
    margin: 0 0 var(--space-3);
    font-size: var(--text-sm);
}

.ctt-dash[b-3x74o3te3n]  .ctt-defs dt {
    font-weight: var(--weight-medium);
    color: var(--muted);
}

.ctt-dash[b-3x74o3te3n]  .ctt-defs dd {
    margin: 0;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}

.ctt-dash[b-3x74o3te3n]  .ctt-detail__headline {
    margin: 0 0 var(--space-2);
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    color: var(--ink);
}

.ctt-dash[b-3x74o3te3n]  .ctt-detail__p {
    margin: 0 0 var(--space-3);
    max-width: 68ch;
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    color: var(--ink);
}

.ctt-dash[b-3x74o3te3n]  .ctt-detail__source {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    font-size: var(--text-xs);
    color: var(--muted);
}

.ctt-panel[b-3x74o3te3n],
.ctt-dash[b-3x74o3te3n]  .ctt-panel {
    padding: var(--space-3);
    border: 1px solid var(--rule);
    border-left: 3px solid var(--rule);
    border-radius: var(--radius-md);
    background-color: var(--surface);
}

.ctt-panel--warn[b-3x74o3te3n],
.ctt-dash[b-3x74o3te3n]  .ctt-panel--warn {
    border-left-color: var(--warn);
    background-color: var(--warn-wash);
}

.ctt-panel--crit[b-3x74o3te3n],
.ctt-dash[b-3x74o3te3n]  .ctt-panel--crit {
    border-left-color: var(--crit);
    background-color: var(--crit-wash);
}

.ctt-panel__head[b-3x74o3te3n],
.ctt-dash[b-3x74o3te3n]  .ctt-panel__head {
    margin: 0 0 var(--space-1);
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    /* Text on a wash is always --ink, so the panel reads at full contrast whatever it means. */
    color: var(--ink);
}

.ctt-panel__body[b-3x74o3te3n],
.ctt-dash[b-3x74o3te3n]  .ctt-panel__body {
    margin: 0;
    max-width: 72ch;
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    color: var(--ink);
}

/* A card used as a dialog body. No frame of its own - the dialog already has one. */
.ctt-dash[b-3x74o3te3n]  .ctt-bare {
    border: 0;
    background: none;
}

.ctt-dash[b-3x74o3te3n]  .ctt-bare__body {
    padding: 0;
}

.ctt-list[b-3x74o3te3n],
.ctt-dash[b-3x74o3te3n]  .ctt-list {
    margin: 0 0 var(--space-2);
    padding-left: var(--space-4);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    color: var(--ink);
}

.ctt-list > li[b-3x74o3te3n],
.ctt-dash[b-3x74o3te3n]  .ctt-list > li {
    margin-bottom: var(--space-1);
}

.ctt-dim[b-3x74o3te3n],
.ctt-dash[b-3x74o3te3n]  .ctt-dim {
    color: var(--muted);
}
/* /Pages/Import.razor.rz.scp.css */
/*
    Scoped to the Import/Export page. Tokens only.

    Kept out of wwwroot/css/app.css on purpose: that stylesheet belongs to the shared kit and three
    other screens are being rebuilt against it right now.
*/

/*
    The replace card. The breach colour is a left edge and a heading, never a fill: a card filled red
    is a card the reader learns to close, and this is the one card on the page they must read.
*/
.ctt-danger-card[b-hou553jkx7] {
    border-left: 3px solid var(--crit);
}

.ctt-danger-card h3[b-hou553jkx7] {
    color: var(--crit);
}

/* The "I am still there today" switch. Same shape as the settings switches, for the same reason. */
.ctt-switch[b-hou553jkx7] {
    padding-left: 2.75rem;
    margin: 0;
}

.ctt-switch .form-check-input[b-hou553jkx7] {
    margin-left: -2.75rem;
    width: 2.25rem;
    height: 1.15rem;
    margin-top: 0.15rem;
    cursor: pointer;
}

.ctt-switch .form-check-input:checked[b-hou553jkx7] {
    background-color: var(--accent);
    border-color: var(--accent);
}

.ctt-switch .form-check-label[b-hou553jkx7] {
    cursor: pointer;
    display: block;
}

.ctt-switch__label[b-hou553jkx7] {
    display: block;
    color: var(--ink);
    font-weight: var(--weight-semibold);
}

.ctt-switch__consequence[b-hou553jkx7] {
    display: block;
    color: var(--ink);
    font-size: var(--text-sm);
    margin-top: 0.15rem;
}
/* /Pages/Settings.razor.rz.scp.css */
/*
    Scoped to the Settings page. Tokens only - no hex values, no font stacks.

    Kept out of wwwroot/css/app.css on purpose: that stylesheet belongs to the shared kit and three
    other screens are being rebuilt against it right now.
*/

.ctt-switches[b-z1da8x6w98] {
    border-top: 1px solid var(--rule);
}

/* Shown / not shown. Words and an icon, never colour alone. */
.ctt-shown[b-z1da8x6w98],
.ctt-not-shown[b-z1da8x6w98] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    white-space: nowrap;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
}

.ctt-shown[b-z1da8x6w98] {
    color: var(--ok);
}

/*
    NOT the breach colour. A hidden tracker is not a breach - it is usually correct, because the
    reader said the tracker does not apply to them. Red here would read as an error on every
    well-answered profile, and a reader who learns to ignore red on this screen ignores it everywhere.
*/
.ctt-not-shown[b-z1da8x6w98] {
    color: var(--muted);
}
/* /Pages/SignIn.razor.rz.scp.css */
/*
    The sign-in screen's own rules. Four of them, and nothing that belongs to the shared kit.

    It redefines no .ctt-chip, .ctt-tile, .ctt-hint, .ctt-disclosure, .ctt-empty or .ctt-page-note
    rule: those live once, in wwwroot/css/app.css. A second copy here is how the same warning comes to
    look different on two screens.

    Colours are tokens. --warn is used for the two warning lines, and that is a legitimate semantic
    use: both say the app may not do what the reader expects.
*/

/* The Google button. Full width, so it reads as the first of two equal ways in. It is an anchor
   wearing .btn, so its text needs the centring a real button's gets for free. */
.ctt-signin__google[b-bldpz0i4fj] {
    text-align: center;
}

/* The line under the Google button saying that pressing it leaves this site. Directly under it, on
   purpose: an explanation two paragraphs from the control it explains is one nobody connects to it.
   Muted rather than warn-coloured, because it warns of nothing - it sets an expectation. */
.ctt-signin__note[b-bldpz0i4fj] {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    margin-top: var(--space-2);
    color: var(--muted);
    font-size: var(--text-sm);
}

/* The two warnings on the code step: nobody will ask you for this code, and the mail may be slow.
   Ink, not muted - they change what the reader does next, so they are not a footnote. */
.ctt-signin__warn[b-bldpz0i4fj] {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    color: var(--ink);
    border-left: 3px solid var(--warn);
    padding-left: var(--space-3);
    margin-bottom: var(--space-3);
    max-width: 60ch;
}

/* The code field. Monospace and spaced out, because six digits copied out of a mail are read back
   digit by digit against the screen. */
.ctt-signin__code[b-bldpz0i4fj] {
    font-family: var(--font-mono);
    font-size: var(--text-md);
    letter-spacing: 0.25em;
    max-width: 12rem;
}
