﻿/* ══════════════════════════════════════════════════════════════════
   UI atoms — small, reusable bits that compose into pages.

   Grouped by kind rather than by file-per-component. A component
   graduates out to its own file only when it gets truly large or
   its concerns diverge from the rest of this group (rough rule: if
   this file crosses ~1500 lines or a section stops sharing tokens
   with its neighbors, promote it).

   Sections (numbering is historical — not all numbers are unique):
     1.  Button (c-button)
     2.  Choice list (c-choice-list / c-choice / c-choice-actions)
     3.  Persona card + grid (c-persona-card)
     3.  Checklist (c-checklist)
     4.  Form error (c-form-error)
         Notice (c-notice)
     5.  Upload (c-upload, app-upload tag helper)
     6.  Readout (c-readout)
     7.  Form field (c-form-field)
     8.  Card (c-card)
     9.  Disclosure (c-disclosure — <details>/<summary> accordion)
     10. Page note (c-page-note — hairline-topped muted page footer)
   ══════════════════════════════════════════════════════════════════ */

@layer components {

    /* ─── 1. Button ───────────────────────────────────────────────── */

    .c-button {
        display: inline-flex;
        align-items: center;
        gap: var(--space-2);
        font: inherit;
        font-weight: 500;
        line-height: 1;
        padding: var(--space-2) var(--space-4);
        border: 1px solid transparent;
        border-radius: var(--radius-pill);
        background: transparent;
        color: inherit;
        cursor: pointer;
        text-decoration: none;
        transition: background var(--dur-base) var(--ease),
                    color var(--dur-base) var(--ease),
                    border-color var(--dur-base) var(--ease);
    }

    .c-button:focus-visible {
        outline: 2px solid var(--color-accent);
        outline-offset: 2px;
    }

    .c-button:disabled,
    .c-button[aria-disabled="true"] {
        opacity: 0.5;
        pointer-events: none;
    }

    /* Variants */

    /* Primary CTA — the page's most important action ("Continue",
       "Subscribe", "Select Plan", etc.). Uses the host's brand colour.
       Hosts rebind --color-accent in their brand layer; unbranded contexts
       fall back to a near-black neutral so the button still reads as primary. */
    .c-button--solid {
        background: var(--color-accent);
        color: var(--color-on-dark);
    }

    .c-button--solid:hover {
        background: var(--color-accent-deep);
    }

    .c-button--ghost {
        border-color: var(--color-line);
    }

    .c-button--ghost:hover {
        border-color: var(--color-ink);
    }

    .c-button--link {
        padding-inline: 0;
        color: var(--color-accent);
        text-decoration: underline;
        text-underline-offset: 0.2em;
    }

    /* A small text action that sits beside content — "Edit details", "Add date", "View" —
       sized to the UI text around it, not to a button, and underlined only on hover. */
    .c-action-link {
        font-size: var(--fs-ui);
        font-weight: 600;
        color: var(--color-accent);
        text-decoration: none;
        white-space: nowrap;
    }

    .c-action-link:hover,
    .c-action-link:focus-visible {
        text-decoration: underline;
        text-underline-offset: 0.2em;
    }

    /* Destructive action — delete / hard-reset / irreversible. First-class
       button variant (app-button variant="Danger" → this class); also used
       by app-confirm.js for the OK button when type=danger. */
    .c-button--danger {
        background: var(--color-danger, #b91c1c);
        border-color: var(--color-danger, #b91c1c);
        color: var(--color-on-danger, #ffffff);
    }

    .c-button--danger:hover,
    .c-button--danger:focus-visible {
        background: var(--color-danger-strong, #991b1b);
        border-color: var(--color-danger-strong, #991b1b);
    }

    /* Sizes */
    .c-button--sm {
        padding: var(--space-1) var(--space-3);
        font-size: var(--fs-ui-sm);
    }

    .c-button--lg {
        padding: var(--space-3) var(--space-5);
        font-size: var(--fs-body-lg);
    }


    /* ─── 2. Choice list ──────────────────────────────────────────────
     Stacked toggle-card list: each card pairs a control (switch /
     radio / checkbox) with a title + description block. Used for
     settings panels — privacy choices, notification prefs, feature
     opt-ins. Grid layout (not flex) is deterministic when controls
     mount via JS after first paint, avoiding the layout shifts that
     a flex-with-fixed-width-toggle pattern can produce. */

    .c-choice-list {
        list-style: none;
        margin: 0 0 var(--space-7);
        padding: 0;
        display: grid;
        gap: var(--space-4);
    }

    .c-choice {
        display: grid;
        grid-template-columns: auto 1fr;
        column-gap: var(--space-5);
        align-items: start;
        padding: var(--space-5);
        background: var(--color-surface-alt);
        border: 1px solid var(--color-line);
        border-radius: var(--radius-md);
    }

    .c-choice__toggle {
        /* No width constraint — let the control size itself.
           Optical-alignment nudge so a switch sits with the first
           line of the title rather than the very top of the card. */
        padding-top: 0.125rem;
    }

    .c-choice__title {
        margin: 0 0 var(--space-1);
        font-family: var(--font-display);
        font-size: var(--fs-body-lg);
        font-weight: 500;
        line-height: 1.2;
        color: var(--color-ink-h3);
    }

    .c-choice__desc {
        margin: 0;
        font-size: var(--fs-body);
        line-height: 1.55;
        color: var(--color-ink-soft);
    }

    /* Action row sitting below a .c-choice-list — right-aligned button
       group, wraps on narrow viewports. */
    .c-choice-actions {
        display: flex;
        gap: var(--space-3);
        justify-content: flex-end;
        flex-wrap: wrap;
    }


    /* ─── 3. Persona card + grid ──────────────────────────────────── */

    /* Used on the onboarding picker (/onboarding) where a new user
       chooses their path: Company / Professional / Credentialing
       Authority / Relying Party. Each card is a self-contained block
       with icon, heading, description, and a primary + secondary
       action row. Responsive grid:
         ≥1200px  — 4 across (wide desktop)
         600-1199 — 2 across (tablet, small desktop; 4 columns at this
                    width squeeze the descriptions too tightly)
         <600px   — 1 across (phone) */

    .c-persona-grid {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: var(--space-5);
    }

    @media (max-width: 1199px) {
        .c-persona-grid {
            grid-template-columns: repeat(2, 1fr);
        }
    }

    @media (max-width: 599px) {
        .c-persona-grid {
            grid-template-columns: 1fr;
        }
    }

    .c-persona-card {
        display: flex;
        flex-direction: column;
        padding: var(--space-6);
        background: var(--color-surface);
        border: 1px solid var(--color-line);
        border-radius: var(--radius-lg, 12px);
        transition: border-color var(--dur-fast) var(--ease),
                    box-shadow var(--dur-fast) var(--ease),
                    transform var(--dur-fast) var(--ease);
    }

    .c-persona-card:hover {
        border-color: var(--color-ink);
        box-shadow: 0 6px 20px -6px rgb(0 0 0 / .08);
    }

    /* Fixed-square icon badge; FontAwesome glyph centered inside. */
    .c-persona-card__icon {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 3rem;
        height: 3rem;
        margin-bottom: var(--space-4);
        font-size: 1.5rem;
        color: var(--color-accent);
        background: color-mix(in srgb, var(--color-accent) 10%, transparent);
        border-radius: var(--radius-md, 8px);
    }

    .c-persona-card__title {
        margin: 0 0 var(--space-2);
        font-family: var(--font-display);
        font-size: var(--fs-heading);
        font-weight: 500;
        line-height: 1.2;
        color: var(--color-ink-h3);
    }

    /* flex: 1 pushes the action row to the bottom so buttons align
       across cards even when descriptions differ in length. */
    .c-persona-card__desc {
        flex: 1;
        margin: 0 0 var(--space-5);
        font-size: var(--fs-body);
        line-height: 1.5;
        color: var(--color-ink-soft);
    }

    .c-persona-card__actions {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-4);
    }

    .c-persona-card__learn {
        font-size: var(--fs-ui-sm);
        color: var(--color-accent);
        text-decoration: none;
        white-space: nowrap;
    }

    .c-persona-card__learn:hover,
    .c-persona-card__learn:focus-visible {
        text-decoration: underline;
        text-underline-offset: 0.2em;
    }

    /* .c-persona-card--unavailable and .c-persona-card__unavailable
       live in the host (AfricaDocumentsWebSite/wwwroot/css/custom/) —
       they're AD-specific until another product needs the sales-gated
       persona variant. */

    /* ─── 2b. Country-unavailable hero ───────────────────────────────
       Used by Commerce/CommerceCountry/CountrySalesUnavailable.cshtml.
       Forward-looking conversion-recovery moment (user came with buying
       intent; the page tells them "not yet, here's what's next"). Pairs
       with .c-persona-card below for the action cards. Host-agnostic,
       semantic tokens only — country names render in --color-accent. */

    .c-unavailable {
        max-width: 56rem;
        margin-inline: auto;
        padding: var(--space-6) 0 var(--space-8);
    }

    .c-unavailable__heading {
        font-family: var(--font-display);
        font-weight: 400;
        font-size: clamp(2.25rem, 5vw, 4rem);
        line-height: 1.05;
        letter-spacing: -0.02em;
        margin: 0 0 var(--space-5);
        color: var(--color-ink);
    }

    .c-unavailable__heading em {
        font-style: italic;
        font-weight: 400;
        color: var(--color-accent);
    }

    .c-unavailable__lede {
        font-size: var(--fs-body-lg);
        line-height: 1.55;
        color: var(--color-ink-soft);
        max-width: 56ch;
        margin: 0;
    }

    /* ─── 3. Checklist ────────────────────────────────────────────────
       Tick + label list. Used in marketing pages (homepage, trust
       center) and in the wizard welcome step. */

    .c-checklist {
        list-style: none;
        margin: 0;
        padding: 0;
    }

    .c-checklist__item {
        padding: var(--space-4) 0;
        border-top: 1px solid var(--color-line);
        display: flex;
        align-items: center;
        gap: var(--space-4);
        font-size: var(--fs-ui);
    }

    .c-checklist__item:last-child {
        border-bottom: 1px solid var(--color-line);
    }

    .c-checklist__tick {
        width: 1.25rem;
        height: 1.25rem;
        border-radius: var(--radius-circle);
        background: var(--color-accent);
        color: var(--color-on-dark);
        display: grid;
        place-items: center;
        font-size: var(--fs-caption);
        flex-shrink: 0;
    }

    /* ─── 4. Form error ───────────────────────────────────────────────
       Form-level error callout — emitted by the <app-form-error> tag
       helper. Sits at the top of a form to announce submission errors
       (validation failures, server problems, network errors). Field-level
       errors live next to their input via <app-form-field-wrapper>; this
       is the global "something went wrong with this submission" target.

       Visual treatment: left-stripe + tinted background + error-deep
       text — the same shape as .c-wizard__warning but in error red
       rather than warn amber. No icon; modern form-error convention
       (Stripe / Sumsub / Onfido / GOV.UK) skips it because the visual
       treatment alone is sufficient signal.

       role="alert" on the element gives screen-reader announcement when
       content changes. The :empty rule auto-hides the element when
       there's no error content (defensive — current JS helpers also set
       display explicitly, but :empty protects against future callers
       that forget to). */

    .c-form-error {
        padding: var(--space-3) var(--space-4);
        border-left: 4px solid var(--color-error);
        background: var(--color-error-soft);
        border-radius: var(--radius-sm);
        color: var(--color-error-deep);
        font-size: var(--fs-body);
        font-weight: 500;
        line-height: var(--lh-normal);
        margin-bottom: var(--space-5);
    }

    .c-form-error:empty {
        display: none;
    }

    /* ─── Notice ──────────────────────────────────────────────────────
       Generic informational / state callout. Same structural pattern as
       c-form-error (left-stripe + soft tint + deep text), tone-by-modifier.
       Default: info. Modifiers: --warn, --danger. (c-form-error keeps its own
       error treatment — that one carries role="alert" and JS-driven content,
       where this is static copy the server rendered.) */

    .c-notice {
        padding: var(--space-3) var(--space-4);
        border-left: 4px solid var(--color-info);
        background: var(--color-info-soft);
        border-radius: var(--radius-sm);
        color: var(--color-info-deep);
        font-size: var(--fs-body);
        line-height: var(--lh-normal);
        margin-bottom: var(--space-5);
    }

    .c-notice--warn {
        border-left-color: var(--color-warn);
        background: var(--color-warn-soft);
        color: var(--color-warn-deep);
    }

    .c-notice--danger {
        border-left-color: var(--color-error);
        background: var(--color-error-soft);
        color: var(--color-error-deep);
    }

    /* ─── Usage meter (c-meter) ────────────────────────────────────────
       Consumption of a metered quota (seats, storage, …) against a limit:
       a neutral bordered panel with a count, a progress bar, and a
       contextual message when near/at the limit. NOT a content card
       (c-card) or a notice (c-notice) — state colour lives on the bar,
       the count, and the alert (--warn nearing the limit, --full at it). */
    .c-meter {
        border: 1px solid var(--color-line);
        border-radius: var(--radius-md);
        padding: var(--space-3) var(--space-4);
        font-size: var(--fs-ui);
    }

    .c-meter__row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-4);
    }

    /* .c-meter__body is the block holding the count/detail line + the progress bar.
       By default it sizes to its text (so the bar is only as wide as the text).
       The --expand modifier makes it fill the row so the bar spans the full
       container width — more readable, used inside the capacity cards. */
    .c-meter--expand .c-meter__body {
        flex: 1;
        min-width: 0;
    }

    .c-meter__count {
        font-weight: 600;
    }

    .c-meter__detail {
        color: var(--color-ink-mute);
        font-size: var(--fs-ui-sm);
    }

    .c-meter__bar {
        height: 4px;
        margin-top: var(--space-2);
        background: var(--color-line);
        border-radius: var(--radius-pill);
        overflow: hidden;
    }

    .c-meter__fill {
        height: 100%;
        background: var(--color-success);
        border-radius: var(--radius-pill);
    }

    .c-meter--warn .c-meter__fill {
        background: var(--color-warn);
    }

    .c-meter--warn .c-meter__count {
        color: var(--color-warn-deep);
    }

    .c-meter--full .c-meter__fill {
        background: var(--color-error);
    }

    .c-meter--full .c-meter__count {
        color: var(--color-error-deep);
    }

    .c-meter__alert {
        display: flex;
        /* flex-start, not center: inside a usage tile the message always wraps to
           two or more lines, and centring floats the icon halfway down the
           paragraph instead of sitting beside the first line. */
        align-items: flex-start;
        gap: var(--space-2);
        margin-top: var(--space-2);
        padding: var(--space-2) var(--space-4);
        border-radius: var(--radius-md);
        background: var(--color-warn-soft);
        color: var(--color-warn-deep);
    }

    .c-meter--full .c-meter__alert {
        background: var(--color-error-soft);
        color: var(--color-error-deep);
    }

    .c-meter__alert a {
        color: inherit;
        text-decoration: underline;
        font-weight: 600;
    }

    /* ─── 5. Upload (app-upload tag helper) ───────────────────────────
       Two-block form: idle (file picker + actions) and in-flight
       (progress bar + status label). JS toggles which is visible.

       Real upload progress drives the determinate bar; once bytes are
       sent the bar goes indeterminate (sliding stripe) while server-side
       processing runs. */

    /* width:100% stops .app-section's flex `align-items:flex-start` from
       shrinking the widget to content width; max-width caps it at a usable
       form width. NO margin auto — it left-aligns with the rest of the page
       instead of centering. (Onboarding's .c-wizard column governs that shell;
       this cap just keeps the field usable in the wider app shell.) */
    .c-upload {
        width: 100%;
        max-width: 44rem;
    }

    /* Left-aligned content column for KYC step / form pages in the app shell.
       The app's .c-page is full-width, so without this the editor form fields
       balloon across the whole screen. Caps the column at the onboarding
       wizard width (44rem) and does NOT center — content stays at the page's
       left edge. Wrap a page's <app-section> content in it. */
    .c-form-column {
        width: 100%;
        max-width: 44rem;
    }

    .c-upload__field {
        display: flex;
        flex-direction: column;
        gap: var(--space-2);
    }

    .c-upload__field-label {
        font-size: var(--fs-ui);
        font-weight: 500;
    }

    .c-upload__field-hint {
        font-size: var(--fs-ui-sm);
        color: var(--color-ink-mute);
        margin: 0;
    }

    .c-upload__field input[type="file"] {
        padding: var(--space-3);
        border: 1px dashed var(--color-line);
        border-radius: var(--radius-sm);
        background: var(--color-surface-alt);
        width: 100%;
    }

    .c-upload__actions {
        display: flex;
        gap: var(--space-3);
        justify-content: flex-end;
        margin-top: var(--space-6);
    }

    .c-upload__progress {
        display: flex;
        flex-direction: column;
        gap: var(--space-3);
        padding-block: var(--space-7);
        align-items: stretch;
        text-align: center;
    }

    .c-upload__progress progress {
        width: 100%;
        height: 0.5rem;
        border: none;
        border-radius: var(--radius-pill);
        background: var(--color-line);
        overflow: hidden;
        appearance: none;
    }

    .c-upload__progress progress::-webkit-progress-bar {
        background: var(--color-line);
        border-radius: var(--radius-pill);
    }
    .c-upload__progress progress::-webkit-progress-value {
        background: var(--color-accent);
        border-radius: var(--radius-pill);
        transition: width var(--dur-fast) var(--ease-out);
    }
    .c-upload__progress progress::-moz-progress-bar {
        background: var(--color-accent);
        border-radius: var(--radius-pill);
    }

    /* Indeterminate during post-upload phases — sliding stripe. */
    .c-upload__progress progress:indeterminate {
        background: linear-gradient(
            90deg,
            var(--color-line) 0%,
            var(--color-accent) 50%,
            var(--color-line) 100%
        );
        background-size: 200% 100%;
        animation: c-upload-progress-indeterminate 1.5s linear infinite;
    }
    .c-upload__progress progress:indeterminate::-webkit-progress-bar {
        background: transparent;
    }
    .c-upload__progress progress:indeterminate::-webkit-progress-value {
        background: transparent;
    }
    .c-upload__progress progress:indeterminate::-moz-progress-bar {
        background: transparent;
    }

    @keyframes c-upload-progress-indeterminate {
        0%   { background-position: 200% 0; }
        100% { background-position: -200% 0; }
    }

    .c-upload__progress-label {
        font-size: var(--fs-ui);
        color: var(--color-ink-soft);
        margin: 0;
    }

    @media (max-width: 48rem) {
        .c-upload__actions {
            flex-direction: column-reverse;
        }
        .c-upload__actions .c-button {
            width: 100%;
            text-align: center;
            justify-content: center;
        }
    }

    /* ─── 6. Readout ──────────────────────────────────────────────────
       Definition-list-style key/value display for read-only record
       summaries. Container-independent: rows stay as rows regardless
       of where the readout is dropped. Collapses to stacked
       label/value at narrow viewports.
       ─────────────────────────────────────────────────────────────── */

    .c-readout {
        display: flex;
        flex-direction: column;
        gap: var(--space-2);
    }

    .c-readout__row {
        display: flex;
        gap: var(--space-3);
    }

    .c-readout__label {
        font-size: var(--fs-ui-sm);
        color: var(--color-ink-mute);
        min-width: 12rem;
        flex-shrink: 0;
    }

    @media (max-width: 48rem) {
        .c-readout__row {
            flex-direction: column;
            gap: var(--space-1);
        }

        .c-readout__label {
            min-width: 0;
        }
    }

    /* Responsive grid of readout cards — the data-driven <app-readout-cards>
       renderer over a ReadoutCardCollection. 1→N columns with no media queries:
       one card per row on mobile, more as the viewport allows. Cards size to
       content (align-items: start).

       auto-FILL (not auto-fit): auto-fit COLLAPSES empty tracks, so with only a
       few cards they stretch to swallow all the free space — on a wide screen
       two cards balloon to ~50% each, sparse and far apart, hurting readability.
       auto-fill KEEPS the empty tracks, so cards hold a comfortable ~18–22rem
       reading width and a wide screen simply gets more columns instead of wider
       cards.

       align-self: stretch is REQUIRED — .app-section lays its content out as a
       flex column with align-items: flex-start, so without this the grid box
       shrinks to its content width and collapses to a single column. Same fix
       .c-card itself uses for the same reason. */
    .c-readout-cards {
        display: grid;
        /* --readout-card-min (set inline by <app-readout-cards minCardWidth="..">) can only
           WIDEN the track; max(18rem, ..) floors it so cards never go below the default. */
        grid-template-columns: repeat(auto-fill, minmax(max(18rem, var(--readout-card-min, 18rem)), 1fr));
        gap: var(--space-4);
        align-items: start;
        align-self: stretch;
        width: 100%;
        /* Breathing room above/below the grid so it reads as its own block,
           separated from the surrounding page elements. Matches the inter-card
           gap for a consistent rhythm. */
        margin-block: var(--space-4);
    }

    /* Document-view detail (Company/Professional ViewDocument): the header — document
       title + Activity button — sits above the readout cards, and the button right-aligns
       to the cards' right edge at ANY width. The wrapper hugs the cards (fit-content) and
       the cards flex-wrap, so the button tracks the rightmost card as they wrap. (A
       fit-content wrapper can't use the auto-fill grid — it collapses to one column under
       intrinsic sizing — so the cards switch to flex-wrap for THIS wrapper only; every
       other <app-readout-cards> keeps the shared auto-fill grid untouched.) */
    .app-doc-detail {
        width: fit-content;
        max-width: 100%;
    }
    .app-doc-detail__header {
        width: 100%;
    }
    .app-doc-detail .c-readout-cards {
        display: flex;
        flex-wrap: wrap;
    }
    .app-doc-detail .c-readout-cards .c-card {
        flex: 0 0 max(18rem, var(--readout-card-min, 18rem));
    }

    /* Compact card chrome — tighter padding; the grid gap handles inter-card
       spacing, so suppress .c-card's own margin. */
    .c-readout-cards .c-card {
        /* Denser grid variant — only the spacing differs from the shared shell. */
        margin-bottom: 0;
        padding: var(--space-4);
    }

    /* Compact rows: label left (muted), value right-aligned on the same line;
       long values wrap below the value column, not under the label. Denser than
       the default full-width readout — the 12rem label min-width drops to ~5rem
       so the value gets the room. (Document-properties redesign.) */
    /* Row padding (below) is the only inter-row spacer — no list gap on top of
       it, or the two stack and rows sit too far apart. */
    .c-readout-cards .c-readout {
        gap: 0;
    }
    .c-readout-cards .c-readout__row {
        flex-direction: row;
        gap: var(--space-3);
        padding: var(--space-1) 0;
        font-size: var(--fs-ui-sm);
    }
    .c-readout-cards .c-readout__label {
        /* --readout-label-min (set inline by <app-readout-cards labelMinWidth="..">) can only
           WIDEN; max(5rem, ..) floors it so the label column never goes below the default. */
        min-width: max(5rem, var(--readout-label-min, 5rem));
        flex-shrink: 0;
    }
    .c-readout-cards .c-readout__row dd {
        flex: 1;
        min-width: 0;
        margin: 0;
        overflow-wrap: break-word;
        /* Alignment is per-item, driven by ReadoutItem.ValueAlignment via the
           .c-readout__value--* class below (default left; numbers set Right) —
           NOT a blanket right-align. Value one rung above the 13px label
           (--fs-ui = 14px): the value is the content the user came for; the
           label is a navigation aid. rem-based, so it respects the user's
           browser font-size preference. */
        font-size: var(--fs-ui);
    }

    /* Per-item value alignment, driven by ReadoutItem.ValueAlignment. Default is
       left (the readout norm); numbers/sizes opt into right. */
    .c-readout__value--left    { text-align: left; }
    .c-readout__value--center  { text-align: center; }
    .c-readout__value--right   { text-align: right; }
    .c-readout__value--justify { text-align: justify; }

    /* Quiet, section-marker card titles with a divider — scoped, because the
       global .c-card__title is a large heading used elsewhere. */
    .c-readout-cards .c-card__head {
        margin-bottom: var(--space-3);
        padding-bottom: var(--space-2);
        border-bottom: 1px solid var(--color-line);
    }
    .c-readout-cards .c-card__title {
        /* flex (not inline-flex) so the title fills the head cell, and min-width:0 so
           it can shrink within the flex head — together these let a long title wrap
           instead of forcing the card wider / overflowing its border. */
        display: flex;
        align-items: center;
        gap: var(--space-2);
        min-width: 0;
        font-size: var(--fs-body);
        font-weight: 600;
    }
    .c-readout-cards .c-card__title span {
        /* Break long / unbroken titles (e.g. a lengthy database name) onto the next
           line rather than spilling past the card edge. */
        min-width: 0;
        overflow-wrap: anywhere;
    }
    .c-readout-cards .c-card__title i {
        color: var(--color-ink-mute);
        font-size: 1.1em;
        flex-shrink: 0; /* keep the icon its natural size while the title text wraps */
    }

    /* Optional top-right card-header action (e.g. an Edit pen). The head is
       flex space-between, so it sits hard right of the title. Muted by default,
       accent on hover/focus. */
    .c-readout-cards .c-readout-card__action {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        padding: var(--space-1);
        border: none;
        background: transparent;
        color: var(--color-ink-mute);
        border-radius: var(--radius-sm);
        line-height: 1;
        cursor: pointer;
    }
    .c-readout-cards .c-readout-card__action:hover,
    .c-readout-cards .c-readout-card__action:focus-visible {
        color: var(--color-accent);
        background: var(--color-surface-alt);
    }

    /* A card that spans all columns of the readout grid (e.g. a wide audit card). */
    .c-readout-cards__card--full {
        grid-column: 1 / -1;
    }

    /* ----- app-dialog — native <dialog> modal (the <app-dialog> tag helper) --
       Opened NON-MODALLY (app-dialog.js show(), not showModal) so it stays OUT of the
       browser top layer — that lets Syncfusion popups (which append to <body> and compute
       a z-index above the dialog) render in front, with no reparenting. So the backdrop is
       a real overlay (a top-layer ::backdrop only exists for showModal), and we position
       the dialog ourselves. z-index is high so the dialog clears page content; Syncfusion
       still computes its popups above it. */
    .app-dialog {
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        margin: 0;
        z-index: 1000;
        width: min(32rem, calc(100vw - var(--space-6)));
        max-height: calc(100vh - var(--space-6));
        overflow: auto;
        padding: var(--space-5);
        border: 1px solid var(--color-line);
        border-radius: var(--radius-md, 0.5rem);
        background: var(--color-surface);
        color: var(--color-ink);
    }
    body.app-dialog-open::before {
        content: '';
        position: fixed;
        inset: 0;
        background: rgb(0 0 0 / 0.4);
        z-index: 999;
    }
    .app-dialog__head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-3);
        margin-bottom: var(--space-4);
    }
    .app-dialog__title {
        font-size: var(--fs-body);
        font-weight: 600;
    }
    .app-dialog__close {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        padding: var(--space-1);
        border: none;
        background: transparent;
        color: var(--color-ink-mute);
        border-radius: var(--radius-sm);
        cursor: pointer;
    }
    .app-dialog__close:hover,
    .app-dialog__close:focus-visible {
        color: var(--color-ink);
        background: var(--color-surface-alt);
    }
    /* Stack the form fields with consistent spacing so the native controls
       don't run together. */
    .app-dialog__body form {
        display: flex;
        flex-direction: column;
        gap: var(--space-4);
    }

    /* Monospaced identifier value (ReadoutItem Kind=Code) — codes/reference
       numbers read as identifiers, not prose. */
    .c-readout__code {
        font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
        font-size: var(--fs-ui-sm);
    }

    /* Small status dot + text (ReadoutItem Kind=Status) — the lighter sibling of
       the pill badge, coloured by tone. Same status palette as the badge. */
    .c-readout__status {
        display: inline-flex;
        align-items: center;
        gap: var(--space-2);
    }
    .c-readout__dot {
        width: var(--space-2);
        height: var(--space-2);
        border-radius: 50%;
        flex-shrink: 0;
    }
    .c-readout__dot--neutral { background: var(--color-ink-mute); }
    .c-readout__dot--info    { background: var(--color-info); }
    .c-readout__dot--success { background: var(--color-success); }
    .c-readout__dot--warning { background: var(--color-warn); }
    .c-readout__dot--danger  { background: var(--color-error); }

    /* Generic tone badge for a ReadoutItem with Kind=Badge. Same shape and
       token palette as .app-doc-expiry-pill, but tone-driven (Neutral / Info /
       Success / Warning / Danger) so any readout can use it without coupling to
       a domain. */
    .c-readout__badge {
        display: inline-flex;
        align-items: center;
        gap: var(--space-1);
        padding: var(--space-1) var(--space-2);
        border: 1px solid transparent;
        border-radius: var(--radius-pill);
        font-size: var(--fs-ui-sm);
        font-weight: 500;
        line-height: 1;
        white-space: nowrap;
    }
    .c-readout__badge--neutral { background: var(--color-surface-alt);  color: var(--color-ink-soft);     border-color: var(--color-line); }
    .c-readout__badge--info    { background: var(--color-info-soft);    color: var(--color-info-deep);    border-color: var(--color-info); }
    .c-readout__badge--success { background: var(--color-success-soft); color: var(--color-success-deep); border-color: var(--color-success); }
    .c-readout__badge--warning { background: var(--color-warn-soft);    color: var(--color-warn-deep);    border-color: var(--color-warn); }
    .c-readout__badge--danger  { background: var(--color-error-soft);   color: var(--color-error-deep);   border-color: var(--color-error); }

    /* ─── 7. Form field ───────────────────────────────────────────────
       Editable field cluster — label on top, input below. Container-
       independent: renders the same regardless of where it's dropped.
       Use .c-form-field-row to put two fields side-by-side; collapses
       to stacked at narrow viewports.

       Mirrors the wizard's .c-wizard__field set so anything moving from
       a wizard context to a generic form context can swap class prefixes
       and look identical.
       ─────────────────────────────────────────────────────────────── */

    .c-form-field {
        display: flex;
        flex-direction: column;
        gap: var(--space-2);
    }

    .c-form-field-label {
        font-size: var(--fs-ui);
        font-weight: 500;
    }

    .c-form-field-hint {
        font-size: var(--fs-ui-sm);
        color: var(--color-ink-mute);
    }

    .c-form-field input[type="text"],
    .c-form-field input[type="date"],
    .c-form-field input[type="email"],
    .c-form-field input[type="tel"],
    .c-form-field input[type="number"],
    .c-form-field select,
    .c-form-field textarea {
        width: 100%;
        padding: var(--space-3);
        border: 1px solid var(--color-line);
        border-radius: var(--radius-sm);
        font: inherit;
    }

    .c-form-field input[type="file"] {
        padding: var(--space-3);
        border: 1px dashed var(--color-line);
        border-radius: var(--radius-sm);
        background: var(--color-surface-alt);
        width: 100%;
    }

    .c-form-field--flagged input,
    .c-form-field--flagged select {
        border-color: var(--color-warn);
        box-shadow: 0 0 0 3px var(--color-warn-glow);
    }

    .c-form-field--flagged .c-form-field-flag {
        font-size: var(--fs-ui-sm);
        color: var(--color-warn-deep);
        font-weight: 500;
    }

    .c-form-field-row {
        display: flex;
        gap: var(--space-3);
    }

    .c-form-field-row > .c-form-field {
        flex: 1;
    }

    @media (max-width: 48rem) {
        .c-form-field-row {
            flex-direction: column;
        }
    }

    /* ─── 8. Card ─────────────────────────────────────────────────────
       Boxed content panel with optional head row (title + action link).
       Generic — wraps any content. The head row is not rendered when
       neither title nor action is supplied. Container-independent.
       ─────────────────────────────────────────────────────────────── */

    /* Shared card shell — the readout cards (<app-readout-card> /
       <app-readout-cards>), the wizard cards (.c-wizard__card, incl. the
       registry-extract viewer) and every <app-form-section> render the same
       tinted, bordered panel. One definition so the look can't drift between
       them; the wizard-specific head/title/subtitle rules live in app-c-wizard.css. */
    .c-card,
    .c-wizard__card {
        /* Rebound inside a panel: hairlines take the panel's line so dividers stay
           visible on the tint, and muted text darkens a step to keep AA contrast. */
        --color-line: var(--color-panel-line);
        --color-ink-mute: var(--color-panel-ink-mute);
        border: 1px solid var(--color-panel-line);
        border-radius: var(--radius-md);
        padding: var(--space-5);
        margin-bottom: var(--space-5);
        background: var(--color-panel);
        /* Fill the cross-axis when dropped inside a flex container that doesn't
           stretch its children (the common .app-section sets align-items:
           flex-start) — otherwise sibling cards shrink to their own content and
           render at different widths. No-op in normal block flow. */
        align-self: stretch;
    }

    .c-card__head {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: var(--space-4);
    }

    .c-card__title {
        font-size: var(--fs-heading);
        font-weight: 600;
        margin: 0;
    }

    /* A card with one destination is one link (the stretched-link pattern): the heading's
       <a class="c-card__link"> is the only real link, and its ::after covers the card, so a
       click anywhere goes there while middle-click, new tab and copy link still work. Neither
       the link nor anything between it and the card may be positioned or transformed, or the
       stretch stops at that element. Other controls inside are lifted above it. */
    .c-card--link {
        position: relative;
        cursor: pointer;
        transition: border-color var(--dur-fast) var(--ease),
                    background var(--dur-fast) var(--ease);
    }

    .c-card--link:hover {
        border-color: var(--color-ink);
        background: var(--color-accent-wash);
    }

    .c-card--link :is(a, button, input, select, textarea):not(.c-card__link) {
        position: relative;
        z-index: 1;
    }

    .c-card__link {
        color: inherit;
        text-decoration: none;
    }

    .c-card__link::after {
        content: "";
        position: absolute;
        inset: 0;
        border-radius: var(--radius-md);
    }

    .c-card__link:focus-visible {
        outline: none;
    }

    .c-card__link:focus-visible::after {
        outline: 2px solid var(--color-accent);
        outline-offset: 2px;
    }

    /* ─── 9. Disclosure ───────────────────────────────────────────────
       Native <details>/<summary> accordion styled to the design
       system. Use anywhere a row should expand to reveal more text
       — FAQs, glossary entries, expandable policy clauses,
       "Read more" panels, settings sections. Zero JS.

       Markup:
         <details class="c-disclosure">
             <summary class="c-disclosure__summary">Question</summary>
             <div class="c-disclosure__body">
                 <p>Answer paragraph(s).</p>
             </div>
         </details>

       Rows separate themselves with hairline borders. Use a
       <section class="u-mb-9"> wrapper to group several together. */

    .c-disclosure {
        border-bottom: 1px solid var(--color-line);
    }

    .c-disclosure:first-of-type {
        border-top: 1px solid var(--color-line);
    }

    /* The summary is the disclosure trigger. We suppress the
       browser's default marker on both Blink (list-style) and
       WebKit (::-webkit-details-marker) and provide our own
       chevron via ::after. */
    .c-disclosure__summary {
        list-style: none;
        font-family: var(--font-display);
        font-size: var(--fs-body-lg);
        font-weight: 400;
        color: var(--color-ink);
        padding: var(--space-5) var(--space-2);
        cursor: pointer;
        display: flex;
        align-items: center;
        gap: var(--space-4);
        line-height: 1.3;
        transition: color var(--dur-base) var(--ease);
    }

    .c-disclosure__summary::-webkit-details-marker {
        display: none;
    }

    /* Chevron pointing down when closed, up when open. Pure CSS
       — two adjacent borders rotated 45°. */
    .c-disclosure__summary::after {
        content: "";
        flex-shrink: 0;
        margin-left: auto;
        width: 0.5rem;
        height: 0.5rem;
        border-right: 1.5px solid currentColor;
        border-bottom: 1.5px solid currentColor;
        transform: rotate(45deg) translate(-2px, -2px);
        transition: transform var(--dur-base) var(--ease);
        color: var(--color-ink-mute);
    }

    .c-disclosure[open] > .c-disclosure__summary::after {
        transform: rotate(-135deg) translate(-2px, -2px);
    }

    .c-disclosure__summary:hover,
    .c-disclosure__summary:hover::after {
        color: var(--color-accent);
    }

    .c-disclosure__summary:focus-visible {
        outline: 2px solid var(--color-accent);
        outline-offset: 4px;
        border-radius: 2px;
    }

    /* The expanded body. Constrained reading measure, muted body
       colour, ink-strong emphasis, brand-coloured links. */
    .c-disclosure__body {
        padding: 0 var(--space-2) var(--space-6);
        color: var(--color-ink-soft);
        font-size: var(--fs-body);
        line-height: 1.6;
        max-width: 70ch;
    }

    .c-disclosure__body > * + * {
        margin-top: var(--space-4);
    }

    .c-disclosure__body p {
        margin: 0;
    }

    .c-disclosure__body strong {
        color: var(--color-ink);
        font-weight: 500;
    }

    .c-disclosure__body ul {
        margin: 0;
        padding-left: var(--space-5);
    }

    .c-disclosure__body li {
        margin: 0;
    }

    .c-disclosure__body li + li {
        margin-top: var(--space-2);
    }

    .c-disclosure__body a {
        color: var(--color-accent);
        text-decoration: underline;
        text-underline-offset: 0.2em;
    }

    .c-disclosure__body a:hover {
        color: var(--color-accent-deep);
    }

    @media (prefers-reduced-motion: reduce) {
        .c-disclosure__summary,
        .c-disclosure__summary::after {
            transition: none;
        }
    }

    /* ─── 10. Page note ───────────────────────────────────────────────
       Hairline-topped muted text block at the bottom of a reference
       page — typically contact info or a "for more information"
       footer. Generic; use on any page that needs a low-key
       end-of-content note. */
    .c-page-note {
        margin-top: var(--space-9);
        padding-top: var(--space-6);
        border-top: 1px solid var(--color-line);
        color: var(--color-ink-mute);
        font-size: var(--fs-body-sm);
    }

    .c-page-note p {
        margin: 0;
    }

    .c-page-note a {
        color: var(--color-accent);
        text-decoration: underline;
        text-underline-offset: 0.2em;
    }

    .c-page-note a:hover {
        color: var(--color-accent-deep);
    }

    /* ─── 11. Avatar ──────────────────────────────────────────────────
       Fixed circle holding an identity's initials (or a FontAwesome
       glyph). Lives here rather than in a feature file because any list
       of parties wants it — folder access, company people, KYC party
       lists. Sized in tokens; the caller supplies the text.

       Not composable from utilities: the utility set has no fixed
       width/height classes, and a circle needs both locked to the same
       value or it renders as an ellipse when the initials are wide. */
    .c-avatar {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 auto;
        inline-size: var(--space-6);
        block-size: var(--space-6);
        border-radius: var(--radius-pill);
        background: var(--color-surface-alt);
        color: var(--color-ink-soft);
        font-size: var(--fs-ui-sm);
        font-weight: 600;
        line-height: 1;
        text-transform: uppercase;
        user-select: none;
    }

    /* Denied identities read as blocked at a glance — the row's badge
       says so in words, this says it in colour. */
    .c-avatar--denied {
        background: var(--color-error-soft);
        color: var(--color-error-deep);
    }

    /* <app-breadcrumb>: Company / Profile / Addresses. */

    .c-breadcrumb {
        display: flex;
        flex-wrap: wrap;
        gap: var(--space-2);
        margin: 0 0 var(--space-2);
        padding: 0;
        list-style: none;
        font-family: var(--font-mono);
        font-size: var(--fs-caption);
        letter-spacing: .08em;
        text-transform: uppercase;
        color: var(--color-ink-mute);
    }

    /* The base layer spaces list items apart vertically (li + li), which would drop every
       crumb after the first. */
    .c-breadcrumb > li {
        margin: 0;
    }

    /* The empty alt text keeps screen readers from reading each separator; the list already
       says how many levels there are. */
    .c-breadcrumb > li + li::before {
        content: "/" / "";
        margin-inline-end: var(--space-2);
    }

    .c-breadcrumb a {
        color: inherit;
        text-decoration: none;
    }

    .c-breadcrumb a:hover,
    .c-breadcrumb a:focus-visible {
        color: var(--color-ink);
        text-decoration: underline;
    }
}
