/* Dispatch. One screen, read at arm's length in a cradle, in full sun and at night, by a thumb.

   Follows the phone's own light or dark. The brand is JollyDrivers': amber #FFB300 on night #121212. Amber is never
   text on a light ground (it doesn't reach 3:1), so light mode has its own deeper accent for words. No web fonts:
   the phone's own face is the sharpest it can draw, and it costs no bytes. Every target is at least 44px. */

:root {
    color-scheme: light dark;

    --amber: #ffb300;
    --amber-deep: #ff8f00;
    --on-amber: #121212;

    --bg: #121212;
    --surface: #1d1d1f;
    --surface-2: #2a2a2d;
    --line: #38383c;
    --text: #ffffff;
    --text-2: #b9b9bf;
    --accent-text: #ffc53d;
    --good: #4ade80;
    --bad: #ff6b60;
    --bad-bg: #3a1a18;
    --warn-bg: #3a2c0c;
    --shadow: 0 -10px 30px rgba(0, 0, 0, 0.45);

    /* The glow's colour, as numbers so its strength stays in one place, and the quieter words wherever it can be behind
       them. Plain --text-2 doesn't reach 4.5:1 against the glow's strongest. GlowTests measures this one. */
    --glow: 255, 179, 0;
    --on-glow-2: #ebebef;

    --radius: 16px;
    --gutter: 16px;
    --top: env(safe-area-inset-top, 0px);
    --bottom: env(safe-area-inset-bottom, 0px);
}

@media (prefers-color-scheme: light) {
    :root {
        --bg: #f6f5f2;
        --surface: #ffffff;
        --surface-2: #efede8;
        --line: #dcd9d2;
        --text: #121212;
        --text-2: #55555b;
        --accent-text: #8a5700;
        --good: #137a3c;
        --bad: #b3261e;
        --bad-bg: #fbe9e7;
        --warn-bg: #fff3d6;
        --shadow: 0 -8px 24px rgba(0, 0, 0, 0.12);
        --on-glow-2: #3f3f44;
    }
}

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

html, body {
    margin: 0;
    height: 100%;
    background: var(--bg);
    color: var(--text);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 17px;
    line-height: 1.35;
    -webkit-text-size-adjust: 100%;
    -webkit-tap-highlight-color: transparent;
    overscroll-behavior: none;
}

#app { height: 100%; }

/* The picture of the last screen, up before .NET starts: nothing on it is live yet (js/boot.js). */
#app.is-shell * { pointer-events: none; }
#app.is-shell [data-live] { visibility: hidden; }

h1, h2, p, ol, ul { margin: 0; padding: 0; }
ol, ul { list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
:focus-visible { outline: 3px solid var(--amber); outline-offset: 2px; }

.icon { width: 1.25em; height: 1.25em; flex: none; fill: currentColor; }

/* ── the glow ───────────────────────────────────────────────────────────────────────────── */

/* Where the job has got to, read at a glance from a cradle: amber, then green once they're on board, red when late.
   It sits behind everything and is gone before the dock. Screens with no stage to show stay amber. */
.screen, .welcome { position: relative; isolation: isolate; }

.screen::before, .welcome::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    z-index: -1;
    height: 58%;
    pointer-events: none;
    background: radial-gradient(130% 92% at 12% -8%, rgba(var(--glow), 0.5), rgba(var(--glow), 0) 72%);
}

.screen.is-green { --glow: 34, 197, 94; }
.screen.is-red { --glow: 239, 68, 68; }

.bar, .scroll, .welcome { --text-2: var(--on-glow-2); }

/* ── starting, signing in, nothing to show ──────────────────────────────────────────────── */

.splash, .welcome {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: calc(var(--top) + 24px) 24px calc(var(--bottom) + 24px);
    text-align: center;
}

.splash-mark, .welcome-mark { width: 96px; height: 96px; }
.splash-word { font-weight: 700; color: var(--text-2); }

.welcome h1 { font-size: 2rem; font-weight: 800; letter-spacing: -0.02em; }
.welcome-line { color: var(--text-2); margin-bottom: 20px; }
.welcome-problem { width: 100%; max-width: 340px; padding: 12px 14px; border-radius: 12px; background: var(--warn-bg); }
.welcome-foot { max-width: 300px; font-size: 0.875rem; color: var(--text-2); }

.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 56px 24px;
    text-align: center;
    color: var(--text-2);
}

.empty h1 { font-size: 1.4rem; font-weight: 800; color: var(--text); }
.empty-mark { width: 72px; height: 72px; margin-bottom: 8px; }
.empty .button { margin-top: 10px; }

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 52px;
    padding: 0 22px;
    border-radius: 14px;
    border: 1px solid var(--line);
    background: var(--surface);
    font-weight: 700;
}

.button.is-primary { border-color: transparent; background: var(--amber); color: var(--on-amber); }
.button.is-wide { width: 100%; max-width: 340px; }
.button.is-danger { border-color: var(--bad); background: var(--bad-bg); color: var(--bad); }

/* ── the frame ──────────────────────────────────────────────────────────────────────────── */

.screen { height: 100%; display: flex; flex-direction: column; }

.bar {
    position: relative;
    z-index: 3;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-height: calc(var(--top) + 48px);
    padding: var(--top) 6px 0 var(--gutter);
}

.bar-brand { display: flex; align-items: center; gap: 8px; font-weight: 700; }
.bar-mark { width: 24px; height: 24px; }
.bar-end { display: flex; align-items: center; gap: 2px; min-width: 0; }

.bar-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    flex: none;
    border-radius: 50%;
    color: var(--text-2);
}

.pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 26px;
    padding: 0 10px;
    border-radius: 13px;
    font-size: 0.8125rem;
    font-weight: 600;
    white-space: nowrap;
    background: var(--surface-2);
    color: var(--text-2);
}

.pill::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.pill.is-live::before { background: var(--good); }
.pill.is-offline { background: var(--warn-bg); color: var(--accent-text); }
.pill.is-off { color: var(--text-2); }
.pill.is-waiting { background: var(--amber); color: var(--on-amber); }

.scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    padding: 2px var(--gutter) 16px;
}

/* ── things to read first ───────────────────────────────────────────────────────────────── */

.notice, .install {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-bottom: 10px;
    padding: 12px 6px 12px 14px;
    border-radius: var(--radius);
    background: var(--surface-2);
    font-size: 0.95rem;
}

.notice.is-problem { background: var(--bad-bg); }
.notice-text, .install-text { flex: 1; min-width: 0; }
.notice-title { font-weight: 700; }
.install .button { margin-top: 8px; min-height: 44px; }

/* ── the job ────────────────────────────────────────────────────────────────────────────── */

.hero { padding: 6px 0 10px; }
.hero-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }

.eyebrow {
    font-size: 0.8125rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-2);
}

.hero.is-late .eyebrow, .hero.is-underway .eyebrow, .hero.is-finished .eyebrow { color: var(--text); }

.chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-height: 28px;
    padding: 0 10px;
    border-radius: 14px;
    background: var(--surface-2);
    font-size: 0.875rem;
    font-weight: 600;
    white-space: nowrap;
}

.chip.is-paid { color: var(--good); }

/* The operator, just under Next job (WISH-2167): whose job it is is the first thing after what it is. */
.hero-operator { display: flex; align-items: center; gap: 8px; min-height: 32px; margin-top: 4px; font-weight: 700; overflow-wrap: anywhere; }
.hero-logo { flex: none; width: 32px; height: 32px; }

.hero-time {
    margin-top: 2px;
    font-size: clamp(3.25rem, 19vw, 5rem);
    font-weight: 800;
    letter-spacing: -0.04em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.hero-when { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin-top: 6px; font-size: 1.125rem; }
.hero-until { font-weight: 700; }
.hero-zone { font-size: 0.9rem; color: var(--text-2); }

.who { padding: 10px 0; border-top: 1px solid var(--line); }
.who-name { display: flex; align-items: center; gap: 8px; font-size: 1.6rem; font-weight: 800; letter-spacing: -0.02em; line-height: 1.15; }
.who-name.is-button { max-width: 100%; min-height: 44px; text-align: left; }
.who-name.is-button > span:first-child { min-width: 0; overflow-wrap: anywhere; }
.who-more { padding: 1px 9px; border-radius: 12px; background: var(--amber); color: var(--on-amber); font-size: 1rem; font-weight: 800; letter-spacing: 0; }
.who-call { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 50%; background: var(--surface-2); color: var(--accent-text); }
.who-call .icon { width: 20px; height: 20px; }
.who-meta { margin-top: 2px; color: var(--text-2); font-size: 0.95rem; }
.who-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; }

/* A fare the driver can change (WISH-2167): a button, so it is bordered and has a thumb's height. */
.chip.is-fare { min-height: 44px; padding: 0 14px; border: 1px solid var(--line); background: var(--surface); font-size: 0.95rem; font-weight: 700; }
.chip.is-fare .icon { width: 16px; height: 16px; color: var(--accent-text); }
/* Pay link after the fare (WISH-2170): the fare chip's size, so the two read as a pair. */
.chip.is-paylink { min-height: 44px; padding: 0 14px; border: 1px solid var(--line); background: var(--surface); font-size: 0.95rem; font-weight: 700; }
.chip.is-paylink .icon { width: 16px; height: 16px; color: var(--accent-text); }

.route { padding: 6px 0; border-top: 1px solid var(--line); }
.route-stop { position: relative; }

/* The road between the dots. */
.route-stop:not(:last-child)::after {
    content: "";
    position: absolute;
    left: 7px;
    top: 34px;
    bottom: -10px;
    border-left: 2px dashed var(--amber);
}

.route-link { display: flex; align-items: flex-start; gap: 14px; min-height: 48px; padding: 8px 0; }
.route-dot { position: relative; z-index: 1; flex: none; width: 16px; height: 16px; margin-top: 3px; border-radius: 50%; border: 3px solid var(--text-2); background: var(--bg); }
.route-stop.is-destination .route-dot { border-radius: 4px; }
.route-stop.is-next .route-dot { border-color: var(--amber); background: var(--amber); box-shadow: 0 0 0 4px rgba(255, 179, 0, 0.25); }
.route-text { display: flex; flex-direction: column; min-width: 0; font-size: 1.0625rem; }
.route-text strong { font-weight: 700; }
.route-stop.is-next .route-text { font-weight: 700; }

/* The flight, as a stop on the road: two lines, so it costs no more height than a stop does. Where it stands is a chip and
   not a coloured word, because a coloured word on the glow falls under 4.5:1 and a chip brings its own ground. GlowTests
   measures these. */
.route-stop.is-flight { padding: 4px 0 6px; }
.route-stop.is-flight::after { top: 28px; }

.flight { display: flex; align-items: center; gap: 14px; min-height: 52px; }
.flight-plane { position: relative; z-index: 1; flex: none; align-self: flex-start; width: 20px; height: 20px; margin: 5px -2px 0; color: var(--text-2); }
.flight-text { flex: 1; min-width: 0; }
.flight-head { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 7px; margin-bottom: 2px; font-size: 0.95rem; font-weight: 700; line-height: 1.25; }
.flight-chip { min-height: 25px; padding: 0 9px; border-radius: 13px; font-size: 0.8125rem; font-weight: 700; }
.flight-sub, .flight-note { font-size: 0.8125rem; color: var(--text-2); line-height: 1.25; }
.flight-note { margin-top: 2px; }

.is-flight.is-fine .flight-plane, .is-flight.is-fine .flight-chip { color: var(--good); }
.is-flight.is-late .flight-plane { color: var(--accent-text); }
.is-flight.is-late .flight-chip { background: var(--warn-bg); color: var(--accent-text); }
.is-flight.is-off .flight-plane { color: var(--bad); }
.is-flight.is-off .flight-chip { background: var(--bad-bg); color: var(--bad); }

.flight-check {
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    width: 58px;
    min-height: 48px;
    border-radius: 12px;
    background: var(--surface-2);
    font-size: 0.6875rem;
    font-weight: 700;
    line-height: 1.1;
}

.flight-check .icon { width: 18px; height: 18px; }
.flight-check:disabled { background: none; color: var(--text-2); cursor: default; font-weight: 600; }
.flight-check.is-checking .icon { animation: flight-turn 900ms linear infinite; }

@keyframes flight-turn { to { transform: rotate(360deg); } }

.note { margin-top: 6px; padding: 10px 14px; border-radius: 12px; background: var(--warn-bg); border-left: 4px solid var(--amber); }
.note-label { display: flex; align-items: center; gap: 4px; font-size: 0.8125rem; font-weight: 800; letter-spacing: 0.04em; color: var(--accent-text); }
.note-text { margin-top: 2px; white-space: pre-line; overflow-wrap: anywhere; }

.out { margin-top: 12px; text-align: center; font-size: 0.95rem; color: var(--text-2); }
.out a { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; }

/* ── the dock ───────────────────────────────────────────────────────────────────────────── */

.dock {
    position: relative;
    z-index: 2;
    flex: none;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px var(--gutter) calc(var(--bottom) + 12px);
    background: var(--surface);
    border-radius: 20px 20px 0 0;
    box-shadow: var(--shadow);
}

.rail { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 44px; margin-block: -5px; color: var(--text-2); font-size: 0.875rem; font-weight: 600; }
.rail-steps { flex: 1; display: flex; gap: 4px; }
.rail-step { flex: 1; height: 6px; border-radius: 3px; background: var(--surface-2); }
.rail-step.is-done { background: var(--good); }
.rail-step.is-skipped { background: repeating-linear-gradient(90deg, var(--good) 0 4px, transparent 4px 7px); }
.rail-step.is-waiting { background: var(--amber); opacity: 0.6; }
.rail-step.is-next { background: var(--amber); }
.rail-words { white-space: nowrap; }

.action {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    min-height: 56px;
    border-radius: 14px;
    background: var(--surface-2);
    font-size: 0.8125rem;
    font-weight: 700;
}

.action .icon { width: 24px; height: 24px; }

.dock-note { display: flex; align-items: center; gap: 8px; padding: 6px 2px; color: var(--text-2); font-size: 0.95rem; }

/* The finished job (WISH-2173): Text the pay link and Next job where the swipe was, one under the other, because side by side at
   375px "Text the pay link" has no room. Next job is the plain one when there's a link to text, and the bright one when not. */
.finished { display: flex; flex-direction: column; gap: 8px; }
.finished .button { width: 100%; gap: 8px; }
.finished .button .icon { width: 20px; height: 20px; }

.dock-out { display: flex; flex-direction: column; align-items: center; padding: 10px; border-radius: 14px; background: var(--amber); color: var(--on-amber); font-weight: 800; }
.dock-out-why { font-size: 0.8125rem; font-weight: 600; }

/* ── the swipe ──────────────────────────────────────────────────────────────────────────── */

.swipe-hint, .swipe-saves { font-size: 0.875rem; color: var(--text-2); }

.places { display: grid; grid-template-columns: 3fr 2fr; gap: 8px; }

.place {
    display: flex;
    align-items: center;
    gap: 6px;
    min-height: 52px;
    min-width: 0;
    padding: 4px 10px;
    border-radius: 12px;
    border: 2px solid var(--line);
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.2;
    text-align: left;
}

.place.is-on { border-color: var(--amber); background: var(--warn-bg); }
/* Two lines at most: a driver choosing a place has to be able to read which place. */
.place-words { min-width: 0; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }

.swipe {
    --swipe-p: 0;
    position: relative;
    height: 64px;
    border-radius: 32px;
    background: var(--surface-2);
    overflow: hidden;
    touch-action: pan-y;
    user-select: none;
    -webkit-user-select: none;
}

.swipe-fill { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--amber); }
.swipe.is-settling .swipe-fill { transition: width 220ms ease; }
.swipe.is-holding .swipe-fill { width: 100%; transition: width 1000ms linear; }
.swipe.is-danger .swipe-fill { background: var(--bad); }

.swipe-words {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 0 16px 0 72px;
    text-align: center;
    pointer-events: none;
    opacity: calc(1 - var(--swipe-p) * 1.5);
}

.swipe-label { font-size: 1.0625rem; font-weight: 800; }
.swipe-under { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.8125rem; font-weight: 600; color: var(--text-2); }

.swipe-thumb {
    position: absolute;
    top: 4px;
    left: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--amber);
    color: var(--on-amber);
    touch-action: none;
    cursor: grab;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}

.swipe-thumb .icon { width: 32px; height: 32px; }
.swipe-thumb:disabled { background: var(--line); color: var(--text-2); box-shadow: none; cursor: default; }
.swipe.is-danger .swipe-thumb { background: var(--bad); color: #ffffff; }
/* A red swipe still waiting on something (the cancel card's reason) is as grey as any other that can't be swiped. */
.swipe.is-danger .swipe-thumb:disabled { background: var(--line); color: var(--text-2); box-shadow: none; }
.swipe.is-dragging .swipe-thumb { cursor: grabbing; }
.swipe.is-settling .swipe-thumb { transition: transform 220ms cubic-bezier(0.2, 0.9, 0.3, 1.2); }
.swipe.is-hinting .swipe-thumb { animation: swipe-hop 600ms ease; }

@keyframes swipe-hop {
    35% { transform: translateX(26px); }
    70% { transform: translateX(-3px); }
}

.undo {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 64px;
    padding: 0 8px 0 18px;
    border-radius: 18px;
    background: var(--amber);
    color: var(--on-amber);
    overflow: hidden;
    font-weight: 700;
}

.undo-bar { position: absolute; left: 0; bottom: 0; height: 5px; width: 100%; background: rgba(0, 0, 0, 0.45); transform-origin: left; animation: undo-run 5s linear forwards; }

@keyframes undo-run { to { transform: scaleX(0); } }

.undo-words { flex: 1; min-width: 0; }
.undo-button { display: flex; align-items: center; gap: 6px; min-height: 48px; padding: 0 16px; border-radius: 14px; background: var(--on-amber); color: var(--amber); font-weight: 800; }

/* ── the sheets ─────────────────────────────────────────────────────────────────────────── */

.scrim { position: fixed; inset: 0; z-index: 4; background: rgba(0, 0, 0, 0.55); animation: fade 160ms ease; }
.scrim.is-top { z-index: 6; }

.sheet {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 5;
    display: flex;
    flex-direction: column;
    max-height: calc(100% - var(--top) - 32px);
    border-radius: 20px 20px 0 0;
    background: var(--bg);
    animation: rise 200ms cubic-bezier(0.2, 0.8, 0.3, 1);
}

@keyframes rise { from { transform: translateY(28px); opacity: 0.4; } }
@keyframes fade { from { opacity: 0; } }

.sheet-head { flex: none; display: flex; align-items: center; justify-content: space-between; padding: 8px 6px 4px var(--gutter); }
.sheet-head h2 { font-size: 1.2rem; font-weight: 800; }
.sheet-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; padding: 4px var(--gutter) calc(var(--bottom) + 16px); }

.stage { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; border-radius: var(--radius); background: var(--surface); }
.stage-head { display: flex; align-items: flex-start; gap: 10px; }
.stage-icon { flex: none; display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 50%; background: var(--surface-2); color: var(--text-2); }
.stage.is-done .stage-icon { background: var(--good); color: var(--bg); }
.stage.is-waiting .stage-icon { background: var(--amber); color: var(--on-amber); }
.stage.is-next .stage-icon { background: var(--amber); color: var(--on-amber); }
.stage.is-locked .stage-title { color: var(--text-2); }
.stage-text { display: flex; flex-direction: column; min-width: 0; }
.stage-title { font-weight: 700; }
.stage-sub, .stage-place { font-size: 0.9rem; color: var(--text-2); }
.stage-badge { margin-left: 6px; padding: 0 7px; border-radius: 9px; background: var(--surface-2); font-size: 0.75rem; font-weight: 700; }

/* The cancel card (WISH-2174), as the trip page's: a reason, a note and a red swipe. 16px in the boxes, because an iPhone
   zooms into anything smaller, and 48px to tap. */
.stage.cancel .stage-icon { background: var(--bad-bg); color: var(--bad); }
.stage.cancel .stage-text { flex: 1; }
.cancel-field { display: flex; flex-direction: column; gap: 4px; font-size: 0.875rem; font-weight: 600; color: var(--text-2); }
.cancel-field select, .cancel-field textarea {
    width: 100%;
    min-height: 48px;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--bg);
    color: var(--text);
    font: inherit;
    font-size: 16px;
    font-weight: 400;
}
.cancel-field textarea { resize: vertical; }
.cancel-field select:focus, .cancel-field textarea:focus { border-color: var(--accent-text); outline: none; }
.cancel-undo { flex: none; display: flex; align-items: center; gap: 6px; min-height: 48px; padding: 0 14px; border-radius: 14px; border: 2px solid var(--line); font-weight: 800; }
.cancel-undo .icon { width: 20px; height: 20px; }

.sheet.is-full { height: 100%; }

.chat-closed { color: var(--text-2); }
.chat-lines { padding-bottom: 8px; }
.chat-line { max-width: 88%; padding: 8px 12px; border-radius: var(--radius); background: var(--surface); white-space: pre-line; overflow-wrap: anywhere; }
.chat-line.is-driver { align-self: flex-end; background: var(--amber); color: var(--on-amber); }
.chat-line.is-waiting { color: var(--text-2); }
.chat-line a { color: inherit; text-decoration: underline; }
.chat-problem { color: var(--text-2); font-size: 0.9rem; }
.chat-buttons { display: flex; flex-wrap: wrap; gap: 6px; max-width: 88%; }
.chat-reply, .chat-link { min-height: 44px; max-width: 100%; padding: 6px 14px; border-radius: 22px; font-weight: 700; text-align: left; overflow-wrap: anywhere; }
.chat-reply { border: 1px solid var(--accent-text); color: var(--accent-text); }
.chat-link { display: inline-flex; flex-direction: column; justify-content: center; background: var(--surface-2); }
.chat-link-words { display: inline-flex; align-items: center; gap: 6px; }
.chat-site { font-size: 0.8125rem; font-weight: 400; color: var(--text-2); }

/* A report Ask wrote up (WISH-2135 slice 4): a card in its own right, set apart from the answer above it. */
.chat-report { display: flex; flex-direction: column; gap: 6px; max-width: 88%; padding: 12px; border: 1px solid var(--accent-text); border-radius: var(--radius); background: var(--surface); }
.chat-report-head { color: var(--accent-text); font-size: 0.8125rem; font-weight: 700; }
.chat-report-title { font-weight: 700; overflow-wrap: anywhere; }
.chat-report-words { white-space: pre-line; overflow-wrap: anywhere; }
.chat-report-note { color: var(--text-2); font-size: 0.875rem; }
.chat-report .button { align-self: flex-start; }
.sheet-tools { display: flex; align-items: center; gap: 4px; }
.chat-again { min-height: 44px; padding: 0 12px; border-radius: 22px; color: var(--accent-text); font-weight: 700; }
.chat-erase { font-weight: 700; }
.chat-erase-row { display: flex; gap: 8px; }
.chat-erase-row .button { flex: 1; }

.chat-box { flex: none; display: flex; flex-direction: column; gap: 6px; padding: 8px var(--gutter) calc(var(--bottom) + 8px); border-top: 1px solid var(--line); }
.chat-row { display: flex; align-items: flex-end; gap: 8px; }

/* 16px, because an iPhone zooms the page into anything smaller when it gets the keyboard. */
.chat-row textarea {
    flex: 1;
    min-width: 0;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: 16px;
    resize: none;
}

.chat-send { flex: none; display: flex; align-items: center; justify-content: center; width: 48px; height: 48px; border-radius: 50%; background: var(--amber); color: var(--on-amber); }
.chat-send:disabled { background: var(--surface-2); color: var(--text-2); }

.ask {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 7;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 18px var(--gutter) calc(var(--bottom) + 16px);
    border-radius: 20px 20px 0 0;
    background: var(--surface);
    animation: rise 200ms cubic-bezier(0.2, 0.8, 0.3, 1);
}

.ask h2 { font-size: 1.3rem; font-weight: 800; }
.ask ul { padding-left: 1.2rem; list-style: disc; }
.ask-buttons { display: grid; grid-template-columns: 1fr 1.4fr; gap: 8px; margin-top: 6px; }
.ask-buttons .button { padding: 0 10px; }

/* Call and Text, from the passenger's name (WISH-2167): the dock's two buttons, a row for each person. With everyone else
   travelling on it too (WISH-2171) it can outgrow a small phone, so the window stops short of the top, as the sheets do, and
   the list scrolls under the heading, which keeps Close in reach. */
.people { max-height: calc(100% - var(--top) - 32px); }
.people-head { flex: none; display: flex; align-items: center; justify-content: space-between; margin: -10px -10px -4px 0; }
.people-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; display: flex; flex-direction: column; gap: 10px; }
.person { display: flex; flex-direction: column; gap: 8px; }
.person-name { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; }
.person-name strong { font-size: 1.1rem; font-weight: 800; overflow-wrap: anywhere; }
.person-name span { font-size: 0.9rem; color: var(--text-2); }
.person-actions { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 8px; }

/* The fare window (WISH-2167). 16px or more in the box, because an iPhone zooms into anything smaller. */
.fare-now, .fare-advice { color: var(--text-2); }
.fare-box { display: flex; align-items: center; gap: 6px; min-height: 60px; padding: 0 14px; border: 2px solid var(--line); border-radius: 14px; background: var(--bg); font-size: 1.6rem; font-weight: 800; }
.fare-box:focus-within { border-color: var(--accent-text); }
.fare-box input { flex: 1; min-width: 0; padding: 0; border: 0; background: none; color: var(--text); font: inherit; font-variant-numeric: tabular-nums; outline: none; }
.fare-box input::placeholder { color: var(--text-2); font-weight: 600; }
.fare-problem { color: var(--bad); font-size: 0.95rem; font-weight: 600; }
.fare-notes { display: flex; flex-direction: column; gap: 4px; padding-left: 1.1rem; list-style: disc; color: var(--text-2); font-size: 0.875rem; }
.fare-saved { font-size: 1.1rem; font-weight: 700; }
.fare .button:disabled { opacity: 0.45; cursor: default; }

/* The Pay link window (WISH-2170). Tall enough for two people and their words, and it scrolls on a small phone. */
.paylink { max-height: 92vh; overflow-y: auto; }
.ask .paylink-warnings { display: flex; flex-direction: column; gap: 4px; padding: 10px 12px 10px 1.9rem; border-radius: 12px; background: var(--warn-bg); font-size: 0.9rem; }
.paylink-words { padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--bg); font-size: 0.95rem; overflow-wrap: anywhere; }
.paylink .button.is-primary { gap: 8px; }
.paylink .button .icon { width: 20px; height: 20px; }
.paylink-opened { color: var(--good); font-weight: 700; }
.paylink-foot, .paylink-wait { color: var(--text-2); font-size: 0.9rem; }

#blazor-error-ui {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 9;
    padding: 14px var(--gutter) calc(var(--bottom) + 14px);
    background: var(--bad-bg);
    font-weight: 600;
}

#blazor-error-ui a { text-decoration: underline; }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: 1ms !important; transition-duration: 1ms !important; }
    .undo-bar { animation-duration: 5s !important; }
    .flight-check.is-checking .icon { animation: none; }
}

.menu-card { flex: none; display: flex; align-items: center; gap: 12px; width: 100%; min-height: 64px; padding: 10px 12px; border-radius: var(--radius); background: var(--surface); text-align: left; }
.menu-card.is-closed { opacity: 0.55; }
.menu-card .icon { color: var(--accent-text); }
.menu-card-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.menu-card-text strong { font-weight: 700; }
.menu-card-text span { font-size: 0.9rem; color: var(--text-2); }
.menu-item { flex: none; display: flex; align-items: center; width: 100%; min-height: 44px; padding: 0 12px; border-radius: 10px; text-align: left; }
.menu-item.is-danger { color: var(--bad); font-weight: 700; }
.menu-warn { padding: 0 12px; font-size: 0.9rem; color: var(--text-2); }
.menu-foot { padding: 0 12px; font-size: 0.75rem; color: var(--text-2); }

.jobs-tabs { flex: none; display: flex; gap: 8px; padding: 4px var(--gutter) 8px; }
.jobs-tab { flex: 1; min-height: 44px; border-radius: 12px; background: var(--surface); color: var(--text-2); font-weight: 700; }
.jobs-tab[aria-selected="true"] { background: var(--amber); color: var(--on-amber); }
.jobs-words { color: var(--text-2); }
.jobs-end { flex: none; height: 1px; }

.job-row { flex: none; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; padding: 10px 12px; border-radius: var(--radius); background: var(--surface); }
.job-when { font-size: 0.9rem; color: var(--text-2); }
.job-when strong { color: var(--text); font-weight: 700; }
.job-fare { display: inline-flex; align-items: center; gap: 4px; font-weight: 800; }
.job-paid { display: inline-flex; color: var(--good); }
.job-who { grid-column: 1 / -1; font-size: 1.05rem; font-weight: 700; overflow-wrap: anywhere; }
.job-line { grid-column: 1 / -1; font-size: 0.9rem; color: var(--text-2); overflow-wrap: anywhere; }
.job-note { grid-column: 1 / -1; font-size: 0.9rem; font-weight: 700; color: var(--bad); }
