/*
 * cash-buddy.co.uk
 *
 * Every other site in this estate loads a shared site.css and adds a small
 * theme on top. This one never picked up site.css: every page still carries
 * its own inline <style> block, a Tailwind Play CDN tag, and a sidebar-and-
 * top-bar "app" shell copied from page to page. That shell stays; rebuilding
 * it across sixteen pages is a separate job. What changes is what it reads
 * as: a paying-in book and a cash analysis ledger rather than a dashboard
 * template, using the tokens this file declares for itself.
 *
 * The idea: this is the tool for money that does not touch a bank feed, cash
 * counted by hand and reconciled at the end of the day. So the page is set as
 * a ledger page rather than a SaaS product: ruled sections instead of white
 * cards, a spine down the side instead of a dark app sidebar, and the
 * balance figures set large and in tabular numerals because they are the
 * reason anyone opened the tool.
 *
 * The masthead carries the ruling off a paying-in book counterfoil, which is
 * the one element here that could not be lifted onto another site.
 *
 * Loaded last in <head> on purpose. Tailwind's Play CDN injects its own
 * stylesheet at runtime, after everything already in the document, so a
 * bare utility class always wins a specificity tie against a rule in this
 * file. Wherever that matters, this file either uses a selector Tailwind
 * cannot generate (an id, an id-qualified descendant, an element+class
 * compound) or says explicitly why it reaches for !important.
 */

/* ---------------------------------------------------------------- tokens */

:root {
    --paper: #FBFAF8;
    --card: #FFFFFF;
    --ink: #1A1D21;
    --ink-soft: #454C54;
    --muted: #6B747E;
    --rule: #E3E0DA;
    --rule-strong: #CFCBC3;

    --accent: #3B6242;
    --accent-deep: #2B4931;
    --accent-tint: #EBEFEC;
    --accent-ink: #FFFFFF;

    /*
     * The sidebar's own ground. Not the accent itself (a whole wall of it
     * would be heavy) and not the dashboard-template navy the page arrived
     * with, but the darkest step of the same green scale the rest of the
     * site uses, so the spine and the accent read as one palette.
     */
    --spine: #1B2D1E;
    --spine-hover: #253D29;
    --spine-ink: #D3DED5;
    --spine-ink-soft: #B1C9B5;
    --spine-rule: #83AF8B;

    --font-display: 'Fraunces', Georgia, serif;
    --font-body: 'Public Sans', system-ui, sans-serif;
    --font-figure: ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, monospace;

    --step-0: 1rem;
    --step-1: 1.2rem;
    --step-2: 1.44rem;
    --step-3: 1.728rem;
    --step-4: 2.074rem;
    --step-5: 2.488rem;
    --step-6: 3.2rem;
    --step-7: 4.4rem;
}

/*
 * Every figure on the page is set in tabular numerals: this only affects how
 * digits are spaced, so it is safe to apply everywhere rather than chase
 * roughly thirty individual ids.
 */
body {
    font-variant-numeric: tabular-nums;
}

.section-mark,
.masthead-kicker,
.topbar-label,
.sidebar-title,
.ledger-label {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

/* -------------------------------------------------------------- masthead */

/*
 * Full bleed, because the top of a paying-in book runs to the edge of the
 * page. Every page this sits on already has its own side padding (either
 * the 4xl content column's 1rem, or the app shell's 24px), so the negative
 * margin below cancels exactly that padding rather than a guessed value,
 * then the padding is put straight back so the text lines up with
 * everything under it.
 */
.masthead {
    margin-inline: -1rem;
    padding-inline: 1rem;
    background-color: var(--accent);
    background-image: url('/img/paying-in-ruling.webp');
    background-size: cover;
    background-position: center;
    background-blend-mode: multiply;
    color: #fff;
    /*
     * A paying-in book is a squat landscape pad, wider than it is tall,
     * so the band sits between the cheque's and the bill's.
     */
    padding-block: clamp(2.4rem, 6.5vw, 4rem) clamp(1.9rem, 4.5vw, 2.75rem);
    border-bottom: 4px solid var(--spine);
    margin-bottom: clamp(1.5rem, 4vw, 2.5rem);
}

.main-content .masthead {
    margin-inline: -24px;
    padding-inline: 24px;
}

.masthead-inner {
    max-width: 40rem;
}

.masthead-breadcrumb {
    margin-bottom: 1rem;
    font-size: 0.85rem;
    opacity: 0.85;
}

.masthead-breadcrumb a {
    color: #fff;
}

.masthead-kicker {
    display: block;
    color: #fff;
    opacity: 0.85;
    margin-bottom: 1.1rem;
}

.masthead h1 {
    font-family: var(--font-display);
    font-size: clamp(2rem, 5.2vw, var(--step-6));
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: #fff;
    margin: 0;
    max-width: 20ch;
}

.masthead-standfirst {
    margin-top: 1rem;
    font-size: var(--step-1);
    line-height: 1.5;
    max-width: 46ch;
    color: #fff;
    opacity: 0.9;
}

/*
 * The persistent top bar on the two pages that keep one (index, faq) used to
 * carry its own <h1>, which meant the page had two: one in the fixed chrome,
 * one nowhere. It is wayfinding text now, not a heading, and the masthead
 * below it carries the one real h1.
 */
.topbar-label {
    color: var(--ink-soft);
    margin: 0;
}

/* ------------------------------------------------------ the dark sidebar */

/*
 * Twelve of these pages inline the same "Family A" sidebar: 220px, fixed,
 * background #1a1a2e. That is a dashboard-template navy with nothing to do
 * with this site. It keeps its shape and stays dark, because a wall of the
 * flat accent would be heavy at this size, but the colour comes from the
 * same green scale as the accent, and it picks up the rules and the small
 * capitals the rest of the page now uses.
 */
.app-sidebar {
    background: var(--spine);
}

.sidebar-header {
    border-bottom-color: rgba(255, 255, 255, 0.12);
}

.sidebar-logo {
    color: var(--spine-rule);
}

.sidebar-title {
    color: #fff;
    letter-spacing: 0.1em;
}

.app-sidebar .sidebar-link {
    color: var(--spine-ink-soft);
    border-left-color: transparent;
}

.app-sidebar .sidebar-link:hover {
    background: var(--spine-hover);
    color: var(--spine-ink);
    border-left-color: var(--spine-rule);
}

.sidebar-footer {
    border-top-color: rgba(255, 255, 255, 0.12);
}

.sidebar-footer .sidebar-link-small {
    color: var(--spine-ink-soft);
}

.dark-mode-toggle {
    background: rgba(255, 255, 255, 0.1);
    color: #fff;
}

.dark-mode-toggle:hover {
    background: rgba(255, 255, 255, 0.18);
}

/*
 * Family A's own mobile toggle, fixed and floating rather than sitting in a
 * top bar. Scoped to a direct child of .app-layout, because index.html and
 * faq.html reuse the same "hamburger" class name on a plain icon button
 * inside their light top-nav, which must stay transparent, not spine-dark.
 */
.app-layout > .hamburger {
    background: var(--spine);
}

/*
 * Accent-on-dark measured 2.09:1, well under the 3:1 a focus ring needs as a
 * UI component, so the dark sidebar gets its own outline colour rather than
 * the site-wide one.
 */
.app-sidebar a:focus-visible,
.app-sidebar button:focus-visible,
.app-layout > .hamburger:focus-visible {
    outline-color: #fff !important;
}

/* ----------------------------------------------------- the light sidebar */

/*
 * index.html (and, awkwardly, a second copy nested inside faq.html: see the
 * note in the commit) carries a different, lighter "Family B" sidebar. It
 * was already close to the house register, so it keeps its white ground and
 * picks up a spine stripe, ruled divisions and small capitals instead.
 */
.sidebar {
    border-right-color: var(--rule);
    border-top: 4px solid var(--accent);
}

.sidebar .logo-section svg {
    color: var(--accent);
}

.sidebar-text h2 {
    font-family: var(--font-display);
    color: var(--ink);
}

.sidebar .sidebar-link {
    color: var(--ink-soft);
    border-left-color: transparent;
}

.sidebar .sidebar-link:hover {
    background: var(--accent-tint);
    color: var(--accent-deep);
    border-left-color: var(--accent);
}

.sidebar .sidebar-link.active {
    background: var(--accent-tint);
    color: var(--accent-deep);
    border-left-color: var(--accent);
    font-weight: 650;
}

.sidebar .border-t {
    border-top-color: var(--rule) !important;
}

.data-management-section h3 {
    color: var(--ink-soft);
}

.collapse-toggle-btn:hover {
    background: var(--accent-tint) !important;
    color: var(--accent-deep) !important;
}

/* --------------------------------------------------------------- top bar */

.top-nav {
    background: var(--paper);
    border-bottom-color: var(--rule);
}

.top-nav a {
    color: var(--accent);
}

.top-nav a:hover {
    color: var(--accent-deep);
}

/*
 * The "Start Tour" button carries its own Tailwind gradient. Overridden by
 * attribute selector rather than by stripping the class, because the class
 * also carries the layout (flex, gap, padding) this restyle wants to keep.
 */
.top-nav button[onclick="startTour()"] {
    background: var(--accent);
    background-image: none;
    box-shadow: none;
    border-radius: var(--radius-sm, 6px);
}

.top-nav button[onclick="startTour()"]:hover {
    background: var(--accent-deep);
    box-shadow: none;
}

/* ---------------------------------------------------- the welcome banner */

/*
 * This used to be a solid-colour rounded card carrying generic marketing
 * copy ("Take control of your finances..."). It is a dismissible aside, not
 * the page's opening statement, so it is set as a ruled note instead of a
 * second, competing banner under the masthead.
 */
#welcomeBanner {
    background: none !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    color: var(--ink-soft) !important;
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
    padding-block: 1rem !important;
}

#welcomeBanner p {
    color: var(--ink-soft);
}

#welcomeBanner button {
    color: var(--muted) !important;
}

#welcomeBanner button:hover {
    color: var(--ink) !important;
}

/* ---------------------------------------------------------- de-carding */

/*
 * The nine main tool sections on index.html each carry their own stable id
 * (used already for the intro tour and the sidebar's jump links), which
 * gives an id-qualified selector for free: an id beats any Tailwind utility
 * class regardless of source order, so the white rounded card underneath
 * every one of these can be lifted off without touching the markup.
 */
#overview,
#expenses,
#income,
#payday,
#loan,
#budget,
#visualize,
#visualize ~ section {
    background: none;
    box-shadow: none;
    border-radius: 0;
    border: 0;
    border-top: 1px solid var(--rule);
    padding-inline: 0;
    padding-block: clamp(1.75rem, 4vw, 2.75rem);
}

#expenses,
#income {
    border-top-width: 4px;
    border-top-color: var(--accent);
}

.card-hover,
.card-hover:hover {
    transform: none;
    box-shadow: none;
}

/*
 * The four headline stats in the Financial Overview grid were four identical
 * pastel tiles. Net Balance is why anyone opened the page, so it is pulled
 * onto its own row and set at the top of the extended scale; the other three
 * remain supporting figures underneath. :has() is a progressive enhancement:
 * without it every tile is simply equal-sized again, which still works.
 */
#overview .grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.75rem 1.5rem;
}

@media (min-width: 40rem) {
    #overview .grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

#overview .grid > div {
    background: none;
    box-shadow: none;
    border-radius: 0;
    border-top: 3px solid var(--rule-strong);
    padding: 0.85rem 0 0;
}

#overview .grid > div:has(#netBalanceDisplay) {
    grid-column: 1 / -1;
    order: -1;
    border-top: 3px solid var(--accent);
    padding-block: 0.5rem 1.25rem;
    margin-bottom: 0.5rem;
}

#netBalanceDisplay {
    display: block;
    font-family: var(--font-display);
    font-size: clamp(2.75rem, 9vw, var(--step-7));
    font-weight: 700;
    line-height: 0.98;
    letter-spacing: -0.03em;
    color: var(--accent) !important;
}

/* Prominent, but a supporting figure inside a four-column row, not the hero. */
#netBalance {
    font-size: var(--step-3) !important;
    color: var(--accent) !important;
}

#monthlyRemainingText,
#weeklyRemainingText {
    font-size: var(--step-1) !important;
}

#countdownDisplay {
    font-family: var(--font-display);
    font-size: clamp(1.75rem, 4vw, var(--step-4));
}

#paydayCountdown,
.bg-gradient-to-br.from-accent-50 {
    background: none !important;
    border: 1px solid var(--rule-strong);
    border-top: 3px solid var(--accent);
    border-radius: 0 !important;
}

/*
 * The loan calculator's three results were pastel rows in a tinted box. Set
 * as a small ledger table instead: a rule under each row, the figure on the
 * right in the display face.
 */
#loanResults {
    background: none !important;
    border-radius: 0 !important;
    border: 1px solid var(--rule-strong);
    border-top: 3px solid var(--accent);
}

#loanResults p {
    border-bottom: 1px solid var(--rule);
    padding-block: 0.6rem;
    margin: 0;
}

#loanResults p:last-child {
    border-bottom: 0;
    font-weight: 700;
}

#loanResults span[id] {
    font-family: var(--font-figure);
    color: var(--accent) !important;
}

/*
 * Budget progress: the pastel status tiles become ruled blocks, and the
 * progress bar loses its gradient fill for a flat accent one, which reads
 * as a level being filled rather than a decoration.
 */
#monthlyBudgetStatus,
#weeklyBudgetStatus {
    background: none !important;
    border: 1px solid var(--rule-strong) !important;
    border-radius: 0 !important;
    border-left: 3px solid var(--accent) !important;
}

#monthlyBudgetBar,
#weeklyBudgetBar {
    background: var(--accent) !important;
    background-image: none !important;
    border-radius: 0 !important;
}

#budgetStatus .bg-gray-200 {
    background: var(--rule) !important;
    border-radius: 0 !important;
}

/*
 * Every page invented its own colour for these two buttons: teal-to-emerald
 * on index, emerald-to-blue on faq. Neither is the site's own accent. Custom
 * classes, so a plain override (no !important needed) is enough.
 */
.btn-gradient,
.btn-accent {
    background: var(--accent);
    box-shadow: none;
}

.btn-gradient:hover,
.btn-accent:hover {
    background: var(--accent-deep);
    box-shadow: none;
    transform: none;
}

.btn-gradient:focus,
.btn-accent:focus {
    box-shadow: none;
}

/* --------------------------------------------------------------- inputs */

.input-focus {
    border-radius: 0 !important;
    border-color: var(--rule-strong) !important;
    background: var(--card);
}

.input-focus:focus {
    border-color: var(--accent) !important;
}

/*
 * A handful of pages (contact, privacy, terms, and a couple of stat tiles on
 * index) reach for Tailwind's teal scale ad hoc, unrelated to the site's own
 * accent. Overridden with !important because these are bare Tailwind
 * utilities of the same specificity this file cannot otherwise beat.
 */
.text-teal-600,
.text-teal-700 {
    color: var(--accent) !important;
}

.hover\:text-teal-700:hover {
    color: var(--accent-deep) !important;
}

.bg-teal-50,
.bg-teal-100 {
    background: var(--accent-tint) !important;
}

.border-teal-500 {
    border-color: var(--accent) !important;
}

.bg-gradient-to-r.from-teal-700.to-teal-600,
.bg-gradient-to-r.from-teal-800.to-teal-700 {
    background-image: none !important;
    background-color: var(--accent) !important;
}

.bg-gradient-to-r.from-teal-700.to-teal-600:hover,
.bg-gradient-to-r.from-teal-800.to-teal-700:hover {
    background-color: var(--accent-deep) !important;
}

/* -------------------------------------------------------------- footer */

/*
 * The footer carried a solid teal (or, on other pages, emerald-to-blue)
 * block with no relation to the rest of the site. It becomes the accent, set
 * as a ledger closing band: a rule dividing the link groups from the legal
 * line, not a second hero.
 */
.gradient-bg,
footer.gradient-bg {
    background: var(--accent) !important;
    background-image: none !important;
}

footer.gradient-bg {
    border-radius: 0 !important;
}

footer.gradient-bg h3,
footer.gradient-bg h4 {
    font-family: var(--font-display);
    color: #fff;
}

footer.gradient-bg p,
footer.gradient-bg li,
footer.gradient-bg a {
    color: rgba(255, 255, 255, 0.9);
}

footer.gradient-bg a:hover {
    color: #fff;
}

footer.gradient-bg .border-t {
    border-top-color: rgba(255, 255, 255, 0.25) !important;
}

footer.gradient-bg a:focus-visible,
footer.gradient-bg button:focus-visible {
    outline-color: #fff !important;
}

/* ------------------------------------------------------ reference pages */

/*
 * guide.html's own custom classes (not Tailwind, so a plain override is
 * enough): the rounded, shadowed card becomes a ruled section, and the two
 * inline boxes become side notes instead of coloured panels.
 */
.guide-section {
    background: none;
    border-radius: 0;
    box-shadow: none;
    padding: 1.5rem 0;
    border-top: 1px solid var(--rule);
    margin-bottom: 0;
}

.guide-section:hover {
    box-shadow: none;
    transform: none;
}

.tip-box {
    background: none;
    border-radius: 0;
    border-left: 3px solid var(--accent);
}

.warning-box {
    background: none;
    border-radius: 0;
    border-left: 3px solid var(--muted);
    border-top: 0;
}

/*
 * The blog list and the plain content pages (about, contact) repeat the same
 * Tailwind card by hand on every entry with no id to hook. Those elements
 * were given a shared "sheet-block" class when the copy was rewritten, so
 * this is a plain override rather than a specificity fight.
 */
.sheet-block {
    background: none;
    border-radius: 0;
    box-shadow: none;
    border: 0;
    border-top: 1px solid var(--rule);
    padding: 1.5rem 0;
    margin-bottom: 0;
}

.sheet-block:first-of-type {
    border-top: 0;
    padding-top: 0;
}

article.sheet-block {
    border-top: 1px solid var(--rule);
}

article.sheet-block:first-of-type {
    border-top: 0;
}

.sheet-block h2 {
    margin-bottom: 0.5rem;
}

/* faq.html's own question list, same treatment as the guide's tip boxes. */
.faq-item-row {
    border-top: 1px solid var(--rule);
    padding-block: 1.25rem;
}

.faq-item-row:first-child {
    border-top: 0;
    padding-top: 0;
}

/* -------------------------------------------------------------- contrast */

/*
 * Tailwind's own focus:outline-none utility is injected after this file and
 * targets :focus, so it beats a plain :focus-visible rule of lower
 * specificity here regardless of source order. !important is the deliberate
 * fix: every interactive element gets a real indicator back.
 */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 3px solid var(--accent) !important;
    outline-offset: 2px;
    box-shadow: none;
}

.masthead a:focus-visible,
.masthead button:focus-visible {
    outline-color: #fff !important;
}

/* ------------------------------------------------------------------ print */

@media print {
    .app-sidebar,
    .sidebar,
    .top-nav,
    .hamburger,
    .sidebar-overlay,
    .book-plug,
    ins.adsbygoogle,
    [data-cc-open] {
        display: none !important;
    }

    .app-main,
    .main-content {
        margin: 0 !important;
    }

    .masthead {
        background: none !important;
        color: #000 !important;
        border-bottom: 2px solid #000;
    }

    .masthead h1,
    .masthead-standfirst,
    .masthead-kicker {
        color: #000 !important;
        opacity: 1 !important;
    }

    #netBalanceDisplay,
    #netBalance {
        color: #000 !important;
    }
}

/* -------------------------------------------------------------- dark mode */

/*
 * The manual dark-mode toggle these pages already ship sets body.dark-mode
 * and overrides a handful of Tailwind colours with !important. The sidebar
 * and top bar rules above are not Tailwind utilities, so body.dark-mode's
 * own (lower-specificity, earlier) rules would otherwise win back the old
 * colours; these keep the ledger palette in the toggled state too.
 */
body.dark-mode .app-sidebar {
    background: #12201a;
}

body.dark-mode .sidebar {
    background: #1B1F24;
    border-right-color: #2A2F36;
}

body.dark-mode .top-nav {
    background: #1B1F24;
    border-bottom-color: #2A2F36;
}

body.dark-mode #overview,
body.dark-mode #expenses,
body.dark-mode #income,
body.dark-mode #payday,
body.dark-mode #loan,
body.dark-mode #budget,
body.dark-mode #visualize,
body.dark-mode #visualize ~ section {
    border-top-color: #2A2F36;
}

body.dark-mode #welcomeBanner {
    border-top-color: #2A2F36;
    border-bottom-color: #2A2F36;
    color: #BFC5CC !important;
}

/* ------------------------------------------------------- the spine, dark */

/*
 * The inline sheet on these pages sets `body.dark-mode .sidebar` and
 * `body.dark-mode .top-nav` to #1a1a2e, the dashboard navy this restyle exists
 * to get rid of. That selector is more specific than the bare `.sidebar` rule
 * above, so in dark mode the spine reverted to the template colour and the
 * green only survived in light. It is matched here rather than out-specified
 * by accident.
 */
body.dark-mode .sidebar,
body.dark-mode .app-sidebar {
    background: var(--spine);
    border-right-color: var(--spine-hover);
}

body.dark-mode .top-nav {
    background: var(--spine);
    border-bottom-color: var(--spine-hover);
}

/* ------------------------------------------------- the reference pages */

/*
 * The margin column, carrying the section mark the way a ledger heads its
 * columns. It is only on the reference pages: the calculator itself is an app
 * shell with a fixed sidebar, and that rail already does this job, so a second
 * margin column inside it would be fussy rather than editorial.
 *
 * Below 60rem it collapses and the mark sits above its section, which is where
 * it reads on a phone anyway.
 */
.sheet-grid {
    display: grid;
    gap: clamp(1rem, 3vw, 2.25rem);
}

@media (min-width: 60rem) {
    .sheet-grid {
        grid-template-columns: 8.5rem minmax(0, 1fr);
        align-items: start;
    }
}

.sheet-grid > .section-mark {
    color: var(--accent);
    padding-top: 0.4rem;
    margin: 0;
}

@media (min-width: 60rem) {
    .sheet-grid > .section-mark {
        text-align: right;
        border-top: 2px solid var(--accent);
    }
}

/*
 * The Tailwind type utilities have been stripped off the headings and copy on
 * these pages, so the sheet can finally set them. Until now the card was
 * retired but the type inside it was still Tailwind's.
 */
.sheet-block h2 {
    font-family: var(--font-display);
    font-size: var(--step-3);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.01em;
    color: var(--ink);
    margin-bottom: 0.75rem;
    max-width: 32ch;
}

.sheet-block h3 {
    font-family: var(--font-display);
    font-size: var(--step-1);
    font-weight: 700;
    color: var(--ink);
    margin-top: 1.5rem;
    margin-bottom: 0.35rem;
}

.sheet-block p,
.sheet-block li {
    color: var(--ink-soft);
    max-width: 66ch;
}

.sheet-block p + p {
    margin-top: 0.85rem;
}

.sheet-block + .sheet-block {
    margin-top: clamp(1.75rem, 4vw, 2.75rem);
    padding-top: clamp(1.75rem, 4vw, 2.75rem);
    border-top: 1px solid var(--rule);
}

/*
 * A placeholder is a hint, not a value.
 *
 * The fields on these pages were enlarged so the figure people type is legible
 * at the scale of the answer. At that size a placeholder set in the input's own
 * colour and weight reads as a filled field, and somebody arrives at a form that
 * looks already answered. Every field here carries a visible label, so the
 * placeholder is free to recede.
 */
input::placeholder,
textarea::placeholder {
    color: color-mix(in srgb, currentColor 38%, transparent);
    font-size: 0.66em;
    font-weight: 400;
    letter-spacing: 0.04em;
    opacity: 1;
}

/* placeholder specificity */
input[type="text"]::placeholder,
input[type="number"]::placeholder,
input[type="search"]::placeholder {
    color: color-mix(in srgb, currentColor 38%, transparent);
    font-size: 0.66em;
    font-weight: 400;
    letter-spacing: 0.04em;
    opacity: 1;
}

/* --------------------------------------------------- validation and status */

/*
 * The estate used alert() for every validation failure. A modal is unreadable
 * on a phone, says nothing about which field is wrong, and blocks the page for
 * someone working at speed, so the message now sits under the field it belongs
 * to. The red is checked against this site's own paper rather than reused from
 * another site.
 */

:root {
    --form-error: #A3231B;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme='light']) {
        --form-error: #FFB4AB;
    }
}

:root[data-theme='dark'] {
    --form-error: #FFB4AB;
}

.form-error {
    margin: 0.4rem 0 0;
    font-size: 0.9rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--form-error);
}

.form-error[hidden] {
    display: none;
}

[aria-invalid='true'] {
    border-color: var(--form-error);
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------------------- notices */

/*
 * Fourteen alert() calls sat between this dashboard and anyone using it at
 * speed. The replacement is a notice on the page, in the flow, that a screen
 * reader announces once and that clears itself.
 */

.notice-stack {
    display: grid;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.notice-stack:empty {
    display: none;
}

.notice {
    margin: 0;
    padding: 0.75rem 1rem;
    font-weight: 600;
    border: 1px solid var(--rule);
    border-left: 4px solid var(--accent);
    background: var(--card, transparent);
}

.notice-bad {
    border-left-color: var(--form-error);
    color: var(--form-error);
}
