/*
 * Base styles. Everything here is expressed in terms of the tokens in tokens.css, so
 * the PRD 3 sizing rules are changed in one place rather than per component.
 */

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

html {
    font-size: 100%;
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    font-family: var(--gy-font);

    /* 18px floor for all body text (PRD 3.2). */
    font-size: var(--gy-text-base);
    line-height: var(--gy-line);
    color: var(--gy-ink);
    background-color: var(--gy-surface-sunken);

    /* Keeps content clear of the notch and the home indicator when installed. */
    padding: env(safe-area-inset-top) env(safe-area-inset-right)
             env(safe-area-inset-bottom) env(safe-area-inset-left);
}

h1, h2, h3 {
    margin: 0 0 var(--gy-space-4);
    line-height: 1.25;
    font-weight: var(--gy-weight-bold);
}

h1 { font-size: var(--gy-text-xl); }
h2 { font-size: var(--gy-text-lg); }
h3 { font-size: var(--gy-text-base); }

/* Desktop is the same layout, widened — not a separate design (PRD 3.1). */
.gy-page {
    max-width: var(--gy-content-max);
    margin: 0 auto;
    padding: var(--gy-space-4);
}

/* ---- Interactive elements ---------------------------------------------------------
 * Every tappable thing meets the 48px minimum in both directions, and adjacent ones
 * are kept apart so a gloved thumb cannot reach two at once.
 */

button,
.gy-button,
input,
select,
textarea {
    font-family: inherit;
    font-size: var(--gy-text-base);
}

button,
.gy-button {
    min-height: var(--gy-touch-min);
    min-width: var(--gy-touch-min);
    padding: var(--gy-space-3) var(--gy-space-5);
    border: var(--gy-border-width) solid transparent;
    border-radius: var(--gy-radius);
    font-weight: var(--gy-weight-medium);
    cursor: pointer;

    /* Removes the 300ms tap delay and the double-tap-to-zoom gesture on buttons,
       without disabling zoom for the page as a whole. */
    touch-action: manipulation;
}

.gy-button--primary {
    background-color: var(--gy-brand);
    color: var(--gy-brand-ink);
    min-height: var(--gy-touch-primary);
    font-size: var(--gy-text-lg);
}

.gy-button--secondary {
    background-color: var(--gy-surface);
    color: var(--gy-ink);
    border-color: var(--gy-border-strong);
}

.gy-button + .gy-button,
button + button {
    margin-left: var(--gy-touch-gap);
}

/* ---- Forms -----------------------------------------------------------------------
 * One column, one field per row, large inputs (PRD 3.4).
 */

.gy-field {
    display: flex;
    flex-direction: column;
    gap: var(--gy-space-2);
    margin-bottom: var(--gy-space-5);
}

.gy-field__label {
    font-size: var(--gy-text-lg);
    font-weight: var(--gy-weight-medium);
}

.gy-field__input {
    min-height: var(--gy-touch-comfortable);
    padding: var(--gy-space-3) var(--gy-space-4);
    border: var(--gy-border-width) solid var(--gy-border-strong);
    border-radius: var(--gy-radius);
    background-color: var(--gy-surface);
    color: var(--gy-ink);
    width: 100%;
}

/* iOS zooms the whole page in when a focused input is under 16px. The 18px floor
   already avoids this; the rule is stated so a future "compact" variant cannot
   quietly reintroduce it. */
.gy-field__input,
.gy-field__input::placeholder {
    font-size: var(--gy-text-base);
}

.gy-field__input--plate {
    font-size: var(--gy-text-2xl);
    font-weight: var(--gy-weight-bold);
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

/* Warnings are things the operator may save past; errors block. Most of this system's
   rules are warnings (PRD 4.2.1, 4.2.2), so the two must not look alike. */
.gy-field__warning,
.gy-field__error {
    font-size: var(--gy-text-base);
    padding: var(--gy-space-2) var(--gy-space-3);
    border-radius: var(--gy-radius);
    border-left: 4px solid;
}

.gy-field__warning {
    color: var(--gy-warning);
    background-color: var(--gy-warning-soft);
    border-left-color: var(--gy-warning);
}

.gy-field__error {
    color: var(--gy-error);
    background-color: var(--gy-error-soft);
    border-left-color: var(--gy-error);
}

/* ---- Focus -----------------------------------------------------------------------
 * A visible focus ring, always. Outdoors on a phone this is often the only feedback
 * that a tap landed where the operator intended.
 */

:focus-visible {
    outline: 3px solid var(--gy-focus);
    outline-offset: 2px;
    box-shadow: var(--gy-focus-ring);
}

/* ---- Paid / unpaid ---------------------------------------------------------------
 * Colour AND text (PRD 4.4). The label is part of the component, not decoration, so
 * the state survives a colour-blind operator and a sun-washed screen.
 */

.gy-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--gy-space-2);
    padding: var(--gy-space-2) var(--gy-space-4);
    border-radius: var(--gy-radius);
    font-size: var(--gy-text-base);
    font-weight: var(--gy-weight-bold);
    border: var(--gy-border-width) solid;
}

.gy-badge--paid {
    color: var(--gy-paid);
    background-color: var(--gy-paid-soft);
    border-color: var(--gy-paid);
}

.gy-badge--unpaid {
    color: var(--gy-unpaid);
    background-color: var(--gy-unpaid-soft);
    border-color: var(--gy-unpaid);
}

/* ---- Vehicle card ---------------------------------------------------------------- */

.gy-card {
    background-color: var(--gy-surface);
    border: var(--gy-border-width) solid var(--gy-border);
    border-radius: var(--gy-radius-lg);
    box-shadow: var(--gy-shadow-card);
    padding: var(--gy-space-4);
    margin-bottom: var(--gy-touch-gap);
}

/* The plate is the largest element on the card (PRD 4.4) — it is how staff identify
   a vehicle at a glance while walking past it. */
.gy-card__plate {
    font-size: var(--gy-text-2xl);
    font-weight: var(--gy-weight-bold);
    letter-spacing: 0.05em;
    margin: 0 0 var(--gy-space-2);
}

.gy-card__meta {
    font-size: var(--gy-text-lg);
    color: var(--gy-ink-soft);
}

.gy-card__price {
    font-size: var(--gy-text-xl);
    font-weight: var(--gy-weight-bold);
}

/* ---- Blazor plumbing -------------------------------------------------------------- */

.loading-progress {
    position: relative;
    display: block;
    width: 8rem;
    height: 8rem;
    margin: 20vh auto 1rem;
}

.loading-progress circle {
    fill: none;
    stroke: var(--gy-brand-soft);
    stroke-width: 0.6rem;
    transform-origin: 50% 50%;
    transform: rotate(-90deg);
}

.loading-progress circle:last-child {
    stroke: var(--gy-brand);
    stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
    transition: stroke-dasharray 0.05s ease-in-out;
}

.loading-progress-text {
    text-align: center;
    font-weight: var(--gy-weight-medium);
}

.loading-progress-text:after {
    content: var(--blazor-load-percentage-text, "Hleð...");
}

#blazor-error-ui {
    background: var(--gy-warning-soft);
    color: var(--gy-ink);
    bottom: 0;
    display: none;
    left: 0;
    padding: var(--gy-space-4);
    position: fixed;
    width: 100%;
    z-index: 1000;
    font-size: var(--gy-text-base);
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: var(--gy-space-4);
    top: var(--gy-space-4);
    min-width: var(--gy-touch-min);
    min-height: var(--gy-touch-min);
}

/* ---- Shell and header ------------------------------------------------------------- */

.gy-header {
    display: flex;
    align-items: center;
    gap: var(--gy-touch-gap);
    padding: var(--gy-space-3) var(--gy-space-4);
    background-color: var(--gy-brand);
    color: var(--gy-brand-ink);
}

.gy-header__brand {
    font-size: var(--gy-text-lg);
    font-weight: var(--gy-weight-bold);
    color: var(--gy-brand-ink);
    text-decoration: none;
    min-height: var(--gy-touch-min);
    display: flex;
    align-items: center;
}

/* Which winter is on screen. Always visible, because registering into the wrong
   season is the mistake PRD 4.8 is written to prevent. */
.gy-header__season {
    font-size: var(--gy-text-base);
    font-weight: var(--gy-weight-medium);
    padding: var(--gy-space-1) var(--gy-space-3);
    border: 2px solid rgb(255 255 255 / 55%);
    border-radius: var(--gy-radius);
}

.gy-header__signout {
    margin-left: auto;
}

/* ---- Buttons ---------------------------------------------------------------------- */

.gy-button--block {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    margin-bottom: var(--gy-space-5);
    text-decoration: none;
}

.gy-actions,
.gy-record-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gy-touch-gap);
    margin-top: var(--gy-space-5);
}

/* The gap already separates these; the generic sibling margin would double it. */
.gy-actions .gy-button + .gy-button,
.gy-record-actions .gy-button + .gy-button,
.gy-card__actions button + button {
    margin-left: 0;
}

/* ---- Summary ---------------------------------------------------------------------- */

.gy-summary {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--gy-space-3);
    margin-bottom: var(--gy-space-5);
}

.gy-summary__item {
    background-color: var(--gy-surface);
    border: var(--gy-border-width) solid var(--gy-border);
    border-radius: var(--gy-radius);
    padding: var(--gy-space-3);
    display: flex;
    flex-direction: column;
    gap: var(--gy-space-1);
}

.gy-summary__value {
    font-size: var(--gy-text-xl);
    font-weight: var(--gy-weight-bold);
}

.gy-summary__value--unpaid {
    color: var(--gy-unpaid);
}

.gy-summary__label {
    font-size: var(--gy-text-base);
    color: var(--gy-ink-soft);
}

@media (min-width: 600px) {
    .gy-summary {
        grid-template-columns: repeat(4, 1fr);
    }
}

/* ---- Filters ---------------------------------------------------------------------- */

.gy-filters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gy-touch-gap);
    margin-bottom: var(--gy-space-5);
}

.gy-filter {
    background-color: var(--gy-surface);
    color: var(--gy-ink);
    border: var(--gy-border-width) solid var(--gy-border-strong);
    border-radius: var(--gy-radius);
}

.gy-filter--active {
    background-color: var(--gy-brand);
    color: var(--gy-brand-ink);
    border-color: var(--gy-brand);
}

/* ---- List and cards --------------------------------------------------------------- */

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

.gy-card__link {
    display: block;
    color: inherit;
    text-decoration: none;

    /* The whole card body is the tap target for opening the record, which is far
       easier to hit outdoors than a link inside it. */
    min-height: var(--gy-touch-min);
}

.gy-card__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gy-touch-gap);
    margin-top: var(--gy-space-3);
}

.gy-badge--gone {
    color: var(--gy-ink-soft);
    background-color: var(--gy-surface-sunken);
    border-color: var(--gy-border-strong);
}

/* The paid/unpaid badge is also a button, so it must meet the touch minimum. */
button.gy-badge {
    min-height: var(--gy-touch-comfortable);
    cursor: pointer;
}

/* ---- Forms ------------------------------------------------------------------------ */

.gy-field__optional {
    font-weight: var(--gy-weight-normal);
    color: var(--gy-ink-soft);
    font-size: var(--gy-text-base);
}

.gy-optional {
    margin-bottom: var(--gy-space-5);
}

.gy-optional__summary {
    min-height: var(--gy-touch-min);
    display: flex;
    align-items: center;
    font-size: var(--gy-text-lg);
    font-weight: var(--gy-weight-medium);
    cursor: pointer;
}

.gy-price-line {
    font-size: var(--gy-text-xl);
    font-weight: var(--gy-weight-bold);
}

.gy-hint,
.gy-empty {
    color: var(--gy-ink-soft);
}

.gy-login {
    max-width: 420px;
    margin-top: var(--gy-space-7);
}

/* ---- Utilities -------------------------------------------------------------------- */

/* Available to screen readers, invisible on screen. Used where a heading is needed for
   document structure but would be noise above a list that is obviously the list. */
.gy-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ---- Price block ------------------------------------------------------------------
 * PRD 4.3: the price shows its working so the operator can sanity-check it and read it
 * out to the owner. The amount is large enough to read at arm's length; the derivation
 * sits under it in a smaller but still legible size.
 */

.gy-price {
    background-color: var(--gy-brand-soft);
    border: var(--gy-border-width) solid var(--gy-brand);
    border-radius: var(--gy-radius);
    padding: var(--gy-space-4);
    margin-bottom: var(--gy-space-5);
}

.gy-price__amount {
    font-size: var(--gy-text-2xl);
    font-weight: var(--gy-weight-bold);
}

.gy-price__working {
    font-size: var(--gy-text-base);
    color: var(--gy-ink-soft);
    margin-top: var(--gy-space-1);
}

.gy-price__override {
    margin-top: var(--gy-space-2);
    font-size: var(--gy-text-base);
    font-weight: var(--gy-weight-medium);
    color: var(--gy-warning);
}

.gy-override {
    margin-top: var(--gy-space-5);
    padding: var(--gy-space-4);
    background-color: var(--gy-surface);
    border: var(--gy-border-width) solid var(--gy-border);
    border-radius: var(--gy-radius);
}

/* ---- Rates admin ------------------------------------------------------------------ */

.gy-rate-row {
    display: flex;
    align-items: center;
    gap: var(--gy-touch-gap);
    flex-wrap: wrap;
    margin-top: var(--gy-space-3);
}

.gy-rate-input {
    width: 9ch;
    flex: 0 0 auto;
    font-size: var(--gy-text-lg);
    font-weight: var(--gy-weight-medium);
}

.gy-rate-unit {
    font-size: var(--gy-text-base);
    color: var(--gy-ink-soft);
}

.gy-card--compact {
    padding: var(--gy-space-3);
}

.gy-card__meta--quiet {
    font-size: var(--gy-text-sm);
}

/* ---- Confirmation ----------------------------------------------------------------- */

.gy-confirm {
    position: fixed;
    inset: auto 0 0 0;
    background-color: var(--gy-surface);
    border-top: 3px solid var(--gy-brand);
    padding: var(--gy-space-5);
    box-shadow: 0 -4px 16px rgb(20 24 28 / 20%);
    z-index: 100;
}

.gy-confirm__text {
    font-size: var(--gy-text-lg);
    margin-top: 0;
}

/* ---- Admin navigation -------------------------------------------------------------- */

.gy-adminnav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gy-touch-gap);
    padding: var(--gy-space-3) var(--gy-space-4);
    background-color: var(--gy-surface);
    border-bottom: var(--gy-border-width) solid var(--gy-border);
}

.gy-adminnav__link {
    display: flex;
    align-items: center;
    min-height: var(--gy-touch-min);
    padding: 0 var(--gy-space-4);
    border: var(--gy-border-width) solid var(--gy-border-strong);
    border-radius: var(--gy-radius);
    color: var(--gy-ink);
    text-decoration: none;
    font-size: var(--gy-text-base);
}

.gy-adminnav__link.active {
    background-color: var(--gy-brand);
    color: var(--gy-brand-ink);
    border-color: var(--gy-brand);
}

/* ---- Result bar -------------------------------------------------------------------- */

.gy-resultbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gy-touch-gap);
    margin-bottom: var(--gy-space-4);
}

.gy-resultbar__count {
    font-size: var(--gy-text-base);
    color: var(--gy-ink-soft);
}

/* ---- Notes -------------------------------------------------------------------------
 * PRD 4.5. A note is read at arm's length in poor light, so the body text is the same
 * size as everything else rather than shrunk to fit more of them on screen.
 */

.gy-notes {
    margin-top: var(--gy-space-6);
    padding-top: var(--gy-space-5);
    border-top: var(--gy-border-width) solid var(--gy-border);
}

.gy-notes__input {
    /* Comfortably taller than the 48px minimum: notes are typed, not tapped. */
    min-height: 96px;
    resize: vertical;
    font-family: inherit;
    line-height: var(--gy-line);
}

.gy-notes__list {
    margin-top: var(--gy-space-5);
}

.gy-note__body {
    margin: 0 0 var(--gy-space-2);
    font-size: var(--gy-text-base);

    /* Keeps line breaks the operator typed, without letting a long unbroken string
       push the card sideways off a phone screen. */
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.gy-note__meta {
    font-size: var(--gy-text-sm);
    color: var(--gy-ink-soft);
}

.gy-note__edited {
    margin-left: var(--gy-space-2);
    font-style: italic;
}

.gy-note__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gy-touch-gap);
    margin-top: var(--gy-space-3);
}

.gy-note__actions .gy-button + .gy-button {
    margin-left: 0;
}

/* ---- Returning vehicles ------------------------------------------------------------
 * PRD 4.8. The offer has to be noticeable without being alarming: it is good news, not
 * a problem, so it uses the brand colour rather than the warning one.
 */

.gy-returning {
    background-color: var(--gy-brand-soft);
    border: var(--gy-border-width) solid var(--gy-brand);
    border-radius: var(--gy-radius);
    padding: var(--gy-space-4);
    margin-bottom: var(--gy-space-5);
}

.gy-returning__text {
    margin: 0 0 var(--gy-space-3);
    font-size: var(--gy-text-lg);
    font-weight: var(--gy-weight-medium);
}

.gy-returning__note {
    margin: var(--gy-space-3) 0 0;
    font-size: var(--gy-text-base);
    color: var(--gy-ink-soft);
}

.gy-history {
    margin-top: var(--gy-space-6);
    padding-top: var(--gy-space-5);
    border-top: var(--gy-border-width) solid var(--gy-border);
}

.gy-history__season {
    font-size: var(--gy-text-lg);
    font-weight: var(--gy-weight-bold);
}

/* ---- Photos ------------------------------------------------------------------------
 * PRD 4.6.
 */

.gy-photos {
    margin-top: var(--gy-space-6);
    padding-top: var(--gy-space-5);
    border-top: var(--gy-border-width) solid var(--gy-border);
}

.gy-photos__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gy-touch-gap);
    margin-bottom: var(--gy-space-5);
}

/* The capture controls are labels wrapping a hidden input, so they need the button
   sizing applied explicitly rather than inherited from <button>. */
.gy-photos__actions .gy-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--gy-touch-primary);
    cursor: pointer;
}

.gy-photos__grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;

    /* Two per row on a phone, more as the screen widens — desktop is the same layout
       widened, not a different one. */
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: var(--gy-touch-gap);
}

.gy-photos__tile {
    display: block;
    width: 100%;
    padding: 0;
    border: var(--gy-border-width) solid var(--gy-border);
    border-radius: var(--gy-radius);
    overflow: hidden;
    background: none;
    min-height: auto;
    cursor: pointer;
}

.gy-photos__tile img {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
}

/* ---- Upload progress ---------------------------------------------------------------
 * A failed upload stays visible with a retry rather than disappearing: on the data this
 * runs over, failure is routine and silent loss is the worst outcome (PRD 5).
 */

.gy-upload {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--gy-touch-gap);
    padding: var(--gy-space-3);
    margin-bottom: var(--gy-space-2);
    border-radius: var(--gy-radius);
    background-color: var(--gy-surface);
    border: var(--gy-border-width) solid var(--gy-border);
    font-size: var(--gy-text-base);
}

.gy-upload--failed {
    background-color: var(--gy-error-soft);
    border-color: var(--gy-error);
    color: var(--gy-error);
}

.gy-upload__name {
    font-weight: var(--gy-weight-medium);
    overflow-wrap: anywhere;
}

.gy-upload__state {
    margin-left: auto;
}

/* ---- Full-screen viewer ------------------------------------------------------------ */

.gy-lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    background-color: #000;
    display: flex;
    flex-direction: column;
}

.gy-lightbox__image {
    flex: 1;
    min-height: 0;
    width: 100%;
    object-fit: contain;
}

.gy-lightbox__bar {
    display: flex;
    align-items: center;
    gap: var(--gy-touch-gap);
    padding: var(--gy-space-4);
    padding-bottom: calc(var(--gy-space-4) + env(safe-area-inset-bottom));
    background-color: var(--gy-surface);
}

.gy-lightbox__caption {
    margin-left: auto;
    margin-right: auto;
    font-size: var(--gy-text-base);
    color: var(--gy-ink-soft);
}

.gy-button--danger {
    background-color: var(--gy-unpaid);
    color: #fff;
    border-color: var(--gy-unpaid);
}

/* ---- SMS composer ------------------------------------------------------------------
 * PRD 4.7. The counter is the point of this block: it is the only thing standing
 * between a long Icelandic sentence and three times the expected bill.
 */

.gy-composer__body {
    min-height: 120px;
    resize: vertical;
    font-family: inherit;
    line-height: var(--gy-line);
}

.gy-composer__counter {
    font-size: var(--gy-text-base);
    color: var(--gy-ink-soft);
    margin-bottom: var(--gy-space-4);
}

.gy-composer__counter--multi {
    color: var(--gy-warning);
    font-weight: var(--gy-weight-medium);
}

.gy-composer__alphabet {
    display: block;
    margin-top: var(--gy-space-1);
}

.gy-preview {
    background-color: var(--gy-surface);
    border: var(--gy-border-width) solid var(--gy-border-strong);
    border-radius: var(--gy-radius);
    padding: var(--gy-space-4);
    margin-bottom: var(--gy-space-4);
}

.gy-preview__headline {
    font-size: var(--gy-text-lg);
    font-weight: var(--gy-weight-bold);
    margin-top: 0;
}

/* Shown as the owner will see it, so a broken placeholder is obvious before sending. */
.gy-preview__sample {
    background-color: var(--gy-surface-sunken);
    border-radius: var(--gy-radius);
    padding: var(--gy-space-3);
    font-size: var(--gy-text-base);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    margin-bottom: var(--gy-space-3);
}

.gy-preview__skipped summary {
    min-height: var(--gy-touch-min);
    display: flex;
    align-items: center;
    cursor: pointer;
    font-weight: var(--gy-weight-medium);
    color: var(--gy-warning);
}

.gy-smssend,
.gy-smslog {
    margin-top: var(--gy-space-6);
    padding-top: var(--gy-space-5);
    border-top: var(--gy-border-width) solid var(--gy-border);
}

.gy-smslog__status {
    font-weight: var(--gy-weight-medium);
}

.gy-smslog__status--ok {
    color: var(--gy-paid);
}

.gy-smslog__status--failed {
    color: var(--gy-error);
}

/* ---- Plate from photo ---------------------------------------------------------------
 * PRD 4.6 and section 9. Presented as an aid beside the plate field, never as the
 * primary way in — the manual path must not feel like a fallback.
 */

.gy-platephoto {
    margin: calc(var(--gy-space-5) * -1) 0 var(--gy-space-5);
}

.gy-platephoto .gy-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.gy-platephoto__suggestion {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--gy-touch-gap);
    margin-top: var(--gy-space-3);
    padding: var(--gy-space-3);
    background-color: var(--gy-brand-soft);
    border: var(--gy-border-width) solid var(--gy-brand);
    border-radius: var(--gy-radius);
}

.gy-platephoto__label {
    font-size: var(--gy-text-base);
    color: var(--gy-ink-soft);
}

/* Large enough to check against the plate in front of the operator without squinting. */
.gy-platephoto__value {
    font-size: var(--gy-text-xl);
    font-weight: var(--gy-weight-bold);
    letter-spacing: 0.05em;
}

/* Quiet, not an error: an unreadable plate is an ordinary outcome in an Icelandic
   winter, and styling it as a failure would make the manual path feel like a fallback. */
.gy-platephoto__none {
    margin-top: var(--gy-space-3);
    font-size: var(--gy-text-base);
    color: var(--gy-ink-soft);
}

/* ---- Menu drawer --------------------------------------------------------------------
 * Navigation used to be seven links rendered above every page, which on a phone pushed
 * the actual work below the fold. It now lives behind one control.
 */

.gy-header__menu {
    margin-left: auto;
    min-width: var(--gy-touch-comfortable);
    min-height: var(--gy-touch-comfortable);
    font-size: var(--gy-text-xl);
    background-color: transparent;
    color: var(--gy-brand-ink);
    border-color: rgb(255 255 255 / 55%);
}

.gy-menu__scrim {
    position: fixed;
    inset: 0;
    background-color: rgb(20 24 28 / 45%);
    z-index: 150;
}

.gy-menu {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 151;
    width: min(320px, 85vw);
    background-color: var(--gy-surface);
    border-left: var(--gy-border-width) solid var(--gy-border);
    padding: var(--gy-space-4);
    padding-top: calc(var(--gy-space-4) + env(safe-area-inset-top));
    overflow-y: auto;

    display: flex;
    flex-direction: column;
    gap: var(--gy-space-2);
}

.gy-menu__user {
    font-size: var(--gy-text-base);
    color: var(--gy-ink-soft);
    padding-bottom: var(--gy-space-3);
    border-bottom: var(--gy-border-width) solid var(--gy-border);
    overflow-wrap: anywhere;
}

.gy-menu__group {
    margin-top: var(--gy-space-4);
    padding-top: var(--gy-space-3);
    border-top: var(--gy-border-width) solid var(--gy-border);
    font-size: var(--gy-text-sm);
    font-weight: var(--gy-weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--gy-ink-soft);
}

.gy-menu__link {
    display: flex;
    align-items: center;
    min-height: var(--gy-touch-comfortable);
    padding: 0 var(--gy-space-3);
    border-radius: var(--gy-radius);
    color: var(--gy-ink);
    text-decoration: none;
    font-size: var(--gy-text-lg);
    background: none;
    border: none;
    width: 100%;
    text-align: left;
    cursor: pointer;
}

.gy-menu__link.active {
    background-color: var(--gy-brand-soft);
    font-weight: var(--gy-weight-medium);
}

.gy-menu__link--signout {
    margin-top: auto;
    border-top: var(--gy-border-width) solid var(--gy-border);
    border-radius: 0;
    color: var(--gy-unpaid);
    font-weight: var(--gy-weight-medium);
}

/* ---- Home screen hierarchy ----------------------------------------------------------
 * One dominant action, a two-figure status line, then the list. Everything else is a
 * tap away rather than on screen.
 */

.gy-button--hero {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 72px;
    font-size: var(--gy-text-xl);
    margin-bottom: var(--gy-space-5);
    text-decoration: none;
}

.gy-status {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--gy-space-2);
    font-size: var(--gy-text-lg);
    margin-bottom: var(--gy-space-4);
}

.gy-status__item strong {
    font-size: var(--gy-text-xl);
}

.gy-status__item--unpaid {
    color: var(--gy-unpaid);
}

.gy-status__divider {
    color: var(--gy-ink-soft);
}

.gy-status__more {
    margin-left: auto;
    min-height: var(--gy-touch-min);
    background: none;
    border: none;
    color: var(--gy-brand);
    font-size: var(--gy-text-base);
    text-decoration: underline;
    cursor: pointer;
}

.gy-revenue {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gy-space-4);
    padding: var(--gy-space-3);
    margin-bottom: var(--gy-space-4);
    background-color: var(--gy-surface);
    border: var(--gy-border-width) solid var(--gy-border);
    border-radius: var(--gy-radius);
    font-size: var(--gy-text-base);
}

.gy-revenue span {
    color: var(--gy-ink-soft);
}

.gy-searchbar {
    display: flex;
    align-items: center;
    gap: var(--gy-touch-gap);
    margin-bottom: var(--gy-space-4);
}

.gy-searchbar__toggle--open {
    background-color: var(--gy-brand);
    color: var(--gy-brand-ink);
    border-color: var(--gy-brand);
}

.gy-searchbar__clear {
    min-height: var(--gy-touch-min);
    background: none;
    border: none;
    color: var(--gy-unpaid);
    font-size: var(--gy-text-base);
    text-decoration: underline;
    cursor: pointer;
}

/* ---- Staff ---------------------------------------------------------------------------- */

.gy-card--muted {
    opacity: 0.72;
}

.gy-checkline {
    display: flex;
    align-items: center;
    gap: var(--gy-space-3);
    min-height: var(--gy-touch-min);
    font-size: var(--gy-text-lg);
    cursor: pointer;
}

.gy-checkline input {
    width: 28px;
    height: 28px;
}

/* ---- Paired fields --------------------------------------------------------------------
 * Two narrow fields on one row. The flex basis is what makes this safe on a phone: each
 * child asks for 150px, so when the screen cannot give both that much they wrap back to
 * one per row rather than shrinking below a comfortable tap target.
 */

.gy-field-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gy-touch-gap);
}

.gy-field-row > .gy-field {
    flex: 1 1 150px;

    /* Without this a long vehicle type name forces the row wider than the screen. */
    min-width: 0;
}

/* ---- Attribution ----------------------------------------------------------------------
 * Who registered a vehicle and who marked it paid (PRD 5). Quiet by design: the card was
 * simplified deliberately, and this is information you go looking for rather than
 * something that should compete with the licence plate.
 */

.gy-card__by {
    margin-top: var(--gy-space-2);
    font-size: var(--gy-text-sm);
    color: var(--gy-ink-soft);

    /* Flex with a gap rather than margins on the separator: spacing then does not
       depend on whitespace surviving between Razor elements, and the line wraps
       cleanly on a narrow screen instead of breaking mid-name. */
    display: flex;
    flex-wrap: wrap;
    gap: var(--gy-space-1);
}

.gy-recordmeta {
    margin-top: var(--gy-space-5);
    padding: var(--gy-space-3);
    background-color: var(--gy-surface-sunken);
    border-radius: var(--gy-radius);
    font-size: var(--gy-text-base);
    color: var(--gy-ink-soft);
}
