/*
 * parking-appeal-letter.co.uk
 *
 * The idea: two registers on one page, because there are two documents.
 *
 * The thing you were given is a penalty charge notice: hazard yellow, asphalt,
 * block capitals, a reference number in character cells. The thing you send
 * back is a formal letter. So the top of the page is the notice and the output
 * is typeset as correspondence, and the gap between the two is the design.
 *
 * That also settles the question this site poses and the others do not. The
 * answer here is not a figure, it is a document, so it is not set as a big
 * number: it is given the width of a sheet, a real measure and proper leading,
 * and it prints on its own. The one genuine figure on the page is the deadline,
 * and that gets the big-number treatment instead, because the date is the thing
 * people are actually frightened of.
 *
 * What it replaces: a centred column of white rounded cards with soft shadows,
 * bordered in four unrelated accent colours, under a centred hero carrying
 * "Fight Your Parking Fine" and a three-item row of ticks.
 */

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

:root {
    /* Dark amber rather than the estate's one blue. 7.19:1 on white. */
    --accent: #7A4E08;
    --accent-deep: #5A3A06;
    --accent-tint: #F6EEDC;
    --accent-ink: #FFFFFF;

    /* The road. White on it is 12.62:1, so the masthead has room to spare. */
    --asphalt: #39322A;

    /*
     * Enforcement yellow. It only ever appears on the dark ground or carrying
     * near-black type, never as type on white, where it would be unreadable.
     */
    --hazard: #F5C518;

    --paper: #F2F0EB;
    --card: #FFFFFF;
    --ink: #1A1714;
    --ink-soft: #443E37;
    --muted: #66635C;
    --rule: #DCD8D0;
    --rule-strong: #BFB9AE;

    --good: #2F6B4F;
    --warn: #8A6212;
    --bad: #9A3324;
    --warn-tint: #FBF3E0;
    --bad-tint: #FBEDEA;

    --font-body: Archivo, system-ui, -apple-system, sans-serif;
    /*
     * The letter is the one thing on the site that is not interface, so it is
     * not set in the interface face. Georgia is already on every machine, so a
     * posted letter costs no extra request.
     */
    --font-letter: Georgia, 'Times New Roman', serif;
    --font-cell: ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, monospace;

    --step-0: 1rem;
    --step-1: 1.2rem;
    --step-2: 1.44rem;
    --step-3: 1.728rem;
    --step-4: 2.074rem;
    --step-5: 2.488rem;
    /* Extended at the top only, for the deadline. The ratio below is unchanged. */
    --step-6: 3.1rem;
    --step-7: 4.8rem;

    --page: 64rem;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme='light']) {
        --accent: #E0A843;
        --accent-deep: #F0C070;
        --accent-tint: #2B2314;
        --accent-ink: #1A1206;
        --paper: #171613;
        --card: #1F1D1A;
        --ink: #ECE9E4;
        --ink-soft: #C6C1B9;
        --muted: #989289;
        --rule: #2E2B27;
        --rule-strong: #443F39;
    }
}

:root[data-theme='dark'],
body.dark-mode {
    --accent: #E0A843;
    --accent-deep: #F0C070;
    --accent-tint: #2B2314;
    --accent-ink: #1A1206;
    --paper: #171613;
    --card: #1F1D1A;
    --ink: #ECE9E4;
    --ink-soft: #C6C1B9;
    --muted: #989289;
    --rule: #2E2B27;
    --rule-strong: #443F39;
}

body {
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-body);
}

/* The page's own rule, kept so the JS that toggles sections keeps working. */
.hidden {
    display: none !important;
}

/* ------------------------------------------------------------ the hazard */

/*
 * The stripe across the top of the notice. It carries no type, which is what
 * makes the yellow safe to use at full strength: nothing has to be read on it.
 */
.hazard {
    height: 10px;
    background: repeating-linear-gradient(
        135deg,
        var(--hazard) 0 18px,
        var(--asphalt) 18px 36px
    );
}

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

/*
 * Full bleed. The road surface is multiplied over the asphalt rather than laid
 * on top of it, which can only darken the ground: white type on this band is
 * never worse than white on the flat colour, whatever the image looks like.
 */
.masthead {
    background-color: var(--asphalt);
    background-image: url('/img/asphalt.webp');
    background-size: 640px auto;
    background-blend-mode: multiply;
    color: #fff;
    padding-block: clamp(2.25rem, 6vw, 4.25rem) clamp(1.75rem, 4vw, 3rem);
}

.masthead-inner {
    max-width: var(--page);
    margin-inline: auto;
    padding-inline: clamp(1rem, 4vw, 2rem);
}

.masthead-kicker {
    display: block;
    color: var(--hazard);
    margin-bottom: 1.1rem;
}

.masthead h1 {
    font-size: clamp(2rem, 5.4vw, var(--step-6));
    font-weight: 800;
    line-height: 1.03;
    letter-spacing: -0.02em;
    max-width: 16ch;
    color: #fff;
    margin: 0;
}

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

/* ------------------------------------------------------------------ layout */

.doc {
    max-width: var(--page);
    margin-inline: auto;
    padding-inline: clamp(1rem, 4vw, 2rem);
    padding-block: clamp(2rem, 4vw, 3rem) 4rem;
}

/*
 * An editorial grid rather than one centred column. The margin carries the
 * section mark; below 62rem it collapses and the mark sits above its section.
 */
.doc-grid {
    display: grid;
    gap: clamp(0.75rem, 3vw, 2.25rem);
}

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

.doc-grid + .doc-grid {
    margin-top: clamp(2rem, 4vw, 3rem);
}

.section-mark {
    color: var(--accent);
    padding-top: 0.45rem;
    margin: 0;
}

@media (min-width: 62rem) {
    .section-mark {
        text-align: right;
        border-top: 3px solid var(--accent);
    }
}

/* -------------------------------------------------------------------- type */

/*
 * Tracked capitals at a small size, for anything that names a box rather than
 * saying something. This is how a notice labels a field, and it is the one
 * mannerism the interface allows itself.
 */
.field-name,
.masthead-kicker,
.section-mark,
.panel-note,
.deadline-label,
.letter-label {
    font-size: 0.71rem;
    font-weight: 700;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    font-feature-settings: 'tnum';
}

.panel {
    background: var(--card);
    border: 1px solid var(--rule-strong);
    border-top: 4px solid var(--asphalt);
    padding: clamp(1.15rem, 3.5vw, 2rem);
}

.panel-title {
    font-size: var(--step-2);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.01em;
    margin: 0 0 0.3rem;
}

.panel-note {
    color: var(--muted);
    margin: 0 0 1.6rem;
}

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

.fields {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 1.5rem;
}

@media (min-width: 46rem) {
    .fields {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }

    .fields > li.wide {
        grid-column: 1 / -1;
    }
}

.fields > li {
    display: grid;
    grid-template-columns: 1.5rem minmax(0, 1fr);
    column-gap: 0.55rem;
    align-items: baseline;
    margin: 0;
}

.field-num {
    font-family: var(--font-cell);
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}

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

.field-name {
    display: block;
    color: var(--ink-soft);
    margin-bottom: 0.35rem;
}

.field-name .req {
    color: var(--bad);
    font-weight: 700;
}

/*
 * A ruled line rather than a rounded box. --rule-strong is 1.62:1 on the card,
 * and once the box is gone this rule is the only thing identifying the field,
 * which SC 1.4.11 wants at 3:1. --muted is 5.99:1.
 */
.field-body input,
.field-body select,
.field-body textarea {
    width: 100%;
    border: 0;
    border-bottom: 2px solid var(--muted);
    border-radius: 0;
    background: transparent;
    padding: 0.4rem 0 0.45rem;
    font-family: inherit;
    font-size: 1.02rem;
    color: var(--ink);
    box-shadow: none;
}

.field-body textarea {
    min-height: 5.5rem;
    resize: vertical;
    line-height: 1.55;
}

/*
 * The registration and the notice number are the two things you copy off the
 * ticket in block capitals, so they are set the way the ticket sets them: one
 * character per cell, in a monospace, with the cell ticks ruled underneath.
 * Nothing else on the site looks like this, and nothing on the other sites
 * could borrow it.
 */
.field-body input.cells {
    font-family: var(--font-cell);
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: 0.42em;
    text-transform: uppercase;
    padding-bottom: 0.6rem;
    border-bottom-color: var(--ink);
    background-image: repeating-linear-gradient(
        to right,
        var(--rule-strong) 0 1px,
        transparent 1px 1.52em
    );
    background-repeat: no-repeat;
    background-position: 0 100%;
    background-size: 100% 0.45rem;
}

.field-body input:hover,
.field-body select:hover,
.field-body textarea:hover {
    border-bottom-color: var(--ink);
}

.field-body input:focus-visible,
.field-body select:focus-visible,
.field-body textarea:focus-visible {
    border-bottom-color: var(--accent);
    outline: 3px solid var(--accent);
    outline-offset: 3px;
}

.field-body input::placeholder,
.field-body textarea::placeholder {
    color: var(--muted);
    letter-spacing: 0;
    text-transform: none;
    font-weight: 400;
}

.field-hint {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.81rem;
    color: var(--muted);
}

/* ------------------------------------------------------------- the buttons */

.btn {
    display: inline-block;
    background: var(--accent);
    color: var(--accent-ink);
    border: 2px solid var(--accent);
    border-radius: 0;
    padding: 0.85rem 1.6rem;
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    cursor: pointer;
    text-decoration: none;
}

.btn:hover {
    background: var(--accent-deep);
    border-color: var(--accent-deep);
}

.btn:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
}

.btn.quiet {
    background: transparent;
    color: var(--accent);
}

.btn.quiet:hover {
    background: var(--accent-tint);
    color: var(--accent-deep);
}

.btn.danger {
    background: transparent;
    border-color: var(--bad);
    color: var(--bad);
}

.btn.danger:hover {
    background: var(--bad-tint);
    border-color: var(--bad);
    color: var(--bad);
}

.actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: center;
    margin-top: 1.9rem;
}

.copy-note {
    color: var(--good);
    font-weight: 600;
    font-size: 0.9rem;
}

/* -------------------------------------------------------------- the letter */

/*
 * The output, and the reason the site exists. It is a document rather than a
 * figure, so it is given a sheet of its own, a real measure and the leading of
 * something meant to be read on paper, and it is set in a serif because the
 * previous monospace made a formal letter read as terminal output.
 */
.letter-sheet {
    background: var(--card);
    border: 1px solid var(--rule-strong);
    border-top: 4px solid var(--accent);
    padding: 0;
}

.letter-head {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    align-items: baseline;
    justify-content: space-between;
    padding: clamp(1.1rem, 3vw, 1.6rem) clamp(1.15rem, 3.5vw, 2.25rem);
    border-bottom: 1px solid var(--rule);
}

.letter-label {
    color: var(--accent);
    margin: 0;
}

.letter-title {
    font-size: var(--step-2);
    font-weight: 700;
    letter-spacing: -0.01em;
    margin: 0;
}

.letter {
    font-family: var(--font-letter);
    font-size: 1.02rem;
    line-height: 1.75;
    white-space: pre-wrap;
    word-break: normal;
    overflow-wrap: anywhere;
    color: var(--ink);
    background: none;
    border: 0;
    border-radius: 0;
    margin: 0;
    padding: clamp(1.5rem, 5vw, 3rem) clamp(1.15rem, 3.5vw, 2.25rem);
    max-width: 68ch;
}

/*
 * A posted letter is folded in three to fit the envelope. The rule is where it
 * folds, and it is the detail that tells you this is meant to go in the post
 * rather than be read on a screen.
 */
.letter-sheet .fold {
    height: 0;
    border-top: 1px dashed var(--rule);
    margin: 0 clamp(1.15rem, 3.5vw, 2.25rem);
}

.letter-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: center;
    padding: clamp(1.1rem, 3vw, 1.6rem) clamp(1.15rem, 3.5vw, 2.25rem);
    border-top: 1px solid var(--rule);
}

/* ------------------------------------------------------------ the deadline */

/*
 * The one real figure on the page. A letter cannot be set as a big number, but
 * the date it has to be in by can, and that is the thing people are actually
 * frightened of.
 */
.deadline-panel {
    background: var(--card);
    border: 1px solid var(--rule-strong);
    border-top: 4px solid var(--accent);
    padding: clamp(1.15rem, 3.5vw, 2rem);
}

.deadline-row {
    border-left: 6px solid var(--muted);
    padding-left: clamp(0.9rem, 3vw, 1.4rem);
}

.deadline-row + .deadline-row {
    margin-top: 1.75rem;
    padding-top: 1.75rem;
    border-top: 1px solid var(--rule);
}

.deadline-label {
    display: block;
    color: var(--accent);
    margin-bottom: 0.25rem;
}

.deadline-figure {
    display: block;
    font-size: clamp(2.6rem, 10vw, var(--step-7));
    font-weight: 800;
    line-height: 0.95;
    letter-spacing: -0.035em;
    font-variant-numeric: tabular-nums;
    color: var(--ink);
}

.deadline-unit {
    display: block;
    margin-top: 0.35rem;
    font-size: var(--step-1);
    color: var(--ink-soft);
}

.deadline-note {
    margin: 0.7rem 0 0;
    max-width: 52ch;
    color: var(--ink-soft);
    line-height: 1.6;
}

/*
 * Urgency is carried by the rule and by the wording in the note. The colour is
 * the third signal, never the only one, because the row still has to work for
 * anyone who cannot tell these three apart.
 */
.deadline-row.ok {
    border-left-color: var(--good);
}

.deadline-row.warn {
    border-left-color: var(--warn);
}

.deadline-row.bad {
    border-left-color: var(--bad);
}

.deadline-row.bad .deadline-figure {
    color: var(--bad);
}

.deadline-row.past {
    border-left-color: var(--rule-strong);
}

.deadline-row.past .deadline-figure {
    color: var(--muted);
}

/* ------------------------------------------------------------ the evidence */

.tick + .tick {
    border-top: 1px solid var(--rule);
}

.tick label {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    padding: 0.7rem 0;
    cursor: pointer;
    line-height: 1.55;
    max-width: 62ch;
}

.tick input[type='checkbox'] {
    width: 1.15rem;
    height: 1.15rem;
    margin: 0.2rem 0 0;
    accent-color: var(--accent);
    flex: none;
}

.tick input[type='checkbox']:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
}

/* -------------------------------------------------------------- the saved */

.empty {
    color: var(--muted);
    margin: 0.5rem 0 0;
}

.saved + .saved {
    margin-top: 1.5rem;
}

.saved-head h3 {
    font-size: var(--step-1);
    font-weight: 700;
    margin: 0;
}

.saved-date {
    margin: 0.1rem 0 0;
    font-size: 0.85rem;
    color: var(--muted);
}

.saved-facts {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 0.25rem 1rem;
    margin: 0.9rem 0 0;
    font-size: 0.92rem;
}

.saved-facts dt {
    color: var(--muted);
    font-weight: 600;
}

.saved-facts dd {
    margin: 0;
    font-family: var(--font-cell);
    font-variant-numeric: tabular-nums;
}

.saved .actions {
    margin-top: 1.1rem;
}

.saved .btn {
    padding: 0.55rem 1rem;
    font-size: 0.72rem;
}

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

/*
 * Everything below the tool is reference material and is set as such: one
 * measure, rules between sections, no cards. Each of these used to sit in its
 * own bordered, shadowed box outlined in a different accent colour, which made
 * a FAQ shout as loudly as the answer.
 */
.reference {
    margin-top: clamp(2.5rem, 5vw, 4rem);
}

.reference .doc-grid + .doc-grid {
    padding-top: clamp(2rem, 4vw, 3rem);
    border-top: 1px solid var(--rule-strong);
}

.reference h2 {
    font-size: var(--step-3);
    font-weight: 700;
    line-height: 1.16;
    letter-spacing: -0.015em;
    margin: 0 0 0.7rem;
    max-width: 28ch;
}

.reference h3 {
    font-size: var(--step-1);
    font-weight: 700;
    margin: 1.7rem 0 0.3rem;
}

.reference p,
.reference li {
    max-width: 66ch;
    line-height: 1.65;
}

.reference ul,
.reference ol {
    padding-left: 1.15rem;
}

.reference li + li {
    margin-top: 0.3rem;
}

.qa {
    display: grid;
    gap: 0;
}

.qa > div {
    border-top: 1px solid var(--rule);
    padding-block: 1.1rem;
}

.qa > div:last-child {
    border-bottom: 1px solid var(--rule);
}

.qa h3 {
    margin: 0 0 0.3rem;
    font-size: var(--step-0);
}

.qa p {
    margin: 0;
    color: var(--ink-soft);
}

/* ----------------------------------------------------- the rest of the site */

/*
 * The interior pages were built from the same white card and still carry their
 * utility classes, so this only reaches their palette, their links and their
 * focus ring. They are not the designed page, but they should not be a
 * different site either.
 */
a {
    color: var(--accent);
}

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

:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 2px;
}

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

/*
 * The entire point of the site is a letter you post, so printing gives you the
 * letter on a clean sheet and nothing else. Without this you print the
 * masthead, the form you already filled in and the FAQ.
 */
@media print {
    .no-print,
    .book-plug,
    .letter-head,
    .letter-actions,
    .fold,
    .section-mark {
        display: none !important;
    }

    body {
        background: #fff;
    }

    .letter-sheet {
        border: 0;
    }

    .letter {
        padding: 0;
        font-size: 12pt;
        line-height: 1.6;
        max-width: none;
    }
}

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

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

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

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

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

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

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

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

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

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

.save-row {
    margin-bottom: 1rem;
}

.save-row input {
    width: 100%;
    max-width: 24rem;
}
