/* AOA FlightDesk — dark, glove-friendly, mobile-first. Grows over phases. */
:root {
  /* ===== Surfaces — AOA warm-charcoal dark ramp (was cool navy) ===== */
  --navy: #161312;    /* page background      (AOA --ink) */
  --navy-2: #2a2523;  /* raised controls: inputs, steppers, iconbtn, avatars, tabbar, chips */
  --panel: #211d1c;   /* cards / sheets       (AOA --ink-elevated) */
  /* ===== The one accent — AOA orange (canonical) ===== */
  --orange: #f47321;      /* brand: fills, rails, icons, active, selection */
  --orange-dim: #d5641c;  /* pressed/active state of orange controls */
  /* ===== Text on dark (AOA on-ink roles) ===== */
  --text: #f3efe9;    /* primary text — warm paper */
  --muted: #b9b2ac;   /* secondary / metadata */
  --cream: #f3efe9;   /* light accent (tail pills etc.) */
  /* ===== Status — dark-tuned from AOA's CALM palette (never SaaS-neon) ===== */
  --green: #4caf7d;   /* success / confirmed */
  --amber: #d9a441;   /* caution / suggested / stale / sync-waiting */
  --red: #e0616a;     /* ERROR / destructive ONLY */
  /* ===== Warm hairlines (replace hardcoded cool-navy borders) ===== */
  --line: #34302d;    /* borders on controls */
  --divider: #2b2624; /* row/section dividers */
  --press: #2f2927;   /* pressed row/step fill */
  /* ===== AOA type stack ===== */
  --font-display: 'Oswald', 'Arial Narrow', sans-serif;          /* headings, buttons, labels, tabs — uppercase */
  --font-body: 'Roboto', system-ui, -apple-system, sans-serif;   /* body copy */
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;        /* numbers, Hobbs, durations, codes */
  /* ===== AOA structural tokens ===== */
  --orange-soft: rgba(244,115,33,0.10);            /* tint bg for rails/active */
  --focus-ring: 0 0 0 3px rgba(244,115,33,0.15);   /* the AOA orange focus glow */
  --shadow-elevated: 0 8px 32px rgba(0,0,0,0.35);  /* sheets / toast / lightbox */
  /* ===== unchanged ===== */
  --radius: 14px;   /* == AOA --r-xl */
  --tap: 56px; /* minimum touch target — glove-friendly, do not shrink */
  --maxw: 560px;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--navy);
  color: var(--text);
  font: 16px/1.45 var(--font-body);
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}
.app { max-width: var(--maxw); margin: 0 auto; min-height: 100vh; display: flex; flex-direction: column; }
.boot { padding: 40px; text-align: center; color: var(--muted); }

.screen { padding: 20px 18px 96px; flex: 1; }
.brand { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; margin: 8px 0 22px; }
.brand .logo { width: auto; height: 20px; max-width: 100%; border-radius: 0; background: none; }
.brand h1 { font-family: var(--font-display); font-weight: 700; font-size: 20px; margin: 0; letter-spacing: .3px; }
.brand .sub { color: var(--muted); font-size: 13px; }

h2 { font-family: var(--font-display); font-weight: 600; font-size: 18px; margin: 0 0 14px; }
.card { background: var(--panel); border-radius: var(--radius); padding: 18px; margin-bottom: 16px; }
label { display: block; font-family: var(--font-display); font-weight: 600; text-transform: uppercase; letter-spacing: .08em; font-size: 13px; color: var(--muted); margin: 0 0 6px; }
input[type=text], input[type=email], input[type=password], input[type=number], input[type=date], select, textarea {
  width: 100%; min-height: var(--tap); padding: 12px 14px; margin-bottom: 14px;
  background: var(--navy-2); border: 1px solid var(--line); border-radius: 10px;
  color: var(--text); font-family: var(--font-body); font-size: 17px; /* 17px avoids iOS zoom-on-focus */
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--orange); border-color: var(--orange); box-shadow: var(--focus-ring); }
button:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }

.btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; min-height: var(--tap); border: none; border-radius: 10px;
  background: var(--orange); color: var(--navy);
  font-family: var(--font-display); font-weight: 600; text-transform: uppercase; letter-spacing: .08em; font-size: 17px;
  cursor: pointer; padding: 0 18px;
}
.btn:active { background: var(--orange-dim); }
.btn:focus-visible { outline-color: var(--cream); }
.btn[disabled] { opacity: .5; }
.btn.secondary { background: transparent; color: var(--text); border: 1px solid var(--line); }
.btn.ghost { background: transparent; color: var(--muted); border: none; }

.msg { padding: 12px 14px; border-radius: 10px; margin-bottom: 14px; font-size: 14px; }
.msg.err { background: rgba(224,97,106,.14); color: #ffb4b4; border: 1px solid rgba(224,97,106,.4); }
.msg.ok  { background: rgba(76,175,125,.14); color: #b6f2d6; border: 1px solid rgba(76,175,125,.4); }

.row { display: flex; gap: 12px; align-items: center; }
.spacer { flex: 1; }
.muted { color: var(--muted); }
.center { text-align: center; }
.footer-badge { text-align: center; font-family: var(--font-mono); color: var(--muted); font-size: 12px; padding: 20px 0; }

/* --- shell + tab bar --- */
.shell { display: flex; flex-direction: column; min-height: 100vh; }
.screen-host { flex: 1; }
.tabbar {
  position: sticky; bottom: 0; display: flex; gap: 2px;
  background: var(--navy-2); border-top: 1px solid var(--divider);
  padding: 6px 6px calc(6px + env(safe-area-inset-bottom));
}
.tab {
  flex: 1; min-height: 52px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  background: transparent; border: none; color: var(--muted); font-family: var(--font-display); text-transform: uppercase; letter-spacing: .08em; font-size: 11px; font-weight: 600; cursor: pointer; border-radius: 10px;
}
.tab .ic { font-size: 20px; line-height: 1; }
.tab.active { color: var(--orange); background: var(--orange-soft); }

/* --- section header with action --- */
.sec-head { display: flex; align-items: center; margin: 6px 0 14px; }
.sec-head h2 { margin: 0; }
.iconbtn { min-width: 44px; min-height: 44px; border-radius: 10px; border: 1px solid var(--line); background: var(--navy-2); color: var(--text); font-size: 22px; cursor: pointer; }

/* --- list rows --- */
.list { display: flex; flex-direction: column; gap: 10px; }
.rowcard { display: flex; align-items: center; gap: 12px; background: var(--panel); border-radius: 12px; padding: 14px 16px; min-height: var(--tap); cursor: pointer; border: none; width: 100%; text-align: left; color: var(--text); }
.rowcard:active { background: var(--press); }
.avatar { width: 40px; height: 40px; border-radius: 50%; background: var(--navy-2); display: grid; place-items: center; font-weight: 800; color: var(--orange); flex: none; }
.rowcard .main { flex: 1; min-width: 0; }
.rowcard .name { font-weight: 700; }
.rowcard .meta { color: var(--muted); font-size: 13px; }
.pill { font-family: var(--font-display); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; padding: 3px 9px; border-radius: 999px; background: var(--navy-2); color: var(--muted); }
.pill.goal { color: var(--cream); }
.pill.stale { color: var(--amber); }

.thumb { width: 48px; height: 48px; border-radius: 8px; object-fit: cover; background: var(--navy-2); flex: none; }
/* Native-button wrapper for a row thumbnail — the tap opens the lightbox reliably
   on iOS (a bare <img> click listener often doesn't fire on touch). */
.thumb-btn { flex: none; width: 48px; height: 48px; padding: 0; border: none; border-radius: 8px; background: var(--navy-2); overflow: hidden; cursor: zoom-in; }
.thumb-btn .thumb { display: block; width: 100%; height: 100%; }
.empty { text-align: center; color: var(--muted); padding: 40px 20px; }
.stub { text-align: center; color: var(--muted); padding: 48px 24px; }
.stub .big { font-size: 40px; margin-bottom: 10px; }

/* --- modal sheet --- */
.sheet-bg { position: fixed; inset: 0; background: rgba(0,0,0,.5); display: flex; align-items: flex-end; justify-content: center; z-index: 50; }
.sheet { background: var(--navy-2); width: 100%; max-width: var(--maxw); border-radius: 18px 18px 0 0; padding: 20px 18px calc(20px + env(safe-area-inset-bottom)); box-shadow: 0 -6px 24px rgba(0,0,0,0.35); }
.sheet h2 { margin-top: 0; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.chip { min-height: 44px; padding: 0 16px; border-radius: 999px; border: 1px solid var(--line); background: var(--navy-2); color: var(--text); font-family: var(--font-display); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; cursor: pointer; }
.chip.on { background: var(--orange); color: var(--navy); border-color: var(--orange); }
.chip.sm { min-height: 38px; padding: 0 12px; font-size: 13px; }
.chip.mod { border-style: dashed; }
.chip.mod.on { border-style: solid; }
/* One-time (un-rostered) student: selected, but a dashed orange outline so it
   reads as distinct from a filled roster-student chip and from Other. */
.chip.onetime { background: var(--navy-2); color: var(--orange); border: 1px dashed var(--orange); }

/* --- badges / pill variants --- */
.pill.open { background: rgba(244,115,33,.18); color: var(--orange); }
.pill.tail { background: rgba(243,239,233,.14); color: var(--cream); font-family: var(--font-mono); letter-spacing: .02em; font-variant-numeric: tabular-nums; }
.pill.ok { background: rgba(76,175,125,.18); color: var(--green); }
.pill.info { background: rgba(93,173,226,.18); color: #9fd3f2; }
.pill.warn { background: rgba(217,164,65,.18); color: var(--amber); }
.avatar.sm { width: 34px; height: 34px; font-size: 15px; position: relative; }
.solo-dot { position: absolute; right: -2px; bottom: -2px; color: var(--orange); font-size: 20px; line-height: 1; }
.rowcard.pinned { border: 1px solid var(--orange); }
.rowcard.sel { outline: 2px solid var(--orange); }
.rowactions { display: flex; flex-direction: column; gap: 4px; }
.linkbtn { background: none; border: none; color: var(--orange); font-family: var(--font-display); text-transform: uppercase; letter-spacing: .06em; font-weight: 600; font-size: 13px; cursor: pointer; padding: 6px 8px; }

/* --- steppers --- */
.stepper, .ground-ctl { display: flex; align-items: center; gap: 6px; }
.stepbtn { min-width: 48px; min-height: 48px; border-radius: 10px; border: 1px solid var(--line); background: var(--navy-2); color: var(--text); font-size: 20px; font-weight: 800; cursor: pointer; }
.stepbtn:active { background: var(--press); }
.stepval { min-width: 46px; text-align: center; font-family: var(--font-mono); font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
.locked .stepbtn { opacity: .4; pointer-events: none; }
.locked .stepval { opacity: .5; }

/* --- capture-card header + aircraft switcher --- */
.log-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.log-head h2 { margin: 0; }
.acf-switch { margin-bottom: 0; flex-wrap: wrap; justify-content: flex-end; }
.acf-switch[hidden] { display: none; }
/* SIM tag inside an aircraft-switcher chip (blue, matches .pill.info palette). */
.pill.sim { margin-left: 6px; padding: 1px 6px; font-size: 10px; background: rgba(93,173,226,.22); color: #9fd3f2; }

/* --- flight card --- */
.fcard { }
.field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 8px; }
.field-grid > div { min-width: 0; }
.ldg-wrap { display: flex; flex-direction: column; gap: 6px; }
.dur-line { font-family: var(--font-mono); font-weight: 700; color: var(--orange); margin: 12px 0; font-size: 16px; }
.otherbox { margin-bottom: 12px; }
/* sim session-time field (replaces the Hobbs meter grid in sim mode) */
.sim-time { margin: 4px 0 14px; }

/* --- progressive-disclosure sub-sections (instrument split, holds/full-stop) --- */
.disc-box { margin: 0 0 8px; }
.disc-box[hidden] { display: none; }

/* --- derived (server-owned) read-only value, e.g. the approaches sum --- */
.derived-val { min-height: 48px; display: flex; align-items: center; font-family: var(--font-mono); font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* --- approach detail rows --- */
.appr-detail { margin-bottom: 12px; }
.ar-list { display: flex; flex-direction: column; }
.approach-row {
  display: grid; gap: 8px; align-items: center; margin-bottom: 10px; padding-bottom: 10px;
  grid-template-columns: 1fr auto auto;
  grid-template-areas: "type count remove" "airport airport airport";
  border-bottom: 1px solid var(--divider);
}
.approach-row .ar-type { grid-area: type; margin-bottom: 0; min-height: 48px; }
.approach-row .ar-count { grid-area: count; }
.approach-row .ar-airport { grid-area: airport; margin-bottom: 0; }
.approach-row .ar-remove { grid-area: remove; min-width: 44px; min-height: 44px; color: var(--muted); }
.appr-add { width: auto; }

.hobbs-grid { display: grid; grid-template-columns: 1fr auto 1fr; gap: 8px; align-items: stretch; }
.harrow { display: grid; place-items: center; color: var(--muted); font-size: 22px; }
.hfield { background: var(--navy-2); border: 1px solid var(--line); border-radius: 12px; padding: 10px; min-height: 92px; }
.hfield.pending { border-color: var(--muted); }
.hfield.suggested { border-color: var(--amber); }
.hfield.confirmed { border-color: var(--green); }
.hf-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-family: var(--font-display); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); font-weight: 600; margin-bottom: 6px; }
.hf-cam { background: none; border: none; padding: 0 2px; font-size: 15px; line-height: 1; cursor: pointer; opacity: .75; -webkit-tap-highlight-color: transparent; }
.hf-cam:active { opacity: 1; transform: scale(0.94); }
.hf-body { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.hf-crop { width: 100%; max-height: 60px; object-fit: cover; border-radius: 8px; background: var(--navy); }
.hf-val { font-family: var(--font-mono); font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; background: none; border: none; color: var(--text); cursor: pointer; padding: 2px 0; }
.hf-val.amber { color: var(--amber); text-decoration: underline; }
.hf-val.green { color: var(--green); }
.hf-confirm { min-width: 44px; min-height: 44px; border-radius: 999px; border: none; background: var(--green); color: var(--navy); font-size: 20px; font-weight: 800; cursor: pointer; margin-left: auto; }
.hf-note { font-size: 11px; color: var(--muted); margin-top: 6px; }
.hf-input { width: 100%; min-height: var(--tap); padding: 10px 12px; background: var(--navy); border: 1px solid var(--line); border-radius: 10px; color: var(--text); font-family: var(--font-mono); font-size: 20px; font-weight: 700; }
.hf-actions { display: flex; flex-direction: column; gap: 8px; }
.hf-shimmer { color: var(--muted); font-style: italic; }
.btn.sm { min-height: 44px; font-size: 15px; }

/* --- banners --- */
.banners { }
.banner { border-radius: 10px; padding: 12px 14px; margin: 10px 0; font-size: 14px; }
.banner.block { background: rgba(224,97,106,.14); border: 1px solid rgba(224,97,106,.4); color: #ffb4b4; }
.banner.warn { background: rgba(217,164,65,.14); border: 1px solid rgba(217,164,65,.4); color: #ffe3a3; }
.banner-msg { margin-bottom: 8px; }
.banner-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.banner-btn { min-height: 40px; padding: 0 14px; border-radius: 8px; border: 1px solid currentColor; background: transparent; color: inherit; font-weight: 700; cursor: pointer; }

/* --- savebar (bottom-anchored primary action) --- */
/* Sticky above the ~64px tab bar (52px tabs + 12px padding + safe-area) so the
   Log/Save button clears it instead of overlapping the tab labels. */
.savebar { position: sticky; bottom: calc(70px + env(safe-area-inset-bottom)); margin-top: 18px; display: flex; flex-direction: column; gap: 8px; }
.btn.danger { color: var(--red); }

/* --- month --- */
.monthnav { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.monthlabel { flex: 1; text-align: center; font-family: var(--font-display); font-weight: 600; font-size: 17px; }
.stat-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; }
.stat { background: var(--panel); border-radius: 12px; padding: 14px 10px; text-align: center; }
.stat-val { font-family: var(--font-mono); font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
.stat-lbl { font-family: var(--font-display); text-transform: uppercase; letter-spacing: .08em; font-size: 11px; color: var(--muted); margin-top: 4px; }
.meter-card { text-align: center; }
.meter-big { font-family: var(--font-mono); font-size: 26px; font-weight: 700; color: var(--orange); }
.note-box { padding: 12px 14px; background: var(--navy-2); border-radius: 10px; font-size: 13px; margin: 14px 0; }

/* --- batch AIRPLANE control (put a whole day's flights on one airplane) --- */
/* Sits above the flight cards; one tap re-attributes every non-overridden flight,
   so two same-day flights can't sit on different meter chains and hide the gap. */
.batch-acf { background: var(--panel); border-radius: 12px; padding: 12px 14px; margin-bottom: 14px; border: 1px solid var(--line); }
.batch-acf-label { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .08em; font-size: 13px; color: var(--muted); margin-bottom: 8px; }
.batch-acf-row { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; }
.batch-acf-sub { font-family: var(--font-display); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; font-size: 13px; color: var(--text); }
.batch-acf-row .chips { margin-bottom: 0; }
/* A mixed batch (flights split across airplanes) is exactly the bug — flag it. */
.batch-acf.mixed { border-color: rgba(217,164,65,.6); border-left: 4px solid var(--amber); }
.batch-acf-hint { margin-top: 10px; font-size: 13px; color: #ffe3a3; }
.batch-acf-hint[hidden] { display: none; }

/* --- pairing --- */
.pair-card { background: var(--panel); border-radius: 12px; padding: 14px; margin-bottom: 12px; }
.pair-rail { border-left: 3px solid var(--orange); padding-left: 12px; }
/* .pair-photo is a native <button> (iOS-reliable tap) that wraps the meter image
   AND its value — button chrome reset so it reads as the photo, not a control. */
.pair-photo { display: flex; align-items: center; gap: 8px; margin: 4px 0; width: 100%; padding: 0; border: none; background: none; color: inherit; font: inherit; text-align: left; cursor: zoom-in; }
.pair-photo span { font-family: var(--font-mono); font-weight: 700; font-variant-numeric: tabular-nums; }
.pair-mid { font-size: 13px; color: var(--muted); margin: 6px 0; display: flex; align-items: center; gap: 10px; }
.studentpick { margin-top: 12px; }
/* per-card DATE (editable) + TIME (read-only, from the photo) */
.pair-datetime { display: flex; gap: 12px; margin-top: 12px; align-items: flex-start; }
.pair-datetime .pdt-date { flex: 1; min-width: 0; }
.pair-datetime .pdt-time { flex: none; }
.pair-datetime input[type=date] { margin-bottom: 0; }
.pair-time { min-height: var(--tap); display: flex; flex-direction: column; justify-content: center; font-family: var(--font-mono); font-weight: 700; font-variant-numeric: tabular-nums; }
.pair-time .hf-note { margin-top: 2px; }
.pair-note { margin-bottom: 4px; }
/* SELECT control — full-width toggle. Kept tap-friendly (≥50px) but lower-emphasis
   than the primary "Log selected" button so it doesn't dominate the card:
   unselected reads muted/secondary, selected lights orange. */
.selbtn { margin-top: 2px; min-height: 50px; font-size: 15px; letter-spacing: .05em; }
.selbtn:not(.on) { color: var(--muted); border-color: var(--line); font-weight: 600; }
.selbtn.on { background: var(--orange-soft); border-color: var(--orange); color: var(--orange); }
.pair-selecthint { font-size: 12px; color: var(--muted); margin-top: 6px; }
/* Select all / Clear affordance above the bottom "Log selected" button */
.pair-bulk { display: flex; gap: 16px; justify-content: center; }

/* Pairing photos: LARGE + tap-to-enlarge so the meter digits are readable. Scoped
   to .pair-photo so inbox/unpaired row .thumb (48px) stays compact. */
.pair-photo .pair-thumb { width: 104px; height: 104px; border-radius: 10px; cursor: zoom-in; }
.pair-photo .pair-thumb:active { opacity: .85; }
.pair-photo span { font-size: 20px; }

/* --- MANUAL (photoless gap-fill) card --- */
/* Same rail as a photo card, but the two Hobbs readings are editable inputs (typed
   entry) instead of meter photos. The rail flips amber and a dashed tag marks it as
   a no-photo entry so it's never mistaken for a photographed flight. */
.pair-rail.manual { border-left-color: var(--amber); }
.pair-manual-input { margin: 6px 0; }
.pair-manual-input label { margin-bottom: 4px; }
.pair-hobbs { font-family: var(--font-mono); font-weight: 700; font-variant-numeric: tabular-nums; font-size: 20px; margin-bottom: 0; }
.manual-tag { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; font-size: 12px; color: var(--amber); }
/* (The photoless card's old "Remove" link folded into the unified Delete below —
   it did exactly what Delete does, and one label per action beats two.) */

/* --- SPLIT LEG (photographed at one end, typed at the other) --- */
/* A leg is a real photographed flight at one end and a value Chris typed at the
   other, so it gets the orange rail (it is a photo flight) drawn DASHED (one end
   isn't). No new colour — the dash carries the difference. */
.pair-rail.split { border-left-style: dashed; }

/* --- per-card ACTIONS (Unpair / Split / Delete) --- */
/* Every action for a card lives in one predictable place: the .pair-mid line
   between the two readings. They wrap as a group so the duration never separates
   from the flight it describes. Delete is the destructive token (--red, the one
   sanctioned use) but stays a small text link — quieter than the Select button
   and far quieter than "Log selected", which is the primary flow. */
.pair-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; }
.card-delete { color: var(--red); }

/* --- the SPLIT panel (type the intermediate Hobbs) --- */
.pair-split-slot:empty { display: none; }
.split-box { margin: 0 0 12px; padding: 12px 14px; border-radius: 10px; background: var(--navy-2); border: 1px dashed var(--line); }
.split-box[hidden] { display: none; }
.split-chain { font-family: var(--font-mono); font-weight: 700; font-variant-numeric: tabular-nums; font-size: 18px; margin-bottom: 8px; }
.split-chain .split-q { color: var(--orange); }
.split-box .split-mid { margin-bottom: 12px; }
.split-box .chips { margin-bottom: 0; }
.split-hint { font-size: 12px; color: var(--muted); margin-top: 10px; }
.split-err:empty { display: none; }
.split-err { color: var(--red); font-size: 13px; margin-top: 8px; }

/* --- LOGGED (locked, read-only) card --- */
/* A committed flight persists on the page so Chris can watch the day fill in.
   Dimmed with a green "✓ LOGGED" badge and a compact committed summary; no
   editable controls, no select checkbox. Its photos stay small + tap-to-enlarge. */
.pair-card.logged { opacity: .74; border: 1px solid rgba(76,175,125,.35); background: linear-gradient(0deg, rgba(76,175,125,.05), rgba(76,175,125,.05)), var(--panel); }
.pair-logged-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 12px; margin-bottom: 10px; }
.logged-badge { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .07em; font-size: 14px; color: var(--green); }
.logged-hobbs { font-family: var(--font-mono); font-weight: 700; font-variant-numeric: tabular-nums; font-size: 16px; color: var(--text); }
.pair-logged-body { display: flex; gap: 12px; align-items: flex-start; }
.logged-photos { display: flex; gap: 6px; flex: none; }
.logged-thumb-btn { padding: 0; border: none; background: none; cursor: zoom-in; flex: none; }
.logged-thumb { width: 52px; height: 52px; border-radius: 8px; }
.logged-meta { flex: 1; min-width: 0; font-size: 14px; }
.logged-line { margin: 2px 0; }
.logged-line.strong { font-weight: 700; }
.logged-line.muted { color: var(--muted); font-size: 13px; }
.logged-line.note { color: var(--muted); font-style: italic; }

/* --- all-logged done banner (bottom bar) --- */
.pair-alllogged { text-align: center; font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--green); padding: 4px 0; }

/* --- per-card DISCREPANCY banner (prominent — bigger/bolder than a chip) --- */
.pair-banner-slot:empty { display: none; }
.pair-banner { border-radius: 10px; padding: 12px 14px; margin: 0 0 12px; }
.pair-banner.warn { background: rgba(217,164,65,.18); border: 1.5px solid rgba(217,164,65,.55); color: #ffe3a3; }
.pair-banner.block { background: rgba(224,97,106,.18); border: 1.5px solid rgba(224,97,106,.6); color: #ffb4b4; }
.pair-banner.ok { background: rgba(76,175,125,.16); border: 1px solid rgba(76,175,125,.5); color: #b6f2d6; }
.pb-head { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .07em; font-size: 15px; margin-bottom: 4px; }
.pair-banner.ok .pb-head { margin-bottom: 0; }
.pb-msg { font-size: 14px; margin-bottom: 10px; }
.pb-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.pb-btn { min-height: 44px; padding: 0 14px; border-radius: 8px; border: 1px solid currentColor; background: transparent; color: inherit; font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; font-size: 13px; cursor: pointer; }
.pb-btn:active { opacity: .8; }
.pb-reason { margin-top: 10px; }
.pb-reason[hidden] { display: none; }
.pb-reason-inp { margin-bottom: 8px; }
.pb-msg-err { color: var(--red); font-size: 13px; }

/* --- between-cards GAP MARKER (a likely MISSING flight) --- */
/* An inter-card separator, NOT a card: full-width amber block with generous
   vertical margin + a heavy left rail so it reads as a break in the timeline
   sitting between two flights. Flips green once the gap is waived. */
.gap-marker { margin: 4px 0 14px; padding: 12px 14px; border-radius: 10px; background: rgba(217,164,65,.14); border: 1px dashed rgba(217,164,65,.7); border-left: 4px solid var(--amber); color: #ffe3a3; }
.gap-marker.resolved { background: rgba(76,175,125,.14); border: 1px solid rgba(76,175,125,.5); border-left: 4px solid var(--green); color: #b6f2d6; }
.gap-line { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; }
.gap-badge { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .07em; font-size: 15px; color: var(--amber); }
.gap-badge.ok { color: var(--green); }
.gap-text { font-size: 14px; }
.gap-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.gap-reason { margin-top: 10px; }
.gap-reason[hidden] { display: none; }
.gap-reason-inp { margin-bottom: 8px; }

/* --- pairing SUMMARY bar (what the engine found + the one-tap ACCEPT ALL) --- */
/* The headline of the screen: the count, the photo ledger that proves nothing
   vanished, and the primary Accept. Accept SELECTS — the note says so out loud,
   because committing hours to a logbook stays a deliberate second action. */
.pair-summary { background: var(--panel); border: 1px solid var(--line); border-left: 4px solid var(--orange); border-radius: 12px; padding: 14px 16px; margin-bottom: 14px; }
.ps-head { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; font-size: 17px; }
.ps-ledger { font-family: var(--font-mono); font-size: 12px; font-variant-numeric: tabular-nums; color: var(--muted); margin-top: 4px; }
.ps-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-top: 12px; }
.ps-side { font-size: 13px; color: var(--amber); }
.ps-note { font-size: 12px; color: var(--muted); margin-top: 8px; }

/* --- DAY sections (the shape Chris thinks in: one heading per day flown) ---
   THE DAY IS ONE CARD. Chris, 2026-08-10: "the date and 'Set this day' at the
   top, and then everything down below — that should all be one card."
   It used to be a floating heading with a divider under it and detached
   .pair-cards below, so the header didn't visibly own its flights and a
   multi-flight day read as unrelated pieces. Now: the day is a bounded panel,
   the header is its header, and each flight is an inset block INSIDE it — so a
   one-flight day (the common case) reads as exactly one card, and a
   three-flight day reads as one day containing three. */
.day-sec {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 2px 12px 12px;
  margin-bottom: 16px;
}
.day-head { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px; padding: 12px 2px 10px; border-bottom: 1px solid var(--divider); }
/* min-width forces the ACTION BUTTONS to wrap as a group to the next line when
   things get tight, instead of the summary line breaking mid-Hobbs-range
   ("4695.5 →" / "4696.1"), which is unreadable. */
.day-titlewrap { flex: 1 1 auto; min-width: 200px; }
.day-title { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .07em; font-size: 15px; }
.day-sum { font-family: var(--font-mono); font-size: 12px; font-variant-numeric: tabular-nums; color: var(--muted); }
.day-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.day-btn { min-height: 44px; padding: 0 14px; border-radius: 999px; border: 1px solid var(--line); background: var(--navy-2); color: var(--text); font-family: var(--font-display); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; font-size: 13px; cursor: pointer; }
.day-btn.accept { background: var(--orange-soft); border-color: var(--orange); color: var(--orange); }
.day-btn:active { opacity: .8; }
.day-accepted { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; font-size: 12px; color: var(--green); }
.day-body { padding-top: 12px; }
.batch-acf.day-batch { margin: 12px 0; }

/* A flight INSIDE a day card. It can't stay on --panel or it dissolves into the
   day card it now sits in, so it steps up to the raised surface with a border —
   the same "nested item" treatment the rest of the app uses for controls. The
   last one drops its trailing margin so the day card closes tight. */
.day-sec .pair-card {
  background: var(--navy-2);
  border: 1px solid var(--line);
}
.day-sec .day-body > :last-child { margin-bottom: 0; }

/* ONE FLIGHT THAT DAY = ONE CARD, FULL STOP. Chris asked for "the entire flight
   should be one card", and a lone flight boxed inside a day box is still two
   boxes. When it's the only thing in the day, the flight dissolves INTO the day
   card and the day card simply IS the flight card. A day with two or more keeps
   the inset treatment above, because there the boxes are carrying real meaning —
   they're telling you which reading belongs to which flight. */
.day-sec .day-body > .pair-card:only-child {
  background: transparent;
  border: none;
  padding: 0;
}

/* --- the CONFIDENCE strip (the engine explaining itself, on every card) --- */
/* Driven by timingClass, never hidden: green when the clock backs up the meter,
   amber when a photo was shot hours off, red when the pairing is impossible. */
.pair-conf-slot:empty { display: none; }
.pair-conf { border: 1px solid var(--line); background: var(--navy-2); border-radius: 10px; padding: 10px 12px; margin: 0 0 12px; }
.pc-head { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; font-size: 13px; }
.pc-msg { font-size: 13px; color: var(--muted); margin-top: 4px; }
.pair-conf.tight { background: rgba(76,175,125,.10); border-color: rgba(76,175,125,.35); }
.pair-conf.tight .pc-head { color: var(--green); }
.pair-conf.loose { background: rgba(217,164,65,.14); border-color: rgba(217,164,65,.5); }
.pair-conf.loose .pc-head { color: var(--amber); }
.pair-conf.loose .pc-msg { color: #ffe3a3; }
.pair-conf.impossible { background: rgba(224,97,106,.14); border-color: rgba(224,97,106,.5); }
.pair-conf.impossible .pc-head { color: var(--red); }
.pair-conf.impossible .pc-msg { color: #ffb4b4; }
.pair-conf.unknown .pc-head, .pair-conf.hand .pc-head { color: var(--muted); }

/* --- Current Flight timer panels (ground-run protection, migration 0007) ---
   The shutdown page's Current Flight column measures THE FLIGHT; the meter
   delta measures METER MOVEMENT. These panels are where the difference —
   ground running that must never be billed to a student — gets said out loud:
   three plain numbers, the billing proposal, and the waive-as-maintenance
   escape hatch for the "0.2 with no timer" runup. */
.pair-timer-slot:empty { display: none; }
.timer-panels { margin: 0 0 12px; display: flex; flex-direction: column; gap: 8px; }
.pair-timer { border-radius: 10px; padding: 10px 12px; border: 1px solid var(--line); background: var(--navy-2); }
.pt-head { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; font-size: 13px; }
.pt-note { font-size: 13px; color: var(--muted); margin-top: 4px; }
.pt-nums { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 6px; font-size: 13px; }
.pt-nums strong { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 15px; }
.pt-bill { margin-top: 8px; }
.pt-acts { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin-top: 8px; }
.pt-alt { font-size: 12px; color: var(--muted); }
.pair-timer.ok { background: rgba(76,175,125,.10); border-color: rgba(76,175,125,.35); padding: 8px 12px; }
.pair-timer.ok .pt-head { color: var(--green); }
.pair-timer.ground,
.pair-timer.suspect,
.pair-timer.short { background: rgba(217,164,65,.14); border-color: rgba(217,164,65,.5); }
.pair-timer.ground .pt-head,
.pair-timer.suspect .pt-head,
.pair-timer.short .pt-head { color: var(--amber); }
.pair-timer.ground .pt-nums { color: #ffe3a3; }
.pair-timer.ground .pt-note,
.pair-timer.suspect .pt-note,
.pair-timer.short .pt-note { color: #ffe3a3; }
.pair-timer.bad { background: rgba(224,97,106,.14); border-color: rgba(224,97,106,.5); }
.pair-timer.bad .pt-head { color: var(--red); }
.pair-timer.bad .pt-note { color: #ffb4b4; }

/* Possible-overcharge list (auditBilledVsTimer) — billed hours vs the flight
   timer, side by side. Generic classes so the meter-audit screen (or any list
   over logged flights) can render the audit without new styling. */
.overcharge-row { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 12px; }
.overcharge-nums { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-weight: 700; }
.overcharge-diff { color: var(--amber); font-weight: 700; }

/* --- collapsed retakes (a photo the engine folded away still has a link) --- */
.pair-dupe { display: flex; align-items: center; flex-wrap: wrap; gap: 2px 6px; font-size: 12px; color: var(--muted); margin: 2px 0 6px; }
.pair-dupe .linkbtn { padding: 6px 4px; font-size: 12px; }

/* --- ORPHAN card (a photo with no flight, carrying the engine's diagnosis) --- */
.orphan-card { align-items: flex-start; }
.orphan-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; }
.orphan-badge { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; font-size: 12px; color: var(--muted); }
.orphan-badge.warn { color: var(--amber); }
.orphan-badge.bad { color: var(--red); }
.orphan-hobbs { font-family: var(--font-mono); font-weight: 700; font-variant-numeric: tabular-nums; font-size: 16px; }
.orphan-diag { font-size: 13px; color: var(--muted); margin: 4px 0; }
.orphan-card .meta { margin-top: 2px; }

/* --- per-card override pin (a hand-set Purpose/Student the batch must skip) --- */
.pin-tag { font-family: var(--font-display); font-weight: 700; letter-spacing: .06em; font-size: 11px; color: var(--orange); margin-left: 8px; }
.pin-reset { padding: 2px 6px; font-size: 11px; }

/* --- batch PURPOSE + STUDENT strip (mirrors the batch AIRPLANE control) --- */
.batch-who .batch-acf-row { margin-top: 8px; }
.batch-acf-hint.plain { color: var(--muted); }

/* --- full-size photo lightbox --- */
.lightbox { position: fixed; inset: 0; z-index: 80; background: rgba(0,0,0,.92); display: flex; align-items: center; justify-content: center; padding: 24px; }
.lightbox-img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 8px; box-shadow: var(--shadow-elevated); }
.lightbox-close { position: absolute; top: calc(14px + env(safe-area-inset-top)); right: 16px; min-width: 48px; min-height: 48px; border-radius: 999px; border: 1px solid rgba(243,239,233,.3); background: rgba(0,0,0,.45); color: var(--cream); font-size: 22px; cursor: pointer; }

/* --- reconcile --- */
.recon-sec { margin-bottom: 12px; }
.recon-head { display: flex; justify-content: space-between; align-items: center; width: 100%; min-height: var(--tap); background: var(--panel); border: none; border-radius: 12px; padding: 0 16px; color: var(--text); font-weight: 700; cursor: pointer; }
.recon-body { padding: 8px 4px; }
.recon-row { padding: 8px 4px; font-size: 13px; border-bottom: 1px solid var(--divider); }
.recon-title { font-weight: 800; margin: 18px 0 10px; font-size: 15px; }
.recon-card { background: var(--panel); border-radius: 12px; padding: 14px; margin-bottom: 10px; }
.recon-line { margin-bottom: 4px; }
.recon-hint { font-size: 12px; margin: 6px 0; }
.recon-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.recon-cands { display: flex; flex-direction: column; margin-top: 8px; }
.chev { color: var(--muted); }

/* --- offline sync banner --- */
.syncbar {
  position: sticky; top: 0; z-index: 40;
  background: rgba(217,164,65,.16); color: var(--amber);
  border-bottom: 1px solid rgba(217,164,65,.4);
  font-size: 13px; font-weight: 700; text-align: center;
  padding: 8px 14px;
}
.syncbar[hidden] { display: none; }
.syncbar-line { text-align: center; }
/* poison/skipped items — more urgent than the amber "waiting" line, so it reads
   as an error the user must act on (Retry / Discard). */
.syncbar-fail {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: 6px 12px; color: var(--red); font-weight: 700;
}
.syncbar-line + .syncbar-fail {
  margin-top: 6px; padding-top: 6px; border-top: 1px solid rgba(217,164,65,.4);
}
.syncbar-fail .sf-actions { display: flex; gap: 8px; }
.syncbar-fail .btn.sm {
  width: auto; min-height: 32px; padding: 0 12px; font-size: 13px; border-radius: 8px;
  border: 1px solid rgba(224,97,106,.5);
}
.syncbar-fail .btn.sm[data-a="retry"] { color: var(--amber); }
.syncbar-fail .btn.sm[data-a="discard"] { color: var(--red); }

/* --- add-to-home-screen coach card --- */
.a2hs { display: flex; align-items: center; gap: 12px; }
.a2hs .a2hs-body { flex: 1; min-width: 0; font-size: 14px; }
.a2hs .btn.ghost.sm { width: auto; flex: none; padding: 0 14px; }

/* --- toast --- */
.toast { position: fixed; left: 50%; bottom: 90px; transform: translateX(-50%) translateY(20px); background: var(--panel); color: var(--text); padding: 12px 18px; border-radius: 999px; border: 1px solid var(--green); box-shadow: var(--shadow-elevated); font-weight: 700; opacity: 0; transition: opacity .25s, transform .25s; z-index: 60; max-width: 90%; text-align: center; }
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* --- re-read control (inbox: backfill the OCR fields 0006 added) ---
   Deliberately quiet. It sits under the primary "Pair into flights" button and
   must never compete with it — this is the chore that makes pairing good, not
   the job itself. The progress bar is the one moving element, and it moves
   because a run that spends money should visibly be spending it. */
.reread { margin-bottom: 14px; }
.reread .btn { margin-top: 8px; }
.reread-line { font-size: 13px; color: var(--muted); line-height: 1.45; }
.reread-line.warn { color: var(--amber); }
.reread-bar { height: 4px; border-radius: 999px; background: var(--navy-2); overflow: hidden; margin-top: 8px; }
.reread-bar > span { display: block; height: 100%; background: var(--orange); border-radius: 999px; transition: width .25s ease; }
/* Cost block in the confirm sheet — the number Chris is agreeing to spend, so
   it gets the mono treatment every other real number in the app gets. */
.reread-est { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 14px; line-height: 1.5; margin-bottom: 12px; }
.reread-est .muted { font-size: 12px; }
.reread-guarantee { font-size: 12px; line-height: 1.5; }

/* --- respect reduced-motion (AOA calm-motion doctrine) --- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}

/* ============================================================================
   DESKTOP / WIDE LAYOUT — everything below is additive and lives behind a
   min-width query. The phone layout above is untouched and pixel-identical.
   ----------------------------------------------------------------------------
   The brief is Chris's real desktop workflow: shoot Hobbs photos at the
   airplane on the phone, then sit at the Mac and bulk-reconcile a whole day.
   So the two screens that actually get better here are the photo INBOX and the
   PAIRING screen — more flights on screen, bigger meter photos, less scrolling.
   Everything else just has to stay calm and legible at width.
   No new colors, no new fonts — existing :root tokens only.
   ========================================================================= */
@media (min-width: 900px) {
  :root {
    --rail-w: 196px;      /* left nav rail (was the bottom tab bar) */
    --frame-w: 1360px;    /* the centred app frame */
    --content-w: 1080px;  /* readable cap for a screen inside the main column */
    --pad-x: 34px;        /* .screen horizontal padding at width */
    --pair-photo-w: 200px;/* meter-photo column inside a pairing card */
  }

  /* --- the frame ------------------------------------------------------ */
  .app { max-width: var(--frame-w); }

  /* Pre-auth: loginScreen() mounts a bare .screen straight into .app (there is
     no .shell yet). Keep it a narrow centred card, not a frame-wide form. */
  .app > .screen { max-width: 460px; margin: 0 auto; padding: 7vh 20px 60px; }

  /* Authed shell → nav rail + main column. Source order is
     syncbar / screen-host / tabbar, so placement is by named area. */
  .shell {
    display: grid;
    grid-template-columns: var(--rail-w) minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas:
      "rail sync"
      "rail main";
  }
  .syncbar { grid-area: sync; }
  .screen-host { grid-area: main; min-width: 0; }

  /* --- bottom tab bar → left vertical nav rail ------------------------ */
  /* Sticky + 100vh so the tabs stay put while a long pairing list scrolls. */
  .tabbar {
    grid-area: rail;
    position: sticky; top: 0; align-self: start; height: 100vh;
    flex-direction: column; justify-content: flex-start; gap: 4px;
    padding: 26px 12px;
    border-top: none;
    border-right: 1px solid var(--divider);
    overflow-y: auto;   /* very short windows keep every tab reachable */
  }
  .tab {
    flex: none; flex-direction: row; justify-content: flex-start;
    gap: 12px; min-height: 48px; padding: 0 14px; font-size: 13px;
  }
  .tab .ic { font-size: 19px; width: 22px; text-align: center; }
  .tab.active { box-shadow: inset 3px 0 0 var(--orange); }  /* AOA orange rail */

  /* --- main column ---------------------------------------------------- */
  /* The 96px bottom padding existed only to clear the phone tab bar. */
  .screen { max-width: var(--content-w); margin: 0 auto; padding: 26px var(--pad-x) 56px; }
  .brand { margin: 2px 0 26px; gap: 8px 14px; }
  .brand .logo { height: 24px; }   /* content-sized — never stretches */
  .brand h1 { font-size: 24px; }
  h2 { font-size: 19px; }

  /* --- savebar: the +70px offset existed to clear the bottom tab bar --- */
  .savebar { bottom: 0; }
  /* Pairing puts .savebar directly in .screen → make it a real action bar:
     bulk links left, primary button right, full-bleed to the screen edges. */
  .screen > .savebar {
    flex-direction: row; align-items: center; justify-content: flex-end; gap: 14px;
    margin: 24px calc(-1 * var(--pad-x)) 0;
    padding: 14px var(--pad-x);
    background: var(--navy);
    border-top: 1px solid var(--divider);
  }
  .screen > .savebar > .btn { width: auto; min-width: 260px; }
  .screen > .savebar > .pair-bulk,
  .screen > .savebar > .pair-alllogged { margin-right: auto; padding: 0; }
  /* The flight card's savebar lives INSIDE the card. Sticking it is a phone
     affordance; on desktop the card fits, so let the buttons sit naturally. */
  .fcard > .savebar { position: static; margin-top: 20px; }
  .fcard > .savebar > .btn { max-width: 320px; }

  /* ==================================================================== */
  /* PAIRING / RECONCILIATION — the priority screen                       */
  /* ==================================================================== */
  /* DELIBERATELY NOT a multi-column card grid. .gap-marker is a POSITIONAL
     signal — "a flight is missing between this card and the one above it" —
     and its meaning is carried entirely by sitting in the vertical chain. In a
     2-up grid the next card is to the RIGHT, so a marker either forces a row
     break (reads as unrelated) or sits in a cell (reads as a card). Reading
     the meter chain correctly beats column count, so instead: ONE wide column
     with the cards laid out HORIZONTALLY — meter photos left, everything else
     right. That roughly halves card height, which is the same win. */
  /* Tighter than other screens on purpose: the card's right column holds chips
     and short fields, so extra width would just be dead space beside them. */
  .screen:has(#batchacf) { max-width: 980px; }

  /* Summary bar: headline on its own line, ledger left, ACCEPT ALL hard right. */
  .pair-summary { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 24px; padding: 16px 20px; }
  .pair-summary .ps-head { flex-basis: 100%; font-size: 19px; }
  .pair-summary .ps-ledger { flex: 1; min-width: 260px; margin-top: 0; }
  .pair-summary .ps-actions { margin-top: 0; justify-content: flex-end; }
  .pair-summary .ps-note { flex-basis: 100%; margin-top: 2px; }
  .pair-summary .ps-accept { width: auto; min-width: 220px; }

  /* Day heading — a real section rule once there's width to give it. */
  .day-head { margin-top: 20px; padding: 14px 0 10px; gap: 8px 18px; }
  .day-sec:first-child .day-head { margin-top: 0; }
  .day-title { font-size: 17px; }
  .day-sum { font-size: 13px; }
  .day-body { padding-top: 14px; }

  /* Batch purpose/student: the same horizontal strip as the airplane control.
     Two-class selector so it beats the .batch-acf { align-items: center } below —
     the label belongs beside the FIRST row, not floating between two of them. */
  .batch-acf.batch-who, .batch-acf.day-batch { align-items: flex-start; }
  .batch-who-rows { flex: 1; min-width: 340px; }
  .batch-who .batch-acf-row { margin-top: 0; }
  .batch-who .batch-acf-row + .batch-acf-row { margin-top: 10px; }

  .pair-card {
    display: grid;
    grid-template-columns: var(--pair-photo-w) minmax(0, 1fr);
    column-gap: 24px;
    padding: 18px 20px;
    margin-bottom: 18px;
  }
  .pair-card > * { grid-column: 2; min-width: 0; }
  .pair-card > .pair-banner-slot { grid-column: 1 / -1; }   /* banner spans the top */
  /* The engine's verdict on the pairing reads across the whole card, above the
     photos it is talking about — never squeezed into the form column. */
  .pair-card > .pair-conf-slot { grid-column: 1 / -1; }
  .pair-card > .pair-rail { grid-column: 1; grid-row: span 24; align-self: start; }

  /* One line at width: verdict left, the engine's sentence filling the rest. */
  .pair-conf { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 14px; padding: 12px 16px; }
  .pc-head { font-size: 14px; }
  .pc-msg { flex: 1; min-width: 320px; margin-top: 0; }

  /* Orphan rows sit in the day chain now (not #loose) — same bigger thumb, since
     the whole point is that Chris can read the meter digits. */
  .orphan-card .thumb-btn, .orphan-card .thumb { width: 72px; height: 72px; }
  .orphan-diag { font-size: 14px; max-width: 78ch; }   /* readable measure, not full-bleed */

  /* The meter photos are the thing being read — make them big. */
  .pair-rail { border-left-width: 4px; padding-left: 16px; }
  .pair-photo { flex-direction: column; align-items: stretch; gap: 6px; margin: 0; }
  .pair-photo .pair-thumb { width: 100%; height: auto; aspect-ratio: 4 / 3; }
  .pair-photo span { font-size: 26px; text-align: center; }
  .pair-mid { justify-content: center; margin: 10px 0; }

  /* Keep the form side scannable — single fields don't run 670px wide. */
  .pair-card .pair-datetime { max-width: 420px; }
  .pair-card .pair-note { max-width: 420px; }   /* flush with .pair-datetime */
  .pair-card .selbtn { max-width: 340px; }

  /* Logged (locked) cards keep their own compact layout — opting them out of
     the two-column grid, they only have two children. */
  .pair-card.logged { display: block; padding: 16px 20px; }
  .pair-logged-body { gap: 16px; }
  .logged-thumb { width: 72px; height: 72px; }

  /* GAP MARKER — unmistakable at width: heavier rail, more air above/below,
     actions pulled to the right, reason field wraps to its own line. */
  .gap-marker {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px 20px;
    margin: 14px 0 20px; padding: 14px 18px; border-left-width: 6px;
  }
  .gap-marker.resolved { border-left-width: 6px; }
  .gap-line { flex: 1; min-width: 280px; }
  .gap-badge { font-size: 16px; }
  .gap-actions { margin-top: 0; }
  .gap-reason { flex-basis: 100%; margin-top: 2px; }

  /* Batch airplane control — a deliberate horizontal strip, not a stretched box. */
  .batch-acf { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 20px; padding: 14px 18px; }
  .batch-acf-label { margin-bottom: 0; flex: none; }
  .batch-acf-row { flex: 1; min-width: 320px; }
  .batch-acf-hint { flex-basis: 100%; margin-top: 0; }

  /* Loose (unpaired / unreadable) photo rows below the cards — still photos
     being read, so give them a bigger thumb than the phone's 48px. */
  #loose .rowcard .thumb { width: 72px; height: 72px; }

  /* ==================================================================== */
  /* PHOTO INBOX — denser grid, bigger thumbnails                         */
  /* ==================================================================== */
  .screen:has(#picker) > #list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 12px;
  }
  .screen:has(#picker) > #list > .empty,
  .screen:has(#picker) > #list > .msg { grid-column: 1 / -1; }
  .screen:has(#picker) > #list .thumb-btn,
  .screen:has(#picker) > #list .thumb { width: 84px; height: 84px; }
  .screen:has(#picker) > #list .rowcard { padding: 12px 14px; }
  .screen:has(#picker) > #list .name { font-size: 17px; }   /* reading badge stays legible */
  .screen:has(#picker) > #pairBar > .btn { width: fit-content; min-width: 300px; }

  /* ==================================================================== */
  /* FLY — capture card beside Recent flights                             */
  /* ==================================================================== */
  /* Rows are placed EXPLICITLY, not auto-flowed. Auto-flow puts the tall Log
     card in one row, which then sizes that row — leaving a dead gap under the
     inbox link in the right column. Instead the card spans rows 4-9 and row 9
     is `1fr`: per the grid spec a spanning item contributes no intrinsic size
     across a flexible track, so rows 4-8 hug the right column's content and
     the card's leftover height is absorbed by the empty flexible row. */
  .screen:has(#logCard) {
    display: grid;
    grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr);
    grid-template-rows: auto auto auto auto auto auto auto auto 1fr;
    column-gap: 30px;
    align-items: start;
  }
  .screen:has(#logCard) > * { min-width: 0; }
  .screen:has(#logCard) > .brand        { grid-area: 1 / 1 / 2 / 3; }
  .screen:has(#logCard) > .a2hs         { grid-area: 2 / 1 / 3 / 3; }
  .screen:has(#logCard) > #openWrap     { grid-area: 3 / 1 / 4 / 3; }
  .screen:has(#logCard) > #logCard      { grid-area: 4 / 1 / 10 / 2; }
  .screen:has(#logCard) > #inboxLink    { grid-area: 4 / 2 / 5 / 3; }
  .screen:has(#logCard) > .sec-head     { grid-area: 5 / 2 / 6 / 3; }
  .screen:has(#logCard) > #recent       { grid-area: 6 / 2 / 7 / 3; }
  .screen:has(#logCard) > #logout       { grid-area: 7 / 2 / 8 / 3; }
  .screen:has(#logCard) > .footer-badge { grid-area: 8 / 2 / 9 / 3; }
  /* Log out is a chrome-less ghost .btn and base .btn is width:100% + centered.
     Stretched across the right column with no border or fill it stops reading as
     a control and becomes floating centred text in the column's dead space. At
     width, shrink it to its content and flush it to the column's left edge so it
     lines up with "Recent flights" and the rows above it; same for the build
     badge, which base CSS centres. Tap height (var(--tap)) is untouched. */
  .screen:has(#logCard) > #logout       { width: fit-content; padding-left: 0; }
  .screen:has(#logCard) > .footer-badge { text-align: left; }

  /* ==================================================================== */
  /* STUDENTS / MONTH — spend the width on rows, not on single fields      */
  /* ==================================================================== */
  /* Roster: the only other screen with a direct #list child (inbox has #picker). */
  .screen:has(#list):not(:has(#picker)) > #list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
    gap: 10px;
  }
  .screen:has(#list):not(:has(#picker)) > #list > .empty { grid-column: 1 / -1; }
  /* Student detail */
  .screen:has(#totals) { max-width: 880px; }
  .screen:has(#totals) > #flights {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
    gap: 10px;
  }
  /* Month */
  .screen:has(#mlabel) { max-width: 880px; }
  .screen:has(#mlabel) #body > .stat-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .screen:has(#mlabel) #body > .card:not(.meter-card) { max-width: 620px; }
  .screen:has(#mlabel) #body > .list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
    gap: 10px;
  }
  .screen:has(#mlabel) #body > .btn { width: fit-content; min-width: 220px; }

  /* --- narrow utility screens ----------------------------------------- */
  .screen:has(#pills) { max-width: 780px; }     /* flight detail / edit */
  .screen:has(#recon),                          /* garmin reconcile */
  .screen:has(#ma-body) { max-width: 860px; }   /* meter audit */

  /* --- forms: cap field widths so a flight card stays scannable -------- */
  .card input[type=text], .card input[type=email], .card input[type=password],
  .card input[type=number], .card input[type=date], .card select { max-width: 520px; }
  .field-grid { max-width: 560px; }
  .hobbs-grid { max-width: 620px; }
  .hf-crop { max-height: 120px; }   /* meter crop in the flight card — readable */

  /* --- sheets / lightbox / toast at width ------------------------------ */
  .sheet-bg { align-items: center; padding: 24px; }
  .sheet { border-radius: 18px; padding: 24px; max-height: 86vh; overflow-y: auto; }
  .lightbox-img { max-width: min(100%, 1100px); }
  .toast { bottom: 32px; }
}

/* --- pointer affordances (desktop has a mouse; the phone doesn't) ------- */
@media (min-width: 900px) and (hover: hover) {
  .rowcard:hover { background: var(--press); }
  .tab:hover:not(.active) { background: rgba(243,239,233,.05); color: var(--text); }
  .btn:not([disabled]):hover { background: var(--orange-dim); }
  .btn.secondary:not([disabled]):hover,
  .btn.ghost:not([disabled]):hover { background: var(--navy-2); }
  .chip:hover:not(.on) { border-color: var(--muted); }
  .iconbtn:hover, .stepbtn:hover, .recon-head:hover { background: var(--press); }
  .day-btn:hover { border-color: var(--muted); }
  .day-btn.accept:hover { border-color: var(--orange); background: rgba(244,115,33,.18); }
  .linkbtn:hover, .pb-btn:hover, .banner-btn:hover { text-decoration: underline; }
  .thumb-btn:hover, .logged-thumb-btn:hover { outline: 2px solid var(--orange); outline-offset: 2px; }
  .pair-photo:hover .pair-thumb { outline: 2px solid var(--orange); outline-offset: 2px; }
}

/* --- roomier tier: a wider rail and bigger meter photos once there's space -- */
@media (min-width: 1200px) {
  :root { --rail-w: 228px; --pair-photo-w: 240px; }
}

/* --- very wide screens: hairlines so the frame reads as deliberate ------- */
@media (min-width: 1500px) {
  :root { --content-w: 1160px; }
  .app { box-shadow: 1px 0 0 var(--divider), -1px 0 0 var(--divider); }
  .screen:has(#batchacf) { max-width: 1020px; }
}

/* --- Attribution queue ("who flew these?") -------------------------------
   The screen that turns meter-ledger entries into logbook entries. Grouped by
   day because that is the unit Chris actually remembers, and because naming a
   whole day in one tap is what keeps this from becoming another backlog. */
.daygroup { background: var(--panel); border-radius: 14px; padding: 14px 16px 16px; margin-bottom: 14px; border: 1px solid var(--line); }
.daygroup.busy { opacity: .55; pointer-events: none; }
.dg-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.dg-day { font-family: var(--font-display); font-weight: 700; font-size: 17px; letter-spacing: .01em; }
.dg-flights { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
/* A read-only row: the meter facts are settled and this screen cannot edit
   them, so it must not look tappable. */
.dg-flights .rowcard.static { cursor: default; background: var(--navy-2); padding: 10px 14px; min-height: 0; }
.dg-flights .rowcard.static .name { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-weight: 600; }
.dg-actions { display: flex; flex-direction: column; gap: 8px; }
.chiprow { display: flex; flex-wrap: wrap; gap: 8px; }
.chiprow.subtle { padding-top: 2px; }
.chip.ghost { background: transparent; color: var(--muted); border-style: dashed; }
.chip .avatar.sm { width: 24px; height: 24px; font-size: 12px; margin-right: 8px; }
