/**
 * Appeal form styles.
 *
 * Deliberately low-specificity and variable-driven so the city theme can
 * override without !important. No CSS framework is loaded — the reference
 * donation app pulls a whole Bootstrap build plus five unpinned CDN scripts
 * onto a page handling card data, which is not worth repeating.
 */

.cof-ap {
    /* Measured from the live Formidable form so this sits in the page rather
       than beside it. Type comes from the theme (Poppins) via `font: inherit`. */
    --cof-ap-ink: #404040;         /* body text */
    --cof-ap-label: #3f4b5b;       /* field labels */
    --cof-ap-muted: #6b7480;
    --cof-ap-line: #d5dae0;
    --cof-ap-input-border: #bfc3c8;
    --cof-ap-accent: #1b62ab;      /* fresno.gov link/button blue */
    --cof-ap-accent-dark: #14487d; /* hover, and the site's footer blue */
    --cof-ap-error: #b32d2e;
    --cof-ap-error-bg: #fdf3f3;
    --cof-ap-radius: 4px;

    color: var(--cof-ap-ink);
    font-size: 16px;
    line-height: 1.5;

    /* Fill the theme's content column rather than imposing a width. Block
       themes wrap post content in flex/grid containers, and a fixed max-width
       here reads as a narrow strip next to the site's own full-width content. */
    width: 100%;
    max-width: 100%;
    min-width: 0;
}

/*
 * Block themes lay content out with flex and grid. Two defaults bite there:
 * a flex/grid item's min-width resolves to `auto` (so it will not shrink below
 * min-content, but *will* shrink-wrap), and <fieldset> ships a UA default of
 * `min-inline-size: min-content` which makes it refuse to fill its parent.
 * Together those collapse the whole form into a narrow column and squeeze long
 * label text into one character per line. Neutralise both explicitly.
 */
.cof-ap,
.cof-ap-form,
.cof-ap-section {
    min-inline-size: 0;
}

.cof-ap *,
.cof-ap *::before,
.cof-ap *::after {
    box-sizing: border-box;
}

/* ------------------------------------------------------------- sections */

/*
 * Flat, not boxed. The live Formidable form this replaces has no section
 * chrome at all, and bordered fieldsets sitting inside the site's own layout
 * read as a widget bolted on rather than part of the page.
 */
.cof-ap-section {
    width: 100%;
    box-sizing: border-box;
    border: 0;
    padding: 0;
    margin: 0 0 2rem;
}

.cof-ap-section > legend {
    font-weight: 700;
    font-size: 1.05rem;
    padding: 0;
    margin: 0 0 0.75rem;
    color: var(--cof-ap-accent);
    border-bottom: 1px solid var(--cof-ap-line);
    padding-bottom: 0.4rem;
    width: 100%;
}

/* The one section that keeps a surface: money deserves to feel separated. */
.cof-ap-section--payment {
    background: #f5f8fb;
    border: 1px solid var(--cof-ap-line);
    border-radius: var(--cof-ap-radius);
    padding: 1.25rem;
}

/*
 * A <legend> is painted straddling its fieldset's border by default, so the
 * heading sits *on* the box edge rather than inside it. Floating it removes it
 * from that special rendering and lays it out as an ordinary block within the
 * fieldset — the clearfix below stops the fields wrapping around it.
 */
.cof-ap-section--payment > legend {
    float: left;
    width: 100%;
    margin: 0 0 1rem;
    padding: 0 0 0.5rem;
    color: var(--cof-ap-ink);
    border-bottom: 1px solid var(--cof-ap-line);
}

/*
 * Whatever follows the legend starts below it. Without this, a flex container
 * or table placed first (the amount picker) establishes its own formatting
 * context, which is laid out BESIDE a float rather than under it — squeezed
 * into the zero width left next to a 100%-wide legend.
 */
.cof-ap-section--payment > legend + * {
    clear: both;
}

.cof-ap-section--payment::after {
    content: "";
    display: table;
    clear: both;
}

/* --------------------------------------------------------------- fields */

.cof-ap-field {
    margin: 0 0 20px;
    flex: 1 1 0;
    min-width: 0;
}

.cof-ap-field:last-child {
    margin-bottom: 0;
}

.cof-ap-field label,
.cof-ap-label {
    display: block;
    font-weight: 400;
    font-size: 15px;
    line-height: 1.5;
    color: var(--cof-ap-label);
    margin: 0;
}

/* The original bolds only what it bolds itself — the FMC §1-409(g) warning
   inside the relief label, and the two all-caps notices. */
.cof-ap-field label strong,
.cof-ap-label strong {
    font-weight: 700;
}

.cof-ap input[type="text"],
.cof-ap input[type="email"],
.cof-ap input[type="tel"],
.cof-ap input[type="date"],
.cof-ap select,
.cof-ap textarea {
    width: 100%;
    padding: 6px 10px;
    font: inherit;
    font-size: 14px;
    line-height: 1.3;   /* gives the original's 32px control height */
    color: var(--cof-ap-ink);
    background: #fff;
    border: 1px solid var(--cof-ap-input-border);
    border-radius: var(--cof-ap-radius);
}

/* iOS zooms the page when a focused control is under 16px. The original has
   that quirk; no reason to inherit it on the screen size where it bites. */
@media (max-width: 40rem) {
    .cof-ap input[type="text"],
    .cof-ap input[type="email"],
    .cof-ap input[type="tel"],
    .cof-ap input[type="date"],
    .cof-ap select,
    .cof-ap textarea {
        font-size: 16px;
    }
}

.cof-ap textarea {
    resize: vertical;
    min-height: 5rem;
}

.cof-ap input:focus,
.cof-ap select:focus,
.cof-ap textarea:focus {
    border-color: var(--cof-ap-accent);
    outline: 2px solid rgba(26, 60, 94, 0.25);
    outline-offset: 0;
}

.cof-ap .cof-ap-invalid {
    border-color: var(--cof-ap-error);
    background: var(--cof-ap-error-bg);
}

.cof-ap-req {
    color: var(--cof-ap-error);
}

.cof-ap-help {
    font-size: 0.85rem;
    color: var(--cof-ap-muted);
    margin: 0 0 0.4rem;
}

/*
 * The two all-caps notices the original form carries between the last question
 * and the declaration. Centred and bold there, so centred and bold here.
 */
.cof-ap-statement {
    text-align: center;
    font-weight: 700;
    font-size: 14px;
    line-height: 1.6;
    margin: 0 0 1.1rem;
    padding: 0 1rem;
}

/* Separate the notice block from the last question above it and the
   declaration below it, rather than letting all three run together. */
.cof-ap-field + .cof-ap-statement {
    margin-top: 2.75rem;
}

.cof-ap-statement + .cof-ap-field {
    margin-top: 2.75rem;
}

/* Holds the right half of a row open when the original leaves it empty. */
.cof-ap-field--spacer {
    margin: 0;
}

@media (max-width: 40rem) {
    .cof-ap-field--spacer {
        display: none;
    }
}

.cof-ap-help--strong {
    color: var(--cof-ap-ink);
    font-weight: 600;
}

.cof-ap-muted {
    font-size: 0.85rem;
    color: var(--cof-ap-muted);
}

.cof-ap-row {
    display: flex;
    gap: 1.5rem;
    flex-wrap: wrap;
}

.cof-ap-row > .cof-ap-field {
    flex: 1 1 14rem;
    min-width: 0;
}

/*
 * State and ZIP are short answers. Left on the row's default 14rem basis they
 * claim as much width as the city and wrap the group onto three lines long
 * before the viewport is genuinely narrow.
 */
.cof-ap-row > .cof-ap-field--narrow {
    flex: 0 1 8rem;
}

/*
 * The billing block is toggled with the `hidden` attribute, which only works
 * while nothing outclasses the UA stylesheet's `display: none`. Themes that
 * blanket-style `div` do exactly that, and the failure is silent: the block
 * stays on screen with every field disabled.
 */
.cof-ap-billing[hidden] {
    display: none;
}

/*
 * Grid, not flex, and deliberately so.
 *
 * With flex the checkbox is a flex item at `flex: 0 0 auto`, which resolves its
 * size from the `width` property — and themes very commonly ship a blanket
 * `input { width: 100% }`. The checkbox then claims the whole row and the label
 * text is squeezed to nothing, rendering one character per line.
 *
 * A grid track fixed at 1.15rem cannot be widened by the input's own width, so
 * this holds no matter what the surrounding theme does to form controls. The
 * explicit width/height on the control itself is the second belt.
 */
.cof-ap-field label.cof-ap-check,
.cof-ap-check {
    display: grid;
    grid-template-columns: 16px minmax(0, 1fr);
    column-gap: 10px;
    align-items: start;
    font-weight: 400;
    font-size: 13px;
    line-height: 1.6;
    color: var(--cof-ap-ink);
    margin: 0 0 6px;
}

.cof-ap .cof-ap-check input[type="checkbox"],
.cof-ap .cof-ap-check input[type="radio"] {
    width: 16px;
    height: 16px;
    min-width: 0;
    max-width: none;
    margin: 2px 0 0;
    padding: 0;
    flex: none;
    appearance: auto;
    -webkit-appearance: checkbox;
}

.cof-ap .cof-ap-check input[type="radio"] {
    -webkit-appearance: radio;
}

.cof-ap-check > span {
    min-width: 0;
}

.cof-ap-check--declaration {
    line-height: 1.55;
}

/* The declaration reads as a paragraph on the original — same size and weight
   as the questions, just longer. */
.cof-ap-declaration-text {
    font-weight: 400;
    font-size: 15px;
    line-height: 1.6;
    color: var(--cof-ap-label);
    margin: 0 0 10px;
}

/* --------------------------------------------------------- hosted fields */

/*
 * Each .cof-ap-hosted holds an iframe served by Global Payments. The height is
 * fixed because the iframe cannot size its own parent.
 */
.cof-ap-hosted {
    min-height: 44px;
}

/* Mirrors .cof-ap-invalid on a normal control. The border lives out here
   because the input itself is inside a cross-origin iframe we cannot style
   from this stylesheet — GlobalPayments gets its own styles via JS. */
.cof-ap-hosted--invalid {
    outline: 1px solid var(--cof-ap-error);
    outline-offset: 0;
    border-radius: var(--cof-ap-radius);
    background: var(--cof-ap-error-bg);
}

.cof-ap-hosted iframe {
    width: 100%;
    height: 44px;
    border: 0;
    display: block;
}

.cof-ap-fee-summary {
    max-width: 20rem;
    margin: 0 0 0.75rem;
    font-size: 1rem;
}

.cof-ap-fee-summary[hidden] {
    display: none;
}

.cof-ap .cof-ap-fee-summary .cof-ap-fee-line {
    display: flex;
    justify-content: space-between;
    gap: 1.5rem;
    padding: 0.15rem 0;
}

.cof-ap .cof-ap-fee-summary .cof-ap-fee-line > span:last-child {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.cof-ap .cof-ap-fee-summary .cof-ap-fee-line--total {
    margin-top: 0.25rem;
    padding-top: 0.35rem;
    border-top: 1px solid currentColor;
    font-weight: 700;
}

/* Amount choice. Real radios, visually replaced by the pill so keyboard and
   screen-reader behaviour stay native (arrow keys move between amounts). */
.cof-ap-fee-guide {
    margin: 0.5rem 0 0.25rem;
    padding: 0.75rem 1rem;
    font-size: 0.9rem;
    background: #fff;
    border-left: 3px solid var(--cof-ap-accent);
}

.cof-ap-fee-guide p {
    margin: 0 0 0.5rem;
}

.cof-ap-fee-guide ul {
    margin: 0 0 0.5rem 1.25rem;
    padding: 0;
}

.cof-ap-fee-guide ul:last-child {
    margin-bottom: 0;
}

.cof-ap-fee-guide__dept {
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.cof-ap-fee-options {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.4rem;
}

/*
 * Scoped three classes deep on purpose. The theme's blanket label and input
 * rules (see the checkbox note below) otherwise win: a `label { width: 100% }`
 * turns each amount into its own full-width row, and a flex item's basis is
 * its width, so the row can never form.
 */
.cof-ap .cof-ap-fee-options > .cof-ap-fee-option {
    position: relative;
    display: block;
    flex: 0 0 auto;
    width: auto;
    max-width: none;
    margin: 0;
}

.cof-ap .cof-ap-fee-option input[type="radio"] {
    position: absolute;
    top: 0;
    left: 0;
    opacity: 0;
    width: 1px;
    height: 1px;
    min-width: 0;
    margin: 0;
    padding: 0;
}

.cof-ap-fee-option span {
    display: inline-block;
    min-width: 4.5rem;
    padding: 10px 16px;
    font-size: 1.05rem;
    font-weight: 700;
    text-align: center;
    color: var(--cof-ap-accent);
    background: #fff;
    border: 2px solid var(--cof-ap-input-border);
    border-radius: var(--cof-ap-radius);
    cursor: pointer;
}

.cof-ap-fee-option span:hover {
    border-color: var(--cof-ap-accent);
}

.cof-ap-fee-option input:checked + span {
    color: #fff;
    background: var(--cof-ap-accent);
    border-color: var(--cof-ap-accent);
}

.cof-ap-fee-option input:focus-visible + span {
    outline: 2px solid var(--cof-ap-accent);
    outline-offset: 2px;
}

.cof-ap-fee-options--invalid .cof-ap-fee-option span {
    border-color: var(--cof-ap-error);
    background: var(--cof-ap-error-bg);
}

.cof-ap-fee-warning {
    font-size: 0.9rem;
    margin: 0.25rem 0 0.75rem;
}

/* -------------------------------------------------------------- uploads */

.cof-ap-filelist {
    list-style: none;
    margin: 0.6rem 0 0;
    padding: 0;
}

.cof-ap-filelist__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--cof-ap-line);
    border-radius: var(--cof-ap-radius);
    margin: 0 0 0.4rem;
    font-size: 0.9rem;
    background: #fff;
}

/*
 * Dropzone. The real <input type="file"> sits inside, visually hidden but still
 * focusable, so keyboard and screen-reader behaviour stay native; the zone
 * shows its focus ring via :focus-within.
 */
.cof-ap .cof-ap-dropzone {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    margin: 0.35rem 0 0;
    padding: 1.5rem 1rem;
    min-height: 9rem;
    text-align: center;
    color: var(--cof-ap-label);
    background: #f7f9fb;
    border: 2px dashed var(--cof-ap-input-border);
    border-radius: 8px;
    cursor: pointer;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.cof-ap .cof-ap-dropzone:hover {
    border-color: var(--cof-ap-accent);
    background: #f1f6fb;
}

.cof-ap .cof-ap-dropzone:focus-within {
    border-color: var(--cof-ap-accent);
    outline: 2px solid rgba(26, 60, 94, 0.25);
    outline-offset: 2px;
}

/* setFieldError() marks the (hidden) input; show it on the zone instead. */
.cof-ap .cof-ap-dropzone:has(.cof-ap-invalid) {
    border-color: var(--cof-ap-error);
    background: var(--cof-ap-error-bg);
}

/* A file is being dragged over the zone. After the error rule so a new drag
   still highlights while an earlier error is showing. */
.cof-ap .cof-ap-dropzone--over {
    border-color: var(--cof-ap-accent);
    border-style: solid;
    background: #e8f0f9;
}

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

.cof-ap-dropzone__icon {
    color: var(--cof-ap-accent);
    flex: none;
}

.cof-ap-dropzone__title {
    font-weight: 600;
    font-size: 1rem;
}

.cof-ap-dropzone__browse {
    color: var(--cof-ap-accent);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.cof-ap-dropzone__meta {
    font-size: 0.85rem;
    color: var(--cof-ap-muted);
}

/* One title at a time: drag wording for a mouse, tap wording for touch, and
   "Drop to attach" while a file is over the zone. */
.cof-ap-dropzone__tap,
.cof-ap-dropzone__over {
    display: none;
}

.cof-ap-dropzone--over .cof-ap-dropzone__drag,
.cof-ap-dropzone--over .cof-ap-dropzone__tap {
    display: none;
}

.cof-ap-dropzone--over .cof-ap-dropzone__over {
    display: inline;
}

@media (hover: none) and (pointer: coarse) {
    .cof-ap-dropzone__drag {
        display: none;
    }
    .cof-ap-dropzone__tap {
        display: inline;
        color: var(--cof-ap-accent);
    }
}

/* Errors land after the file list, right under the zone. */
.cof-ap-field--files > .cof-ap-error-msg {
    margin-top: 0.4rem;
}

.cof-ap-filelist:empty {
    display: none;
}

.cof-ap-filelist__item > span {
    overflow-wrap: anywhere;
}

.cof-ap-filelist__remove {
    background: none;
    border: 0;
    color: var(--cof-ap-error);
    cursor: pointer;
    font: inherit;
    font-size: 0.85rem;
    text-decoration: underline;
    padding: 0;
}

/* ------------------------------------------------------------- messaging */

.cof-ap-notice {
    padding: 0.85rem 1rem;
    border-radius: var(--cof-ap-radius);
    border-left: 4px solid var(--cof-ap-error);
    background: var(--cof-ap-error-bg);
    margin: 0 0 1.25rem;
    font-size: 14px;
}

.cof-ap-notice__text {
    margin: 0;
    font-weight: 700;
    color: var(--cof-ap-error);
}


/*
 * Per-field message, injected under the control it belongs to. This is the
 * behaviour Formidable had and the native validation bubble does not: every
 * problem visible at once, and still on screen while the user fixes it.
 */
.cof-ap-error-msg {
    display: block;
    margin: 4px 0 0;
    font-size: 13px;
    line-height: 1.4;
    font-weight: 600;
    color: var(--cof-ap-error);
}

/* A 16px checkbox turning red is easy to miss, so flag the whole row. */
.cof-ap-check--invalid {
    color: var(--cof-ap-error);
}

.cof-ap .cof-ap-check--invalid input[type="checkbox"] {
    outline: 2px solid var(--cof-ap-error);
    outline-offset: 1px;
}

.cof-ap-success {
    padding: 1.5rem;
    border: 1px solid #b7d8bd;
    background: #f3faf4;
    border-radius: var(--cof-ap-radius);
}

.cof-ap-success h2 {
    margin: 0 0 0.5rem;
    font-size: 1.3rem;
}

.cof-ap-success__number {
    font-size: 1.1rem;
    font-weight: 600;
    margin: 0 0 0.5rem;
}

/* --------------------------------------------------------------- submit */

.cof-ap-submit {
    display: inline-block;
    width: auto;
    padding: 16px 24px;
    font: inherit;
    font-size: 16px;
    font-weight: 900;
    line-height: 1;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: #fff;
    background: var(--cof-ap-accent);
    border: 0;
    border-radius: 0;
    cursor: pointer;
}

.cof-ap-submit:hover:not(:disabled) {
    background: var(--cof-ap-accent-dark);
}

.cof-ap-submit:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.cof-ap-busy {
    opacity: 0.75;
}

/* ------------------------------------------------------------- honeypot */

/*
 * Off-screen rather than display:none — some bots skip hidden inputs, and this
 * one is meant to be filled in.
 */
.cof-ap-hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
    .cof-ap * {
        scroll-behavior: auto !important;
    }
    .cof-ap .cof-ap-dropzone {
        transition: none;
    }
}

/*
 * The hosted submit field required by GlobalPayments.js (see appeal-form.php).
 * Moved off-screen rather than display:none — a hidden iframe is not reliably
 * loaded, and this one has to load and register or cardForm.ready() never
 * fires and the form reports its card fields as unavailable.
 *
 * Three layers keep it out of reach: `inert` on the container (tab order and
 * accessibility tree), pointer-events:none here (mouse), and a check in
 * token-success that drops any tokenization the form did not itself start.
 * The last one is the real guarantee — the others can be defeated by a browser
 * that does not support inert.
 */
.cof-ap-hosted-offscreen {
    position: absolute;
    left: -9999px;
    top: 0;
    width: 1px;
    height: 1px;
    overflow: hidden;
    pointer-events: none;
}
