:root { --ink: #0B1B24; --brass: #A8844A; --mineral: #53798F; }
* { box-sizing: border-box; } body { margin: 0; font: 16px/1.4 system-ui, sans-serif; color: var(--ink); background: #f4f6f7; }
#bar { position: sticky; top: 0; z-index: 5; display: flex; align-items: center; gap: 10px; padding: 10px 14px; background: var(--ink); color: #fff; }
#bar a { color: #fff; text-decoration: none; } .logo { font-family: Georgia, serif; font-size: 18px; flex: 1; } .gear { font-size: 22px; }
.net { font-size: 12px; padding: 2px 8px; border-radius: 10px; background: #2d6a4f; } .net.off { background: #9b1c1c; }
#testbanner { background: var(--brass); color: #fff; text-align: center; font-size: 12px; padding: 3px; }
#testbanner.live { background: #8a1c1c; font-size: 13px; padding: 6px 8px; }
#realconfirm { position: fixed; inset: 0; background: rgba(0,0,0,.55); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 16px; }
#realconfirm .card { max-width: 420px; width: 100%; }
#realconfirm button { min-height: 44px; min-width: 110px; }
main { padding: 12px; max-width: 720px; margin: 0 auto; }
.card { background: #fff; border-radius: 10px; padding: 12px; margin-bottom: 10px; box-shadow: 0 1px 2px rgba(0,0,0,.08); }
.card h2, .card h3 { margin: 0 0 6px; } .muted { color: #5b6b74; font-size: 14px; } .row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
button, .btn { font: inherit; border: 0; border-radius: 8px; padding: 12px 14px; min-height: 46px; background: var(--mineral); color: #fff; cursor: pointer; text-decoration: none; display: inline-block; }
button.sec { background: #e3e9ec; color: var(--ink); } button.warn { background: #9b1c1c; } button.go { background: #2d6a4f; } button:disabled { opacity: .5; }
.choice button { background: #e3e9ec; color: var(--ink); min-width: 64px; } .choice button.on { background: var(--mineral); color: #fff; }
label { display: block; font-weight: 600; margin: 10px 0 4px; } input, select, textarea { width: 100%; font: inherit; padding: 10px; border: 1px solid #c9d3d9; border-radius: 8px; background: #fff; }
textarea { min-height: 70px; } .ref { font-size: 13px; color: var(--mineral); margin-top: 2px; } .err { color: #9b1c1c; font-size: 13px; }
.status { font-size: 12px; padding: 2px 8px; border-radius: 10px; background: #e3e9ec; } .status.held { background: #f6d7a7; } .status.submitted { background: #cfe8d9; }
.hold { background: #fff4e0; border-left: 4px solid var(--brass); padding: 8px; margin: 8px 0; } .notice { background: #eef4f7; padding: 8px; border-radius: 8px; margin: 6px 0; font-size: 14px; }
canvas.sig { width: 100%; height: 140px; border: 1px dashed #9aa; border-radius: 8px; background: #fff; touch-action: none; }
iframe.preview { width: 100%; height: 70vh; border: 1px solid #c9d3d9; background: #fff; } .sticky { position: sticky; bottom: 0; background: #f4f6f7; padding: 8px 0; }
/* Offline batch (24 Oct): "Ready for offline" in the bar; results of forms issued by the phone's queue; waiting photos */
#bar .net.ready { border: 0; color: #fff; font: inherit; font-size: 12px; line-height: 1.4; padding: 2px 8px; min-height: 0; width: auto; margin: 0; border-radius: 10px; background: #2d6a4f; cursor: pointer; }
#bar .net.ready.stale { background: #6b5a2e; }
.fr-result { background: #eef4f7; padding: 8px; border-radius: 8px; margin: 6px 0; font-size: 14px; }
.fr-result.warn { background: #fdf0e6; border-left: 4px solid #9b1c1c; }
.fr-result button.link, .fr-result a.link { background: none; border: 0; padding: 0; color: inherit; text-decoration: underline; font: inherit; width: auto; }
figure.waiting img { opacity: .7; outline: 2px dashed #A8844A; }

/* iPhone sweep (Test Bot mobile sweep 24 Oct, E-1..E-3): 320-430 px wide, keyboard up.
   E-1: input rows wrap instead of squeezing: a .full input/select takes its own line; numbers share a line at >= 120 px each. */
.frow > input, .frow > select { flex: 1 1 120px; min-width: 120px; width: auto; }
.frow > .full { flex: 1 1 100%; }
.frow > button { flex: 0 0 auto; min-width: 64px; }
.frow > label { flex: 1 1 auto; }
/* E-2 / E-3 and the rest of the bar: tap targets at least 44 x 44 px */
#bar .logo, #bar .gear { display: inline-flex; align-items: center; min-height: 44px; }
#bar .gear { min-width: 44px; justify-content: center; }
#bar .net.ready { min-height: 44px; display: inline-flex; align-items: center; padding: 2px 12px; border-radius: 22px; }
summary { min-height: 44px; display: flex; align-items: center; gap: 6px; cursor: pointer; list-style: none; }
summary::-webkit-details-marker { display: none; }
summary::before { content: '▸'; } details[open] > summary::before { content: '▾'; }
button.sec { min-width: 44px; }
/* keyboard up: a focused field is scrolled clear of the sticky top bar and any sticky bottom bar */
html { scroll-padding-top: 72px; scroll-padding-bottom: 96px; }
/* keyboard up (short viewport): the sticky bottom bar stops floating, so it can't cover the field being typed in */
@media (max-height: 520px) { .sticky { position: static; } }
a.back { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }
/* F-3 (Test Bot 042a44f): the "Franklyn Robinson" heading stays on one line at 320-430 px; the small status pills give way instead */
#bar .logo { white-space: nowrap; flex: 1 0 auto; }
#bar .net { text-align: center; }   /* min-width stays auto, so a word never sticks out of its pill */
@media (max-width: 400px) { #bar { gap: 6px; padding: 8px 10px; } #bar .logo { font-size: 15px; } #bar .net.ready { padding: 2px 8px; } }
/* Test Bot 5e978c9 lows: the Ready pill never collapses to a sliver while it loads (min 44 px) and its words stay on one line.
   At 320 px there is no room for both pills on one line beside the heading, so under 360 px only one shows: "Ready for
   offline" while online with nothing waiting (the plain "online" pill steps aside), otherwise the sync / offline pill. */
#bar [hidden] { display: none !important; }
#bar .net.ready { min-width: 44px; white-space: nowrap; justify-content: center; }
@media (max-width: 359px) { #bar:has(#ready:not([hidden])) #net.plain { display: none; } #bar:has(#net:not(.plain)) #ready { display: none; } }
/* Test Bot b4859db M-1: with the other pill showing (offline, 'N to sync'), 'Ready for offline' wraps to two lines INSIDE its
   pill (it is the one screen Frankie looks at with no signal, so it stays visible); alone, it keeps to one line. */
#bar:has(#net:not(.plain)) #ready { white-space: normal; }
