/* ============================================================
   funding.css — the funding app's own stylesheet.

   Loaded AFTER themeV0.01.css (which supplies every colour token and the
   font) and after topbar.css. Nothing here hard-codes a colour: a literal
   hex is invisible to the other skin, which is the rule the theme file sets
   out and this file follows.

   It exists as a FILE rather than the <style nonce> block index.php used to
   carry, because D10 turns one page into five. Five copies of the same rules
   is five places to forget; a linked stylesheet is also covered by
   style-src 'self', cached once, and never at risk of losing its nonce.
============================================================ */

/* ------------------------------------------------------------
   nav — the funding app's own bar, under the sitewide topbar
------------------------------------------------------------ */

.fx-nav {
    display: flex;
    align-items: center;
    gap: 24px;
    flex-wrap: wrap;
    padding: 10px 20px;
    background: var(--panel-alt);
    border-bottom: 1px solid var(--border);
}

.fx-nav__brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-weight: 700;
    color: var(--text-strong);
    text-decoration: none;
}

.fx-nav__mark {
    font-size: 20px;
    color: var(--accent-soft);
}

.fx-nav__list {
    display: flex;
    gap: 18px;
    list-style: none;
    margin: 0;
    padding: 0;
    flex-wrap: wrap;
}

.fx-nav__link {
    color: var(--text-dim);
    text-decoration: none;
}

.fx-nav__link:hover,
.fx-nav__link:focus {
    color: var(--text);
}

.fx-nav__link.is-current {
    color: var(--text-strong);
    font-weight: 600;
}

/* ------------------------------------------------------------
   page shell
------------------------------------------------------------ */

.fx-wrap {
    max-width: 1000px;
    margin: 0 auto;
    padding: 24px 20px 56px;
}

.fx-wrap h1 {
    color: var(--text-strong);
    line-height: 1.25;
    margin: 8px 0 12px;
}

.fx-wrap h2 {
    color: var(--text-strong);
    margin: 32px 0 12px;
    font-size: 20px;
}

.fx-wrap a {
    color: var(--accent-soft);
}

.fx-lede {
    color: var(--text-dim);
    line-height: 1.65;
    max-width: 70ch;
}

/* Breadcrumbs. The visible twin of the BreadcrumbList JSON-LD every entity
   page emits — search engines are told the same trail the reader sees. */
.fx-crumbs {
    font-size: 14px;
    color: var(--text-mute);
    margin-bottom: 4px;
}

.fx-crumbs a {
    color: var(--text-dim);
    text-decoration: none;
}

.fx-crumbs a:hover {
    color: var(--text);
    text-decoration: underline;
}

.fx-crumbs span::after {
    content: "›";
    margin: 0 8px;
    color: var(--border);
}

/* ------------------------------------------------------------
   stat tiles (landing page)
------------------------------------------------------------ */

.fx-stats {
    display: grid;
    gap: 16px;
    margin: 28px 0;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.fx-stat {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 16px;
}

.fx-stat__n {
    display: block;
    font-size: 28px;
    font-weight: 700;
    line-height: 1.1;
    color: var(--text-strong);
}

.fx-stat__l {
    color: var(--text-dim);
    font-size: 14px;
}

/* ------------------------------------------------------------
   entity header + status badge
------------------------------------------------------------ */

.fx-badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
    border: 1px solid var(--border);
    background: var(--panel-light);
    color: var(--text-dim);
    vertical-align: middle;
}

.fx-badge--open {
    color: var(--success);
    border-color: var(--success);
}

.fx-badge--forthcoming {
    color: var(--warn);
    border-color: var(--warn);
}

.fx-badge--closed {
    color: var(--text-mute);
}

/* "Not stated" — the source published no status. Deliberately NOT styled like
   `closed`: reading as closed is the exact misreading this status exists to
   prevent. Dashed border says "no answer here", not "the answer is no". */
.fx-badge--unknown {
    color: var(--text-dim);
    border-style: dashed;
    border-color: var(--text-mute);
}

/* The one-line explanation under the badge. Quiet, but never hidden — it is
   what separates a claim the publisher made from one we worked out. */
.fx-status-basis {
    margin: -4px 0 14px;
    font-size: 13px;
    line-height: 1.6;
    color: var(--text-mute);
    max-width: 70ch;
}

/* ------------------------------------------------------------
   facts table — the key/value block under every entity title
------------------------------------------------------------ */

.fx-facts {
    display: grid;
    grid-template-columns: minmax(9rem, auto) 1fr;
    gap: 10px 20px;
    margin: 20px 0 0;
    padding: 18px 20px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 12px;
}

.fx-facts dt {
    color: var(--text-mute);
    font-size: 14px;
}

.fx-facts dd {
    margin: 0;
    color: var(--text);
}

/* ------------------------------------------------------------
   related-entity lists
------------------------------------------------------------ */

.fx-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 10px;
}

.fx-item {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 16px;
}

.fx-item a {
    text-decoration: none;
    font-weight: 600;
}

.fx-item a:hover {
    text-decoration: underline;
}

.fx-item__meta {
    display: block;
    margin-top: 4px;
    font-size: 14px;
    color: var(--text-mute);
}

.fx-empty {
    color: var(--text-mute);
    font-style: italic;
}

.fx-more {
    margin-top: 12px;
    font-size: 14px;
}

/* ------------------------------------------------------------
   attribution — mandatory, never decorative

   Every entity page renders this from its own payload. The SNPSAP aviso
   legal makes the source citation, the last-update date and the
   dissociation statement obligations; they are small print, not optional
   print, so they are dimmed but never hidden.
------------------------------------------------------------ */

.fx-attr {
    margin-top: 40px;
    padding: 16px 20px;
    background: var(--bg-deep);
    border: 1px solid var(--border-soft);
    border-radius: 10px;
    font-size: 13px;
    line-height: 1.65;
    color: var(--text-mute);
}

.fx-attr h2 {
    font-size: 14px;
    margin: 0 0 6px;
    color: var(--text-dim);
}

.fx-attr p {
    margin: 0 0 4px;
}

.fx-attr__licence {
    display: block;
}

/* ------------------------------------------------------------
   provenance — the exact document behind the page, and how its
   values have moved. Sits directly above the attribution block:
   attribution says who is owed credit, provenance says what can
   be checked. Same quiet register, since neither is the content
   a visitor came for, but both must be reachable without effort.
------------------------------------------------------------ */

.fx-prov {
    margin-top: 32px;
    padding: 16px 20px;
    background: var(--bg-deep);
    border: 1px solid var(--border-soft);
    border-radius: 10px;
    font-size: 13px;
    line-height: 1.65;
    color: var(--text-mute);
}

.fx-prov h2 {
    font-size: 14px;
    margin: 0 0 8px;
    color: var(--text-dim);
}

.fx-prov h3 {
    font-size: 13px;
    margin: 14px 0 6px;
    color: var(--text-dim);
}

.fx-prov__doc {
    display: grid;
    grid-template-columns: minmax(9rem, auto) 1fr;
    gap: 2px 16px;
    margin: 0;
}

.fx-prov__doc dt {
    color: var(--text-dim);
}

.fx-prov__doc dd {
    margin: 0;
    /* Document URLs are long and unbreakable; let them wrap rather than push
       the page into a horizontal scroll on a phone. */
    overflow-wrap: anywhere;
}

.fx-prov__note {
    color: var(--text-mute);
}

.fx-prov__history {
    margin: 0;
    padding-left: 18px;
}

.fx-prov__history li {
    margin-bottom: 3px;
    overflow-wrap: anywhere;
}

.fx-prov__field {
    color: var(--text-dim);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12px;
}

.fx-prov__from {
    text-decoration: line-through;
}

.fx-prov__to {
    color: var(--text-dim);
}

.fx-sources {
    color: var(--text-dim);
    font-size: 14px;
    line-height: 1.7;
    max-width: 80ch;
}

/* ------------------------------------------------------------
   search (D11)
------------------------------------------------------------ */

.fx-search {
    background: var(--panel-alt);
    border: 1px solid var(--border-soft);
    border-radius: 10px;
    padding: 16px;
    margin: 0 0 24px;
}

.fx-search__row {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 12px;
}

.fx-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 140px;
}

/* The keyword box takes whatever the fixed-width selects leave behind. */
.fx-field--grow {
    flex: 1 1 260px;
}

.fx-field > span {
    color: var(--text-dim);
    font-size: 12px;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.fx-field input,
.fx-field select {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font: inherit;
    padding: 8px 10px;
    /* Without this a long <select> option stretches the flex row instead of
       being clipped, and the layout jumps as the country list loads. */
    max-width: 100%;
}

.fx-field input:focus-visible,
.fx-field select:focus-visible {
    outline: 2px solid var(--accent-soft);
    outline-offset: 1px;
}

.fx-search__actions {
    display: flex;
    align-items: center;
    gap: 10px;
}

.fx-btn {
    background: var(--accent-soft);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text-strong);
    cursor: pointer;
    font: inherit;
    padding: 8px 18px;
    text-decoration: none;
}

.fx-btn--quiet {
    background: transparent;
    color: var(--text-dim);
}

.fx-count {
    color: var(--text-dim);
    font-size: 14px;
    margin: 0 0 12px;
}

.fx-list--results .fx-item {
    padding-bottom: 14px;
}

.fx-item__excerpt {
    color: var(--text-mute);
    font-size: 14px;
    line-height: 1.6;
    margin: 6px 0 0;
    max-width: 80ch;
}

.fx-item__prog {
    font-size: 13px;
    margin: 4px 0 0;
}

/* aria-busy is the only signal that a fetch is in flight; fading the block
   makes it visible without moving anything, so results do not jump. */
#fx-results[aria-busy="true"] {
    opacity: 0.55;
    transition: opacity 120ms ease-in;
}

.fx-pager {
    align-items: center;
    display: flex;
    gap: 16px;
    margin-top: 20px;
}

.fx-pager__at {
    color: var(--text-dim);
    font-size: 14px;
}

/* ------------------------------------------------------------
   accounts: bookmarks + saved searches (D13)
------------------------------------------------------------ */

.fx-bookmark {
    margin: 0 0 16px;
}

/* The remove button sits inside a list item that is otherwise a stack of
   text, so the form must not introduce a block break of its own. */
.fx-inline-form {
    display: inline-block;
    margin-top: 6px;
}

.fx-savesearch {
    align-items: flex-end;
    background: var(--panel-alt);
    border: 1px solid var(--border-soft);
    border-radius: 10px;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0 0 20px;
    padding: 12px 16px;
}

.fx-savesearch__done {
    color: var(--text-dim);
    font-size: 14px;
}

/* aria-pressed carries the state for assistive tech; this is the visual half of
   the same fact, so the two cannot drift apart. */
.fx-btn[aria-pressed="true"] {
    border-color: var(--success);
}

/* ------------------------------------------------------------
   mobile
------------------------------------------------------------ */

/* -- the paid AI summary ------------------------------------------------------
   Visually a panel rather than body copy, because the one thing a reader must
   never be unsure of is which words came from the official source and which
   came from a model. Same border/background tokens as the other panels, so it
   reads as part of the page and not as an advertisement. */
.fx-ai {
    margin: 22px 0;
}

.fx-ai-body {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 16px 18px;
}

.fx-ai-title {
    font-size: 1rem;
    margin: 0 0 8px;
}

.fx-ai-body p {
    margin: 0 0 10px;
}

.fx-ai-body p:last-child {
    margin-bottom: 0;
}

/* The provenance line and the "not enough source text" line. Quieter than the
   summary itself — it is a caveat, not a finding. */
.fx-ai-note,
.fx-ai-wait {
    font-size: 0.9rem;
    color: var(--text-dim);
}

@media (max-width: 560px) {
    .fx-savesearch {
        flex-direction: column;
        align-items: stretch;
    }

    /* Every filter on its own line: at this width two side-by-side selects
       leave neither wide enough to read its own option text. */
    .fx-search__row {
        flex-direction: column;
        gap: 10px;
    }

    .fx-field {
        min-width: 0;
    }

    .fx-nav {
        gap: 12px;
        padding: 10px 14px;
    }

    .fx-wrap {
        padding: 18px 14px 40px;
    }

    /* Two columns of key/value do not fit; stack them and keep the label
       tight against its value so the pairing survives the reflow. */
    .fx-facts {
        grid-template-columns: 1fr;
        gap: 2px 0;
    }

    .fx-facts dd {
        margin-bottom: 12px;
    }
}

/* I6 — the alert form. Deliberately a plain stack of labelled rows rather than
   a grid: it has seven fields of very different widths (a two-character country
   code next to a multi-select), and every grid I tried made the short ones look
   broken at some width. Stacking is boring and correct at every size. */
.fx-alert-form {
    background: var(--panel-alt);
    border: 1px solid var(--border-soft);
    border-radius: 10px;
    padding: 14px 16px;
    margin: 12px 0 20px;
}

.fx-alert-form p {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 10px;
}

.fx-alert-form label {
    color: var(--muted);
    font-size: 0.92rem;
    min-width: 8.5rem;
}

.fx-alert-form input[type="text"],
.fx-alert-form input[type="number"],
.fx-alert-form select {
    background: var(--panel);
    border: 1px solid var(--border-soft);
    border-radius: 6px;
    color: inherit;
    font: inherit;
    padding: 6px 8px;
}

/* The multi-select is the one control that needs room to be usable at all. */
.fx-alert-form select[multiple] {
    min-width: 16rem;
}

/* Country switcher. A row of links rather than a <select>: the set is small
   (only countries with a published page appear), it must work without
   JavaScript under the site's CSP, and a link is crawlable where a form control
   is not — these pages exist to be indexed. */
.fx-countrynav {
    align-items: baseline;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    margin: 4px 0 22px;
}

.fx-countrynav__l {
    color: var(--muted);
    font-size: 0.92rem;
}

.fx-countrynav a {
    border: 1px solid var(--border-soft);
    border-radius: 999px;
    padding: 3px 12px;
    text-decoration: none;
}

.fx-countrynav a:hover,
.fx-countrynav a:focus {
    background: var(--panel-alt);
    text-decoration: underline;
}

/* -- W1 workspace: folder + tag filters over the saved list ---------------- */

.fx-ws-filters,
.fx-ws-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    margin: 12px 0;
}

.fx-ws-filters a,
.fx-ws-tags a {
    border: 1px solid var(--border-soft);
    border-radius: 999px;
    padding: 3px 12px;
    text-decoration: none;
    font-size: 0.9rem;
    color: var(--text-dim);
}

.fx-ws-filters a:hover,
.fx-ws-tags a:hover,
.fx-ws-filters a:focus,
.fx-ws-tags a:focus {
    background: var(--panel-alt);
}

.fx-ws-filters a.is-on,
.fx-ws-tags a.is-on {
    border-color: var(--text-strong);
    color: var(--text-strong);
    font-weight: 600;
}

/* Tags are the user's own words, so they read quieter than the folders that
   organise them — a filter row that shouts competes with the list it filters. */
.fx-ws-tags a {
    font-size: 0.82rem;
}

.fx-ws-count {
    font-variant-numeric: tabular-nums;
    color: var(--text-mute);
}

.fx-ws-clear {
    border-style: dashed !important;
}

.fx-ws-folders {
    border: 1px solid var(--border-soft);
    border-radius: 8px;
    padding: 10px 14px;
    margin: 12px 0 18px;
}

.fx-ws-folders > summary {
    cursor: pointer;
    color: var(--text-dim);
    font-size: 0.92rem;
}

.fx-ws-folders .fx-inline-form {
    margin-top: 10px;
}

.fx-ws-field {
    display: inline-flex;
    flex-direction: column;
    gap: 3px;
    font-size: 0.8rem;
    color: var(--text-mute);
}

/* -- W4 deadline calendar -------------------------------------------------- */

.fx-cal-intro { color: var(--text-dim); }

.fx-cal-note {
    color: var(--text-mute);
    font-size: 0.85rem;
    max-width: 62ch;
}

.fx-cal-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin: 16px 0 8px;
}

.fx-cal-head a { text-decoration: none; color: var(--text-dim); }
.fx-cal-head a:hover, .fx-cal-head a:focus { text-decoration: underline; }

.fx-cal {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    margin-bottom: 24px;
}

.fx-cal th {
    text-align: left;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-mute);
    padding: 4px 6px;
    font-weight: 600;
}

.fx-cal td {
    border: 1px solid var(--border-soft);
    vertical-align: top;
    padding: 4px 6px;
    height: 78px;
}

.fx-cal__pad { background: var(--panel-alt); border-color: var(--panel-alt) !important; }

.fx-cal__n { display: block; font-size: 0.78rem; color: var(--text-mute); }

.fx-cal__day.is-today { outline: 2px solid var(--text-strong); outline-offset: -2px; }
.fx-cal__day.has-items { background: var(--panel); }

/* A deadline in a month cell has to be readable at a glance and cannot be
   allowed to stretch the column — the grid is fixed so twelve deadlines on one
   day do not make that week three screens tall. */
.fx-cal__item {
    display: block;
    font-size: 0.72rem;
    line-height: 1.35;
    margin-top: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-decoration: none;
}

.fx-cal__why { color: var(--text-mute); }

.fx-cal-feed {
    width: 100%;
    max-width: 62ch;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.78rem;
    padding: 6px 8px;
    border: 1px solid var(--border-soft);
    border-radius: 6px;
    background: var(--panel-alt);
    color: inherit;
}

.fx-sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

@media (max-width: 620px) {
    /* The month grid stops being readable long before this; the list below it
       carries the same information in a shape that survives a phone. */
    .fx-cal { display: none; }
    .fx-cal-head { justify-content: flex-start; }
}

/* ── W2: the application checklist ────────────────────────────────────────
   No JavaScript anywhere in this block — every control is a submit button in
   one form, which is what the strict CSP wants and what makes the feature work
   with scripting off. */

/* Used by funding_deadline_html()'s "(time not stated)" since migration 024 and
   never defined, so that caveat has been rendering at full body weight on every
   call page, search row and calendar entry. Found by adding the second user. */
.fx-muted { color: var(--text-mute); }

.fx-checklist { margin: 0 0 1rem; }

.fx-checklist__group {
    border: 1px solid var(--border-soft);
    border-radius: 8px;
    padding: 0.5rem 0.9rem 0.8rem;
    margin: 0 0 0.8rem;
    background: var(--panel-alt);
}

.fx-checklist__group legend {
    padding: 0 0.4rem;
    font-weight: 600;
    color: var(--text-strong);
}

.fx-checklist__item {
    display: grid;
    grid-template-columns: 1.4rem 1fr auto;
    align-items: baseline;
    gap: 0.1rem 0.4rem;
    padding: 0.35rem 0;
    border-top: 1px solid var(--border-soft);
}
.fx-checklist__item:first-of-type { border-top: 0; }

.fx-checklist__item label { cursor: pointer; }

/* Struck through rather than hidden or moved: a done item that vanishes takes
   the sense of progress with it, and one that jumps to the bottom loses the
   reader's place in a list they are working down. */
.fx-checklist__item.is-done > label { color: var(--text-mute); text-decoration: line-through; }

.fx-checklist__scope {
    grid-column: 3;
    grid-row: 1;
    font-size: 0.72rem;
    color: var(--text-mute);
    white-space: nowrap;
}

.fx-checklist__detail {
    grid-column: 2 / -1;
    margin: 0.15rem 0 0;
    font-size: 0.85rem;
    color: var(--text-dim);
    /* The source's own words, quoted. The rule marks where our sentence stops
       and the portal's begins — the distinction the whole feature rests on. */
    border-left: 2px solid var(--border);
    padding-left: 0.6rem;
}

.fx-checklist__ref { color: var(--text-mute); font-size: 0.78rem; white-space: nowrap; }

.fx-checklist__drop {
    grid-column: 3;
    background: none;
    border: 0;
    padding: 0 0.2rem;
    font: inherit;
    font-size: 0.72rem;
    color: var(--text-mute);
    cursor: pointer;
    text-decoration: underline;
}
.fx-checklist__drop:hover, .fx-checklist__drop:focus { color: var(--text); }

@media (max-width: 620px) {
    /* The scope note and the drop control share column 3 on a wide screen; at
       this width there is no column 3 to share. */
    .fx-checklist__item { grid-template-columns: 1.4rem 1fr; }
    .fx-checklist__scope, .fx-checklist__drop { grid-column: 2; }
}
