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;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ==========================================================================
   П5 (M6 prep): self-hosted fonts (Stack §2.5 — host, don't call Google Fonts
   at runtime). Only the Latin and Hebrew subsets are fetched — Cyrillic falls
   through to the system-font tail of --font below, since Heebo/Noto Sans
   Hebrew don't cover it and the interface language until M11.6 is Russian.
   Licenses: heebo-OFL.txt, noto-sans-hebrew-OFL.txt (SIL OFL 1.1),
   roboto-mono-LICENSE.txt (Apache 2.0) next to the font files.
   ========================================================================== */
@font-face {
    font-family: "Heebo";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("fonts/heebo-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Heebo";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("fonts/heebo-400-hebrew.woff2") format("woff2");
    unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}

@font-face {
    font-family: "Heebo";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("fonts/heebo-500-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Heebo";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("fonts/heebo-500-hebrew.woff2") format("woff2");
    unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}

@font-face {
    font-family: "Heebo";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("fonts/heebo-600-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Heebo";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("fonts/heebo-600-hebrew.woff2") format("woff2");
    unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}

@font-face {
    font-family: "Heebo";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("fonts/heebo-700-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Heebo";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("fonts/heebo-700-hebrew.woff2") format("woff2");
    unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}

@font-face {
    font-family: "Noto Sans Hebrew";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("fonts/noto-sans-hebrew-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Noto Sans Hebrew";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("fonts/noto-sans-hebrew-400-hebrew.woff2") format("woff2");
    unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}

@font-face {
    font-family: "Noto Sans Hebrew";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("fonts/noto-sans-hebrew-700-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Noto Sans Hebrew";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("fonts/noto-sans-hebrew-700-hebrew.woff2") format("woff2");
    unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}

@font-face {
    font-family: "Roboto Mono";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("fonts/roboto-mono-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Roboto Mono";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("fonts/roboto-mono-500-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   Task 6.1.1 (day 1 of Milestone 6, Screens §2): tokens for the client
   cabinet (/app/*). Light values first — the only definitions for a token,
   so the dark blocks below only ever override, never introduce one fresh
   (Screens §2.2 "переопределяются все токены, а не половина").
   ========================================================================== */
:root {
    /* M12 (2026-10-17): the palette of the phone app (Colors.xaml), so the cabinet and the app look like one product.
       Fills (buttons, bars, the logo) use the app's emerald as it is; text and links use a darker emerald, because the app's
       #34D399 on white is 1.9:1 and the cabinet keeps Screens §16 (4.5:1 for text). --on-primary is the dark navy of the app's
       sidebar: 8:1 on the light emerald, 5:1 on the dark one. */
    --bg: #FAFAFA;
    --surface: #FFFFFF;
    --border: #E8E9F3;
    --text: #262626;
    --text-muted: #6B7280;
    --primary: #34D399;
    --on-primary: #1E293B;
    --link: #047857;
    --success: #047857;
    --danger: #DC2626;
    --warning: #A85400;
    --tint-success: #E6F7EF;
    --tint-danger: #FBEAEA;
    --tint-warning: #FBF0E2;
    --brand-deep: #1E293B;

    /* Screens §2.5: Heebo covers Hebrew and Latin in one family (Stack §2.5, П5); Cyrillic (Russian, v1's only
       interface language) isn't in either font and falls through to the system tail. */
    --font: "Heebo", "Noto Sans Hebrew", "Segoe UI", system-ui, sans-serif;
    --font-num: "Roboto Mono", ui-monospace, monospace;

    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-6: 24px;
    --space-8: 32px;
    --space-12: 48px;

    --radius-sm: 6px;
    --radius-md: 12px;
    --radius-pill: 999px;
}

/* System dark theme — only when no explicit choice (data-theme) overrides it (Screens §2.2). */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --bg: #262626;
        --surface: #2D2E3A;
        --border: #45464F;
        --text: #FAFAFA;
        --text-muted: #A1A1AA;
        --primary: #00B064;
        --on-primary: #1E293B;
        --link: #34D399;
        --success: #34D399;
        --danger: #F87171;
        --warning: #E5A24D;
        --tint-success: #17352A;
        --tint-danger: #3A1F24;
        --tint-warning: #2E2314;
        --brand-deep: #1E293B;
    }
}

/* Manual dark theme — wins over the media query in both directions (Screens §2.2). */
:root[data-theme="dark"] {
    --bg: #262626;
    --surface: #2D2E3A;
    --border: #45464F;
    --text: #FAFAFA;
    --text-muted: #A1A1AA;
    --primary: #00B064;
    --on-primary: #1E293B;
    --link: #34D399;
    --success: #34D399;
    --danger: #F87171;
    --warning: #E5A24D;
    --tint-success: #17352A;
    --tint-danger: #3A1F24;
    --tint-warning: #2E2314;
    --brand-deep: #1E293B;
}

.app-shell {
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    min-height: 100vh;
}

/* A plain link takes the token like every other cabinet colour. Without it the browser's own blue (and purple once visited) sat on the dark
   background, nearly invisible; found on the phone on 2026-10-15. Classed links (.app-alert-card__action and the rest) are more specific and win. */
.app-shell a {
    color: var(--link);
}

.app-shell h1, .app-shell h2, .app-shell h3 {
    font-weight: 600;
    margin: 0;
    /* Hyphenate at syllables rather than break mid-word on a 188 px viewport (a 375 px phone at 200 % zoom). */
    hyphens: auto;
}

.app-shell h1 {
    font-size: clamp(1.25rem, 9vw, 2rem);
}

/* Every cabinet page wraps its content in its own app-shell--mobile inside the one AppLayout already provides, so the side
   padding was paid twice (2 × 16 px per side — a third of a 188 px viewport). The inner wrapper adds none. */
.app-shell--mobile .app-shell--mobile {
    padding-inline: 0;
    min-height: 0;
}

.app-shell .app-amount--tabular {
    font-family: var(--font-num);
    font-variant-numeric: tabular-nums;
}

.app-shell .app-amount--positive {
    color: var(--danger);
}

.app-shell .app-amount--negative {
    color: var(--success);
}

/* Task 6.1.2: ServiceCard, AlertCard, EmptyState, PromoCountdown — logical properties throughout (Screens §4),
   never left/right, so the same rules hold once Hebrew (M11.6) flips the direction. */
.app-shell .app-service-card {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding-block: var(--space-2);
    border-block-end: 1px solid var(--border);
}

.app-shell .app-service-card__icon {
    color: var(--text-muted);
    flex-shrink: 0;
}

.app-shell .app-service-card__label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.app-shell .app-service-card__status {
    color: var(--text-muted);
    font-size: 13px;
}

.app-shell .app-service-card__flag {
    color: var(--warning);
    display: inline-flex;
}

.app-shell .app-alert-card {
    display: flex;
    gap: var(--space-3);
    padding: var(--space-4);
    background: var(--tint-warning);
    border-radius: var(--radius-md);
    margin-block-end: var(--space-3);
}

.app-shell .app-alert-card__icon {
    color: var(--warning);
    flex-shrink: 0;
}

/* M10 §4.2 (200 % zoom): a flex child doesn't shrink below its content unless allowed to — long titles and the action link pushed the card past the viewport. */
.app-shell .app-alert-card__body {
    min-width: 0;
    overflow-wrap: anywhere;
}

.app-shell .app-alert-card__title {
    font-weight: 600;
    margin-block-end: var(--space-1);
}

.app-shell .app-alert-card__action {
    display: inline-block;
    margin-block-start: var(--space-2);
    color: var(--link);
    font-weight: 600;
    text-decoration: none;
}

/* Task 7.5.5: the anomaly card's "Понятно" dismiss form — same tap target and spacing rules as the action link above. */
.app-shell .app-alert-card__dismiss-form {
    margin-block-start: var(--space-2);
}

.app-shell .app-alert-card__dismiss {
    background: none;
    border: none;
    padding: 0;
    color: var(--link);
    font-weight: 600;
}

.app-shell .app-promo-countdown {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.app-shell .app-promo-countdown__meta {
    color: var(--text-muted);
    font-size: 13px;
}

.app-shell .app-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-3);
    padding: var(--space-12) var(--space-4);
    color: var(--text-muted);
}

.app-shell .app-empty-state__icon {
    color: var(--border);
}

.app-shell .app-empty-state__action {
    color: var(--link);
    font-weight: 600;
    text-decoration: none;
}

/* Task 6.5.1: single column, no fixed heights — em/rem sizing throughout so a 200% OS font-size scale reflows
   instead of clipping (Screens §16). */
.app-shell--mobile {
    max-width: 30rem;
    margin-inline: auto;
    padding: var(--space-4);
    box-sizing: border-box;
}

.app-shell--mobile * {
    box-sizing: border-box;
    overflow-wrap: break-word;
}

/* Tap targets ≥ 44px (Screens §16) on every actionable element in the cabinet. */
.app-shell button,
.app-shell a.app-action,
.app-shell .app-alert-card__action,
.app-shell .app-alert-card__dismiss,
.app-shell .app-empty-state__action {
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding-inline: var(--space-4);
    border-radius: var(--radius-sm);
    font: inherit;
    cursor: pointer;
    /* At 200 % zoom on a 360 px phone one long Russian word is wider than the column: the button stays inside it and breaks the word. */
    max-width: 100%;
    overflow-wrap: anywhere;
    text-align: center;
}

/* A text area keeps the browser's own width (cols="20") unless told otherwise, and that is wider than a narrow column. */
.app-shell textarea {
    width: 100%;
    max-width: 100%;
}

.app-shell button.app-action--primary {
    background: var(--primary);
    color: var(--on-primary);
    border: none;
}

.app-shell button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.app-shell input, .app-shell label {
    font-size: 1rem;
}

/* Task 6.1.3: the household screen itself (Screens §8). */
.app-shell .app-admin-banner {
    background: var(--tint-warning);
    color: var(--text);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    margin-block-end: var(--space-3);
    font-size: 13px;
    font-weight: 600;
}

.app-shell .app-headline {
    font-size: 40px;
    font-weight: 600;
    margin-block: var(--space-2);
}

.app-shell .app-headline__unit {
    font-size: 17px;
    font-weight: 400;
    color: var(--text-muted);
}

.app-shell .app-delta {
    color: var(--text-muted);
    margin-block-end: var(--space-6);
}

.app-shell h2 {
    font-size: 17px;
    margin-block: var(--space-6) var(--space-2);
}

/* Task 6.1.2/6.5.1: loading state — the shape of the future content, not a spinner (Screens §14). */
.app-shell .app-skeleton {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding-block: var(--space-4);
}

.app-shell .app-skeleton__line {
    height: 1.25rem;
    border-radius: var(--radius-sm);
    background: var(--surface);
    width: 60%;
}

.app-shell .app-skeleton__line--wide {
    width: 90%;
    height: 2.5rem;
}

/* Task 6.2.2: service passport (Screens §9) — usage bars, extras, history rows. */
.app-shell .app-service-card-link {
    color: inherit;
    text-decoration: none;
    display: block;
}

.app-shell .app-passport-plan {
    color: var(--text-muted);
    margin-block: 0;
}

.app-shell .app-passport-next-plan {
    color: var(--text-muted);
    font-size: 13px;
}

.app-shell .app-usage-bar {
    margin-block-end: var(--space-3);
}

.app-shell .app-usage-bar__label {
    display: flex;
    justify-content: space-between;
    gap: var(--space-2);
    margin-block-end: var(--space-1);
}

.app-shell .app-usage-bar__value {
    color: var(--text-muted);
    font-family: var(--font-num);
    font-variant-numeric: tabular-nums;
}

.app-shell .app-usage-bar__track {
    block-size: 8px;
    border-radius: var(--radius-pill);
    background: var(--surface);
    overflow: hidden;
}

.app-shell .app-usage-bar__fill {
    block-size: 100%;
    background: var(--primary);
    border-radius: var(--radius-pill);
}

.app-shell .app-recurring-charge {
    margin-block-end: var(--space-1);
}

.app-shell .app-recurring-charge summary {
    cursor: pointer;
}

.app-shell .app-recurring-charge__original {
    display: block;
    color: var(--text-muted);
    font-size: 13px;
    margin-inline-start: var(--space-3);
}

.app-shell .app-recurring-charge__amounts {
    color: var(--text-muted);
    font-size: 13px;
    margin-block-end: var(--space-3);
}

.app-shell a.app-action {
    color: var(--link);
    font-weight: 600;
    text-decoration: none;
    margin-block-end: var(--space-2);
}

.app-shell .app-history-row {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    padding-block: var(--space-2);
    border-block-end: 1px solid var(--border);
}

.app-shell .app-history-row__period {
    flex: 1;
    color: var(--text-muted);
    font-size: 13px;
}

.app-shell .app-history-row__share {
    color: var(--text-muted);
    font-size: 13px;
}

.app-shell .app-history-baseline {
    color: var(--text-muted);
    margin-block-end: var(--space-4);
}

/* Task 6.5.2: /app/login. */
.app-shell .app-form {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-block-start: var(--space-4);
}

.app-shell .app-form label {
    display: block;
    margin-block-end: var(--space-1);
}

.app-shell .app-form input {
    width: 100%;
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
}

.app-shell .app-form-error {
    color: var(--danger);
}

/* M8 Plan §3, task 8.6.3 — the dossier (Screens §10): now/will-be, market cards, arguments, script. */
.app-shell .app-now-then {
    display: flex;
    gap: var(--space-6);
    margin-block: var(--space-3);
}

.app-shell .app-now-then__block {
    flex: 1;
}

.app-shell .app-now-then__label {
    color: var(--text-muted);
    font-size: 13px;
    display: block;
}

.app-shell .app-stay-callout {
    background: var(--tint-success);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    margin-block-end: var(--space-3);
}

.app-shell .app-offer-card {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    margin-block-end: var(--space-3);
}

.app-shell .app-offer-card__title {
    font-weight: 600;
}

.app-shell .app-offer-card__meta {
    color: var(--text-muted);
    font-size: 13px;
}

.app-shell .app-arguments {
    padding-inline-start: var(--space-4);
    margin-block: var(--space-2);
}

.app-shell .app-script-box {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    font-size: 1.1rem;
    line-height: 1.6;
}

.app-shell .app-threshold-line {
    margin-block: var(--space-1);
}

.app-shell .app-contact-actions {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin-block-start: var(--space-3);
}

/* M9 Plan task 9.2.1 — the dialogue screen (Screens §11). Static SSR: no script needed. */
.app-shell .app-thresholds-summary {
    margin-block: var(--space-2);
}

.app-shell .app-message {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    margin-block-end: var(--space-3);
}

.app-shell .app-message--outgoing {
    background: var(--surface);
}

.app-shell .app-message__label {
    color: var(--text-muted);
    font-size: 13px;
    display: block;
}

.app-shell .app-message__he {
    display: block;
    font-size: 1.1rem;
    line-height: 1.6;
}

.app-shell .app-verdict {
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    margin-block: var(--space-3);
}

.app-shell .app-verdict--accept {
    background: var(--tint-success);
}

.app-shell .app-verdict--counter {
    background: var(--tint-warning);
}

.app-shell .app-verdict--walk-away,
.app-shell .app-verdict--refusal {
    background: var(--tint-danger);
}

.app-shell .app-verdict p {
    margin-block: var(--space-1);
}

.app-shell .app-reply-form {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin-block: var(--space-2);
}

.app-shell .app-reply-form textarea,
.app-shell .app-reply-form input {
    width: 100%;
    box-sizing: border-box;
    font: inherit;
}

/* Radios and checkboxes keep their own size; the label is a row: control, then text. */
.app-shell .app-reply-form input[type="radio"],
.app-shell .app-reply-form input[type="checkbox"] {
    width: auto;
    flex: none;
}

.app-shell .app-radio {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.app-shell .app-form-error {
    background: var(--tint-danger);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
}

.app-shell .app-waiting {
    color: var(--text-muted);
}

/* M10 §4.2 (200 % zoom, ≈180 px): the action link's side padding alone is wider than the room left beside the card's icon. */
@media (max-width: 240px) {
    .app-shell .app-alert-card__action,
    .app-shell .app-alert-card__dismiss {
        padding-inline: 0;
        max-width: 100%;
    }
}

/* M11 Plan 11.5.1: the language-choice screen — three full-width buttons, nothing else on the page. */
.app-shell .app-language-choice {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-block-start: var(--space-6, var(--space-4));
}

.app-shell .app-language-switcher {
    display: flex;
    /* At 200 % zoom on a phone the three names no longer fit one row: they wrap instead of pushing the page wider than the screen. */
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-3);
    margin-block-start: var(--space-6, var(--space-4));
}

.app-shell .app-language-switcher button {
    background: none;
    border: 0;
    padding: var(--space-2) var(--space-1);
    color: inherit;
    text-decoration: underline;
    cursor: pointer;
}

.app-shell .app-form-note {
    color: var(--text-muted);
    font-size: 13px;
    margin-block: 0;
}

.app-shell .app-form button:not(.app-action--primary) {
    align-self: flex-start;
}

/* M11 Plan 11.1.2: /app/upload � three stacked options, each its own block. */
.app-shell .app-upload-option {
    margin-block: var(--space-4);
}

.app-shell .app-upload-address {
    overflow-wrap: anywhere;
    padding: var(--space-2) var(--space-3);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    display: inline-block;
}

/* M11 Plan 11.1.4: the processing page � a short list of what is already done and what is happening now. */
.app-shell .app-process-steps {
    list-style: none;
    padding: 0;
    margin-block: var(--space-4);
}

.app-shell .app-process-step {
    padding-block: var(--space-2);
    padding-inline-start: var(--space-6, 1.5rem);
    position: relative;
}

.app-shell .app-process-step::before {
    position: absolute;
    inset-inline-start: 0;
}

.app-shell .app-process-step--done::before {
    content: "?";
    color: var(--success, var(--link));
}

.app-shell .app-process-step--active::before {
    content: "�";
    color: var(--text-muted);
}

.app-shell .app-checkbox-row {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
}

.app-shell .app-checkbox-row input[type="checkbox"] {
    width: auto;
    margin-block-start: 0.3em;
}

.app-shell .app-checkbox-row label {
    margin: 0;
}

/* M11 Plan 11.1.6: the confirmation screen � doubtful fields up front, everything else folded away. */
.app-shell .app-confirm-header {
    margin-block: var(--space-2) var(--space-4);
}

.app-shell .app-confirm-doubt {
    background: var(--tint-warning, var(--surface));
    border-radius: var(--radius-md);
    padding: var(--space-3);
}

.app-shell .app-confirm-page {
    display: block;
    max-width: 100%;
    margin-block: var(--space-2);
    border: 1px solid var(--border);
}

.app-shell .app-confirm-questions {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-3);
}

.app-shell .app-confirm-questions label {
    display: block;
    margin-block: var(--space-1);
}

.app-shell .app-confirm-questions input[type="radio"] {
    width: auto;
    margin-inline-end: var(--space-2);
}

.app-shell .app-notice {
    background: var(--tint-warning, var(--surface));
    border-radius: var(--radius-md);
    padding: var(--space-3);
    margin-block: var(--space-3);
}

.app-shell .app-upload-progress {
    background: var(--tint-success, var(--surface));
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    margin-block: var(--space-4);
}

/* M11 Plan 11.7.1: the teaching sample bill. */
.app-shell .app-teaching__sample {
    margin: var(--space-3) 0;
}

.app-shell .app-teaching__sample img {
    display: block;
    width: 100%;
    max-width: 260px;
    margin-inline: auto;
    border-radius: var(--radius-md);
}

.app-shell .app-teaching__sample figcaption {
    color: var(--text-muted);
    font-size: 13px;
    text-align: center;
    margin-block-start: var(--space-2);
}

/* The step markers are drawn, not typed: the check and ellipsis glyphs are missing from the bundled fonts and fell back to "?" and a diamond. */
.app-shell .app-process-step::before {
    content: "";
    inset-block-start: 0.85em;
    width: 1em;
    height: 1em;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}

.app-shell .app-process-step--done::before {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8.5l3.2 3.2L13 4.8' fill='none' stroke='%232e7d32' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.app-shell .app-process-step--active::before {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='3' cy='8' r='1.5' fill='%239aa0a6'/%3E%3Ccircle cx='8' cy='8' r='1.5' fill='%239aa0a6'/%3E%3Ccircle cx='13' cy='8' r='1.5' fill='%239aa0a6'/%3E%3C/svg%3E");
}

/* M11 Plan 11.2.1: the Google button block above the password form. */
.app-shell .app-google {
    margin-block: var(--space-4);
}

.app-shell a.app-google__button {
    display: block;
    text-align: center;
    padding: var(--space-3);
    border-radius: var(--radius-md);
    background: var(--primary);
    text-decoration: none;
    color: var(--on-primary);
}

.app-shell .app-google__or {
    text-align: center;
    color: var(--text-muted);
    margin-block: var(--space-3) 0;
}

/* M11 Plan 11.5.2: settings sections and the "my documents" list. */
.app-shell section[id] {
    margin-block: var(--space-5, var(--space-4));
}

.app-shell section[id] h2 {
    margin-block-end: var(--space-2);
}

.app-shell .app-form label {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
}

.app-shell .app-form label input[type="radio"],
.app-shell .app-form label input[type="checkbox"] {
    width: auto;
    margin-block-start: 0.3em;
}

.app-shell .app-settings-key {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-block: var(--space-2);
}

.app-shell .app-settings-link {
    margin-block-start: var(--space-6, var(--space-4));
    text-align: center;
}

.app-shell .app-document-list {
    list-style: none;
    padding: 0;
}

.app-shell .app-document-row {
    display: flex;
    gap: var(--space-3);
    align-items: center;
    padding-block: var(--space-3);
    border-block-end: 1px solid var(--border);
}

.app-shell .app-document-row__thumb {
    width: 56px;
    height: 72px;
    object-fit: cover;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}

/* M11 Plan 11.9.1: the iOS "add to Home Screen" hint disappears once the app is already running from there. */
.app-shell .app-ios-hint {
    background: var(--tint-warning, var(--surface));
    border-radius: var(--radius-md);
    padding: var(--space-3);
    font-size: 14px;
}

@media (display-mode: standalone) {
    .app-shell .app-ios-hint {
        display: none;
    }
}

/* A component's own display rule must not undo the hidden attribute: the push and copy buttons are revealed by script. */
.app-shell [hidden] {
    display: none !important;
}

/* M11 11.11.1: filters of the action history, and the administrator's lines set apart. */
.app-shell .app-filter-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-3);
}

.app-shell .app-document-row--admin {
    border-inline-start: 3px solid currentColor;
    padding-inline-start: var(--space-3);
}

/* M12 (2026-10-17): the brand bar above every cabinet page — the logo of the app's splash screen. The bar is the app's sidebar navy in both
   themes, so the logo's emerald and white sit on the same ground as in the app. Logical properties, as everywhere (Screens §4). */
.app-header {
    background: var(--brand-deep);
    color: #FAFAFA;
    padding: var(--space-3) var(--space-4);
    border-block-end: 1px solid var(--border);
}

.app-header .app-brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    color: inherit;
    text-decoration: none;
}

.app-header .app-brand__logo {
    block-size: 36px;
    inline-size: auto;
    flex-shrink: 0;
}

.app-header .app-brand__name {
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: 0.01em;
}

/* The bar sits outside .app-shell, so it takes the cabinet's font itself; the page behind a cabinet page is the cabinet's ground, edge to edge. */
.app-header {
    font-family: var(--font);
}

body:has(.app-header) {
    margin: 0;
    background: var(--bg);
}

/* Document Analysis Plan 3.3: the model writes paragraphs; they keep their breaks. */
.app-shell .app-analysis-text {
    white-space: pre-wrap;
}

.app-shell .app-analysis-list {
    list-style: none;
    padding: 0;
}

.app-shell .app-analysis-list li {
    display: flex;
    flex-direction: column;
    padding: 0.5rem 0;
}
