/* Pascoe Field Services — Air Conditioning
 *
 * Two layouts share one set of tokens. The office layout is dense and
 * information-first; the field layout is sparse, high-contrast and built around
 * targets a gloved thumb can hit. Nothing here is decorative for its own sake:
 * the only strong colour in the product is status colour, so that when
 * something is overdue it is the brightest thing on the screen.
 */

:root {
  /* Ink and paper. A slate navy rather than black — it stays legible on a
     phone screen in daylight without the harshness of pure black on white. */
  --ink:        #0f1b28;
  --ink-2:      #3c4c5e;
  --ink-3:      #6b7c8f;
  --line:       #dfe5ec;
  --line-2:     #eef2f6;
  --paper:      #ffffff;
  --paper-2:    #f6f8fb;
  --paper-3:    #eef2f7;

  --navy:       #0f2740;
  --navy-2:     #17405f;
  --accent:     #0b6bcb;
  --accent-ink: #ffffff;

  --good:       #10714a;
  --good-bg:    #e3f5ec;
  --warn:       #8a5200;
  --warn-bg:    #fdf0da;
  --danger:     #a3211c;
  --danger-bg:  #fdeae9;
  --info:       #10457f;
  --info-bg:    #e6f0fb;

  --r:    10px;
  --r-sm: 7px;
  --shadow: 0 1px 2px rgba(15, 27, 40, .06), 0 4px 14px rgba(15, 27, 40, .05);
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, monospace;

  /* A phone is held at arm's length in bad light; 16px is the floor, and
     16px on inputs is also what stops iOS zooming the page on focus. */
  --tap: 46px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font: 16px/1.5 var(--sans);
  color: var(--ink);
  background: var(--paper-2);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { margin: 0 0 .4em; line-height: 1.25; font-weight: 650; letter-spacing: -.01em; }
h1 { font-size: 1.55rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--navy); color: #fff; padding: .7rem 1rem;
}
.skip:focus { left: 0; }

/* ----------------------------------------------------------- office shell -- */

.app {
  display: grid;
  grid-template-columns: 220px 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas: "top top" "nav main";
  min-height: 100vh;
}

.topbar {
  grid-area: top;
  min-width: 0;
  display: flex; align-items: center; gap: 1rem;
  padding: .55rem 1rem;
  background: var(--navy);
  color: #fff;
  position: sticky; top: 0; z-index: 30;
}
.topbar a { color: #fff; }

.brand { display: flex; align-items: center; gap: .6rem; text-decoration: none; }
.brand:hover { text-decoration: none; }
.brand-mark {
  display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 8px;
  background: linear-gradient(150deg, #2f9be0, #0b6bcb);
  font: 700 12px/1 var(--sans); letter-spacing: .02em; color: #fff;
}
.brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.brand-text b { font-size: .95rem; font-weight: 650; }
.brand-text i { font-style: normal; font-size: .72rem; color: #9fc4e4; }

/* min-width:0 on both, or the search input's intrinsic min-content width
   (a text input defaults to roughly 20 characters) refuses to shrink and
   drags the whole header past the edge of a phone. */
.topsearch { flex: 1 1 0; min-width: 0; max-width: 460px; margin-left: auto; }
.topsearch input {
  width: 100%; min-width: 0; height: 38px; padding: 0 .8rem;
  border: 1px solid rgba(255, 255, 255, .18); border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .1); color: #fff; font-size: .92rem;
}
.topsearch input::placeholder { color: #a9c3da; }
.topsearch input:focus { background: #fff; color: var(--ink); }

.who { display: flex; align-items: center; gap: .9rem; font-size: .82rem; }
.who-name { display: flex; flex-direction: column; line-height: 1.2; text-align: right; }
.who-name i { font-style: normal; color: #9fc4e4; font-size: .72rem; }
.who-link { border: 1px solid rgba(255,255,255,.28); border-radius: 999px; padding: .3rem .75rem; }
.who-link:hover { background: rgba(255,255,255,.12); text-decoration: none; }
.linkish {
  background: none; border: 0; color: #9fc4e4; cursor: pointer;
  font: inherit; padding: .3rem 0; text-decoration: underline;
}
.linkish:hover { color: #fff; }

.menu-toggle { display: none; background: none; border: 0; color: #fff; padding: .4rem; cursor: pointer; }
.menu-toggle svg { width: 24px; height: 24px; }

.sidenav {
  grid-area: nav;
  background: var(--paper);
  border-right: 1px solid var(--line);
  padding: .75rem .5rem;
  position: sticky; top: 53px; align-self: start;
  max-height: calc(100vh - 53px); overflow-y: auto;
}
.nav-item {
  display: flex; align-items: center; gap: .7rem;
  padding: .6rem .75rem; border-radius: var(--r-sm);
  color: var(--ink-2); font-size: .92rem; font-weight: 500;
}
.nav-item:hover { background: var(--paper-3); text-decoration: none; color: var(--ink); }
.nav-item.is-current { background: var(--info-bg); color: var(--info); font-weight: 600; }
.nav-item svg { width: 19px; height: 19px; flex: none; }

svg[viewBox] path { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

main#main { grid-area: main; padding: 1.25rem 1.5rem 4rem; max-width: 1400px; width: 100%;
  min-width: 0; }

.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 1.1rem;
}
.page-actions { display: flex; gap: .5rem; flex-wrap: wrap; }

.crumbs { font-size: .8rem; color: var(--ink-3); margin-bottom: .25rem; }
.crumbs i { margin: 0 .4rem; font-style: normal; color: var(--line); }

/* ------------------------------------------------------------- components -- */

.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  padding: 1.1rem;
  margin-bottom: 1.1rem;
}
.card > h2:first-child, .card > h3:first-child { margin-top: 0; }
.card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .75rem; margin: -.15rem 0 .85rem;
}
.card-head h2, .card-head h3 { margin: 0; }
.card-flush { padding: 0; overflow: hidden; }
.card-flush .card-head { padding: 1rem 1.1rem 0; margin-bottom: .6rem; }
/* The action bar under a flush card's table: the date, the engineer and the
   button that turns the list above into a job. It wraps onto its own rows on a
   phone rather than squeezing the button off the side. */
.cardfoot {
  padding: .85rem 1.1rem 1rem; border-top: 1px solid var(--line);
  background: var(--line-2); align-items: end; gap: .6rem .9rem;
}
.cardfoot .fld { margin: 0; }
.cardfoot .btn { align-self: end; }

/* The ordering queue's per-line form: a reference, a date and a button, sitting
   inside a table cell. It wraps rather than forcing the table wider, because the
   table is already the widest thing on the screen. */
.orderrow { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }

/* What this unit read last time, under the question on the engineer's checklist.
   Quiet enough not to compete with the question, dark enough to read outdoors. */
.lasttime { display: block; margin-top: .15rem; color: var(--ink-2); font-size: .82rem; }
.orderform { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }
.orderform input[type=text] { width: 8.5rem; }
.orderform input[type=date] { width: 9.5rem; }

.grid { display: grid; gap: 1.1rem; }
/* start, not stretch: a short card next to a long one should stay short
   rather than growing a field of empty white. */
.grid { align-items: start; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }

/* Answer tiles. Each one is a question the office needs answering, and the
   number is a link to the list that answers it. */
.tile {
  display: block; background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r); padding: .95rem 1.05rem; box-shadow: var(--shadow);
  color: inherit; border-left: 4px solid var(--line);
}
.tile:hover { text-decoration: none; border-color: var(--ink-3); }
.tile b { display: block; font-size: 2rem; font-weight: 680; line-height: 1.05; letter-spacing: -.02em; }
.tile span { display: block; font-size: .82rem; color: var(--ink-3); margin-top: .25rem; }
.tile-danger { border-left-color: var(--danger); } .tile-danger b { color: var(--danger); }
.tile-warn   { border-left-color: var(--warn); }   .tile-warn b   { color: var(--warn); }
.tile-good   { border-left-color: var(--good); }   .tile-good b   { color: var(--good); }
.tile-info   { border-left-color: var(--accent); } .tile-info b   { color: var(--info); }
.tile-zero b { color: var(--ink-3); }
.tile-zero { border-left-color: var(--line); }

.pill {
  display: inline-block; padding: .16rem .55rem; border-radius: 999px;
  font-size: .74rem; font-weight: 600; letter-spacing: .01em; white-space: nowrap;
  border: 1px solid transparent;
}
.pill-good    { background: var(--good-bg);   color: var(--good);   border-color: #bfe6d3; }
.pill-warn    { background: var(--warn-bg);   color: var(--warn);   border-color: #f2dcae; }
.pill-danger  { background: var(--danger-bg); color: var(--danger); border-color: #f3c5c2; }
.pill-info    { background: var(--info-bg);   color: var(--info);   border-color: #c3dcf5; }
.pill-neutral { background: var(--paper-3);   color: var(--ink-2);  border-color: var(--line); }

/* Wide tables scroll inside their own box; the page never scrolls sideways.
   `position: relative` is load-bearing. Without it, an absolutely positioned
   descendant — every .visually-hidden label in the row — is laid out against the
   viewport instead of against this box, so the overflow rule below does not
   clip it and the label sits at the table's full width. On the parts-required
   table that is 791px of table inside a 332px scroller: the labels are
   invisible, and the whole page scrolls 266px sideways on a phone because of
   them. Putting this box in their containing-block chain is what makes the
   clip apply. */
.tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; position: relative; }
table.data { width: 100%; border-collapse: collapse; font-size: .9rem; }
table.data th, table.data td {
  text-align: left; padding: .6rem .75rem; border-bottom: 1px solid var(--line-2);
  vertical-align: top;
}
table.data th {
  font-size: .74rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-3); font-weight: 650; background: var(--paper-2);
  border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 1;
}
table.data tbody tr:hover { background: var(--paper-2); }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data .mono { font-family: var(--mono); font-size: .84em; }
table.data tr.row-danger td:first-child { box-shadow: inset 3px 0 0 var(--danger); }
table.data tr.row-warn td:first-child   { box-shadow: inset 3px 0 0 var(--warn); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
  min-height: 40px; padding: .45rem 1rem;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--paper); color: var(--ink);
  font: 600 .9rem/1 var(--sans); cursor: pointer; text-decoration: none;
}
.btn:hover { background: var(--paper-2); text-decoration: none; border-color: var(--ink-3); }
.btn svg { width: 17px; height: 17px; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { background: #0959ab; border-color: #0959ab; }
.btn-danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn-danger:hover { background: #8b1c17; }
.btn-ghost { background: transparent; border-color: transparent; color: var(--accent); }
.btn-block { width: 100%; }
.btn-lg { min-height: var(--tap); font-size: 1rem; padding: .7rem 1.3rem; }
/* Anything an engineer taps outdoors gets the full target size. */
.fieldapp .btn { min-height: var(--tap); }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

.alert { padding: .7rem .9rem; border-radius: var(--r-sm); margin: 0 0 .9rem; font-size: .9rem; }
.alert-danger { background: var(--danger-bg); color: var(--danger); border: 1px solid #f3c5c2; }
.alert-warn   { background: var(--warn-bg);   color: var(--warn);   border: 1px solid #f2dcae; }
.alert-info   { background: var(--info-bg);   color: var(--info);   border: 1px solid #c3dcf5; }
.alert-good   { background: var(--good-bg);   color: var(--good);   border: 1px solid #bfe6d3; }

.flash {
  position: fixed; left: 50%; top: 12px; transform: translateX(-50%);
  z-index: 90; padding: .65rem 1.1rem; border-radius: 999px;
  box-shadow: var(--shadow); font-size: .9rem; font-weight: 550;
  max-width: calc(100vw - 2rem);
}
.flash-ok    { background: var(--good);   color: #fff; }
.flash-error { background: var(--danger); color: #fff; }
.flash-warn  { background: var(--warn);   color: #fff; }
/* The field header is fixed at the top, so a toast at 12px covers the site
   name an engineer is using to check they are in the right place. */
body.field .flash { top: calc(56px + env(safe-area-inset-top)); }

.empty {
  text-align: center; padding: 2.5rem 1rem; color: var(--ink-3);
  background: var(--paper); border: 1px dashed var(--line); border-radius: var(--r);
}
.empty h2 { color: var(--ink); }

.muted { color: var(--ink-3); }
.small { font-size: .84rem; }
.mono { font-family: var(--mono); }
.nowrap { white-space: nowrap; }
.stack > * + * { margin-top: .75rem; }
.row { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }
.spread { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }

/* Definition list used for record detail. */
.facts { display: grid; grid-template-columns: max-content 1fr; gap: .45rem 1.1rem; margin: 0; font-size: .92rem; }
.facts dt { color: var(--ink-3); font-size: .82rem; padding-top: .1rem; }
.facts dd { margin: 0; }

/* ------------------------------------------------------------------ forms -- */

.fld { margin-bottom: .9rem; }
.fld > label { display: block; font-size: .84rem; font-weight: 600; color: var(--ink-2); margin-bottom: .28rem; }
.fld abbr { color: var(--danger); text-decoration: none; margin-left: .15rem; }
.fld input, .fld select, .fld textarea {
  width: 100%; min-height: 42px; padding: .5rem .7rem;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--paper); color: var(--ink);
  font: 16px/1.4 var(--sans);   /* 16px stops iOS zooming on focus */
}
.fld textarea { min-height: 90px; resize: vertical; }
.fld input:focus, .fld select:focus, .fld textarea:focus { border-color: var(--accent); }
.fld small { display: block; margin-top: .25rem; font-size: .78rem; color: var(--ink-3); }
.fld-check { display: flex; align-items: center; gap: .6rem; }
.fld-check > label { order: 2; margin: 0; font-weight: 500; font-size: .95rem; }
.fld-check input { width: 22px; height: 22px; min-height: 0; flex: none; accent-color: var(--accent); }
.with-unit { display: flex; align-items: stretch; }
.with-unit input { border-radius: var(--r-sm) 0 0 var(--r-sm); }
.with-unit .unit {
  display: grid; place-items: center; padding: 0 .7rem; font-size: .84rem;
  background: var(--paper-3); border: 1px solid var(--line); border-left: 0;
  border-radius: 0 var(--r-sm) var(--r-sm) 0; color: var(--ink-2); white-space: nowrap;
}
.fldrow { display: grid; gap: 0 .9rem; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
fieldset { border: 0; padding: 0; margin: 0 0 1.2rem; }
fieldset > legend {
  font-size: .76rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); font-weight: 700; padding: 0 0 .5rem;
  border-bottom: 1px solid var(--line); width: 100%; margin-bottom: .8rem;
}

.filters { display: flex; gap: .6rem; flex-wrap: wrap; align-items: flex-end; margin-bottom: 1rem; }
.filters .fld { margin: 0; min-width: 150px; }

/* --------------------------------------------------------------- auth page -- */

body.auth { background: linear-gradient(160deg, #0f2740, #17405f 60%, #0b3552); min-height: 100vh; }
.authbox { max-width: 380px; margin: 0 auto; padding: 8vh 1.2rem 3rem; }
.authbrand { text-align: center; color: #fff; margin-bottom: 1.4rem; }
.authbrand .brand-mark { width: 52px; height: 52px; font-size: 16px; margin: 0 auto .8rem; }
.authbrand h1 { font-size: 1.3rem; margin-bottom: .1rem; }
.authbrand p { margin: 0; color: #9fc4e4; font-size: .9rem; }
/* Unified PASCOE medallion lockup, on the navy auth ground (the lockup always sits on navy).
   CSP here blocks Google Fonts, so the wordmark falls back to the Georgia serif — never sans. */
.pbs-lockup { display: flex; align-items: center; justify-content: center; gap: 16px; margin: 0 auto 1.6rem; }
.pbs-emblem { width: 58px; height: 58px; border-radius: 50%; object-fit: cover; background: transparent; flex: 0 0 auto; }
.pbs-wordmark { text-align: left; }
.pbs-appname { font-family: "Cinzel", Georgia, "Times New Roman", serif; font-weight: 600;
  letter-spacing: .05em; font-size: 26px; line-height: 1.05; color: #f3ead4; }
.pbs-rule { display: block; height: 2px; margin: 6px 0 5px;
  background: linear-gradient(90deg, #c9a24a, transparent); border-radius: 2px; }
.pbs-subline { font-family: "Cinzel", Georgia, "Times New Roman", serif; font-weight: 500;
  font-size: 9.5px; letter-spacing: .30em; color: #c9a24a; }

/* Sign-in form fields. The login markup uses wrapping <label>Text <input></label>
   (implicit association) rather than the .fld helper, so it inherited NO field
   styling: the label text sat inline to the left of the input and the two inputs
   were mismatched widths. Give them the same block layout .fld uses everywhere
   else, so Email and Password read as a clean, aligned, full-width stack. */
.authbox .card label {
  display: block; font-size: .84rem; font-weight: 600;
  color: var(--ink-2); margin-bottom: .9rem;
}
.authbox .card label input {
  display: block; width: 100%; min-height: 42px; margin-top: .28rem;
  padding: .5rem .7rem; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--paper); color: var(--ink); font: 16px/1.4 var(--sans);
}
.authbox .card label input:focus-visible { outline: 2px solid var(--navy); outline-offset: 1px; border-color: var(--navy); }
.authbox .card .btn-block { margin-top: .3rem; }

/* ------------------------------------------------------------ field shell -- */

body.field { background: var(--paper-2); }
.fieldapp { min-height: 100dvh; display: flex; flex-direction: column; }

.fieldbar {
  display: grid; grid-template-columns: 44px 1fr 44px; align-items: center;
  gap: .4rem; padding: max(.4rem, env(safe-area-inset-top)) .5rem .4rem;
  background: var(--navy); color: #fff; position: sticky; top: 0; z-index: 30;
}
.fieldbar h1 { font-size: 1.02rem; margin: 0; text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fieldbar a { color: #fff; display: grid; place-items: center; height: 40px; border-radius: 8px; }
.fieldbar a:hover { background: rgba(255,255,255,.12); text-decoration: none; }
.fieldbar svg { width: 24px; height: 24px; }
.back-spacer { display: block; }

.fieldmain { flex: 1; padding: .8rem .8rem calc(76px + env(safe-area-inset-bottom)); }

.tabbar {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 30;
  display: grid; grid-template-columns: repeat(4, 1fr);
  background: var(--paper); border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}
.tab {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .18rem; min-height: 58px; color: var(--ink-3); font-size: .7rem; font-weight: 600;
}
.tab:hover { text-decoration: none; }
.tab svg { width: 23px; height: 23px; }
.tab.is-current { color: var(--accent); }

/* A job as an engineer sees it: one tall card, everything readable at a glance. */
.jobcard {
  display: block; background: var(--paper); border: 1px solid var(--line);
  border-left: 5px solid var(--line); border-radius: var(--r);
  padding: .85rem .95rem; margin-bottom: .7rem; color: inherit; box-shadow: var(--shadow);
}
.jobcard:hover { text-decoration: none; }
.jobcard-danger { border-left-color: var(--danger); }
.jobcard-warn   { border-left-color: var(--warn); }
.jobcard-info   { border-left-color: var(--accent); }
.jobcard-good   { border-left-color: var(--good); }
.jobcard h3 { margin: 0 0 .2rem; font-size: 1.02rem; }
.jobcard .where { color: var(--ink-2); font-size: .9rem; }
.jobcard .meta { display: flex; gap: .4rem; flex-wrap: wrap; margin-top: .5rem; align-items: center; }

/* The big buttons that move a visit through its states. */
.bigaction {
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  width: 100%; min-height: 56px; font-size: 1.05rem; font-weight: 650;
  border-radius: var(--r); border: 1px solid var(--accent);
  background: var(--accent); color: #fff; cursor: pointer; margin-bottom: .7rem;
}
.bigaction:hover { background: #0959ab; }
.bigaction.secondary { background: var(--paper); color: var(--ink); border-color: var(--line); }
.bigaction.done { background: var(--good); border-color: var(--good); }
.bigaction svg { width: 22px; height: 22px; }

/* Checklist rows: label left, control right, whole row is the target. */
.check {
  display: flex; align-items: center; gap: .8rem; justify-content: space-between;
  padding: .7rem .2rem; border-bottom: 1px solid var(--line-2);
}
.check:last-child { border-bottom: 0; }
.check > .lbl { flex: 1; font-size: .95rem; }
.check > .lbl small { display: block; color: var(--ink-3); font-size: .76rem; }
.check .yesno { display: flex; gap: .4rem; flex: none; }
.check .yesno label {
  display: grid; place-items: center; min-width: 52px; min-height: var(--tap);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  font-size: .88rem; font-weight: 650; cursor: pointer; background: var(--paper);
}
.check .yesno input { position: absolute; opacity: 0; pointer-events: none; }
.check .yesno input:checked + span { color: #fff; }
.check .yesno label:has(input[value="1"]:checked) { background: var(--good); border-color: var(--good); color: #fff; }
.check .yesno label:has(input[value="0"]:checked) { background: var(--danger); border-color: var(--danger); color: #fff; }
.check .yesno label:has(input:focus-visible) { outline: 3px solid var(--accent); outline-offset: 2px; }
.check input[type="number"], .check input[type="text"], .check select {
  width: 118px; min-height: var(--tap); flex: none; text-align: right;
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: .4rem .6rem;
  font: 16px var(--sans);
}
.check .with-unit { flex: none; width: auto; }
.check .with-unit input { width: 84px; }

/* Signature capture. */
.sigpad {
  width: 100%; height: 190px; background: var(--paper);
  border: 2px dashed var(--line); border-radius: var(--r); touch-action: none;
  display: block;
}
.sigpad.signed { border-style: solid; border-color: var(--good); }

.thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: .5rem; }
.thumbs figure { margin: 0; }
.thumbs img {
  width: 100%; aspect-ratio: 1; object-fit: cover;
  border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--paper-3);
}
.thumbs figcaption { font-size: .7rem; color: var(--ink-3); margin-top: .2rem; }

.sectionhead {
  font-size: .74rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-3); font-weight: 700; margin: 1.2rem 0 .2rem;
}

/* -------------------------------------------------------------- responsive -- */

@media (max-width: 900px) {
  .app { grid-template-columns: 1fr; grid-template-areas: "top" "main"; }
  .menu-toggle { display: block; }
  .sidenav {
    position: fixed; inset: 53px auto 0 0; width: 230px; z-index: 40;
    transform: translateX(-100%); transition: transform .18s ease;
    max-height: none; height: calc(100dvh - 53px); box-shadow: var(--shadow);
  }
  .sidenav.is-open { transform: none; }
  .topsearch { max-width: none; }
  .brand-text { display: none; }
  .who-name, .who-link { display: none; }
  main#main { padding: 1rem .85rem 3rem; }
  .facts { grid-template-columns: 1fr; gap: .1rem .5rem; }
  .facts dd { margin-bottom: .5rem; }
}

@media (max-width: 560px) {
  h1 { font-size: 1.3rem; }
  .card { padding: .9rem; border-radius: 8px; }
  .page-head { align-items: stretch; }
  .page-actions .btn { flex: 1; }
}

@media print {
  .topbar, .sidenav, .tabbar, .fieldbar, .page-actions, .flash, .skip { display: none !important; }
  body { background: #fff; }
  .app { display: block; }
  main#main { padding: 0; max-width: none; }
  .card { border: 0; box-shadow: none; padding: 0; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* Pagination. Appears once a register outgrows a single page — which a real
   import does immediately: 1,765 assets is eighteen pages, not a scroll. */
.pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: .8rem; padding: .8rem 1.1rem; border-top: 1px solid var(--line);
  background: var(--paper-2);
}
.pager .btn[aria-disabled="true"] { opacity: .45; pointer-events: none; }

/* The outbox bar. Sits above the tab bar and is the only thing on the field
   screens allowed to be permanently visible, because an engineer needs to know
   at a glance whether their work has actually left the phone. */
.outbox {
  position: fixed; left: 0; right: 0; z-index: 40;
  bottom: calc(58px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: .5rem;
  padding: .55rem .9rem;
  font-size: .86rem; font-weight: 550;
  border-top: 1px solid rgba(0, 0, 0, .1);
}
.outbox b { font-size: 1.05rem; }
.outbox a { margin-left: auto; text-decoration: underline; color: inherit; }
.outbox-waiting { background: var(--warn-bg); color: var(--warn); }
.outbox-sending { background: var(--info-bg); color: var(--info); }
body.field .outbox:not([hidden]) ~ .fieldapp .fieldmain { padding-bottom: 120px; }

.queued {
  background: var(--paper); border: 1px solid var(--line);
  border-left: 4px solid var(--warn); border-radius: var(--r);
  padding: .8rem .9rem; margin-bottom: .6rem;
}
.queued.is-failed { border-left-color: var(--danger); }
.queued h3 { margin: 0 0 .2rem; font-size: .98rem; }
.queued .when { color: var(--ink-3); font-size: .8rem; }

/* The first-run list on an empty dashboard. Numbered because the order is real:
   a site needs a customer, a unit needs a site. */
.startlist { list-style: none; margin: 0; padding: 0; display: grid; gap: .8rem; }
.startlist li {
  display: grid; gap: .25rem;
  padding: .8rem .9rem; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--paper-2);
}
.startlist li b { font-size: 1rem; }
.startlist li span { color: var(--ink-2); font-size: .92rem; }
.startlist li .btn { justify-self: start; margin-top: .35rem; }
.startlist li .btn[aria-disabled="true"] { opacity: .55; }

/* Dispatch: move a job to another day or another engineer without opening it. */
.dispatch { display: flex; gap: .3rem; align-items: center; flex-wrap: nowrap; }
.dispatch input[type="date"], .dispatch select {
  padding: .3rem .4rem; font-size: .88rem; min-height: 34px; width: auto;
}
.dispatch select { max-width: 11rem; }
.dispatch .btn { padding: .3rem .7rem; min-height: 34px; }

/* Present for a screen reader, absent for everybody else. Used where a control
   is obvious in context but would otherwise have no label at all. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Dispatch is a desk job. On a phone the office can still open a job and change
   it there; three controls per row would make the board unreadable, and the row
   would be three times the width of the screen. */
@media (max-width: 700px) {
  .dispatch-cell { display: none; }
}

/* Taking something back on a visit. Small, but still a thumb-sized target —
   an engineer does this with one hand, standing up, wearing gloves. */
.btn-small-danger {
  min-height: 44px; padding: .35rem .8rem; font-size: .85rem;
  border-color: var(--danger); color: var(--danger); background: transparent;
}
.thumbs figure form { margin-top: .3rem; }

/* Choosing one site out of hundreds: a list of links, not a dropdown.
   Each row is a whole tap target, because this is used on a phone. */
.pick { list-style: none; margin: 0; padding: 0; }
.pick li { border-bottom: 1px solid var(--line); }
.pick li:last-child { border-bottom: 0; }
.pick a {
  display: block; padding: .75rem 1rem; text-decoration: none; color: inherit;
  min-height: var(--tap);
}
.pick a:hover, .pick a:focus-visible { background: var(--tint); }
.pick a small { display: block; color: var(--muted); font-size: .8125rem; }
.chosen { margin: .25rem 0 0; }
.chosen a { margin-left: .5rem; }

/* A capped list with its own narrowing box. The search belongs to a separate
   GET form by its `form` attribute, so it can sit inside a POST form. */
.narrow { display: flex; align-items: center; gap: .5rem; margin: .35rem 0 0; flex-wrap: wrap; }
.narrow input[type=search] { flex: 1 1 12rem; min-width: 0; }
.narrow small { color: var(--muted); flex-basis: 100%; }
.btn-sm { padding: .35rem .7rem; min-height: 0; font-size: .875rem; }

/* A card that is itself the link. An engineer standing at a unit taps the whole
   entry, not a word inside it. */
a.cardlink { display: block; text-decoration: none; color: inherit; }
a.cardlink:hover, a.cardlink:focus-visible { border-color: var(--accent); }
a.cardlink .small:last-child { color: var(--accent); display: inline-block; margin-top: .4rem; }
