@font-face {
    font-family: "Courier Prime";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/courier-prime-regular.woff2") format("woff2");
}

@font-face {
    font-family: "Courier Prime";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("../fonts/courier-prime-bold.woff2") format("woff2");
}

/* --stock (targeted row) and --field (form input) can appear touching,
   on the review page's article forms, so moving either means checking
   three pairs: each against --bg, and the two against each other. */
:root {
    --bg: hsl(20 25 95);
    --primary: black;
    --stock: hsl(20 25 94);
    --field: hsl(20 25 83);
    --link: hsl(20 50 40);
    --staff: hsl(20 25 40);
    /* Courier Prime's own metrics: (1600 + 700) / 2048. Written out
       rather than `normal` because --line must equal the rendered line
       box, and `normal` resolves to the fallback Courier's number
       during the font swap. */
    --leading: 1.123;
    /* The unit of vertical space. Horizontal spacing uses ch. */
    --line: calc(1rem * var(--leading));
    --gap: var(--line);
    --gap-region: calc(2 * var(--line));
    --pad: 0.3rem;
    accent-color: var(--primary);
}

/* No element in this sheet sets a vertical margin. Space between two
   blocks belongs to the box holding them both, declared once with gap,
   so nothing collapses and no boundary is claimed twice. */

h1, h2, p, ul, figure, form, hr {
    margin: 0;
}

body,
main,
.regions {
    display: grid;
    gap: var(--gap-region);
}

.stack {
    display: grid;
    gap: var(--gap);
}

.keys {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--pad) 1ch;
}

/* Targets of fragment links: date sections, and the events an edit or
   delete round-trip returns to by id. */
section.date-group,
section.venue-group,
li.event,
article.review-item {
    scroll-margin-top: var(--gap);
}

body {
    font-family: courier prime, courier, monospace;
    background: var(--bg);
    color: var(--primary);
    max-width: 56ch;
    margin: calc(4 * var(--line)) auto;
    padding: 0 2ch;
    line-height: var(--leading);
}

@media (max-width: 600px) {
    body {
        margin: calc(2 * var(--line)) auto;
    }
}

h1,
h2 {
    font-weight: bold;
    text-transform: uppercase;
}

h1 {
    font-size: 2rem;
    letter-spacing: 0.5ch;
}

h2 {
    font-size: 1.5rem;
}

a {
    color: var(--link);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 1px;
}

/* Staff links take the muted ink. Every staff route is under /manage/
   and nothing else is, so the prefix is the whole test. Before the
   focus block: equal specificity there, so the inversion wins on
   order. */
a[href^="/manage/"] {
    color: var(--staff);
}

/* The hidden attribute's UA default loses to any authored display
   value, which has bitten three times. */
[hidden] {
    display: none !important;
}

hr {
    border: none;
    height: 1px;
    background: black;
}

::selection {
    background: var(--primary);
    color: var(--bg);
}

/* Log out is a form only because signing out must be a POST; it sets
   as a word on its line like the nav items above it. */
header nav form {
    display: inline;
}

/* Log out is staff, and a button only because it must POST. */
header nav button {
    background: none;
    border: none;
    padding: 0;
    color: var(--staff);
    text-decoration: underline;
    text-underline-offset: 1px;
}

li.event:target,
article.review-item:target {
    background: var(--stock);
}

/* The marker hangs in the 2ch indent so a wrapped item still reads as
   one item. */
ul {
    list-style: disc;
    padding-left: calc(1rem + 2ch);
}

ul.events {
    display: grid;
    gap: var(--gap);
}

label {
    display: block;
}

/* A lone checkbox sits on its label's line instead of orphaned below
   it (labels are otherwise block). */
.field:has(> input[type="checkbox"]) label {
    display: inline;
}

.field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 1ch;
}

input,
textarea,
button {
    font-family: inherit;
    font-size: inherit;
    border: none;
    padding: var(--pad) 1ch;
}

input,
textarea {
    background: var(--field);
    color: inherit;
    width: 100%;
    box-sizing: border-box;
    line-height: inherit;
}

/* A checkbox takes none of the dress above: padding and the UA's own
   margins both make its line taller than a carriage return. */
input[type="checkbox"] {
    width: auto;
    padding: 0;
    margin: 0;
}

/* No horizontal give of its own: the pseudo-button inside brings its
   own, and the two would stack. */
input[type="file"] {
    padding: var(--pad);
}

/* The file picker's pseudo-button can't inherit the form-button rule. */
input[type="file"]::file-selector-button {
    font: inherit;
    background: none;
    color: var(--primary);
    border: none;
    padding: var(--pad) 1ch;
    cursor: pointer;
    margin-right: 1ch;
    /* CSS can't rename "Choose Files", but it can stop it shouting. */
    text-transform: lowercase;
}

button {
    background: none;
    color: inherit;
    border: none;
    cursor: pointer;
}

form button {
    background: none;
    color: var(--primary);
    cursor: pointer;
}

button.primary {
    background: var(--primary);
    color: var(--bg);
}

/* Unqualified so the focus inversion still outranks it. */
button.danger {
    font-weight: bold;
}

button:disabled {
    opacity: 0.5;
    cursor: default;
}

ul.errorlist {
    font-weight: bold;
}

/* Django renders help text as an inline span. */
.helptext {
    display: block;
}

.duplicate-hint {
    font-weight: bold;
}

.flyer-thumb {
    max-width: 120px;
    border: 1px solid;
}

button.flyer-thumb-button {
    display: block;
    /* Shrink to the image: a full-width block centers the thumbnail
       inside itself (a button's UA text-align is center) and makes the
       whole row the click target. */
    width: fit-content;
    background: none;
    border: none;
    padding: 0;
}

.flyer-field {
    display: grid;
    grid-template-columns: 1fr;
    justify-items: start;
    gap: var(--pad);
}

/* Removal is staged until save; the thumbnail going is the only sign,
   and this is what makes that work with no JavaScript. */
.flyer-field:has(.flyer-clear input:checked) .flyer-thumb-button {
    display: none;
}

/* Nothing to remove until there's a stored flyer (.has-flyer, from the
   server) or a picked file (.has-pick, from flyer.js). */
.flyer-clear {
    display: none;
}

.flyer-field.has-flyer .flyer-clear,
.flyer-field.has-pick .flyer-clear {
    display: block;
}

/* A checkbox so removing survives with JavaScript off, a button to look
   at. Moved off-screen, not display:none — it stays focusable. */
.flyer-clear input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.flyer-clear label {
    display: inline-block;
    padding: var(--pad) 1ch;
    background: none;
    cursor: pointer;
}

.flyer-clear input:focus-visible ~ label {
    outline: 2px solid var(--primary);
}

.flyer-clear input:checked ~ label {
    padding: 0;
    background: none;
    border: none;
    text-decoration: underline;
}

.flyer-clear-on,
.flyer-clear-note {
    display: none;
}

.flyer-clear-note {
    font-weight: bold;
}

.flyer-clear input:checked ~ label .flyer-clear-off {
    display: none;
}

.flyer-clear input:checked ~ label .flyer-clear-on {
    display: inline;
}

/* Only a stored flyer is worth a notice — a cleared pick has nothing to
   warn about. */
.flyer-field.has-flyer .flyer-clear input:checked ~ .flyer-clear-note {
    display: inline;
}

button.flyer-link {
    background: none;
    color: var(--link);
    padding: 0;
    text-decoration: underline;
    text-underline-offset: 1px;
}

/* Full-viewport rather than a floating box: native light dismiss lets
   the closing click land on whatever sits beneath, so nothing sits
   beneath — the .shutter button catches every off-image click and
   closes declaratively. */
.flyer-popover {
    inset: 0;
    margin: 0;
    width: auto;
    height: auto;
    max-width: none;
    max-height: none;
    border: none;
    padding: 0;
    background: none;
    overscroll-behavior: contain;
}

/* Layout only while open: the UA hides a closed popover with a plain
   display:none that any authored display value overrides. */
.flyer-popover:popover-open {
    display: grid;
    place-items: center;
}

.flyer-popover .shutter {
    position: absolute;
    inset: 0;
    background: none;
    border: none;
    padding: 0;
    cursor: default;
}

.flyer-popover figure {
    position: relative;
}

.flyer-popover img {
    display: block;
    max-width: min(90vw, 480px);
    max-height: 90vh;
    border: 1px solid;
}

.flyer-popover .close {
    position: absolute;
    top: 0;
    right: 0;
    background: var(--primary);
    color: var(--bg);
    padding: var(--pad) 1ch;
}

.flyer-popover::backdrop {
    background: rgba(0, 0, 0, 0.5);
}

body:has(.flyer-popover:popover-open) {
    overflow: hidden;
}

/* Focus inverts ink and paper. Last in the file on purpose: it must
   outrank earlier equal-specificity color rules (header nav button,
   button.flyer-link). */
a:focus-visible,
button:focus-visible {
    background: var(--primary);
    color: var(--bg);
    outline: none;
}

button.primary:focus-visible,
.flyer-popover .close:focus-visible {
    background: var(--bg);
    color: var(--primary);
}

/* Keep the ring at 2px: as a hairline it was thinner than what browsers
   draw unasked, which made the smallest controls the hardest to find. */
input:focus-visible,
textarea:focus-visible {
    outline: 2px solid var(--primary);
}
