/* Colours come from css/tokens.css (light and dark); this file only uses the var(--lc-...) names. */

/* Radzen only paints the page itself inside a RadzenLayout, which this site doesn't use, so the
   background is set here -- without it a dark theme would sit on the browser's white page. */
body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, Roboto, sans-serif;
    background: var(--lc-page-bg);
    color: var(--lc-text);
}

a {
    color: var(--lc-link);
}

/* Accessibility, site-wide (audit, planner #220). */

/* Where the keyboard is: 3px, outside the control, from a token, everywhere a page doesn't draw its own. On the blue header, the footer
   and the dark-blue bands the blue ring would vanish, so it is white there, but blue again inside the white menus that open from them. */
:focus-visible {
    outline: 3px solid var(--lc-focus-ring);
    outline-offset: 2px;
}

.site-header :focus-visible, .site-footer :focus-visible, .admin-header :focus-visible, .cta :focus-visible, .friend-panel :focus-visible {
    outline-color: var(--lc-focus-ring-on-brand);
}

    .site-header .nav-dropdown-menu :focus-visible, .site-header .profile-menu-panel :focus-visible,
    .admin-header .profile-menu-panel :focus-visible {
        outline-color: var(--lc-focus-ring);
    }

/* Read out but not shown: "(opens in a new tab)" after a link, a label that the layout already makes plain. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* The countdown before the site restarts for an update (js/update-notice.js, planner #413): built by script on any interactive page,
   so it's styled here rather than in a component's CSS. At the foot of the window, above the newsletter preview (2000). */
.lc-update-notice {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 2100;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 1rem;
    padding: 0.6rem 1rem;
    background: var(--lc-warning-bg);
    color: var(--lc-warning-text);
    border-top: 3px solid var(--lc-warning-strong);
    box-shadow: 0 -2px 8px var(--lc-shadow-strong);
    font-size: 0.95rem;
}

    .lc-update-notice p {
        margin: 0;
    }

    .lc-update-notice-clock {
        font-weight: 700;
        font-variant-numeric: tabular-nums;
        white-space: nowrap;
    }

    .lc-update-notice-message {
        flex: 1 1 20rem;
    }

    .lc-update-notice-hide {
        min-width: 4rem;
        min-height: 2rem;
        padding: 0.2rem 0.8rem;
        background: transparent;
        color: var(--lc-warning-text);
        border: 1px solid var(--lc-warning-text);
        border-radius: 4px;
        font: inherit;
        cursor: pointer;
    }

/* The admin menu's amber "something to do" count (InheritorNavCount, OldSiteNavCount): amber rather than the account-recovery count's
   red, as these wait on staff rather than on someone locked out. Here rather than in each component's own CSS so they stay alike. */
.nav-count {
    display: inline-block;
    margin-left: 0.4rem;
    min-width: 1.4rem;
    padding: 0 0.4rem;
    border-radius: 999px;
    background: var(--lc-warning-strong);
    color: var(--lc-on-warning-strong);
    font-size: 0.75rem;
    font-weight: 700;
    text-align: center;
}

/* A form's problems (planner #223): the message beside the box it's about (tied to it by aria-describedby), and the summary of them
   all that the keyboard is moved to after a failed save, whose links jump to each box (skip-link.js). */
.field-error {
    display: block;
    margin-top: 0.25rem;
    font-weight: 600;
    color: var(--lc-warning-ink);
}

.error-summary a {
    display: inline-block;
    min-height: 24px;
    padding: 2px 0;
    color: inherit;
    text-decoration: underline;
}

/* "Skip to main content": the first thing on every page, out of sight until the keyboard reaches it. */
.skip-link {
    position: absolute;
    left: 0.75rem;
    top: -10rem;
    z-index: 1000;
    background: var(--lc-surface);
    color: var(--lc-link);
    font-weight: 700;
    padding: 0.6rem 1rem;
    border-radius: 0 0 6px 6px;
    box-shadow: 0 2px 6px var(--lc-shadow);
}

    .skip-link:focus {
        top: 0;
    }

/* The strips at the top of the page, in one labelled region (MainLayout); with none showing, the region isn't there either. */
.site-notices:empty {
    display: none;
}

/* A newsletter's Contents list: its links go to places in an issue (written out as /newsletter/archive/<issue>#place when the issue is
   shown), and are at least 24px tall so they're easy to hit (WCAG 2.5.8). */
.newsletter-issue a[href^="#"],
.newsletter-issue a[href^="/newsletter/archive/"][href*="#"] {
    display: inline-block;
    min-height: 24px;
    line-height: 24px;
}

/* A device set to reduce motion gets none: no slides, fades or smooth scrolling anywhere. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Text boxes and dropdowns are one height everywhere (user, 2026-10-11): left to the browser, a dropdown comes out
   shorter or taller than the text box beside it. :where() gives this no weight, so each page's own padding, border and
   colours still apply. Radzen's controls have their own classes and sizes and are left alone. */
:where(select:not([multiple], [size], [class*="rz-"]),
       input:is(:not([type]), [type="text"], [type="email"], [type="number"], [type="date"], [type="datetime-local"],
                [type="search"], [type="tel"], [type="url"], [type="password"]):not([class*="rz-"])) {
    box-sizing: border-box;
    height: 2.5rem;
}

.member-page {
    max-width: var(--lc-max-width);
    margin: 0 auto;
    padding: 1.75rem 1.5rem 3rem;
}

.preview-banner {
    background: var(--lc-warning-bg);
    border: 1px solid var(--lc-warning-border);
    color: var(--lc-warning-text);
    border-radius: 6px;
    padding: 0.75rem 1rem;
    font-size: 0.88rem;
    margin-bottom: 1.5rem;
}

.btn {
    display: inline-block;
    padding: 0.65rem 1.4rem;
    border-radius: 6px;
    font-weight: 700;
    text-decoration: none;
    font-size: 0.95rem;
    border: none;
    cursor: pointer;
}

.btn-primary {
    background: var(--lc-red-accent);
    color: var(--lc-on-brand);
}

    .btn-primary:hover {
        background: var(--lc-red-accent-hover);
    }

/* For the blue bands only (the homepage hero, the dashboard's Friend panel): see-through white, so on a light card it vanishes. On a
   card use .btn-secondary-outline (Alexander, 31 Oct 2026: My Details' "Make a donation" was white on white). */
.btn-secondary {
    background: rgba(255, 255, 255, 0.15);
    color: var(--lc-on-brand);
    border: 1px solid rgba(255, 255, 255, 0.5);
}

    .btn-secondary:hover {
        background: rgba(255, 255, 255, 0.28);
    }

.btn:disabled {
    opacity: 0.6;
    cursor: default;
    pointer-events: none;
}

/* A "button" that is only a label for something not built yet (Coming soon, the sample pages). It's text, not a switched-off control, so
   faded it fell below 4.5:1 (planner #220): it keeps its colours, and a dashed edge shows it can't be pressed. */
.btn-disabled {
    cursor: default;
    pointer-events: none;
    border-style: dashed;
}

    .btn-primary.btn-disabled {
        border: 1px dashed var(--lc-on-brand);
    }

/* A button that reads as a link (Open all, Change my email address, Go back). Pages may restyle it in their own CSS. */
.btn-link,
.btn.btn-link {
    padding: 0;
    border: none;
    background: none;
    color: var(--lc-link);
    font-weight: 600;
    text-decoration: underline;
    cursor: pointer;
}

    .btn.btn-link:hover,
    .btn-link:hover {
        text-decoration-thickness: 2px;
    }

    /* Disabled, it mustn't look like a link that goes somewhere (Tim, 11 Nov 2026: "These look like they're links but they don't go anywhere"). */
    .btn.btn-link:disabled,
    .btn-link:disabled {
        color: var(--lc-text-soft);
        text-decoration: none;
        cursor: default;
        opacity: 1;
    }

/* Long text keeps a centred reading column, wider than it was for big screens (Alexander, 17 Oct). */
.info-page {
    max-width: 1100px;
    margin: 0 auto;
    padding: 2rem 1.5rem 4rem;
    line-height: 1.65;
}

    .info-page h1 {
        color: var(--lc-heading);
        margin-bottom: 0.25rem;
    }

    .info-page .lead {
        color: var(--lc-text-muted);
        margin-top: 0;
        font-size: 1.05rem;
    }

    .info-page h2 {
        color: var(--lc-heading);
        font-size: 1.3rem;
        margin-top: 2.5rem;
        padding-top: 1rem;
        border-top: 1px solid var(--lc-border-subtle);
    }

    .info-page h3 {
        font-size: 1.05rem;
        margin-top: 1.75rem;
        margin-bottom: 0.4rem;
        color: var(--lc-text-strong);
    }

    .info-page p {
        margin: 0 0 1rem;
    }

    .info-page ul,
    .info-page ol {
        margin: 0 0 1rem;
        padding-left: 1.4rem;
    }

    .info-page blockquote {
        margin: 1rem 0;
        padding: 0.75rem 1.25rem;
        border-left: 3px solid var(--lc-accent);
        background: var(--lc-surface-muted);
        font-style: italic;
        color: var(--lc-text-soft);
    }

.info-jump-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    background: var(--lc-surface-muted);
    border-radius: 8px;
    padding: 1rem 1.25rem;
    margin-bottom: 1.5rem;
    font-size: 0.85rem;
}

    .info-jump-nav a {
        white-space: nowrap;
    }

/* Legal documents (/terms, /privacy-policy, /cookies, /retention-policy): the lawyers' numbered clauses, tables and contents list. */
.legal-doc .legal-contents ol {
    columns: 2 22rem;
    column-gap: 2rem;
    margin: 0;
    padding-left: 0;
    list-style: none;
}

    .legal-doc .legal-contents li {
        break-inside: avoid;
    }

    /* At least 24px tall to click (WCAG 2.2 target size). */
    .legal-doc .legal-contents a {
        display: inline-block;
        padding: 0.25rem 0;
        white-space: normal;
    }

.legal-doc .legal-callout {
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.legal-doc .clause {
    display: grid;
    grid-template-columns: 3.25rem 1fr;
    column-gap: 0.5rem;
}

    .legal-doc .clause-l3 {
        margin-left: 3.75rem;
    }

    .legal-doc .clause-no {
        font-variant-numeric: tabular-nums;
        color: var(--lc-text-muted);
    }

.legal-doc .legal-address {
    margin-left: 3.75rem;
}

.legal-doc .legal-table-wrap {
    overflow-x: auto;
    margin: 0 0 1.25rem;
}

.legal-doc .legal-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.95rem;
}

    .legal-doc .legal-table th,
    .legal-doc .legal-table td {
        border: 1px solid var(--lc-border);
        padding: 0.5rem 0.75rem;
        text-align: left;
        vertical-align: top;
    }

    .legal-doc .legal-table thead th {
        background: var(--lc-surface-muted);
    }

    .legal-doc .legal-table p {
        margin: 0 0 0.5rem;
    }

        .legal-doc .legal-table p:last-child {
            margin-bottom: 0;
        }

.legal-doc .legal-placeholder {
    background: var(--lc-warning-bg);
    border: 1px dashed var(--lc-warning-border);
    color: var(--lc-warning-text);
    padding: 0 0.25rem;
}

@media (max-width: 600px) {
    .legal-doc .clause {
        grid-template-columns: 1fr;
    }

    .legal-doc .clause-l3,
    .legal-doc .legal-address {
        margin-left: 1rem;
    }
}

/* Forum map (/forum-map). Here, not in ForumMap.razor.css, because js/forum-map.js builds the chooser and scoped styles don't reach
   elements made by script. */
.forum-map-page {
    max-width: 1180px;
}

    .forum-map-page .lead {
        max-width: 72ch;
    }

.fm-doors {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.75rem;
}

.fm-door {
    display: grid;
    gap: 0.2rem;
    text-align: left;
    font: inherit;
    color: var(--lc-text);
    background: var(--lc-surface);
    border: 1px solid var(--lc-border);
    border-radius: 8px;
    padding: 0.9rem 1.1rem;
    cursor: pointer;
    text-decoration: none;
}

    .fm-door strong {
        font-size: 1.1rem;
        color: var(--lc-heading);
    }

    .fm-door span {
        color: var(--lc-text-muted);
        font-size: 0.9rem;
        line-height: 1.4;
    }

    .fm-door:hover,
    .fm-door[aria-pressed="true"] {
        border-color: var(--lc-accent);
    }

    .fm-door[aria-pressed="true"] {
        box-shadow: inset 0 0 0 1px var(--lc-accent);
    }

.fm-panel {
    margin-top: 0.75rem;
    background: var(--lc-surface-muted);
    border: 1px solid var(--lc-border-subtle);
    border-radius: 8px;
    padding: 1.1rem 1.25rem;
}

.fm-crumbs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    align-items: center;
    font-size: 0.85rem;
    color: var(--lc-text-muted);
    margin-bottom: 0.6rem;
}

    .fm-crumbs button {
        font: inherit;
        background: none;
        border: 0;
        padding: 0;
        color: var(--lc-link);
        cursor: pointer;
        text-decoration: underline;
    }

.forum-map-page .fm-q {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--lc-heading);
    margin: 0 0 0.6rem;
}

.fm-opts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.fm-opt {
    font: inherit;
    font-size: 0.92rem;
    line-height: 1.35;
    text-align: left;
    color: var(--lc-text);
    background: var(--lc-surface);
    border: 1px solid var(--lc-border);
    border-radius: 999px;
    padding: 0.35rem 0.9rem;
    cursor: pointer;
}

    .fm-opt:hover {
        border-color: var(--lc-accent);
    }

    .fm-opt small {
        color: var(--lc-text-muted);
    }

.fm-many .fm-opt {
    font-size: 0.87rem;
    padding: 0.25rem 0.7rem;
}

.fm-result {
    display: grid;
    gap: 0.6rem;
    justify-items: start;
    max-width: 72ch;
}

    .forum-map-page .fm-result p {
        margin: 0;
    }

.forum-map-page .fm-big {
    font-size: 1.05rem;
}

.fm-tag {
    display: inline-block;
    font-size: 0.85rem;
    font-weight: 600;
    padding: 0 0.5rem;
    border-radius: 4px;
    border: 1px solid var(--lc-info-border);
    background: var(--lc-info-bg);
    color: var(--lc-info-text);
}

.fm-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem 1.25rem;
}

.forum-map-page .fm-hint {
    font-size: 0.88rem;
    color: var(--lc-text-muted);
}

.forum-map-page .fm-tour {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.6rem;
    counter-reset: fm-step;
    max-width: 72ch;
}

    .forum-map-page .fm-tour li {
        display: grid;
        grid-template-columns: 2rem minmax(0, 1fr);
        column-gap: 0.6rem;
    }

        .forum-map-page .fm-tour li::before {
            counter-increment: fm-step;
            content: counter(fm-step);
            grid-row: span 2;
            width: 1.7rem;
            height: 1.7rem;
            border-radius: 50%;
            border: 1.5px solid var(--lc-accent);
            color: var(--lc-heading);
            font-weight: 700;
            font-size: 0.9rem;
            display: grid;
            place-items: center;
        }

    .forum-map-page .fm-tour p {
        margin: 0;
        color: var(--lc-text-muted);
        font-size: 0.9rem;
    }

.fm-maphead {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: end;
    gap: 0.5rem 1rem;
    margin-top: 2.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--lc-border-subtle);
    scroll-margin-top: 1rem;
}

    .forum-map-page .fm-maphead h2 {
        margin: 0;
        padding: 0;
        border: 0;
    }

.fm-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem 1rem;
    font-size: 0.85rem;
    color: var(--lc-text-muted);
}

    .fm-legend i {
        margin-right: 0.35rem;
        font-style: normal;
    }

    .fm-legend .fm-page {
        font-style: italic;
    }

/* Sections flow in columns, in the forum's order, each kept whole. */
.fm-sections {
    margin-top: 1rem;
    columns: 340px;
    column-gap: 1rem;
}

.fm-section {
    break-inside: avoid;
    margin: 0 0 1rem;
    background: var(--lc-surface);
    border: 1px solid var(--lc-border);
    border-radius: 8px;
    padding: 0.9rem 1rem;
    display: grid;
    gap: 0.5rem;
}

    .forum-map-page .fm-section h3 {
        margin: 0;
        font-size: 1.05rem;
    }

        .fm-section h3 a {
            color: var(--lc-heading);
            text-decoration: none;
        }

            .fm-section h3 a:hover {
                text-decoration: underline;
            }

    .forum-map-page .fm-desc {
        margin: 0;
        font-size: 0.85rem;
        line-height: 1.45;
        color: var(--lc-text-muted);
    }

.fm-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.fm-chip {
    display: inline-flex;
    gap: 0.35rem;
    align-items: baseline;
    font-size: 0.82rem;
    line-height: 1.5;
    text-decoration: none;
    color: var(--lc-text);
    background: var(--lc-surface);
    border: 1px solid var(--lc-border);
    border-radius: 5px;
    padding: 0 0.45rem;
}

    a.fm-chip:hover {
        border-color: var(--lc-accent);
    }

    .fm-chip.fm-busy {
        background: var(--lc-info-bg);
        border-color: var(--lc-info-border);
        font-weight: 600;
    }

    .fm-chip.fm-empty {
        border-style: dashed;
        color: var(--lc-text-muted);
    }

    .fm-chip.fm-page {
        font-style: italic;
    }

.fm-n {
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--lc-text-muted);
}

.fm-group {
    display: grid;
    gap: 0.3rem;
    padding-left: 0.6rem;
    border-left: 2px solid var(--lc-border);
}

.fm-group-label {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    align-items: baseline;
    font-size: 0.85rem;
    font-weight: 600;
}

    .fm-group-label a {
        color: var(--lc-text-strong);
        text-decoration: none;
    }

        .fm-group-label a:hover {
            text-decoration: underline;
        }

.forum-map-page .fm-asof {
    margin-top: 1rem;
    font-size: 0.85rem;
    color: var(--lc-text-muted);
}

/* The link to a forum's index of resources guides, beside it in the map. */
.fm-chip.fm-guide {
    font-weight: 600;
    border-color: var(--lc-accent);
}

/* "Resources guides": the guides by region, after the map. */
.fm-guides {
    margin-top: 2.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--lc-border-subtle);
    display: grid;
    gap: 0.6rem;
    scroll-margin-top: 1rem;
}

    .forum-map-page .fm-guides h2,
    .forum-map-page .fm-guides h3 {
        margin: 0;
        padding: 0;
        border: 0;
    }

    .forum-map-page .fm-guides h3 {
        font-size: 1.05rem;
    }

        .fm-guides h3 a {
            color: var(--lc-heading);
        }

.fm-guide-groups {
    columns: 300px;
    column-gap: 1rem;
}

.fm-guide-group {
    break-inside: avoid;
    margin: 0 0 0.8rem;
    padding-left: 0.6rem;
    border-left: 2px solid var(--lc-border);
}

    .forum-map-page .fm-guide-group h4 {
        margin: 0 0 0.3rem;
        font-size: 0.85rem;
        font-weight: 600;
        color: var(--lc-text-strong);
    }

    .fm-guide-group ul {
        list-style: none;
        margin: 0;
        padding: 0;
    }

.newsletters-page {
    max-width: var(--lc-max-width);
    margin: 0 auto;
    padding: 2rem 1.5rem 4rem;
    line-height: 1.6;
}

    .newsletters-page h1 {
        color: var(--lc-heading);
        margin-bottom: 0.25rem;
    }

    .newsletters-page .lead {
        color: var(--lc-text-muted);
        margin-top: 0;
        font-size: 1.05rem;
    }

    .newsletters-page h2 {
        color: var(--lc-heading);
        font-size: 1.3rem;
    }

    .newsletters-page h3 {
        font-size: 1.05rem;
        margin: 1.75rem 0 0.4rem;
        scroll-margin-top: 1rem;
    }

.newsletter-latest {
    max-width: 60rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem 1.5rem;
    background: var(--lc-surface-muted);
    border-left: 4px solid var(--lc-header-bg);
    border-radius: 8px;
    padding: 1.25rem 1.5rem;
    margin: 1.5rem 0 2rem;
}

    .newsletter-latest h2 {
        margin: 0.15rem 0 0.25rem;
    }

    .newsletter-latest p {
        margin: 0;
        color: var(--lc-text-muted);
    }

.newsletter-latest-label {
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--lc-brand-label);
}

.newsletter-search {
    max-width: 60rem;
    margin-bottom: 2rem;
}

    .newsletter-search-row {
        display: flex;
        gap: 0.5rem;
    }

    /* All or any of the words, and how to write a phrase or a wildcard. */
    .newsletter-search-match {
        display: flex;
        flex-wrap: wrap;
        gap: 0.25rem 1.25rem;
        align-items: baseline;
        border: none;
        margin: 0.6rem 0 0;
        padding: 0;
    }

        .newsletter-search-match legend {
            float: left;
            margin-right: 0.5rem;
            padding: 0;
            font-weight: 600;
        }

    .newsletter-search-help {
        margin: 0.4rem 0 0;
        font-size: 0.9rem;
        color: var(--lc-text-muted);
    }

    .newsletter-search input[type=search] {
        flex: 1;
        min-width: 0;
        font-size: 1rem;
        padding: 0.6rem 0.9rem;
        border: 1px solid var(--lc-border-strong);
        border-radius: 6px;
    }

        .newsletter-search input[type=search]:focus {
            outline: 2px solid var(--lc-accent);
            border-color: var(--lc-accent);
        }

/* Text boxes marked class="form-control" (account recovery, the agreement version). The site has no Bootstrap, so they fell back to the
   browser's narrow default, sitting beside their buttons (Alexander, 21 Oct 2026): full width up to a readable line, the site's colours. */
.form-control {
    display: block;
    box-sizing: border-box;
    width: 100%;
    max-width: 48rem;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--lc-border-strong);
    border-radius: 4px;
    background: var(--lc-surface);
    color: var(--lc-text);
    font-family: inherit;
    font-size: 1rem;
    font-weight: normal;
    line-height: 1.4;
}

    .form-control:focus {
        outline: 2px solid var(--lc-accent);
        border-color: var(--lc-accent);
    }

    .form-control::placeholder {
        color: var(--lc-text-muted);
    }

.newsletter-list {
    margin: 0 0 1rem;
    padding-left: 1.4rem;
    /* The page is as wide as the site, so a year's issues run in columns rather than one long narrow list. */
    columns: 26rem;
    column-gap: 3rem;
}

    .newsletter-list li {
        margin-bottom: 0.3rem;
        break-inside: avoid;
    }

.newsletter-date,
.newsletter-count {
    color: var(--lc-text-muted);
}

/* A newsletter reads as a white page on a tinted desk: the column keeps lines a comfortable length
   (around 85-95 characters) on wide screens, and the tint makes the space either side look
   intentional. On a phone the page simply fills the screen. The page stays white in the dark theme
   too (tokens.css gives .newsletter-issue the light colours), and only the desk darkens. */
main:has(> .newsletter-issue),
.newsletter-preview-overlay {
    background: var(--lc-desk);
}

.newsletter-issue {
    max-width: 1050px;
    margin: 0 auto;
    padding: 1.5rem 1.5rem 4rem;
    line-height: 1.5;
    overflow-wrap: break-word;
    background: var(--lc-paper);
    color: var(--lc-text);
}

@media (min-width: 1100px) {
    .newsletter-issue {
        margin: 1.5rem auto 2.5rem;
        padding: 2rem 3rem 4rem;
        border: 1px solid var(--lc-paper-border);
        border-radius: 4px;
        box-shadow: 0 2px 10px rgba(30, 50, 70, 0.08);
    }
}

    .newsletter-issue > h1 {
        color: var(--lc-heading);
    }

.newsletter-issue-nav {
    font-size: 0.9rem;
}

/* Newsletter editor: offer of a web-sized copy of a large uploaded picture. */
.large-image-warning {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    margin-top: 0.75rem;
    padding: 0.75rem 1rem;
    max-width: 820px;
    background: var(--lc-warning-bg);
    border: 1px solid var(--lc-warning-border);
    border-radius: 6px;
    color: var(--lc-warning-text);
}

    .large-image-warning img {
        width: 96px;
        height: 72px;
        object-fit: cover;
        border-radius: 4px;
        flex-shrink: 0;
    }

.large-image-actions {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.5rem;
    flex-wrap: wrap;
}

/* The newsletter editor and the notes under it, as one block (NewsletterHtmlEditor). */
.newsletter-html-editor {
    width: 100%;
    min-width: 0;
}

/* The editor's "Describe this picture" box, under the editor (NewsletterHtmlEditor, planner #222). */
.picture-describe {
    margin-top: 0.75rem;
    padding: 0.75rem 1rem;
    max-width: 820px;
    background: var(--lc-info-bg);
    border: 1px solid var(--lc-info-border);
    border-radius: 6px;
    color: var(--lc-info-text);
}

    .picture-describe-title {
        font-size: 1rem;
        margin: 0 0 0.35rem;
        color: var(--lc-info-text);
    }

    .picture-describe-help {
        margin: 0 0 0.75rem;
        font-size: 0.9rem;
    }

.picture-describe-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: flex-end;
    padding: 0.6rem 0;
    border-top: 1px solid var(--lc-info-border);
}

    .picture-describe-row img {
        width: 96px;
        height: 72px;
        object-fit: contain;
        background: var(--lc-paper);
        border-radius: 4px;
        flex-shrink: 0;
    }

.picture-describe-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    flex: 1 1 18rem;
    font-weight: 600;
    font-size: 0.85rem;
}

    .picture-describe-field input {
        font: inherit;
        font-weight: 400;
        padding: 0.45rem 0.6rem;
        border: 1px solid var(--lc-border-strong);
        border-radius: 5px;
        background: var(--lc-surface);
        color: var(--lc-text-strong);
    }

.picture-describe-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* Preview's list of what a screen-reader user would miss (NewsletterPreview, planner #222). */
.newsletter-preview-checks {
    margin: 0 0 1.5rem;
    padding: 0.75rem 1rem;
    background: var(--lc-warning-bg);
    border: 1px solid var(--lc-warning-border);
    border-radius: 6px;
    color: var(--lc-warning-text);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, Roboto, sans-serif;
    font-size: 0.9rem;
}

    .newsletter-preview-checks h2 {
        font-size: 1rem;
        margin: 0 0 0.35rem;
        color: var(--lc-warning-text);
    }

    .newsletter-preview-checks ul {
        margin: 0.35rem 0 0;
        padding-left: 1.25rem;
    }

/* An old issue's bold one-line article title, now a real heading so a screen reader can jump to it (NewsletterAccessibility.ForReaders),
   looking exactly as the bold paragraph did. Radzen and the page style h2s, so everything is put back. */
.newsletter-issue-content h2.lc-was-bold {
    font: inherit;
    font-weight: bold;
    color: inherit;
    letter-spacing: inherit;
    text-transform: none;
    margin: 1em 0;
    padding: 0;
    border: 0;
}

/* The admin newsletter editor's Preview: the public issue page's look, over the editor. */
.newsletter-preview-overlay {
    position: fixed;
    inset: 0;
    z-index: 2000;
    overflow-y: auto;
    /* Background: the tinted "desk" shared with the public page (see .newsletter-issue). */
}

.newsletter-preview-bar {
    position: sticky;
    top: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.6rem 1rem;
    background: var(--lc-warning-bg);
    border-bottom: 1px solid var(--lc-warning-border);
    color: var(--lc-warning-text);
}

    .newsletter-preview-offers {
        font-size: 0.88rem;
    }

/* A jump to a #heading lands below the header and member menu that stay at the top (wwwroot/js/sticky-offsets.js). */
html {
    scroll-padding-top: var(--lc-sticky-top, 0px);
}

/* A section heading with its own Refresh beside it (SectionRefresh; Legacy sync's panels and cards). Here, not in a .razor.css, because
   the heading row sits in several components' markup. */
.section-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.25rem 0.75rem;
}

.section-head > h4 {
    margin-bottom: 0.5rem;
}

.section-refresh {
    min-height: 24px;
}

/* Admin grids are never taller than the window (less what stays at the top, the top bar, the page's title and its tabs, and a margin):
   a long list scrolls inside the grid, so Radzen's sticky heading row (WHEN, USER, ...) and the pager stay in view (issue #20). Short
   grids are unaffected. Here, not in a .razor.css, because the class sits on a Radzen component. */
.admin-grid.rz-data-grid {
    max-height: calc(100vh - var(--lc-sticky-top, 51px) - 2.5rem);
}

/* Admin pages: the page's title, and its row of tabs where it has one, stay under the top bar as the page scrolls (Tim, feedback #19,
   planner #401: "every page that scrolls ... have a fixed header"). The title is the page's first top-level heading, an <h1>, or else
   the first <h3> as the admin pages are written, so a new page has it without doing anything. A row of tabs takes admin-sticky-tabs
   (Radzen's tabs have it here). wwwroot/js/sticky-offsets.js measures them for where the tabs stick and for --lc-sticky-top. On a phone
   they scroll away with the page, as the member pages' header does, to keep the screen for the page. The staff member page keeps its
   own bar (UserDetail's member-bar, with the member's name) instead. Here, not in a .razor.css, because the headings belong to every
   page; the same selector is in sticky-offsets.js. */
@media (min-width: 641px) {
    .admin-content:not(:has(> .member-bar)) > h1:first-of-type,
    .admin-content:not(:has(> h1, > .member-bar)) > h3:first-of-type {
        position: sticky;
        top: var(--lc-admin-bar, 51px);
        z-index: 40;
        /* Across the content's padding, so nothing shows beside it as the page scrolls under. */
        margin: -0.5rem -2rem 0.75rem;
        padding: 0.5rem 2rem;
        background: var(--lc-surface-muted);
        border-bottom: 1px solid var(--lc-border);
    }

    .admin-content > .admin-sticky-tabs,
    .admin-content .rz-tabview-nav {
        position: sticky;
        top: var(--lc-admin-tabs-top, 51px);
        z-index: 39;
        background: var(--lc-surface-muted);
    }
}

/* Manage users: the recovery or inheritor address a member was found by, under their main address (inside the grid's Template, so
   no scoped CSS reaches it). */
.matched-by {
    color: var(--lc-text-subtle);
    font-size: 0.85em;
    /* Wraps rather than being cut off by the grid's one-line cells, so the whole address shows. */
    white-space: normal;
    overflow-wrap: anywhere;
}

/* Printing. The Preview is a fixed, scrolling layer over the editor, so the browser printed only the
   part on screen: while it's open, print just the newsletter, laid out as ordinary pages. The public
   issue page (and an admin's view of a draft there) drops the site's header, footer and links. */
@media print {
    body:has(.newsletter-preview-overlay) .admin-header,
    body:has(.newsletter-preview-overlay) .admin-nav,
    body:has(.newsletter-preview-overlay) .admin-content > :not(.newsletter-preview-overlay),
    .newsletter-preview-bar,
    .newsletter-preview-checks,
    .newsletter-issue > .rz-button,
    .site-header,
    .site-footer,
    .newsletter-issue-nav,
    .newsletter-issue-preview {
        display: none !important;
    }

    .newsletter-preview-overlay {
        position: static;
        overflow: visible;
    }

    main:has(> .newsletter-issue),
    .newsletter-preview-overlay {
        background: none;
    }

    .newsletter-issue {
        max-width: none;
        margin: 0;
        padding: 0;
        border: none;
        box-shadow: none;
    }
}

/* Notification send page: the email as members will get it. The frame keeps the site's own styles
   out, so it looks as it will in an email program. */
.email-preview {
    margin-top: 2rem;
    max-width: 820px;
}

.email-preview-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

    .email-preview-header h4 {
        margin: 0;
    }

.email-preview-note {
    color: var(--lc-text-muted);
    margin: 0.25rem 0 0.75rem;
}

.email-preview-envelope {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.2rem 0.75rem;
    margin: 0;
    padding: 0.6rem 1rem;
    background: var(--lc-surface-sunken);
    border: 1px solid var(--lc-border);
    border-bottom: none;
    border-radius: 6px 6px 0 0;
}

    .email-preview-envelope dt {
        color: var(--lc-text-muted);
    }

    .email-preview-envelope dd {
        margin: 0;
        overflow-wrap: anywhere;
    }

.email-preview-frame {
    display: block;
    width: 100%;
    height: 720px;
    border: 1px solid var(--lc-border);
    border-radius: 0 0 6px 6px;
    /* The email itself, so white whatever the site's theme (the frame keeps the site's styles out). */
    background: var(--lc-paper);
}

.email-preview-window.phone {
    width: 375px;
    max-width: 100%;
}

.email-preview-text {
    margin-top: 0.75rem;
}

    .email-preview-text pre {
        white-space: pre-wrap;
        font-size: 0.85rem;
        padding: 0.75rem 1rem;
        background: var(--lc-surface-sunken);
        border: 1px solid var(--lc-border);
        border-radius: 6px;
    }

.newsletter-issue-preview {
    background: var(--lc-warning-bg);
    border: 1px solid var(--lc-warning-border);
    border-radius: 6px;
    padding: 0.6rem 1rem;
    color: var(--lc-warning-text);
}

/* The issue's own formatting comes inline from Word (see HtmlCleaner); these are the defaults it
   was written against on the old site -- a plain browser page -- so unstyled text still matches. */
.newsletter-issue-content {
    color: var(--lc-paper-text);
    font-family: "Times New Roman", serif;
    line-height: normal;
    margin: 1.5rem 0;
}

    .newsletter-issue-content a {
        color: var(--lc-paper-link);
    }

        .newsletter-issue-content a:visited {
            color: var(--lc-paper-visited);
        }

/* Old issues are Word exports with fixed pixel widths; keep them inside the column on phones. */
.newsletter-issue-content img {
    max-width: 100%;
    height: auto;
}

.newsletter-issue-content table {
    max-width: 100%;
}

/* Newsletters written in the editor (not imported from the old site) share one house font, and the
   editor shows it too so a draft looks the same there as in Preview and once published. Pasted
   fonts are stripped (NewsletterFonts), so everything without a deliberate choice lands on this. */
.newsletter-issue-content.newsletter-house-style,
.newsletter-house-style .rz-html-editor-content {
    color: var(--lc-paper-text);
    font-family: Tahoma, Verdana, "Segoe UI", sans-serif;
}

/* The editor's writing area is the newsletter page, so it stays white with black text in the dark theme
   (the toolbar around it follows the theme). Its text matches what Preview and the published issue show. */
.rz-html-editor .rz-html-editor-content {
    background-color: var(--lc-paper);
    color: var(--lc-paper-text);
    color-scheme: light;
}

/* Affiliate offers in a newsletter (AffiliateOfferMarkup). A banner is a picture, or its text in a box, with the offer's site links
   under it when it has several; "all its links in a row" sits inside a sentence. The editor marks each offer with a dashed outline. In Preview and other staff views every offer shows with a label giving its dates (never printed), and one
   the website isn't showing today is faded. */
.lc-offer-banner {
    margin: 1rem 0;
    text-align: center;
}

    .lc-offer-banner img {
        max-width: 100%;
        height: auto;
    }

    .lc-offer-banner.lc-offer-text {
        padding: 0.75rem 1rem;
        border: 2px solid var(--lc-paper-border);
        border-radius: 6px;
        font-weight: bold;
    }

    .lc-offer-banner .lc-offer-sites {
        margin-top: 0.4rem;
        font-weight: normal;
    }

.newsletter-issue-credit {
    font-size: 0.8rem;
    color: var(--lc-text-muted);
}

    .newsletter-issue-credit a {
        color: var(--lc-paper-link);
    }

/* Every offer link opens a new tab; this says so to screen readers only. */
.lc-offer-new-tab {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.rz-html-editor-content .lc-offer-banner {
    outline: 2px dashed var(--lc-info-border);
    outline-offset: 3px;
    cursor: default;
}

.rz-html-editor-content .lc-offer-link,
.rz-html-editor-content .lc-offer-links,
.lc-offer-link.lc-offer-staff,
.lc-offer-links.lc-offer-staff {
    text-decoration-style: dotted;
    outline: 1px dashed var(--lc-info-border);
}

.lc-offer-label {
    margin-bottom: 0.4rem;
    padding: 0.2rem 0.5rem;
    border-radius: 4px;
    background: var(--lc-info-bg);
    color: var(--lc-info-text);
    font: 0.8rem/1.3 system-ui, "Segoe UI", sans-serif;
    text-align: left;
}

.lc-offer-not-shown .lc-offer-label {
    background: var(--lc-warning-bg);
    color: var(--lc-warning-text);
}

.lc-offer-banner.lc-offer-not-shown > :not(.lc-offer-label),
.lc-offer-link.lc-offer-not-shown,
.lc-offer-links.lc-offer-not-shown {
    opacity: 0.55;
}

@media print {
    .lc-offer-label {
        display: none;
    }

    .lc-offer-banner.lc-offer-not-shown > :not(.lc-offer-label),
    .lc-offer-link.lc-offer-not-shown,
    .lc-offer-links.lc-offer-not-shown {
        opacity: 1;
    }
}

.feedback-form {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    margin-top: 1.5rem;
}

    .feedback-form fieldset {
        border: none;
        padding: 0;
        margin: 0 0 0.5rem;
    }

    .feedback-form legend,
    .feedback-form label {
        font-weight: 600;
        margin-top: 0.6rem;
    }

    .feedback-form .optional {
        font-weight: 400;
        color: var(--lc-text-muted);
    }

/* The pictures to be sent, one row each: the picture as it will be sent (drawn in the browser by js/feedback.js), its name, Remove. */
/* Two classes, to beat the page's own .info-page ul spacing. */
.info-page .feedback-screenshots,
.feedback-screenshots {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.feedback-screenshot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    background: var(--lc-surface-muted);
    border-radius: 6px;
    padding: 0.4rem 0.75rem;
}

.feedback-screenshot-name {
    flex: 1 1 10rem;
    overflow-wrap: anywhere;
}

.feedback-preview {
    max-width: min(100%, 220px);
    max-height: 160px;
    border: 1px solid var(--lc-border);
    border-radius: 6px;
}

/* A picture being dragged over the form. */
.feedback-form.is-dropping {
    outline: 2px dashed var(--lc-accent);
    outline-offset: 6px;
    border-radius: 6px;
}

.feedback-restored {
    background: var(--lc-info-bg);
    color: var(--lc-info-text);
    border-radius: 6px;
    padding: 0.5rem 0.75rem;
    margin: 0.75rem 0 0;
}

.field-hint {
    font-size: 0.85rem;
    color: var(--lc-text-muted);
    margin: 0;
}

.field-error {
    font-size: 0.9rem;
    color: var(--lc-danger-ink);
    margin: 0;
}

/* Staff viewing a member's My Ancestors or its map (AncestorPaths.Staff): whose they are, and the way back. Here because both pages use it. */
.staff-view {
    background: var(--lc-info-bg);
    border: 1px solid var(--lc-info-border);
    color: var(--lc-info-text);
    border-radius: 6px;
    padding: 0.6rem 0.9rem;
    margin: 0 0 0.75rem;
    max-width: 52rem;
}

    /* The banner's own text colour, underlined: the link blue was 4.49:1 on the banner's pale blue. */
    .staff-view a {
        color: inherit;
        text-decoration: underline;
    }

/* Honeypot field: off-screen rather than display:none, which some bots skip. */
.feedback-hp {
    position: absolute;
    left: -10000px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.btn-secondary-outline {
    background: var(--lc-surface);
    color: var(--lc-link);
    border: 1px solid var(--lc-accent);
}

    .btn-secondary-outline:hover {
        background: var(--lc-surface-muted);
    }

/* A heading that folds its card or group (the member's admin page and its forum card, planner #331): the whole heading is the button,
   with a chevron that points down when open. Shared here because the forum card is its own component. */
.card-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 24px;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

    .card-toggle .card-chevron {
        flex: none;
        width: 1.1em;
        height: 1.1em;
        fill: none;
        stroke: currentColor;
        stroke-width: 3;
        stroke-linecap: round;
        stroke-linejoin: round;
        transition: transform 0.15s;
    }

    .card-toggle[aria-expanded="true"] .card-chevron {
        transform: rotate(90deg);
    }

    .card-toggle .optional-tag {
        margin-left: 0.25rem;
    }

@media (prefers-reduced-motion: reduce) {
    .card-toggle .card-chevron {
        transition: none;
    }
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--lc-success-strong);
}

.invalid {
    outline: 1px solid var(--lc-danger-ink);
}

.validation-message {
    color: var(--lc-danger-ink);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, var(--lc-danger-strong);
    padding: 1rem 1rem 1rem 3.7rem;
    color: var(--lc-on-brand);
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

/* Radzen's "Light" buttons are the same grey as the admin page background, so they read as plain text. Give them a white face and an edge,
   site-wide, rather than restyling each one. (Disabled ones keep Radzen's faded look.) */
.rz-button.rz-light.rz-variant-filled:not(.rz-state-disabled) {
    background-color: var(--lc-surface);
    border: 1px solid var(--lc-control-edge);
    color: var(--lc-text-strong);
}

.rz-button.rz-light.rz-variant-filled:not(.rz-state-disabled):hover {
    background-color: var(--lc-info-bg);
    border-color: var(--lc-info-strong);
}

/* A Save button with nothing to save (SaveChangesButton, admin pages): faded like a disabled one but still reachable and pressable (it
   says there's nothing to save). An unavailable control needs no contrast (WCAG 1.4.3); "Unsaved changes" beside a lit one is bold text. */
.rz-button.save-idle,
button.save-idle {
    opacity: 0.45;
    box-shadow: none;
}

.unsaved-note {
    margin-left: 0.75rem;
    font-weight: 600;
    color: var(--lc-warning-ink);
}

.unsaved-note:empty {
    margin-left: 0;
}

/* A chart's hover box near the edge of the window is moved sideways to fit (js/chart-tooltips.js sets --lc-tip-shift; Tim, feedback #22),
   and its little pointer moves back the other way so it still points at the column, never past the box's rounded corners. */
.rz-chart-tooltip.rz-top-chart-tooltip { transform: translate(calc(-50% + var(--lc-tip-shift, 0px)), -100%); }
.rz-chart-tooltip.rz-bottom-chart-tooltip { transform: translate(calc(-50% + var(--lc-tip-shift, 0px)), 0); }

.rz-chart-tooltip.rz-top-chart-tooltip:not(.rz-pie-tooltip) .rz-chart-tooltip-content::after,
.rz-chart-tooltip.rz-bottom-chart-tooltip:not(.rz-pie-tooltip) .rz-chart-tooltip-content::after {
    left: clamp(12px, calc(50% - var(--lc-tip-shift, 0px)), calc(100% - 12px));
}

/* Radzen's orange Primary buttons (admin pages) keep their orange, but white text on it is only 2.8:1, so the
   text is near-black in the light theme and the page navy in the dark one (as FTAnalyzer.Web does with its
   green): 5.7:1 and 6.0:1, still over 4.5:1 on the darker hover. The pressed "darker" shade keeps white (4.7:1). */
:root {
    --rz-on-primary: var(--lc-on-primary);
    --rz-on-primary-light: var(--lc-on-primary);
    --rz-on-primary-dark: var(--lc-on-primary);
    /* Radzen's own focus outline matches the site's (planner #220): 3px of the focus-ring token, not its thin 2px orange. */
    --rz-outline-width: 3px;
    --rz-outline-color: var(--lc-focus-ring);

    /* The same for Radzen's other button colours (accessibility pass on the admin pages, 12 Nov 2026): white on them was 1.6:1
       (Warning) to 2.9:1 (Secondary). Dark text is 5.4:1 (Secondary) to 10.3:1 (Warning) in both themes; on the hover shade 4.6:1
       or more, except Danger's at 4.35:1 in the light theme. As with Primary, the pressed "darker" shade keeps Radzen's white. */
    --rz-on-secondary: var(--lc-on-primary);
    --rz-on-secondary-light: var(--lc-on-primary);
    --rz-on-secondary-dark: var(--lc-on-primary);
    --rz-on-info: var(--lc-on-primary);
    --rz-on-info-light: var(--lc-on-primary);
    --rz-on-info-dark: var(--lc-on-primary);
    --rz-on-success: var(--lc-on-primary);
    --rz-on-success-light: var(--lc-on-primary);
    --rz-on-success-dark: var(--lc-on-primary);
    --rz-on-warning: var(--lc-on-primary);
    --rz-on-warning-light: var(--lc-on-primary);
    --rz-on-warning-dark: var(--lc-on-primary);
    --rz-on-danger: var(--lc-on-primary);
    --rz-on-danger-light: var(--lc-on-primary);
    --rz-on-danger-dark: var(--lc-on-primary);

    /* Radzen's tab names are its Secondary blue, 2.5:1 on the grey tab; the site's link colour is 4.65:1 there. The dark theme
       sets its own tab colours (css/radzen-dark.generated.css), which win over these. */
    --rz-tabs-tab-color: var(--lc-link);
    --rz-tabs-tab-hover-color: var(--lc-link);
    --rz-tabs-tab-focus-color: var(--lc-link);

    /* The chosen option of a select bar (Logs' levels) was the orange on its pale tint, 2:1; dark text there is over 10:1. */
    --rz-on-primary-lighter: var(--lc-on-primary);
    /* A grid's filter icons were Radzen's "disabled" grey, 2.2:1 on the heading row: hard to see they're there at all. */
    --rz-grid-filter-color: var(--lc-text-muted);
}

/* A RadzenFormField's name on its box's edge was Radzen's placeholder grey, 3.8:1; it's the field's label, so it takes the site's
   label colour (accessibility pass on the admin pages, 12 Nov 2026). Radzen colours it from the placeholder variable in a score of
   states, so the variable is changed on the label alone: real placeholders inside the boxes keep their grey. Focused, it was
   Radzen's orange (2.8:1); it's the link colour instead. */
.rz-form-field-label {
    --rz-input-placeholder-color: var(--lc-text-soft);
    --rz-form-field-label-focus-color: var(--lc-link);
}

/* Outlined and text-only Radzen buttons write their label in the colour itself, too light on a white page (2.1:1 to 2.9:1):
   they use the site's ink for that meaning instead. */
.rz-button.rz-variant-outlined.rz-danger.rz-shade-default,
.rz-button.rz-variant-text.rz-danger.rz-shade-default { color: var(--lc-danger-ink); }
.rz-button.rz-variant-outlined.rz-success.rz-shade-default,
.rz-button.rz-variant-text.rz-success.rz-shade-default { color: var(--lc-success-ink); }
.rz-button.rz-variant-outlined.rz-warning.rz-shade-default,
.rz-button.rz-variant-text.rz-warning.rz-shade-default { color: var(--lc-warning-ink); }
.rz-button.rz-variant-outlined.rz-info.rz-shade-default,
.rz-button.rz-variant-text.rz-info.rz-shade-default,
.rz-button.rz-variant-outlined.rz-secondary.rz-shade-default,
.rz-button.rz-variant-text.rz-secondary.rz-shade-default { color: var(--lc-link); }

/* Radzen in the dark theme. css/radzen-dark.generated.css switches Radzen to its own dark theme; these lines
   then retune it to the site's navy (Radzen's dark greys are slate-teal) and patch the things that went
   wrong on FTAnalyzer.Web: inputs taking the page colour and vanishing, popups (rendered at the end of
   <body>, outside any page container) blending into the page, and headings in Radzen's own title colour. */
:root[data-theme="dark"] {
    --rz-base: #5d6f80;
    --rz-base-50: #ffffff;
    --rz-base-100: #eef2f6;
    --rz-base-200: #dce3ea;
    --rz-base-300: #c3cdd6;
    --rz-base-400: #9aa9b6;
    --rz-base-500: #7a8a99;
    --rz-base-600: #5d6f80;
    --rz-base-700: #3a4c5d;
    --rz-base-800: #24323f;
    --rz-base-900: #18232e;
    --rz-base-light: #9aa9b6;
    --rz-base-dark: #3a4c5d;
    --rz-base-darker: #18232e;

    --rz-body-background-color: var(--lc-page-bg);
    --rz-base-background-color: var(--lc-surface);
    --rz-input-background-color: var(--lc-surface);
    --rz-text-color: var(--lc-text);
    --rz-text-title-color: var(--lc-text-strong);
    --rz-text-secondary-color: var(--lc-text-muted);
    --rz-grid-stripe-background-color: var(--lc-surface-hover);
    --rz-link-color: var(--lc-link);
    --rz-link-hover-color: var(--lc-heading);
    /* Selected text: white on the deeper info blue, 7.2:1 (on info-strong it was 2.9:1). */
    --rz-text-selection-background-color: var(--lc-info-border);
    --rz-text-selection-color: var(--lc-on-brand);
}

    :root[data-theme="dark"] .rz-popup {
        border: 1px solid var(--lc-border-strong);
        box-shadow: 0 6px 18px var(--lc-shadow-strong);
    }

    :root[data-theme="dark"] ::selection {
        background: var(--lc-info-border);
        color: var(--lc-on-brand);
    }

    /* The newsletter paper and the editor's writing area stay light (tokens.css), but Radzen colours every
       h1-h6 and link with its own variables, which the dark theme makes near-white: put those back too.
       The site's own link colour as well: "a" uses --lc-link, whose dark value was light blue on the white paper, 2.1:1
       (the editor's contents links; accessibility pass on the admin pages, 12 Nov 2026). */
    :root[data-theme="dark"] .newsletter-issue,
    :root[data-theme="dark"] .lc-light-scope,
    :root[data-theme="dark"] .rz-html-editor-content {
        --rz-text-title-color: var(--lc-paper-heading);
        --rz-text-color: var(--lc-paper-text);
        --rz-link-color: var(--lc-paper-link);
        --rz-link-hover-color: var(--lc-paper-link);
        --lc-link: var(--lc-paper-link);
    }

    /* Radzen's dark tab names were 4.28:1 on the unselected tab's grey; the selected tab still stands out by its background
       and top edge (accessibility pass on the admin pages, 12 Nov 2026). */
    :root[data-theme="dark"] {
        --rz-tabs-tab-color: var(--lc-text);
        /* The chosen option of a select bar sits on a see-through tint of the orange, so it's dark here: light text, not the navy. */
        --rz-on-primary-lighter: var(--lc-text);
    }
