/* donations.css — the donation page's styling (Stage 14 round 8a).
   Match: 4.DOCUMENTS/STAGES/Stage 14 - Donation Page/
          donation-page-mockup.html + campaign-setup-mockup.html's
          preview, using brand tokens or fixed neutrals for every
          colour, never typed values.

   Brand tokens driving every rule below:
     --color-bg               brand's light background colour
     --color-text             body ink
     --color-text-muted       secondary ink
     --color-primary          brand main (accent / selected / button)
     --color-primary-contrast ink on primary / on dark
     --color-border           panel borders
     --color-dark             brand's dark colour (band, demo bar)
     --font-heading           headings
     --font-body              body
     --radius                 corner radius

   Per-campaign overlay from `page_options` is emitted on :root in
   donations/index.php via nine semantic look settings (round 8a):
     --dp-band-bg / -ink / -line     — heading band
     --dp-page-bg / -ink              — page background
     --dp-card-bg / -ink / -line      — form + summary cards
     --dp-tile-bg / -ink / -line      — amount + fund tiles
     --dp-sel-bg  / -ink              — selected amount / fund /
                                        progress bar fill
     --dp-btn-bg  / -ink              — Give button
     --dp-form-shadow                 — form shadow (none / subtle)
     --dp-picture-focus               — image object-position
     --dp-band-track                  — goal-bar track inside the band

   `ink` means dark or light text, picked by WCAG luminance against
   its surface's background. Staff never pick text colours. */

:root {
    /* Fallbacks so the sheet reads correctly if the inline overlay
       is missing (e.g. a brand with no options set yet). Mirror the
       DEFAULTS in PageOptionsRepo (white / main / white etc.). */
    --dp-band-bg:  var(--color-dark);
    --dp-band-ink: var(--color-primary-contrast);
    --dp-band-ink-muted: color-mix(in srgb, var(--color-primary-contrast) 72%, var(--color-dark));
    --dp-band-line: color-mix(in srgb, var(--color-primary-contrast) 18%, transparent);
    --dp-band-track: color-mix(in srgb, var(--color-primary-contrast) 20%, transparent);

    --dp-page-bg:  #ffffff;
    --dp-page-ink: var(--color-text);
    --dp-page-ink-muted: color-mix(in srgb, var(--color-text) 72%, #ffffff);

    --dp-card-bg:  #ffffff;
    --dp-card-ink: var(--color-text);
    --dp-card-ink-muted: color-mix(in srgb, var(--color-text) 72%, #ffffff);
    --dp-card-line: var(--color-border);

    --dp-tile-bg:  #ffffff;
    --dp-tile-ink: var(--color-text);
    --dp-tile-ink-muted: color-mix(in srgb, var(--color-text) 72%, #ffffff);
    --dp-tile-line: var(--color-border);

    --dp-fund-bg:  #ffffff;
    --dp-fund-ink: var(--color-text);
    --dp-fund-ink-muted: color-mix(in srgb, var(--color-text) 72%, #ffffff);
    --dp-fund-line: var(--color-border);

    --dp-sel-bg:   var(--color-primary);
    --dp-sel-ink:  var(--color-primary-contrast);
    --dp-sel-ink-muted: color-mix(in srgb, var(--color-primary-contrast) 85%, var(--color-primary));
    --dp-sel-ring: 0 0 0 0 transparent;
    --dp-btn-ring: 0 0 0 0 transparent;

    --dp-btn-bg:   var(--color-primary);
    --dp-btn-ink:  var(--color-primary-contrast);
    --dp-btn-ink-muted: color-mix(in srgb, var(--color-primary-contrast) 85%, var(--color-primary));

    --dp-form-shadow: 0 10px 30px color-mix(in srgb, var(--color-dark) 10%, transparent);
    --dp-picture-focus: center center;

    /* Widen the shared --max-content-width on this page only so the
       site header, dark band, form row and site footer all line up
       in the same 70rem column. */
    --max-content-width: 70rem;
}
body { background: var(--dp-page-bg); color: var(--dp-page-ink); }

/* Let go of the content cap on .site-main's wrapper so sections can
   paint their own full-width backgrounds (dark band, below zone).
   layout.php's `main.site-main` holds the page body; stripping its
   padding lets the dark band go edge-to-edge. Header and footer
   content stays at --max-content-width via their own inner
   wrappers (now 70rem thanks to the override above). */
.site-main {
    max-width: none;
    padding: 0;
}
.dp-wrap {
    max-width: var(--max-content-width);
    margin: 0 auto;
    padding: 0 1.5rem;
}
@media (max-width: 560px) {
    .dp-wrap { padding: 0 1rem; }
}

/* ------------------------------------------------------------------ */
/* ABOVE THE FORM — picture + dark band.                               */
/* ------------------------------------------------------------------ */

/* Wide banner. Shown above the band when it is first in the saved
   order, and below the band when it comes after. Full-width image;
   cover-fit so the top and bottom are trimmed. */
.dp-banner {
    width: 100%;
    display: block;
    overflow: hidden;
    background: var(--color-border);
}
.dp-banner img {
    display: block;
    width: 100%;
    height: 360px;
    object-fit: cover;
    object-position: var(--dp-picture-focus);
}
@media (max-width: 899px) {
    .dp-banner img { height: 220px; }
}

/* Dark band. Holds the heading, intro and goal bar (and the beside
   picture when picked). Background and text colour come from the
   look settings: --dp-band-bg (chosen from heading_band: dark / main
   / light) and --dp-band-ink (picked automatically by contrast). */
.dp-band {
    background: var(--dp-band-bg);
    color: var(--dp-band-ink);
}
.dp-band .dp-wrap {
    padding-top: 2.75rem;
    padding-bottom: 3rem;
}
.dp-band-inner {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem;
}
.dp-band.has-beside .dp-band-inner {
    grid-template-columns: minmax(0, 1fr) 20rem;
    align-items: center;
}
@media (max-width: 899px) {
    .dp-band.has-beside .dp-band-inner { grid-template-columns: 1fr; }
}
.dp-band-text {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
.dp-band-text .dp-heading {
    margin: 0;
    font-family: var(--font-heading);
    font-weight: 400;
    font-size: clamp(2.125rem, 5vw, 3.25rem);
    line-height: 1.08;
    color: var(--dp-band-ink);
}
.dp-band-text .dp-intro {
    margin: 0;
    font-size: 1.125rem;
    line-height: 1.5;
    max-width: 62ch;
    color: var(--dp-band-ink);
    opacity: .92;
}

/* Goal bar inside the band — mockup's layout. */
.dp-band-text .dp-progress {
    max-width: 35rem;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    margin: .25rem 0 0;
}
.dp-band-text .dp-progress-numbers {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .75rem;
    font-size: .875rem;
    color: var(--dp-band-ink);
    opacity: .92;
}
.dp-band-text .dp-progress-numbers strong {
    color: var(--dp-band-ink);
    opacity: 1;
    font-size: 1.125rem;
    font-weight: 600;
}
.dp-band-text .dp-progress-track {
    height: 8px;
    background: var(--dp-band-track);
    border-radius: 99px;
    overflow: hidden;
}
.dp-band-text .dp-progress-fill {
    height: 100%;
    background: var(--dp-sel-bg);
    border-radius: 99px;
    transition: width .3s;
}

/* Beside picture: inside the band on the right at wide screens,
   stacked below the text on a phone. */
.dp-band-figure {
    display: flex;
    justify-content: center;
}
.dp-band-figure img {
    display: block;
    width: 100%;
    max-width: 20rem;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    object-position: var(--dp-picture-focus);
    border-radius: var(--radius);
}

/* ------------------------------------------------------------------ */
/* FIXED FORM BLOCK — form left, summary right.                        */
/* ------------------------------------------------------------------ */

.dp-form-area {
    background: var(--dp-page-bg);
}
.dp-form-area .dp-wrap {
    padding-top: 2.5rem;
    padding-bottom: 2.5rem;
}
.dp-form-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 20rem;
    gap: 1.75rem;
    align-items: start;
}
@media (max-width: 899px) {
    .dp-form-row {
        grid-template-columns: 1fr;
    }
    /* Summary stacks above the form on a phone. Order flip because
       the DOM lists summary first anyway. */
    .dp-form-row .dp-summary { order: -1; position: static; }
}

/* The form card. Background from form_cards; ink chosen by contrast.
   Round 8a Rob: "subtle shadow around the donate form would be a
   good option too". --dp-form-shadow is 'none' or a subtle lift. */
.dp-card {
    background: var(--dp-card-bg);
    color: var(--dp-card-ink);
    border: 1px solid var(--dp-card-line);
    border-radius: var(--radius);
    padding: 1.75rem;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    margin: 0;
    box-shadow: var(--dp-form-shadow);
}
/* Round 8b.2 fault 5 fix: the form card's own `gap` only applies
   between its direct children. The <form> was that single child
   so .dp-group siblings inside stacked back-to-back with no
   space — Rob flagged the missing gap between "Phone and address"
   and "Give in memory or honor". A matching flex column on the
   form itself gives every label the same space above it. */
.dp-card > form {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}
@media (max-width: 560px) {
    .dp-card { padding: 1.25rem; }
}

/* Label + control group. Each top-level item in the form card is a
   .dp-group so the gap between groups is consistent (round 8a close
   rule 5). Inside a group, the label-to-control gap is tight. */
.dp-group {
    display: flex;
    flex-direction: column;
    gap: .625rem;
}
.dp-group.dp-checks { gap: .375rem; }

.dp-note {
    color: var(--dp-card-ink-muted);
    font-size: .875rem;
    margin: 0;
}

.dp-label {
    display: block;
    font-weight: 600;
    font-size: .875rem;
    margin: 0;
    color: var(--dp-card-ink);
}

/* Segmented toggle (frequency, payment method). Round 8a close
   rule 2: these never follow the tile colour — they are a FIXED
   light style that reads on any card colour. Fixed values:
     track    = --color-border (brand's own soft panel colour)
     chip     = --color-primary-contrast (white)
     text     = --color-text (dark)
   On a brand where --color-border is a dark colour, the system
   defaults still land on a visible pair. */
.dp-freq-fixed {
    display: flex;
    background: var(--color-border);
    border-radius: 10px;
    padding: 4px;
    gap: 4px;
}
.dp-freq-fixed button {
    flex: 1;
    min-height: 44px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    font: inherit;
    font-weight: 600;
    font-size: .9375rem;
    color: var(--color-text);
    cursor: pointer;
}
.dp-freq-fixed button.on {
    background: var(--color-primary-contrast);
    color: var(--color-text);
    box-shadow: 0 1px 3px color-mix(in srgb, var(--color-dark) 15%, transparent);
}

/* Amounts grid. The Other tile sits in the last cell and spans
   whatever columns are left on its row so the grid never shows a
   gap (span is set per preset count via an inline grid-column on
   the <div> that wraps the Other button + input). When picked, the
   button swaps for an inline input in the same cell. The muted
   colour on `.other` is scoped `:not(.on)` so the selected state's
   contrast colour always wins over the "unselected other" colour,
   keeping the text readable. */
.dp-amounts {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
}
.dp-amounts button,
.dp-amt {
    min-height: 52px;
    border: 1px solid var(--dp-tile-line);
    border-radius: 10px;
    background: var(--dp-tile-bg);
    font: inherit;
    font-size: 1.0625rem;
    font-weight: 700;
    color: var(--dp-tile-ink);
    cursor: pointer;
}
.dp-amt.on {
    background: var(--dp-sel-bg);
    border-color: var(--dp-sel-bg);
    color: var(--dp-sel-ink);
    /* Round 8a close rule 4: if the selected fill happens to match
       the tile colour (stored data has them equal), the PHP overlay
       sets --dp-sel-ring to a 3px ring in the card bg so the pick
       is still clearly visible. Normally the ring is transparent. */
    box-shadow: var(--dp-sel-ring);
}
.dp-amt.other:not(.on) {
    font-size: 1rem;
    font-weight: 600;
    color: var(--dp-tile-ink-muted);
}
@media (max-width: 560px) {
    .dp-amounts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Other-amount cell. Wraps the Other button and the inline input
   so they share one grid cell. On click the cell toggles .is-input;
   the button hides and the input shows in its place at the same
   width and height.

   Round 8a B5 fix: the previous build made the wrapper span the
   grid correctly (grid-column: span N), but did not stretch the
   inner button to fill the wide cell — so on the live page the
   Other button rendered at natural width and looked tiny inside
   an empty wide area. Setting `display: grid` on the wrapper
   makes its single visible child (button or input) fill the cell
   by default. The input gets its own width:100% rule too so the
   stretch works whether the browser treats grid-item sizing
   generously or strictly. */
.dp-amt-other-cell {
    display: grid;
    position: relative;
}
.dp-amt-other-cell > .dp-amt {
    width: 100%;
}
.dp-amt-other-cell .dp-amt-other-input { display: none; }
.dp-amt-other-cell.is-input > .dp-amt { display: none; }
.dp-amt-other-cell.is-input .dp-amt-other-input {
    display: block;
    width: 100%;
    min-height: 52px;
    border: 1px solid var(--dp-sel-bg);
    border-radius: 10px;
    padding: 0 .875rem;
    text-align: center;
    font: inherit;
    font-size: 1.0625rem;
    font-weight: 700;
    color: var(--color-text);
    background: var(--color-primary-contrast);
    outline: 2px solid var(--dp-sel-bg);
    outline-offset: -2px;
}
.dp-amt-other-cell.is-input .dp-amt-other-input::placeholder {
    color: var(--color-text-muted);
    font-weight: 500;
}
/* Hide the number input's native spin buttons so the tile reads as
   a clean amount box, not a stepper. */
.dp-amt-other-input::-webkit-inner-spin-button,
.dp-amt-other-input::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.dp-amt-other-input { -moz-appearance: textfield; appearance: textfield; }

/* Fund picker (B4 rule: shown only when 2+ funds). Round 8a close:
   fund_cards is a SEPARATE option from amount_tiles, so staff can
   paint fund tiles differently. --dp-fund-bg / -ink / -ink-muted
   / -line come from the fund_cards choice. */
.dp-funds {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    /* Round 8b.2 fix (fault 2): confine any sibling fund card's
       outline + box-shadow to its own grid cell so the .on card's
       outline never visually overlaps the next card. */
    isolation: isolate;
}
.dp-fund {
    text-align: left;
    border: 2px solid var(--dp-fund-line);
    border-radius: 10px;
    background: var(--dp-fund-bg);
    padding: .75rem .875rem;
    font: inherit;
    color: var(--dp-fund-ink);
    cursor: pointer;
    min-width: 0;
}
.dp-fund.on {
    border-color: var(--dp-sel-bg);
    /* Round 8b.2 fix: the selected state uses a 2px border rather
       than border + outline; the outline-offset:-2px of round 8a
       sat ON TOP of the first-row text at narrow widths and read
       as overlap. The ring below is only on when stored data has
       selected_fill matching the fund colour (round 8a close
       rule 4), extended in round 8b.2 to form_cards. */
    box-shadow: var(--dp-sel-ring);
}
.dp-fund b {
    display: block;
    font-size: .9375rem;
    font-weight: 600;
    margin-bottom: 2px;
    color: var(--dp-fund-ink);
}
.dp-fund span {
    display: block;
    font-size: .8125rem;
    color: var(--dp-fund-ink-muted);
    line-height: 1.4;
}
@media (max-width: 560px) {
    .dp-funds { grid-template-columns: 1fr; }
}

/* Field stack (details, inputs).
   B3 rule (round 8a): fields are always white with a visible
   border, whatever the card colour. The background and ink here
   are the brand's --color-primary-contrast + --color-text, not
   the --dp-card-* vars, so a brand-dark card still shows white
   inputs with dark ink. */
.dp-f { margin: 0; }
.dp-f input,
.dp-f select,
.dp-f textarea {
    width: 100%;
    min-height: 48px;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    padding: 0 .875rem;
    font: inherit;
    font-size: 1rem;
    color: var(--color-text);
    background: var(--color-primary-contrast);
}
.dp-f textarea { min-height: 70px; padding: .75rem .875rem; resize: vertical; }
.dp-f input:focus,
.dp-f select:focus,
.dp-f textarea:focus {
    outline: 2px solid var(--dp-sel-bg);
    outline-offset: 2px;
    border-color: transparent;
}
.dp-f input::placeholder,
.dp-f textarea::placeholder { color: var(--color-text-muted); }
.dp-f-row2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}
@media (max-width: 560px) { .dp-f-row2 { grid-template-columns: 1fr; } }

/* Tick-box rows (Rob: "there is no fcus on the check option they
   should be shaded or white so they stand out"). Custom checkbox:
   a white 20x20 box with a visible border; filled with the
   selected-fill colour and a contrast tick when checked. Works on
   any card colour. */
.dp-check {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    font-size: .9375rem;
    color: var(--dp-card-ink);
    cursor: pointer;
    padding: 4px 0;
    line-height: 1.5;
}
.dp-check input {
    appearance: none;
    -webkit-appearance: none;
    width: 20px;
    height: 20px;
    margin: 2px 0 0;
    flex-shrink: 0;
    border: 1.5px solid var(--color-border);
    border-radius: 4px;
    background: var(--color-primary-contrast);
    position: relative;
    cursor: pointer;
    transition: background .15s, border-color .15s;
}
.dp-check input:checked {
    background: var(--dp-sel-bg);
    border-color: var(--dp-sel-bg);
}
.dp-check input:checked::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 6px;
    width: 5px;
    height: 10px;
    border: solid var(--dp-sel-ink);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
.dp-check input:focus-visible {
    outline: 2px solid var(--dp-sel-bg);
    outline-offset: 2px;
}

/* Collapsible "Phone and address" / "Give in memory or honor".
   Always white with a visible border (B3). */
.dp-more {
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background: var(--color-primary-contrast);
    overflow: hidden;
}
.dp-more > button {
    width: 100%;
    min-height: 48px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 .875rem;
    background: var(--color-primary-contrast);
    border: 0;
    cursor: pointer;
    font: inherit;
    font-size: .9375rem;
    color: var(--color-text);
    text-align: left;
}
.dp-more .cv {
    font-size: .625rem;
    color: var(--color-text-muted);
    transition: transform .2s;
}
.dp-more.open .cv { transform: rotate(180deg); }
.dp-more-body {
    padding: 0 .875rem .875rem;
    display: flex;
    flex-direction: column;
    gap: .5rem;
}
.dp-more:not(.open) .dp-more-body { display: none; }

/* Consent block (monthly only). Always white with a visible
   border (B3). */
.dp-consent {
    display: none;
    background: var(--color-primary-contrast);
    border: 1px solid var(--color-border);
    border-radius: 10px;
    padding: .75rem .875rem;
    font-size: .875rem;
    line-height: 1.55;
    color: var(--color-text);
}
.dp-consent.on { display: block; }

/* Payment panels.
   Round 8b.2 fix (fault 1): the inactive panel is now `display:
   none` rather than visibility-hidden + absolute. On a dark card
   the old position:absolute left the inactive panel stacked under
   the active one and the browser painted both for a frame, which
   read as a duplicate "How would you like to pay?" switch. A hard
   display:none removes it from the box tree. */
.dp-pay-wrap {
    display: flex;
    flex-direction: column;
    gap: .5rem;
}
.dp-pay-inactive { display: none !important; }

/* Card fields — one box: PayPal's own. The wrapper carries no
   border or background; focus and invalid-after-touch show as an
   outline AROUND PayPal's own box. */
.dp-cf-field { }
.dp-cf-label {
    display: block;
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--dp-card-ink-muted);
    margin: 0 0 .375rem;
}
.dp-cf-input {
    min-height: 48px;
    border-radius: 10px;
    transition: outline-color .15s;
}
/* Round 8b.2 B2: in preview mode the PayPal CardFields SDK is
   not loaded, so the four card boxes are empty divs. The stand-in
   class paints a plain input-looking box with a soft placeholder
   so the editor shows a visual "card number", "expiry", etc.
   where the real inputs would be. */
.dp-cf-standin {
    display: flex;
    align-items: center;
    padding: 0 14px;
    border: 1px solid var(--color-border);
    background: #ffffff;
    color: color-mix(in srgb, var(--color-text) 50%, #ffffff);
    font-size: .9375rem;
}
.dp-cf-standin-text { pointer-events: none; }
.dp-cf-input.is-focus,
.dp-cf-input.is-invalid {
    outline: 2px solid var(--dp-sel-bg);
    outline-offset: 2px;
}
.dp-cf-2col {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
}

.dp-card-block {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    opacity: 0;
}
.dp-card-block.ready { opacity: 1; }

.dp-give-btn {
    width: 100%;
    min-height: 56px;
    border: 0;
    border-radius: 12px;
    background: var(--dp-btn-bg);
    color: var(--dp-btn-ink);
    font: inherit;
    font-size: 1.125rem;
    font-weight: 700;
    cursor: pointer;
    /* Round 8b.2 fault 3 safety ring: when stored data has
       give_button matching form_cards the button would vanish
       into the card. The PHP overlay sets --dp-btn-ring to a 3px
       ring in the card bg; normally the ring is transparent. */
    box-shadow: var(--dp-btn-ring);
}
.dp-give-btn:disabled { opacity: .55; cursor: not-allowed; }

.dp-secure {
    font-size: .8125rem;
    color: var(--dp-card-ink-muted);
    text-align: center;
    margin: 0;
}

.dp-error {
    display: none;
    background: var(--color-primary-contrast);
    border: 1px solid var(--color-border);
    border-left: 3px solid var(--dp-sel-bg);
    border-radius: 10px;
    padding: .75rem .875rem;
    font-size: .9375rem;
    color: var(--color-text);
}
.dp-error.on { display: block; }

/* Gap between the "How would you like to pay?" switch and the
   PayPal / Venmo button block below the inactive card panel
   (round 8a close rule 5). The pay-wrap is a flex column so the
   gap applies cleanly whether the Card or PayPal panel is active. */
.dp-pay-wrap { margin-top: .5rem; }
#venmo-button-container { margin-top: 10px; }
#paypal-button-container,
#venmo-button-container { min-height: 0; }
.dp-pay-panel-paypal #paypal-button-container { margin-top: 0; }

/* Summary panel. Background from form_cards (same as the form
   card); ink chosen by contrast. */
.dp-summary {
    background: var(--dp-card-bg);
    color: var(--dp-card-ink);
    border: 1px solid var(--dp-card-line);
    border-radius: var(--radius);
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: .75rem;
    position: sticky;
    top: 1.25rem;
    box-shadow: var(--dp-form-shadow);
}
.dp-summary h2 {
    margin: 0;
    font-family: var(--font-heading);
    font-weight: 400;
    font-size: 1.375rem;
    color: var(--dp-card-ink);
}
.dp-summary-row {
    display: flex;
    justify-content: space-between;
    gap: .75rem;
    font-size: .9375rem;
    padding: .5rem 0;
    border-bottom: 1px solid var(--dp-card-line);
}
/* Stage 20a Round 5a fix 7 — item 4. HTML5 `hidden` attribute has to
   win against `display: flex` above. Without this rule the browser's
   UA stylesheet (`[hidden]{display:none}`) ties on specificity and
   our author stylesheet keeps the row visible even when draw() flips
   `hidden = true`, so a donor would see "Towards our costs $3.75"
   after switching back to "No thanks". `#sCC` carries this attribute
   from the server render too, so the first paint also stays honest. */
.dp-summary-row[hidden] { display: none; }
.dp-summary-row span:first-child { color: var(--dp-card-ink-muted); }
.dp-summary-row span:last-child  { color: var(--dp-card-ink); font-weight: 600; text-align: right; }
.dp-summary-row:last-of-type { border-bottom: 0; }
/* Summary total panel. Round 8a close rule 2: FIXED light style
   (never follows tile colour). The total number itself always
   reads --color-text so a brand with light inks on dark can't
   accidentally hide it; the panel's --color-border background
   stays light on every brand we support. */
.dp-summary-total {
    background: var(--color-border);
    color: var(--color-text);
    border-radius: 10px;
    padding: 1rem;
    text-align: center;
}
.dp-summary-total b {
    display: block;
    font-size: 1.875rem;
    color: var(--color-text);
    font-weight: 700;
}
.dp-summary-total span {
    font-size: .8125rem;
    color: color-mix(in srgb, var(--color-text) 72%, var(--color-border));
}
.dp-trust {
    font-size: .8125rem;
    line-height: 1.5;
    color: var(--dp-card-ink-muted);
    margin: 0;
}

/* ------------------------------------------------------------------ */
/* BELOW THE FORM — sections placed below, in order (text_below).      */
/* ------------------------------------------------------------------ */

.dp-below {
    background: var(--dp-page-bg);
}
.dp-below .dp-wrap {
    padding-bottom: 3rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
.dp-extra {
    background: var(--dp-card-bg);
    color: var(--dp-card-ink);
    border: 1px solid var(--dp-card-line);
    border-radius: var(--radius);
    padding: 1.5rem 1.75rem;
    font-size: 1rem;
    line-height: 1.55;
}

/* ------------------------------------------------------------------ */
/* Closed / not-found status card.                                     */
/* ------------------------------------------------------------------ */

.dp-status {
    background: var(--dp-card-bg);
    color: var(--dp-card-ink);
    border: 1px solid var(--dp-card-line);
    border-radius: var(--radius);
    padding: 2rem 1.75rem;
    text-align: center;
    max-width: 45rem;
    margin: 2rem auto;
}
.dp-status h1 {
    margin: 0 0 .75rem;
    font-family: var(--font-heading);
    font-weight: 400;
    font-size: 1.75rem;
    color: var(--dp-card-ink);
}
.dp-status .dp-note {
    color: var(--dp-card-ink);
    opacity: .85;
    font-size: 1rem;
    margin: 0 0 1.25rem;
}
.dp-status .dp-give-btn {
    display: inline-block;
    width: auto;
    min-height: 48px;
    padding: 0 1.5rem;
    line-height: 48px;
    font-size: 1rem;
}

/* ------------------------------------------------------------------ */
/* Thank-you page shell.                                               */
/* Matches donation-page-mockup.html's sister                           */
/* thank-you-page-mockup.html, using brand tokens for every colour     */
/* and font. The green tick reads --color-success (NOT a brand         */
/* token; fixed in system.css) so it stays green on every brand.       */
/* ------------------------------------------------------------------ */

/* Slim dark band at the top: campaign thank-you heading + text on
   the left, white circle with a green tick on the right. Rob,
   8 October 2026: "move the tick check to the right and make the
   blue header less height so the thank you page fits nealty into
   one fold". */
.dp-ty-band {
    background: var(--color-dark);
    color: var(--color-primary-contrast);
}
.dp-ty-band .dp-wrap {
    padding-top: 2rem;
    padding-bottom: 2.125rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
}
.dp-ty-text {
    display: flex;
    flex-direction: column;
    gap: .625rem;
    min-width: 0;
}
.dp-ty-text h1 {
    margin: 0;
    font-family: var(--font-heading);
    font-weight: 400;
    font-size: clamp(1.875rem, 4.2vw, 2.75rem);
    line-height: 1.08;
    color: var(--color-primary-contrast);
}
.dp-ty-text p {
    margin: 0;
    font-size: 1.125rem;
    max-width: 62ch;
    color: var(--color-primary-contrast);
    opacity: .9;
}
.dp-ty-tick {
    flex: 0 0 72px;
    width: 72px;
    height: 72px;
    border-radius: 50%;
    background: var(--color-primary-contrast);
    display: flex;
    align-items: center;
    justify-content: center;
}
.dp-ty-tick svg { color: var(--color-success); }
@media (max-width: 560px) {
    .dp-ty-tick { flex-basis: 52px; width: 52px; height: 52px; }
    .dp-ty-tick svg { width: 26px; height: 26px; }
}

/* Main area: two-column at wide, single column on phone.
   Left:  "What happens next" steps card.
   Right: Buttons + the questions line. */
.dp-ty-main .dp-wrap {
    padding-top: 1.75rem;
    padding-bottom: 2.25rem;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 20rem;
    gap: 1.75rem;
    align-items: start;
}
@media (max-width: 899px) {
    .dp-ty-main .dp-wrap { grid-template-columns: 1fr; }
}

.dp-ty-card {
    background: var(--color-primary-contrast);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1.75rem;
}
.dp-ty-card h2 {
    margin: 0 0 1rem;
    font-family: var(--font-heading);
    font-weight: 400;
    font-size: 1.5rem;
    color: var(--color-text);
}

/* Numbered steps. The number sits in a soft-cream circle (reads on
   the brand's --color-border). */
.dp-ty-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .875rem;
}
.dp-ty-steps li {
    display: flex;
    gap: .875rem;
    align-items: flex-start;
}
.dp-ty-num {
    flex: 0 0 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--color-border);
    color: var(--color-text);
    font-weight: 700;
    font-size: .875rem;
    display: flex;
    align-items: center;
    justify-content: center;
}
.dp-ty-steps b {
    display: block;
    font-size: 1rem;
    font-weight: 700;
    color: var(--color-text);
}
.dp-ty-steps span {
    display: block;
    font-size: .9375rem;
    color: var(--color-text-muted);
    line-height: 1.5;
    margin-top: 2px;
}

/* Side card: two stacked buttons + questions line. */
.dp-ty-side {
    display: flex;
    flex-direction: column;
    gap: .875rem;
    background: var(--color-primary-contrast);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1.75rem;
}
.dp-ty-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 0 1.125rem;
    min-height: 52px;
    border-radius: 12px;
    background: var(--color-primary);
    color: var(--color-primary-contrast);
    font-weight: 700;
    text-decoration: none;
    font-size: 1rem;
}
.dp-ty-btn-alt {
    background: var(--color-primary-contrast);
    color: var(--color-text);
    border: 1px solid var(--color-border);
}
.dp-ty-small {
    font-size: .8125rem;
    color: var(--color-text-muted);
    margin: 0;
    line-height: 1.5;
}

/* ============================================================
 * Stage 19 Round 4 — "Help cover our costs" card.
 *
 * The card sits in the same .dp-group slot the old fee-cover
 * tick lived in. Buttons use the same --dp-tile-* / --dp-sel-*
 * tokens as the amount tiles so the campaign's brand colours
 * carry (decision 33: the live page wins over the mockup's
 * brown-and-rust demo brand). Mobile folds the row to 2 columns
 * like the amount tiles.
 * ============================================================ */
.dp-cc { gap: 10px; }
.dp-cc-line { margin: 0; color: var(--color-text-muted); font-size: .9375rem; }
.dp-cc-pcts {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 10px;
}
.dp-cc-pct {
    min-height: 56px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    border: 1px solid var(--dp-tile-line);
    border-radius: 10px;
    background: var(--dp-tile-bg);
    color: var(--dp-tile-ink);
    font: inherit;
    cursor: pointer;
    padding: 6px 4px;
}
.dp-cc-pct-label { font-weight: 700; font-size: 1rem; }
.dp-cc-pct-amount { font-size: .8125rem; color: var(--dp-tile-ink-muted); min-height: 1em; }
.dp-cc-pct.on {
    background: var(--dp-sel-bg);
    border-color: var(--dp-sel-bg);
    color: var(--dp-sel-ink);
    box-shadow: var(--dp-sel-ring);
}
.dp-cc-pct.on .dp-cc-pct-amount { color: var(--dp-sel-ink); opacity: .9; }
@media (max-width: 560px) {
    .dp-cc-pcts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
