/* ===========================================================================
   Trinity by Specialised HVAC Services Pty. Ltd.
   Design system + application shell
   =========================================================================== */

:root {
  /* Brand — sampled from the logo lockup: #141e2a ink, #2f7fc4 blue, #48c4d0 teal */
  --navy-900: #0b131d;
  --navy-800: #141e2a;
  --navy-700: #1e3145;
  --navy-600: #2b4a68;
  --blue-700: #0d5f9f;
  --blue-600: #1272b8;
  --blue-500: #2b8fd4;
  --blue-400: #58aee4;
  /* Teal darkens well past the logo's own #48c4d0, which is decorative only —
     anything carrying white text uses --teal-700. */
  --teal-700: #0a6675;
  --teal-600: #0c7d8d;
  --teal-500: #17a2b3;
  --teal-400: #48c4d0;

  /* Neutrals */
  --ink:        #131d29;
  --ink-soft:   #33485e;
  --muted:      #5c7186;
  --muted-deep: #52657a;
  --muted-soft: #8fa1b5;
  --line:       #dce5ee;
  --line-soft:  #eaf0f6;
  --surface:    #ffffff;
  --canvas:     #eef3f8;
  --canvas-alt: #e3ebf3;

  /* Status — darkened just enough to clear AA on their own tinted chips */
  --ok:    #157d56;
  --ok-bg: #e3f6ec;
  --warn:    #a35d05;
  --warn-bg: #fdf1de;
  --bad:    #c62c33;
  --bad-bg: #fdeaea;
  --info:    #0f6398;
  --info-bg: #e4f0fa;

  /* Priority scale — 1 is most urgent */
  --p1: #b3121b; --p1-bg: #fde7e8;
  --p2: #ba4b17; --p2-bg: #fdeee2;
  --p3: #916903; --p3-bg: #fbf4dd;
  --p4: #1668b0; --p4-bg: #e6f1fa;
  --p5: #5a6b7d; --p5-bg: #eef2f6;

  /* Geometry */
  --r-sm: 6px;
  --r:    10px;
  --r-lg: 16px;
  --sidebar-w: 264px;

  --shadow-sm: 0 1px 2px rgba(20, 30, 42, .06), 0 1px 3px rgba(20, 30, 42, .04);
  --shadow:    0 2px 6px rgba(20, 30, 42, .07), 0 8px 24px rgba(20, 30, 42, .06);
  --shadow-lg: 0 18px 48px rgba(20, 30, 42, .18);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

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

/* The browser's own [hidden] rule is weaker than any class that sets display,
   so `<button class="btn" hidden>` stayed on screen — which is how "Sync now"
   came to sit on the tick sheet permanently, doing nothing when tapped
   because there was nothing queued to send. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  /* Keep anchor jumps and scrollIntoView clear of the sticky bars, which would
     otherwise sit over — and swallow taps meant for — the target. */
  scroll-padding-top: 7.5rem;
  scroll-padding-bottom: 8rem;
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5 { margin: 0; font-weight: 650; line-height: 1.25; letter-spacing: -.012em; }
h1 { font-size: 1.375rem; }
h2 { font-size: 1.125rem; }
h3 { font-size: 1rem; }
p  { margin: 0 0 .75rem; }
figure, blockquote { margin: 0; }
p:last-child { margin-bottom: 0; }

a { color: var(--blue-600); text-decoration: none; }
a:hover { text-decoration: underline; }

img, svg { max-width: 100%; }

:focus-visible {
  outline: 2px solid var(--blue-500);
  outline-offset: 2px;
  border-radius: 3px;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--navy-800); color: #fff; padding: .6rem 1rem; border-radius: 0 0 var(--r) 0;
}
.skip-link:focus { left: 0; }

.icon { width: 20px; height: 20px; flex: none; }
.icon--sm { width: 16px; height: 16px; }
.icon--lg { width: 30px; height: 30px; }

/* --------------------------------------------------------------------------
   App shell
   -------------------------------------------------------------------------- */
.shell { display: flex; min-height: 100vh; }

/* The brand lockup is a light-background asset — its wordmark and the dark half of
   its swoosh are near-black — so the sidebar is a light surface rather than navy. */
.sidebar {
  width: var(--sidebar-w);
  flex: none;
  background: linear-gradient(180deg, #ffffff 0%, #f6fafd 100%);
  color: var(--ink-soft);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  z-index: 40;
}

.sidebar__brand {
  display: flex; align-items: center; gap: .5rem;
  padding: 1.1rem 1rem 1rem 1.15rem;
  border-bottom: 1px solid var(--line-soft);
}

.brand { display: flex; align-items: center; min-width: 0; }
.brand:hover { text-decoration: none; }
.brand__logo { display: block; width: 186px; height: auto; }

.sidebar__close { display: none; margin-left: auto; }

.nav { flex: 1; overflow-y: auto; padding: .9rem .7rem 1rem; }
.nav__section + .nav__section { margin-top: 1.1rem; }
.nav__label {
  margin: 0 0 .35rem .55rem;
  font-size: .66rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
}
.nav__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.nav__link {
  display: flex; align-items: center; gap: .65rem;
  padding: .52rem .6rem; border-radius: var(--r-sm);
  color: var(--ink-soft); font-size: .9rem; font-weight: 550;
  transition: background .12s ease, color .12s ease;
}
.nav__link:hover { background: var(--canvas-alt); color: var(--ink); text-decoration: none; }
.nav__link.is-active { background: var(--blue-600); color: #fff; box-shadow: 0 1px 2px rgba(18, 114, 184, .35); }
.nav__link.is-active .nav__icon { opacity: 1; }
.nav__icon { width: 18px; height: 18px; opacity: .72; }

.sidebar__foot {
  display: flex; align-items: center; gap: .4rem;
  padding: .7rem .8rem; border-top: 1px solid var(--line-soft);
}
.userchip { display: flex; align-items: center; gap: .6rem; flex: 1; min-width: 0; padding: .25rem; border-radius: var(--r-sm); color: var(--ink-soft); }
.userchip:hover { background: var(--canvas-alt); text-decoration: none; }
.userchip__text { display: flex; flex-direction: column; min-width: 0; }
.userchip__name { font-size: .85rem; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.userchip__role { font-size: .7rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.avatar {
  width: 34px; height: 34px; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  background: linear-gradient(140deg, var(--blue-600), var(--teal-600));
  color: #fff; font-size: .78rem; font-weight: 700; letter-spacing: .02em;
}

.sidebar__scrim { display: none; }

.content { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* Top bar ------------------------------------------------------------------ */
.topbar {
  display: flex; align-items: flex-start; gap: 1rem;
  padding: 1.1rem 1.75rem;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 30;
}
.topbar__title { flex: 1; min-width: 0; }
.topbar__sub { margin: .15rem 0 0; color: var(--muted); font-size: .875rem; }
.topbar__actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
/* Scoped so it outranks .iconbtn, which is declared later and sets inline-grid. */
.topbar .topbar__menu { display: none; }

.backlink {
  display: inline-flex; align-items: center; gap: .25rem;
  font-size: .78rem; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: .05em; margin-bottom: .2rem;
}
.backlink:hover { color: var(--blue-600); text-decoration: none; }

.main { flex: 1; padding: 1.5rem 1.75rem 2.5rem; max-width: 1400px; width: 100%; min-width: 0; }
.main--wide { max-width: none; }

.foot {
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  padding: 1rem 1.75rem; border-top: 1px solid var(--line);
  color: var(--muted); font-size: .78rem; background: var(--surface);
}
.foot p { margin: 0; }
.foot__who { display: flex; flex-direction: column; gap: .3rem; min-width: 0; }
.foot__who > p:first-child { color: var(--ink-soft); }
/* Statutory small print still has to clear AA, so it steps down in size only. */
.foot__legal { color: var(--muted); font-size: .74rem; line-height: 1.5; }
.foot__legal a { color: inherit; }
.foot__lic { white-space: nowrap; }
.foot__lic + .foot__lic { margin-left: .2rem; }
.foot__lic + .foot__lic::before { content: "·"; margin-right: .45rem; color: var(--muted-soft); }
.foot__lic b { color: var(--ink-soft); font-weight: 600; }

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  padding: .5rem .9rem; min-height: 38px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: .875rem; font-weight: 600;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background .12s ease, border-color .12s ease, box-shadow .12s ease, color .12s ease;
}
.btn:hover { background: var(--canvas); text-decoration: none; }
.btn:active { transform: translateY(.5px); }
.btn[disabled], .btn.is-disabled { opacity: .55; pointer-events: none; }

.btn--primary { background: var(--blue-600); border-color: var(--blue-600); color: #fff; }
.btn--primary:hover { background: var(--blue-700); border-color: var(--blue-700); }

.btn--dark { background: var(--navy-800); border-color: var(--navy-800); color: #fff; }
.btn--dark:hover { background: var(--navy-700); }

.btn--accent { background: var(--teal-700); border-color: var(--teal-700); color: #fff; }
.btn--accent:hover { background: #085563; border-color: #085563; }

.btn--ok { background: var(--ok); border-color: var(--ok); color: #fff; }
.btn--ok:hover { background: #0f6848; border-color: #0f6848; }

.btn--danger { background: var(--bad); border-color: var(--bad); color: #fff; }
.btn--danger:hover { background: #a5232a; }

.btn--ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn--ghost:hover { background: var(--canvas-alt); color: var(--ink); }
.btn--ghost.btn--danger { background: transparent; border-color: transparent; color: var(--bad); }
.btn--ghost.btn--danger:hover { background: var(--bad-bg); color: var(--bad); }

.btn--sm { min-height: 31px; padding: .25rem .6rem; font-size: .8rem; }
.btn--lg { min-height: 46px; padding: .7rem 1.4rem; font-size: .95rem; }
.btn--block { width: 100%; }

.iconbtn {
  display: inline-grid; place-items: center;
  width: 38px; height: 38px; flex: none;
  border: 1px solid transparent; border-radius: var(--r-sm);
  background: transparent; color: inherit; cursor: pointer;
}
.iconbtn:hover { background: rgba(125, 145, 165, .16); text-decoration: none; }

.btn-row { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.btn-row--end { justify-content: flex-end; }
.btn-row--split { justify-content: space-between; }

/* --------------------------------------------------------------------------
   Cards, panels, grids
   -------------------------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.card + .card { margin-top: 1.25rem; }
.card--pad { padding: 1.25rem; }
.card--flush { overflow: visible; }
.card:has([data-address-fields]) { overflow: visible; }

.addr-suggest {
  position: absolute;
  z-index: 120;
  display: flex;
  flex-direction: column;
  gap: .3rem;
  padding: .35rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-sm);
}
.addr-suggest[hidden] { display: none; }
.addr-suggest button {
  text-align: left;
  border: 1px solid #cfe3d4;
  background: #f4faf5;
  color: #1b4332;
  border-radius: var(--r-sm);
  padding: .6rem .7rem;
  font: inherit;
  font-size: .88rem;
  cursor: pointer;
}
.addr-suggest button:hover { background: #e4f4ea; }

.pac-container { z-index: 120; }

.card__head {
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
  padding: .85rem 1.25rem;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, #fbfcfe, #f6f8fb);
}
.card__head h2, .card__head h3 { margin: 0; font-size: .98rem; }
.card__head .spacer, .actionbar .spacer { margin-left: auto; }
.card__sub { color: var(--muted); font-size: .8rem; margin: 0; }
.card__body { padding: 1.25rem; }
.card__foot {
  padding: .85rem 1.25rem; border-top: 1px solid var(--line); background: #fafbfd;
  display: flex; align-items: center; gap: .85rem; flex-wrap: wrap;
}
.card__foot .hint { margin-top: 0; }

.grid { display: grid; gap: 1.25rem; }
/* Tracks are capped at 100% and items are allowed to shrink, otherwise a wide
   table inside one pushes the whole page wider than a phone and the browser
   answers by zooming the document out. */
.grid > * { min-width: 0; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); }
.grid--sidebar { grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); align-items: start; }
@media (max-width: 900px) { .grid--sidebar { grid-template-columns: minmax(0, 1fr); } }

.stack { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }
.stack > * { min-width: 0; }
.stack--sm { gap: .6rem; }

/* Stat tiles --------------------------------------------------------------- */
.stat {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  padding: 1rem 1.1rem; box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; gap: .15rem;
  position: relative; overflow: hidden;
}
.stat::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 3px; background: var(--blue-500); }
.stat--ok::before   { background: var(--ok); }
.stat--warn::before { background: var(--warn); }
.stat--bad::before  { background: var(--bad); }
.stat--muted::before { background: var(--muted-soft); }
.stat__label { font-size: .72rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.stat__value { font-size: 1.75rem; font-weight: 700; line-height: 1.15; letter-spacing: -.02em; }
.stat__meta { font-size: .78rem; color: var(--muted); }
a.stat:hover { text-decoration: none; border-color: var(--blue-400); box-shadow: var(--shadow); }

/* --------------------------------------------------------------------------
   Tables
   -------------------------------------------------------------------------- */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table.data { width: 100%; border-collapse: collapse; font-size: .875rem; }
table.data th, table.data td { padding: .6rem .85rem; text-align: left; vertical-align: middle; }
table.data thead th {
  font-size: .7rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--muted); background: #f7f9fc; border-bottom: 1px solid var(--line);
  white-space: nowrap; position: sticky; top: 0; z-index: 1;
}
table.data tbody tr { border-bottom: 1px solid var(--line-soft); }
table.data tbody tr:last-child { border-bottom: 0; }
table.data tbody tr:hover { background: #f8fafc; }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data td.tight { white-space: nowrap; }
table.data .cell-main { font-weight: 600; color: var(--ink); }
table.data .cell-sub { display: block; font-size: .78rem; color: var(--muted); }
table.data.data--form td { padding: .4rem .5rem; }
table.data.data--form tbody tr:hover { background: transparent; }
table.data td.text-center, table.data th.text-center { text-align: center; }

.code {
  font-family: var(--mono); font-size: .8rem;
  background: var(--canvas-alt); border-radius: 4px; padding: .1rem .35rem; color: var(--ink-soft);
}
/* A code broken across two lines reads as two codes. Every data table scrolls
   sideways, so there is somewhere for the extra width to go. */
table.data .code { white-space: nowrap; }

/* Definition list ---------------------------------------------------------- */
.dl { display: grid; grid-template-columns: minmax(120px, auto) 1fr; gap: .45rem 1rem; margin: 0; font-size: .875rem; }
.dl dt { color: var(--muted); font-weight: 500; }
/* An email address is one long unbreakable word, and the card it sits in
   clips what it cannot fit; break it rather than lose the end of it. */
.dl dd { margin: 0; font-weight: 550; min-width: 0; overflow-wrap: anywhere; }

/* --------------------------------------------------------------------------
   Badges & chips
   -------------------------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: .25rem;
  padding: .12rem .5rem; border-radius: 100px;
  font-size: .72rem; font-weight: 700; letter-spacing: .02em; white-space: nowrap;
  border: 1px solid transparent;
}
.badge--ok    { background: var(--ok-bg);   color: var(--ok);   border-color: #bfe6d1; }
.badge--warn  { background: var(--warn-bg); color: var(--warn); border-color: #f0dcb8; }
.badge--bad   { background: var(--bad-bg);  color: var(--bad);  border-color: #f4c7c8; }
.badge--info  { background: var(--info-bg); color: var(--info); border-color: #c6dcf2; }
/* The grey chip sits on a darker tint than the coloured ones, so its text goes deeper. */
.badge--muted { background: var(--canvas-alt); color: var(--muted-deep); border-color: var(--line); }

.badge--p1 { background: var(--p1-bg); color: var(--p1); border-color: #f3c3c5; }
.badge--p2 { background: var(--p2-bg); color: var(--p2); border-color: #f5d3bb; }
.badge--p3 { background: var(--p3-bg); color: var(--p3); border-color: #eddfa8; }
.badge--p4 { background: var(--p4-bg); color: var(--p4); border-color: #c8dff2; }
.badge--p5 { background: var(--p5-bg); color: var(--p5); border-color: var(--line); }

.chip {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .25rem .65rem; border-radius: 100px;
  border: 1px solid var(--line); background: var(--surface);
  font-size: .8rem; font-weight: 600; color: var(--ink-soft);
}
.chip.is-active { background: var(--navy-800); border-color: var(--navy-800); color: #fff; }
a.chip:hover { text-decoration: none; border-color: var(--blue-400); }

.chip-row { display: flex; gap: .4rem; flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   Alerts
   -------------------------------------------------------------------------- */
.alert {
  display: flex; gap: .6rem; align-items: flex-start;
  padding: .7rem 1rem; border-radius: var(--r-sm);
  border: 1px solid; font-size: .875rem; font-weight: 500;
  margin-bottom: 1.25rem;
}
.alert--ok   { background: var(--ok-bg);   border-color: #bfe6d1; color: #0f6647; }
.alert--bad  { background: var(--bad-bg);  border-color: #f4c7c8; color: #97232a; }
.alert--warn { background: var(--warn-bg); border-color: #f0dcb8; color: #8a4f05; }
.alert--info { background: var(--info-bg); border-color: #c6dcf2; color: #0d4f86; }

.lead { font-size: 1rem; color: var(--ink-soft); }

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
.field { margin-bottom: 1rem; }
.field:last-child { margin-bottom: 0; }

.label {
  display: block; margin-bottom: .3rem;
  font-size: .8rem; font-weight: 650; color: var(--ink-soft);
}
.label .req { color: var(--bad); }

.hint { display: block; margin-top: .3rem; font-size: .78rem; color: var(--muted); }
.error-text { display: block; margin-top: .3rem; font-size: .78rem; color: var(--bad); font-weight: 600; }

.input, .select, .textarea {
  width: 100%; padding: .55rem .7rem; min-height: 40px;
  font: inherit; font-size: .9rem; color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  transition: border-color .12s ease, box-shadow .12s ease;
  appearance: none;
}
.input:hover, .select:hover, .textarea:hover { border-color: #c3cfdc; }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--blue-500);
  box-shadow: 0 0 0 3px rgba(43, 143, 212, .18);
}
.input[aria-invalid="true"], .textarea[aria-invalid="true"] { border-color: var(--bad); }
.input::placeholder, .textarea::placeholder { color: var(--muted-soft); }
.textarea { min-height: 96px; resize: vertical; line-height: 1.5; }

.select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%2364788f' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .7rem center;
  padding-right: 2rem;
}

.form-grid { display: grid; gap: 0 1rem; grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); }
.form-grid .field--full { grid-column: 1 / -1; }
.form-grid--single { grid-template-columns: 1fr; }
/* A fixed pair, for a row of two short fields sitting above full-width ones.
   auto-fit cannot help there: the full-width fields span every track, so none
   is ever empty enough to collapse, and the short pair is left holding two
   columns of a four column row. */
.form-grid--pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Compact variants for tables that are themselves the form. */
.input--sm, .select--sm { min-height: 34px; padding: .3rem .5rem; font-size: .84rem; }
.select--sm { padding-right: 1.7rem; background-position: right .5rem center; }

.checkline { display: flex; align-items: flex-start; gap: .55rem; font-size: .875rem; }
.checkline input[type="checkbox"], .checkline input[type="radio"] { width: 17px; height: 17px; margin-top: .15rem; accent-color: var(--blue-600); flex: none; }

.filterbar {
  display: flex; gap: .6rem; flex-wrap: wrap; align-items: flex-end;
  padding: .85rem 1.25rem; border-bottom: 1px solid var(--line); background: #fafbfd;
}
.filterbar .field { margin: 0; min-width: 150px; }
.filterbar .field--grow { flex: 1; min-width: 200px; }
form[data-livefilter].is-ready .filterbar__submit {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); border: 0;
}
[data-livefilter-results].is-loading { opacity: .55; pointer-events: none; }

.th-sort {
  display: inline-flex; align-items: center; gap: .28rem;
  color: inherit; text-decoration: none;
  letter-spacing: inherit; text-transform: inherit; font: inherit;
}
.th-sort:hover { color: var(--ink); }
.th-sort::after {
  content: "↕"; font-size: .8em; font-weight: 500; letter-spacing: 0; text-transform: none;
  opacity: .28;
}
.th-sort.is-asc::after { content: "↑"; opacity: 1; color: var(--navy-800); }
.th-sort.is-desc::after { content: "↓"; opacity: 1; color: var(--navy-800); }

.listfoot {
  display: flex; align-items: center; gap: .75rem 1.25rem; flex-wrap: wrap;
  padding: .85rem 1.25rem; border-top: 1px solid var(--line); background: #fafbfd;
}
.listfoot__count { margin: 0; font-size: .86rem; color: var(--muted); }
.listfoot__size {
  display: flex; align-items: center; gap: .4rem; margin-left: auto;
  font-size: .84rem; color: var(--muted);
}
.listfoot__size a, .listfoot__size-current {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 32px; min-height: 32px; padding: 0 .45rem;
  border-radius: var(--r); text-decoration: none;
}
.listfoot__size a { color: var(--ink); border: 1px solid var(--line); background: #fff; }
.listfoot__size a:hover { border-color: var(--blue-600); color: var(--blue-600); }
.listfoot__size-current {
  font-weight: 700; color: #fff; background: var(--navy-800); border: 1px solid var(--navy-800);
}
.pager { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
.pager__btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 36px; min-height: 36px; padding: 0 .55rem;
  border: 1px solid var(--line); border-radius: var(--r);
  background: #fff; color: var(--ink); text-decoration: none; font-size: .84rem;
}
.pager__btn:hover { border-color: var(--blue-600); color: var(--blue-600); }
.pager__btn.is-current {
  font-weight: 700; color: #fff; background: var(--navy-800); border-color: var(--navy-800);
}
.pager__btn.is-disabled { color: var(--muted); background: transparent; pointer-events: none; }
.pager__gap { color: var(--muted); padding: 0 .15rem; }

/* --------------------------------------------------------------------------
   Auth screens
   -------------------------------------------------------------------------- */
body.auth { background: var(--navy-900); }

.auth__wrap {
  min-height: 100vh;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
@media (max-width: 860px) { .auth__wrap { grid-template-columns: 1fr; } }

.auth__panel {
  display: flex; flex-direction: column; justify-content: center;
  background: var(--surface);
  padding: 3rem clamp(1.5rem, 6vw, 4.5rem);
}
.auth__panel > * { width: 100%; max-width: 400px; margin-inline: auto; }

.auth__head { margin-bottom: 1.75rem; }
.auth__head h1 { font-size: 1.6rem; margin-bottom: .35rem; }
.auth__head p { color: var(--muted); margin: 0; }

.auth__logo { margin-bottom: 2.25rem; }
.auth__logo img { display: block; width: 232px; height: auto; }

.auth__aside {
  position: relative; overflow: hidden;
  background:
    radial-gradient(900px 500px at 85% 15%, rgba(72, 196, 208, .26), transparent 60%),
    radial-gradient(700px 500px at 15% 90%, rgba(43, 143, 212, .34), transparent 60%),
    linear-gradient(150deg, var(--navy-800), var(--navy-900));
  color: #dbe8f4;
  display: flex; align-items: center; padding: 3rem;
}
@media (max-width: 860px) { .auth__aside { display: none; } }
.auth__aside-inner { max-width: 380px; }
/* The simplified vector mark carries no navy, so it holds up on the dark panel. */
.auth__mark { display: block; width: 60px; height: 60px; margin-bottom: 1.5rem; }
.auth__aside h2 { font-size: 2.25rem; color: #fff; letter-spacing: -.02em; }
.auth__slogan { color: var(--teal-400); font-size: .95rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; margin-bottom: 2rem; }
.auth__points { list-style: none; margin: 0 0 2.5rem; padding: 0; display: flex; flex-direction: column; gap: .8rem; }
.auth__points li { position: relative; padding-left: 1.75rem; font-size: .95rem; color: #b8cbdd; }
.auth__points li::before {
  content: ""; position: absolute; left: 0; top: .35rem; width: 16px; height: 16px;
  border-radius: 50%; background: rgba(72, 196, 208, .22);
  box-shadow: inset 0 0 0 1.5px var(--teal-400);
}
.auth__owner { font-size: .8rem; color: #8ba2b8; letter-spacing: .04em; text-transform: uppercase; }
/* Licence numbers: a client signing in should see who they are dealing with. */
.auth__lic { list-style: none; margin: .9rem 0 0; padding: .9rem 0 0; border-top: 1px solid rgba(255,255,255,.12); display: flex; flex-direction: column; gap: .3rem; }
.auth__lic li { display: flex; justify-content: space-between; gap: 1rem; font-size: .76rem; color: #7f97ad; }
.auth__lic b { color: #b8cbdd; font-weight: 600; font-variant-numeric: tabular-nums; }

.auth__meta { margin-top: 1.75rem; padding-top: 1.25rem; border-top: 1px solid var(--line); font-size: .8rem; color: var(--muted); }

/* --------------------------------------------------------------------------
   Empty state
   -------------------------------------------------------------------------- */
.empty { padding: 3rem 1.5rem; text-align: center; color: var(--muted); }
.empty__icon {
  width: 58px; height: 58px; margin: 0 auto 1rem;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--canvas-alt); color: var(--muted);
}
.empty h3 { color: var(--ink); margin-bottom: .3rem; }
.empty p { max-width: 420px; margin: 0 auto; font-size: .9rem; }
.empty__action { margin-top: 1.25rem; }
.empty__action .hint { margin-top: .6rem; }

/* --------------------------------------------------------------------------
   First-run setup guide
   -------------------------------------------------------------------------- */
.setup__progress { padding: 1.1rem 1.25rem .25rem; }
.setup__count { margin: .5rem 0 0; font-size: .78rem; color: var(--muted); }

.setup__list { list-style: none; margin: 0; padding: .5rem 0 0; counter-reset: none; }
.setup__step {
  display: flex; align-items: flex-start; gap: .9rem;
  padding: .9rem 1.25rem; border-top: 1px solid var(--line-soft);
}
.setup__num {
  flex: 0 0 auto; width: 26px; height: 26px; margin-top: .1rem;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--canvas-alt); color: var(--muted-deep);
  font-size: .8rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.setup__text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .15rem; }
.setup__title { font-weight: 600; color: var(--ink); font-size: .92rem; }
.setup__body { font-size: .83rem; color: var(--muted); }
.setup__later { font-size: .78rem; color: var(--muted-soft); white-space: nowrap; align-self: center; }

.setup__step.is-done .setup__num { background: var(--ok-bg); color: var(--ok); }
.setup__step.is-done .setup__title { color: var(--muted-deep); }
.setup__step.is-next { background: var(--info-bg); }
.setup__step.is-next .setup__num { background: var(--blue-500); color: #fff; }

/* On a phone the action drops onto its own line. Left to itself the text just
   shrinks to a two-word column beside the button instead of wrapping it. */
@media (max-width: 640px) {
  .setup__step { flex-wrap: wrap; row-gap: .6rem; }
  .setup__text { flex: 1 1 calc(100% - 26px - .9rem); }
  .setup__step .btn, .setup__later { margin-left: calc(26px + .9rem); align-self: flex-start; }
}

/* --------------------------------------------------------------------------
   Progress
   -------------------------------------------------------------------------- */
.progress { height: 7px; border-radius: 100px; background: var(--canvas-alt); overflow: hidden; }
.progress__bar { height: 100%; background: linear-gradient(90deg, var(--blue-500), var(--teal-500)); border-radius: 100px; transition: width .3s ease; }

/* --------------------------------------------------------------------------
   Tick sheet
   -------------------------------------------------------------------------- */
.sheet__site {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  margin: 1.5rem 0 .65rem;
}
.sheet__site h2 { font-size: 1.05rem; }
.sheet__site span { font-size: .8rem; color: var(--muted); }

.tick {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface); box-shadow: var(--shadow-sm);
  margin-bottom: .6rem; overflow: hidden;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.tick.is-fault { border-color: #eab7ba; box-shadow: 0 0 0 1px #f6d7d8; }
.tick.is-ok    { border-color: #bfe0cd; }
.tick.is-pending { border-left: 3px solid var(--muted-soft); }
/* A result is recorded but a reading is still blank: not finished, and not
   allowed to read as finished either. */
.tick.is-unfinished { border-color: #e6cf9f; border-left: 3px solid var(--warn); }

.tick__head {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding: .7rem .9rem;
}
.tick__id { min-width: 0; flex: 1 1 240px; }
/* The code and the state share one line, so changing state can never change
   the height of a card the technician is tapping down a list of. */
.tick__idline { display: flex; align-items: center; gap: .45rem; min-width: 0; }
.tick__code {
  font-family: var(--mono); font-size: .82rem; font-weight: 700; color: var(--navy-700);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tick__desc { display: block; font-size: .85rem; color: var(--ink-soft); }
.tick__loc { display: block; font-size: .76rem; color: var(--muted); }

/* Says in words what the colours say in colour. "Not inspected" is the one
   that matters: an asset nobody walked past must never read as a pass. */
.tick__flag {
  flex: none; white-space: nowrap;
  font-size: .68rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  padding: .1rem .4rem; border-radius: 100px;
  background: var(--canvas-alt); color: var(--muted);
}
.tick__flag--pending   { background: #eef1f5; color: #5d6b7a; }
.tick__flag--ok        { background: #e3f6ec; color: #0f6647; }
.tick__flag--fault     { background: #fdeaeb; color: #a3282f; }
.tick__flag--part      { background: #fdf1dd; color: #8a5a08; }
.tick__flag--no_access { background: #fdf1dd; color: #8a5a08; }
.tick__flag--na        { background: #eef1f5; color: #5d6b7a; }

/* Only ever present on the rare paths — a pass turned into a fault by a
   failing item, or back again — so it costs the fast path nothing. */
.tick__auto {
  margin: 0; padding: .5rem .9rem;
  background: var(--info-bg); color: var(--info);
  font-size: .82rem; font-weight: 600;
  border-top: 1px solid var(--line-soft);
}

/* What the last technician wrote here. Server-rendered, so it is on the phone
   before the signal is not, and it never moves anything when it appears. */
.tick__carry {
  display: flex; gap: .5rem; align-items: flex-start;
  padding: .5rem .9rem; border-top: 1px solid var(--line-soft);
  background: #fbf8f0; color: #6b5626; font-size: .8rem;
}
.tick__carry .icon { flex: none; margin-top: .1rem; }
.tick__carry p { margin: 0; }
.tick__carry p + p { margin-top: .15rem; }
.tick__carry[hidden] { display: none; }
.tick__carry--fault {
  background: #fff6f6; color: #7a2a2f; border-top-color: #f2d3d5;
}
.tick__carry--fault .icon { color: var(--bad); }

.tick__choices { display: flex; gap: .3rem; flex-wrap: wrap; }

.choice { position: relative; }
.choice input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.choice > span {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .38rem .8rem; min-height: 36px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink-soft);
  font-size: .82rem; font-weight: 650; white-space: nowrap;
  transition: all .12s ease;
}
.choice input:hover + span { border-color: #b9c6d4; background: var(--canvas); }
.choice input:focus-visible + span { outline: 2px solid var(--blue-500); outline-offset: 2px; }
.choice input:checked + span { color: #fff; }
.choice--ok    input:checked + span { background: var(--ok);   border-color: var(--ok); }
.choice--fault input:checked + span { background: var(--bad);  border-color: var(--bad); }
.choice--noacc input:checked + span { background: var(--warn); border-color: var(--warn); }
.choice--na    input:checked + span { background: var(--muted); border-color: var(--muted); }

/* Fixed width, so the wording changing as an asset is passed cannot rewrap the
   row it sits in and shift the card under a thumb. */
.tick__toggle {
  display: flex; align-items: center; justify-content: flex-start; gap: .4rem;
  border: 0; background: none; color: var(--muted); font: inherit; font-size: .78rem; font-weight: 650;
  cursor: pointer; padding: .35rem .5rem; border-radius: var(--r-sm); white-space: nowrap;
  min-width: 12.5rem; text-align: left;
}
.tick__toggle:hover { background: var(--canvas-alt); color: var(--ink); }
.tick__toggle-flag {
  font-size: .68rem; font-weight: 700; letter-spacing: .04em;
  padding: .1rem .4rem; border-radius: 100px;
  background: var(--info-bg); color: var(--info);
}

.tick__body { border-top: 1px solid var(--line-soft); padding: 1rem .9rem; background: #fbfcfe; }
.tick__showall { margin-top: .55rem; }

.tick__fault { border-top: 1px solid #f2d3d5; padding: 1rem .9rem; background: #fffafa; }
.tick__fault h4 { font-size: .82rem; text-transform: uppercase; letter-spacing: .06em; color: var(--bad); margin-bottom: .75rem; }

.tick__idphoto {
  display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1rem;
  border-top: 1px solid #f0dcb8; padding: .85rem .9rem; background: #fffbf3;
}
.tick__idphoto-copy { flex: 1 1 12rem; min-width: 0; font-size: .88rem; }
.tick__idphoto-copy strong { display: block; color: #8a5a08; margin-bottom: .15rem; }
.tick__idphoto-copy p { font-size: .8rem; color: var(--ink-soft); }
.tick__idphoto-prev {
  width: 72px; flex: none; margin: 0; border-radius: var(--r-sm);
  overflow: hidden; border: 1px solid var(--line); background: var(--canvas-alt);
}
.tick__idphoto-prev img { display: block; width: 72px; height: 54px; object-fit: cover; }
.tick__idphoto-prev figcaption {
  display: block; text-align: center; font-size: .65rem; color: var(--muted);
  padding: .1rem 0 .15rem; background: var(--surface);
}
.tick__idphoto-take { flex: none; cursor: pointer; }
.tick__idphoto-take input { display: none; }
.tick__idphoto.is-done { background: #eef8f2; border-top-color: #bfe6d1; }
.tick__idphoto.is-done .tick__idphoto-copy strong { color: #0f6647; }
.tick__idphoto-status { flex: 1 1 100%; font-size: .8rem; color: var(--muted); }

.idphoto {
  margin: 0; border-radius: var(--r); overflow: hidden;
  border: 1px solid var(--line); background: var(--canvas-alt); aspect-ratio: 4 / 3;
}
.idphoto img { display: block; width: 100%; height: 100%; object-fit: cover; }
.dropzone--compact { padding: .75rem; max-width: none; }
.photos--history { margin-top: 0; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); }
.photos--history .photo { aspect-ratio: 1; }

.checks { display: grid; gap: .35rem; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.check {
  padding: .35rem .5rem; border-radius: var(--r-sm); background: var(--surface);
  border: 1px solid var(--line-soft); font-size: .84rem;
}
.check.has-note { border-color: #cfe0f2; background: #fbfdff; }
/* Just the readings, while the readings are the only thing outstanding. An
   item carrying a note stays on screen, because hiding it would hide the note. */
.tick__body.is-entry-only .check:not(.check--typed):not(.has-note) { display: none; }

/* The label and its answer on one row, with the note button in the corner. */
.check__row {
  display: grid; align-items: center; gap: .6rem;
  grid-template-columns: 1fr auto auto;
  grid-template-areas: "label opts note";
}
.check__label { grid-area: label; min-width: 0; }
.check__opts { grid-area: opts; display: flex; gap: .2rem; flex: none; }
.check__opts .choice > span { padding: .18rem .5rem; min-height: 26px; font-size: .72rem; }
.check__entry { max-width: 110px; }
.choice__long { display: none; }

/* Notes on an item ---------------------------------------------------------
   One small button per row and nothing else until it is asked for. A textarea
   on every line is exactly the clutter this screen exists to remove. */
.check__notebtn {
  grid-area: note; flex: none;
  display: grid; place-items: center; width: 30px; height: 30px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); color: var(--muted); cursor: pointer;
  transition: color .12s ease, border-color .12s ease, background .12s ease;
}
.check__notebtn:hover { color: var(--ink); border-color: #b9c6d4; background: var(--canvas); }
.check__notebtn:focus-visible { outline: 2px solid var(--blue-500); outline-offset: 2px; }
.check.has-note .check__notebtn { color: var(--blue-600); border-color: var(--blue-500); background: var(--info-bg); }

.check__note { margin-top: .45rem; }
.check__notefield { min-height: 54px; font-size: .84rem; }

/* Carried forward from the previous visit, read only. */
.check__prev {
  margin: .35rem 0 0; font-size: .78rem; color: #6b5626;
  background: #fbf8f0; border-radius: var(--r-sm); padding: .3rem .45rem;
}
.check__prev-tag {
  font-size: .66rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: #8a6d2f; margin-right: .3rem;
}

/* Priority selector -------------------------------------------------------- */
.prio { display: flex; gap: .35rem; flex-wrap: wrap; }
.prio label { position: relative; }
.prio input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.prio span {
  display: grid; place-items: center; width: 44px; height: 42px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); font-weight: 700; font-size: .9rem; color: var(--ink-soft);
  transition: all .12s ease;
}
.prio input:hover + span { border-color: #b9c6d4; }
.prio input:focus-visible + span { outline: 2px solid var(--blue-500); outline-offset: 2px; }
.prio--1 input:checked + span { background: var(--p1); border-color: var(--p1); color: #fff; }
.prio--2 input:checked + span { background: var(--p2); border-color: var(--p2); color: #fff; }
.prio--3 input:checked + span { background: var(--p3); border-color: var(--p3); color: #fff; }
.prio--4 input:checked + span { background: var(--p4); border-color: var(--p4); color: #fff; }
.prio--5 input:checked + span { background: var(--p5); border-color: var(--p5); color: #fff; }
.prio__desc { margin-top: .4rem; font-size: .78rem; color: var(--muted); min-height: 1.2em; }

/* Photos ------------------------------------------------------------------- */
.dropzone {
  display: block; max-width: 32rem;
  border: 1.5px dashed #c3cfdc; border-radius: var(--r);
  padding: 1.1rem; text-align: center; background: var(--surface);
  color: var(--muted); font-size: .85rem; cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.dropzone:hover, .dropzone.is-over { border-color: var(--blue-500); background: var(--info-bg); color: var(--info); }
.dropzone input[type="file"] { display: none; }
.dropzone__icon { display: block; width: 26px; height: 26px; margin: 0 auto .4rem; }
.dropzone__touch { display: none; }

.photos { display: grid; gap: .55rem; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); margin-top: .75rem; }
.photo {
  position: relative; border-radius: var(--r-sm); overflow: hidden;
  border: 1px solid var(--line); background: var(--canvas-alt); aspect-ratio: 4 / 3;
}
.photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo__del {
  position: absolute; top: 4px; right: 4px;
  width: 26px; height: 26px; border-radius: 50%;
  border: 0; background: rgba(10, 24, 38, .72); color: #fff;
  display: grid; place-items: center; cursor: pointer;
}
.photo__del:hover { background: var(--bad); }
.photo__cap {
  position: absolute; inset: auto 0 0 0; padding: .2rem .4rem;
  background: linear-gradient(0deg, rgba(11,19,29,.85), transparent);
  color: #fff; font-size: .7rem; line-height: 1.3;
}
.photo.is-uploading { opacity: .55; }

/* --------------------------------------------------------------------------
   Report view
   -------------------------------------------------------------------------- */
.report__hero {
  display: flex; gap: 1.5rem; flex-wrap: wrap; align-items: flex-start;
  padding: 1.35rem 1.5rem; border-radius: var(--r);
  background: linear-gradient(135deg, var(--navy-800), var(--navy-700));
  color: #dceaf6; box-shadow: var(--shadow);
}
.report__hero h2 { color: #fff; font-size: 1.3rem; margin-bottom: .2rem; }
.report__hero .dl dt { color: #8fa9c1; }
.report__hero .dl dd { color: #fff; }
.report__hero-main { flex: 1 1 320px; }
.report__hero-stats { display: flex; gap: 1.5rem; flex-wrap: wrap; }
.report__hero-stat .stat__label { color: #8fa9c1; }
.report__hero-stat .stat__value { color: #fff; }

.faultcard { border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; background: var(--surface); }
.faultcard + .faultcard { margin-top: .85rem; }
.faultcard__head {
  display: flex; gap: .75rem; align-items: center; flex-wrap: wrap;
  padding: .7rem .95rem; background: #fdf6f6; border-bottom: 1px solid #f3dcdd;
}
.faultcard__body { padding: .95rem; }
.faultcard__title { font-weight: 650; }

/* Notes the technician left on the individual checks that failed. They sit
   inside the fault they describe, and are the reason those notes are kept out
   of Observations — the same sentence under two headings reads as two
   findings. */
.faultcard__items { margin: 0; padding-left: 1.1rem; font-size: .85rem; color: var(--muted-deep); }
.faultcard__items li + li { margin-top: .2rem; }
.faultcard__items strong { color: var(--ink); font-weight: 600; }

/* An observation is not a fault, and the report must not let a client read it
   as one — so it is a separate block with none of the fault card's red. */
.observation { border: 1px solid var(--line); border-radius: var(--r); padding: .8rem .95rem; background: var(--surface); }
.observation + .observation { margin-top: .7rem; }
.observation__head { display: flex; gap: .75rem; align-items: baseline; flex-wrap: wrap; }
.observation__item { margin: .4rem 0 .5rem; font-weight: 650; font-size: .9rem; }

.notebox {
  background: var(--canvas); border-left: 3px solid var(--blue-500);
  padding: .6rem .85rem; border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: .875rem; color: var(--ink-soft); white-space: pre-wrap;
}
/* Prose written into a template rather than typed by someone: pre-wrap would
   reproduce the indentation of the source file along with it. */
.notebox--prose { white-space: normal; }

/* --------------------------------------------------------------------------
   Lightbox
   -------------------------------------------------------------------------- */
.lightbox {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(11, 19, 29, .93);
  display: grid; place-items: center;
  padding: 0;
  touch-action: none;
  overscroll-behavior: none;
}
.lightbox__stage {
  width: 100%; height: 100%;
  display: grid; place-items: center;
  padding: 3.75rem .75rem 4.5rem;
  padding-top: max(3.75rem, calc(env(safe-area-inset-top) + 2.75rem));
  padding-bottom: max(4.5rem, calc(env(safe-area-inset-bottom) + 3.25rem));
}
.lightbox img,
.lightbox__img {
  max-width: 100%; max-height: 100%;
  object-fit: contain;
  border-radius: var(--r); box-shadow: var(--shadow-lg);
  user-select: none; -webkit-user-drag: none;
}
.lightbox__cap { color: #cfdcea; text-align: center; margin-top: .85rem; font-size: .875rem; }
.lightbox__close {
  position: absolute; z-index: 2; color: #fff;
  top: max(1rem, env(safe-area-inset-top));
  right: max(1rem, env(safe-area-inset-right));
}
.lightbox__nav {
  position: absolute; z-index: 1; top: 50%;
  width: 48px; height: 72px; margin-top: -36px;
  border: 0; background: rgba(11, 19, 29, .35); color: #fff;
  display: grid; place-items: center; cursor: pointer;
}
.lightbox__nav .icon { width: 28px; height: 28px; }
.lightbox__nav--prev { left: 0; border-radius: 0 10px 10px 0; }
.lightbox__nav--next { right: 0; border-radius: 10px 0 0 10px; }
.lightbox__nav--next .icon { transform: scaleX(-1); }
.lightbox__count {
  position: absolute; left: 0; right: 0;
  bottom: max(1.1rem, env(safe-area-inset-bottom));
  margin: 0; color: #cfdcea; text-align: center;
  font-size: .9rem; font-weight: 650; letter-spacing: .02em;
  pointer-events: none;
}
body.lightbox-open { overflow: hidden; }
.lightbox[hidden],
.lightbox__nav[hidden] { display: none !important; }

/* --------------------------------------------------------------------------
   Utilities
   -------------------------------------------------------------------------- */
.muted { color: var(--muted); }
.small { font-size: .8rem; }
.strong { font-weight: 650; }
.nowrap { white-space: nowrap; }
.mt-0 { margin-top: 0; } .mt-1 { margin-top: .5rem; } .mt-2 { margin-top: 1rem; } .mt-3 { margin-top: 1.5rem; }
.mb-0 { margin-bottom: 0; } .mb-1 { margin-bottom: .5rem; } .mb-2 { margin-bottom: 1rem; } .mb-3 { margin-bottom: 1.5rem; }
.text-right { text-align: right; }
.flex { display: flex; } .flex-between { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.gap-1 { gap: .5rem; } .gap-2 { gap: 1rem; }
.wrap { flex-wrap: wrap; }
.hide { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Correcting a technician's wording ----------------------------------------
   The boxes stand exactly where the finished text stands, because the whole
   question being answered is how the sentence will read in the document. */
.wording__field { min-height: 0; font-size: .9rem; }
.wording__hint { display: block; margin: .35rem 0 .9rem; font-size: .78rem; color: var(--muted); }

/* Shut by default: the corrected sentence is what the report says, and the
   original is there to be asked for rather than to be read past. */
.wording-was { margin-top: .5rem; font-size: .8rem; }
.wording-was > summary {
  cursor: pointer; color: var(--muted-deep); list-style: none;
  display: inline-flex; align-items: center; gap: .4rem;
}
.wording-was > summary::-webkit-details-marker { display: none; }
.wording-was > summary:hover { color: var(--ink); }
.wording-was__text { border-left-color: var(--muted); font-style: italic; }

/* Sticky action bar on long forms ------------------------------------------ */
.actionbar {
  position: sticky; bottom: 0; z-index: 20;
  display: flex; gap: .75rem; align-items: center; flex-wrap: wrap;
  margin-top: 1.5rem; padding: .85rem 1.25rem;
  padding-bottom: calc(.85rem + env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, .96); backdrop-filter: blur(8px);
  border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: 0 -4px 20px rgba(20, 30, 42, .08);
}
.actionbar > .checkline { flex: 1 1 100%; margin: 0; }
.actionbar__status {
  display: flex; align-items: center; gap: .75rem;
  font-size: .82rem; color: var(--muted); margin-left: auto;
}
/* flex-basis 0 and a fixed width on the button between them keep the sync
   control in one place: sized from its content, it slid sideways every time
   the counts or the save note changed length. The counts truncate rather than
   wrap so the row is always exactly two lines, whatever the numbers say. */
.actionbar__counts {
  flex: 1 1 0; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.actionbar__sync { flex: none; width: 5.25rem; padding-left: .25rem; padding-right: .25rem; }
/* The save note keeps its own line whether or not it has anything on it. It
   used to appear only once there was something to say, and because the bar is
   sticky at the bottom of the screen, growing it by that line shoved the whole
   tick sheet up the display every time an autosave finished — which is to say,
   on every keystroke. A reserved line costs 24px and never moves. */
.actionbar__save { display: block; min-height: 1.5rem; }
/* inline-block, because text-overflow does nothing to a flex container: on the
   narrowest phone the longest message was being cut off mid-word. */
.actionbar__save .badge {
  display: inline-block; max-width: 100%; vertical-align: top;
  overflow: hidden; text-overflow: ellipsis;
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1024px) {
  .sidebar {
    position: fixed; inset: 0 auto 0 0;
    transform: translateX(-100%);
    transition: transform .22s ease;
    box-shadow: var(--shadow-lg);
    padding-left: env(safe-area-inset-left);
    overscroll-behavior: contain;
  }
  body.nav-open .sidebar { transform: translateX(0); }
  /* Stop the page behind the drawer scrolling away under the technician's thumb. */
  body.nav-open { overflow: hidden; }
  body.nav-open .sidebar__scrim {
    display: block; position: fixed; inset: 0; z-index: 35;
    background: rgba(11, 19, 29, .55);
  }
  .sidebar__close { display: inline-grid; color: var(--muted); }
  /* Make room for the close button in the drawer. */
  .brand__logo { width: 168px; }
  .topbar .topbar__menu { display: inline-grid; }
  .topbar { padding: .9rem max(1rem, env(safe-area-inset-right)) .9rem max(1rem, env(safe-area-inset-left)); }
  .main { padding: 1.25rem max(1rem, env(safe-area-inset-right)) 2.5rem max(1rem, env(safe-area-inset-left)); }
  .foot { padding: 1rem max(1rem, env(safe-area-inset-right)) calc(1rem + env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left)); }
}

@media (max-width: 640px) {
  /* Field work happens in daylight, so text gets bigger here, not smaller. */
  body { font-size: 16px; }
  /* The heading block runs to ~160px once the page actions wrap. Pinned, that
     plus the action bar claimed 40% of an iPhone before a single asset showed,
     so on phones only the action bar stays put and the title scrolls away. */
  .topbar { position: static; flex-wrap: wrap; padding-top: .75rem; padding-bottom: .75rem; }
  html { scroll-padding-top: 0; }
  /* The bar is sticky, so every line it keeps costs the tick sheet a line. */
  .topbar__sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .topbar__actions { width: 100%; }
  .topbar__actions .btn { flex: 1; }
  .card__head { padding: .75rem 1rem; }
  .card__body, .card--pad { padding: 1rem; }
  .checks { grid-template-columns: 1fr; }
  .form-grid--pair,
  [data-single-system],
  .res-multi,
  .res-indoor { grid-template-columns: 1fr; }
  .dl { grid-template-columns: 1fr; gap: .1rem .5rem; }
  .dl dd { margin-bottom: .5rem; }

  .tick__head { gap: .55rem; padding: .8rem .8rem .7rem; }
  .tick__desc { font-size: .95rem; }
  .tick__loc, .tick__code { font-size: .82rem; }

  /* Two by two beats four across: the labels fit and the targets stay wide. */
  .tick__choices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .4rem; width: 100%; }
  .tick__choices .choice > span { width: 100%; justify-content: center; }

  /* Stack the question above its answer so both get the full card width, with
     the note button in the corner the label was not using anyway. */
  .check { padding: .6rem; }
  .check__row {
    gap: .5rem;
    grid-template-columns: 1fr auto;
    grid-template-areas: "label note" "opts opts";
  }
  .check__label { font-size: .95rem; }
  .check__opts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .4rem; }
  /* Fill the cell — an inline-flex button leaves dead space that looks tappable. */
  .check__opts .choice > span { width: 100%; }
  /* A reading has one field, not three buttons, so it takes the whole row
     rather than a third of it. */
  .check--typed .check__opts { display: block; }
  .check .input { max-width: none !important; }
  .check__entry { max-width: none; }

  /* Full width and its own line, so its wording can change without rewrapping
     anything above it. */
  .tick__toggle { min-width: 0; }

  /* Full bleed to the screen edges, and clear of the home indicator. */
  .actionbar {
    margin: 1.25rem calc(-1 * max(1rem, env(safe-area-inset-right))) 0 calc(-1 * max(1rem, env(safe-area-inset-left)));
    border-radius: 0; border-left: 0; border-right: 0;
    gap: .5rem; padding: .7rem 1rem;
    padding-left: max(1rem, env(safe-area-inset-left));
    padding-right: max(1rem, env(safe-area-inset-right));
    padding-bottom: calc(.7rem + env(safe-area-inset-bottom));
  }
  .actionbar .btn { flex: 1 1 0; min-width: 0; padding-left: .5rem; padding-right: .5rem; }
  /* Deleting something should not be a thumb's width from cancelling, and at
     equal thirds it was. Put it on its own line below the safe choices. */
  .actionbar .btn--danger { flex-basis: 100%; order: 1; }
  /* Its own row above the buttons, tall enough for the sync button whether or
     not the sync button is there, so nothing moves when queued work appears. */
  .actionbar__status { order: -1; width: 100%; margin-left: 0; font-size: .82rem; min-height: 48px; }

  .photos { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
  .lightbox__nav { width: 44px; height: 96px; opacity: .6; }
  .foot { font-size: .8rem; }
  .foot__lic { display: block; }
  .foot__lic + .foot__lic { margin-left: 0; }
  .foot__lic + .foot__lic::before { content: none; }
}

/* --------------------------------------------------------------------------
   Touch
   Keyed off the input device rather than the screen: a technician's thumb is
   the same size on a phone as on the tablet in the van.
   -------------------------------------------------------------------------- */
@media (hover: none) and (pointer: coarse) {
  /* Anything under 16px makes iOS Safari zoom the page in on focus, which
     throws the technician out of position halfway through a form. */
  .input, .select, .textarea, .input--sm, .select--sm { font-size: 16px; }
  .res-items__del { width: 44px; height: 44px; }
  .input, .select { min-height: 48px; }
  .input--sm, .select--sm { min-height: 44px; }
  .textarea { min-height: 110px; }

  .btn { min-height: 46px; padding: .55rem 1rem; }
  .btn--sm { min-height: 44px; padding: .4rem .85rem; font-size: .85rem; }
  .listfoot__size a, .listfoot__size-current { min-width: 44px; min-height: 44px; }
  .pager__btn { min-width: 44px; min-height: 44px; }
  /* One row of buttons, one height — a 44 next to a 46 reads as a misprint. */
  .actionbar .btn, .actionbar .btn--sm { min-height: 48px; }
  .btn--lg { min-height: 52px; }
  .iconbtn { width: 46px; height: 46px; }
  .nav__link { min-height: 48px; }
  .checkline input[type="checkbox"], .checkline input[type="radio"] { width: 22px; height: 22px; }

  /* The result buttons carry the whole inspection; make them unmissable. */
  .choice > span { min-height: 52px; padding: .5rem .9rem; font-size: .95rem; }
  .choice__short { display: none; }
  .choice__long { display: inline; }
  .check__opts .choice > span { min-height: 48px; padding: .4rem .5rem; font-size: .9rem; justify-content: center; }
  /* minmax(0,…) so five buttons always divide the row instead of overflowing it. */
  .prio { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: .45rem; max-width: 430px; }
  .prio label { display: block; }
  .prio span { width: 100%; height: 52px; font-size: 1.05rem; }
  .prio__desc { font-size: .88rem; }
  .tick__toggle {
    min-height: 44px; width: 100%; font-size: .88rem;
    border: 1px solid var(--line); background: var(--canvas);
    justify-content: space-between;
  }
  /* A real target for a gloved thumb, in the dead space beside the label. */
  .check__notebtn { width: 44px; height: 44px; }
  .check__notefield { min-height: 88px; }

  /* Feedback on tap, since there is no hover to lean on. */
  .choice input:active + span, .prio input:active + span { transform: scale(.96); }
  .btn:active, .iconbtn:active { filter: brightness(.94); }

  /* Photographs: one obvious button that opens the camera. */
  .dropzone {
    max-width: none; padding: 1.4rem 1rem; border-style: solid;
    border-color: var(--blue-500); background: var(--info-bg); color: var(--info);
    font-size: 1rem; font-weight: 650;
  }
  .dropzone__icon { width: 32px; height: 32px; }
  .dropzone__touch { display: block; }
  .dropzone__pointer { display: none; }
  .photo__del { width: 44px; height: 44px; top: 5px; right: 5px; }
}

/* --------------------------------------------------------------------------
   Residential area — phone-first job sheet
   -------------------------------------------------------------------------- */
body.app--residential {
  --canvas: #eef3ee;
  --canvas-alt: #e2ebe2;
}
body.app--residential .sidebar {
  background: linear-gradient(180deg, #f4faf4 0%, #eef6ee 100%);
}
.res-banner {
  display: flex; align-items: baseline; gap: .75rem; flex-wrap: wrap;
  padding: .45rem 1.15rem;
  background: #1b4332; color: #d8f3dc;
  font-size: .82rem; font-weight: 650;
}
.res-banner__hint { font-weight: 500; color: #95d5b2; }
.res-banner__back { margin-left: auto; color: #fff; text-decoration: underline; }
.res-banner__back:hover { color: #d8f3dc; }

.res-push {
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
  margin: 0 0 1rem; padding: .85rem 1rem;
  background: var(--info-bg); border: 1px solid #c6dcf2; border-radius: var(--r);
  color: #0d4f86;
}
.res-push__copy { margin: 0; flex: 1 1 16rem; font-size: .9rem; }
.res-push .btn { flex: 0 0 auto; }

.res-jobs { display: grid; gap: .65rem; }
.res-job {
  display: block; padding: 1rem 1.05rem; border-radius: var(--r);
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--shadow-sm); color: inherit;
}
.res-job:hover { text-decoration: none; border-color: #9cc5a8; }
.res-job__top { display: flex; justify-content: space-between; gap: .75rem; align-items: flex-start; }
.res-job__where { font-weight: 750; font-size: 1.05rem; }
.res-job__where--task { display: flex; align-items: flex-start; gap: .4rem; }
.res-job__where--task .icon { margin-top: .18rem; opacity: .7; }
.res-job__where--task span { white-space: pre-wrap; word-break: break-word; }
.res-job__who, .res-job__meta { color: var(--muted); font-size: .86rem; margin-top: .15rem; }
.res-job__go {
  display: inline-flex; align-items: center; justify-content: center;
  margin-top: .75rem; min-height: 44px; width: 100%;
  border-radius: var(--r-sm); background: #2d6a4f; color: #fff; font-weight: 650;
}
.res-job:hover .res-job__go { background: #1b4332; }

.res-check {
  padding: .75rem; border: 1px solid var(--line-soft); border-radius: var(--r-sm);
  background: var(--surface); margin-bottom: .5rem;
}
.res-check--fault { border-color: #e3b4b4; background: #fff6f6; }
.res-check--na { border-color: #d5d5d0; background: #f6f6f4; }
.res-check__label { font-weight: 650; display: block; margin-bottom: .45rem; }
.res-check__hint { font-size: .8rem; color: var(--muted); font-weight: 500; }
.res-opts { display: grid; grid-template-columns: repeat(3, 1fr); gap: .4rem; }
.res-opts .choice > span { width: 100%; justify-content: center; min-height: 44px; }
.res-note { margin-top: .55rem; }
.res-note .textarea { min-height: 72px; font-size: 1rem; }
.res-suggest {
  display: flex; flex-direction: column; gap: .35rem; margin-top: .4rem;
}
.res-suggest button {
  text-align: left; border: 1px solid #cfe3d4; background: #f4faf5;
  color: #1b4332; border-radius: var(--r-sm); padding: .55rem .65rem;
  font: inherit; font-size: .86rem; cursor: pointer;
}
.res-suggest button:hover { background: #e4f4ea; }
.res-suggest__linked {
  display: block; margin-top: .25rem; font-size: .78rem; font-weight: 500;
  color: #3d6b52;
}
.res-note-list { margin: 0; padding-left: 1.15rem; }
.res-note-list li { margin: 0 0 .35rem; }
.res-items__list { list-style: none; margin: 0 0 .55rem; padding: 0; }
.res-items__row {
  display: flex; align-items: flex-start; gap: .5rem;
  margin: 0 0 .4rem; padding: .55rem .65rem;
  background: #f4f8f4; border: 1px solid #d5e3d6; border-radius: var(--r-sm);
}
.res-items__text { flex: 1; min-width: 0; line-height: 1.45; }
.res-items__del {
  flex: 0 0 auto; width: 36px; height: 36px; margin: -.15rem -.2rem -.15rem 0;
  border: 0; border-radius: 50%; background: transparent; color: var(--muted);
  display: grid; place-items: center; cursor: pointer;
}
.res-items__del:hover { background: #f3d6d6; color: var(--bad); }
.res-items__composer {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .45rem;
  align-items: start;
}
.res-items__composer .btn { min-height: 40px; }
.res-items__store { display: none; }
.data tr.is-muted td { opacity: .55; }
.res-photos { display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: .45rem; margin-top: .5rem; }
.res-photo-actions {
  display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; margin-top: .75rem;
}
.res-photo-actions .btn {
  position: relative; width: 100%; min-height: 48px; cursor: pointer;
}
.res-photo-actions input[type="file"] { display: none; }
.res-photo-status {
  margin: .55rem 0 0; font-size: .88rem; font-weight: 650;
}
.res-photo-status--ok { color: #1b4332; }
.res-photo-status--warn { color: #8a5a08; }
.res-photo-status--error { color: var(--bad); }
.photo.is-failed { outline: 2px solid var(--bad); }
.res-photo-toast {
  position: fixed; z-index: 90; left: 50%; bottom: 1rem; transform: translateX(-50%);
  max-width: calc(100vw - 1.5rem); padding: .55rem .85rem;
  background: #12202c; color: #fff; border-radius: 999px;
  font-size: .82rem; font-weight: 650; box-shadow: 0 8px 22px rgba(15, 23, 32, .28);
}
.sked { display: grid; grid-template-columns: 21rem minmax(0, 1fr); gap: 1rem; align-items: start; }
.sked-pool {
  position: sticky; top: 4.5rem; display: flex; flex-direction: column;
  max-height: calc(100vh - 5.25rem); overflow: hidden;
  background: #f6f8f6; border: 1px solid #d5e0d6; border-radius: var(--r);
  box-shadow: var(--shadow-sm);
}
.sked-pool__head { padding: .85rem .85rem .7rem; border-bottom: 1px solid #d5e0d6; background: #eef3ee; }
.sked-pool__title { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-bottom: .55rem; }
.sked-pool__title h2 { margin: 0; font-size: .95rem; }
.sked-pool__search { width: 100%; }
.sked-chips { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .55rem; }
.sked-chip {
  appearance: none; border: 1px solid #c5d4c8; background: #fff; color: #2d4638;
  border-radius: 999px; padding: .28rem .65rem; font: inherit; font-size: .76rem;
  font-weight: 650; cursor: pointer;
}
.sked-chip em { font-style: normal; margin-left: .15rem; color: #5c7a6a; }
.sked-chip.is-on { background: #1b4332; border-color: #1b4332; color: #fff; }
.sked-chip.is-on em { color: #b7e4c7; }
.sked-pop { position: relative; }
.sked-pop__panel {
  position: absolute; z-index: 12; top: calc(100% + .35rem); right: 0;
  width: 16.5rem; padding: .8rem .85rem .9rem;
  background: #16382b; color: #d8f3dc; border-radius: 10px;
  box-shadow: var(--shadow-lg);
}
.sked-pop__label {
  margin: 0 0 .45rem; font-size: .68rem; font-weight: 750;
  letter-spacing: .05em; text-transform: uppercase; color: #95d5b2;
}
.sked-pop__panel .select { width: 100%; }
.sked-staff {
  display: flex; align-items: center; gap: .45rem;
  padding: .28rem 0; color: #fff; font-size: .84rem; cursor: pointer;
}
.sked-staff input { accent-color: #95d5b2; }
.sked-avatar {
  width: 1.7rem; height: 1.7rem; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .62rem; font-weight: 750; letter-spacing: .02em;
}
.sked-pool__jobs {
  flex: 1 1 auto; overflow: auto; min-height: 6rem;
  padding: .55rem .85rem .7rem; background: #f6f8f6;
}
.sked-pool__empty { margin: .7rem 0 .2rem; }
.sked-unschedule {
  flex: none; display: flex; align-items: center; justify-content: flex-start; gap: .45rem;
  margin: 0 .85rem 1rem; padding: .65rem .7rem;
  border: 1px dashed #b7c7bb; border-radius: var(--r-sm);
  color: var(--muted); font-size: .82rem; line-height: 1.3; background: #fff;
}
.sked-unschedule__icon { width: 20px; height: 20px; color: #9f4a4a; }
.sked-unschedule span { min-width: 0; }
.sked-card, .sked-item {
  display: flex; flex-direction: column; gap: .15rem;
  border: 1px solid #cfe3d4; background: #f4faf5; color: #1b4332;
  border-radius: var(--r-sm); padding: .5rem .55rem; cursor: grab; position: relative;
}
.sked-card { margin-top: .45rem; }
.sked-card--job { padding: .55rem .6rem .5rem; box-shadow: 0 1px 0 rgba(27, 67, 50, .04); }
.sked-card--job.is-waiting { border-color: #9cc5a8; background: #fff; }
.sked-card--job.is-booked { border-color: #d3ddd6; background: #f3f6f3; color: #3d5346; }
.sked-card__top { display: flex; align-items: center; justify-content: flex-start; gap: .4rem; flex-wrap: wrap; }
.sked-card__flags { display: flex; flex-wrap: wrap; gap: .25rem; flex: 0 1 auto; }
.sked-card__num { font-size: .92rem; font-weight: 750; letter-spacing: 0; color: #1b4332; }
.sked-card--job.is-booked .sked-card__num { color: #3d5346; }
.sked-card__flag {
  font-size: .65rem; font-weight: 750; letter-spacing: .02em; text-transform: uppercase;
  padding: .12rem .4rem; border-radius: 4px; background: #e4ece6; color: #3d5346;
}
.sked-card__flag--today {
  background: #fff; color: #12202c; border: 1px solid #12202c;
}
.sked-card .sked-card__num, .sked-card .sked-card__flag, .sked-card .res-pill,
.sked-card .sked-card__desc, .sked-card .sked-card__where { opacity: 1; }
.sked-card__desc, .sked-card__where {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.3;
}
.sked-card__desc { font-size: .78rem; color: #33485e; }
.sked-card__where { font-size: .72rem; color: #5c7a6a; }
.sked-pool[data-pool-view="waiting"] .sked-card--job:not([data-status="unassigned"]) { display: none; }
.sked-pool[data-pool-view="booked"] .sked-card--job:not([data-status="scheduled"]) { display: none; }
.sked-card--task { border-color: #d7d2c4; background: #f7f4ea; color: #4a4030; }
.sked-card strong, .sked-item strong { font-size: .82rem; line-height: 1.25; }
.sked-card span, .sked-item span { font-size: .72rem; color: inherit; opacity: .8; }
.sked-card .res-pill {
  font-size: .68rem; color: #fff; opacity: 1;
}
.sked-item .sked-item__badge {
  font-size: .58rem; color: #fff; opacity: 1;
}
.sked-card .sked-card__flag { opacity: 1; }
.sked-card .sked-card__flag--today { color: #12202c; }
.sked-card.is-selected, .sked-item.is-selected { outline: 2px solid #1b4332; outline-offset: 1px; }
.sked-card__del {
  position: absolute; top: .15rem; right: .2rem; border: 0; background: transparent;
  color: inherit; font-size: 1.1rem; line-height: 1; cursor: pointer;
}
.sked-slot.is-over { background: #d8f3dc; }
.sked-unschedule.is-over {
  background: #fdecec; border-color: #e0a0a0; color: #7a2e2e;
}
.sked-taskpop {
  position: fixed; z-index: 80; width: min(22rem, calc(100vw - 1.5rem));
  padding: .85rem .9rem .8rem; border-radius: 12px;
  background: #16382b; color: #d8f3dc;
  box-shadow: 0 16px 40px rgba(15, 23, 32, .28);
}
.sked-taskpop__meta {
  margin: 0 0 .45rem; font-size: .68rem; font-weight: 750;
  letter-spacing: .05em; text-transform: uppercase; color: #95d5b2;
}
.sked-taskpop .input {
  background: #fff; color: #12202c; border-color: transparent;
}
.sked-taskpop__row { display: flex; gap: .4rem; margin-top: .55rem; }
.sked-taskpop .hint { margin: .5rem 0 0; color: #95d5b2; }
.sked-tip {
  position: fixed; z-index: 200; pointer-events: none;
  padding: .35rem .55rem; border-radius: 6px;
  background: #12202c; color: #fff; font-size: .82rem; font-weight: 650;
  box-shadow: 0 6px 18px rgba(15, 23, 32, .28); white-space: nowrap;
}
.sked-nav { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-bottom: .55rem; }
.sked-clock {
  margin-left: auto;
  display: flex; flex-direction: column; align-items: flex-end; justify-content: center;
  min-width: 7.4rem; padding: .22rem .75rem .28rem;
  background: #0b1220; border-radius: 8px; color: #9fe7c2;
  box-shadow: inset 0 0 0 1px rgba(159, 231, 194, .12);
}
.sked-clock__label {
  font-size: .58rem; font-weight: 750; letter-spacing: .08em;
  text-transform: uppercase; color: #7d93a8; line-height: 1.2;
}
.sked-clock__digits {
  display: flex; align-items: baseline; gap: .28rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1.28rem; font-weight: 700; letter-spacing: .08em;
  color: #7CFFB2; line-height: 1.05;
}
.sked-clock__digits small {
  font-size: .62rem; letter-spacing: .08em; color: #9fe7c2; font-weight: 750;
}
.sked-week {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: .3rem;
  margin: 0 0 .75rem;
}
.sked-week__day {
  display: flex; flex-direction: column; align-items: center; gap: .05rem;
  padding: .35rem .15rem .4rem; border-radius: 8px; text-decoration: none;
  background: #fff; border: 1px solid var(--line); color: inherit; min-height: 3.4rem;
}
.sked-week__day:hover { border-color: #9cc5a8; text-decoration: none; }
.sked-week__day em { font-style: normal; font-size: .68rem; font-weight: 650; color: var(--muted); }
.sked-week__day strong { font-size: 1.05rem; line-height: 1.1; }
.sked-week__day span {
  margin-top: .12rem; padding: 0 .35rem; border-radius: 999px;
  background: #d8f3dc; color: #1b4332; font-size: .64rem; font-weight: 750;
}
.sked-week__day.is-today:not(.is-on) { border-color: #1b4332; }
.sked-week__day.is-on { background: #1b4332; border-color: #1b4332; color: #fff; }
.sked-week__day.is-on em, .sked-week__day.is-on strong { color: #fff; }
.sked-scroll { overflow-x: auto; }
.sked-grid { position: relative; min-width: calc(8.6rem + (var(--sked-cols) * 24px)); }
.sked-hours { display: grid; grid-template-columns: 8.6rem minmax(0, 1fr); margin-bottom: 0; }
.sked-who {
  display: flex; align-items: center; gap: .4rem;
  padding: .45rem .4rem; font-weight: 750; font-size: .82rem; line-height: 1.15;
  color: var(--sked, var(--ink)); border-left: 4px solid var(--sked, var(--line));
}
.sked-who__name { min-width: 0; }
.sked-who span { font-weight: 500; color: inherit; opacity: .7; }
.sked-who .sked-avatar { opacity: 1; }
.sked-who .sked-who__hours {
  display: block; margin-top: .12rem; opacity: 1; font-weight: 650;
  font-size: .68rem; letter-spacing: 0; color: var(--sked, var(--ink));
}
.sked-who .sked-who__hours em { font-style: normal; margin-left: .2rem; color: #9a3412; opacity: 1; font-weight: 750; }
.sked-who .sked-who__hours.is-long { color: #9a3412; }
.sked-who--head { min-height: 1.5rem; border-left-color: transparent; }
.sked-track {
  display: grid; grid-template-columns: repeat(var(--sked-cols), minmax(24px, 1fr));
  grid-template-rows: 5.35rem; position: relative;
  border: 1px solid var(--line); border-bottom: 0; background: var(--surface);
}
.sked-grid > .sked-hours:nth-last-child(2) .sked-track { border-bottom: 1px solid var(--line); }
.sked-track--head { grid-template-rows: 1.5rem; border: 0; background: transparent; }
.sked-slot { grid-row: 1; border-left: 1px solid #edf1f5; min-width: 0; }
.sked-slot--hour { font-size: .64rem; color: var(--muted); padding: .1rem .05rem; }
.sked-lane { position: absolute; inset: 0; pointer-events: none; }
.sked-now {
  position: absolute; top: 1.5rem; bottom: 0;
  left: calc(8.6rem + (100% - 8.6rem) * var(--sked-now, 0));
  width: 2px; margin-left: -1px;
  background: #dc2626; pointer-events: none; z-index: 12;
}
.sked-item {
  position: absolute; top: .3rem; bottom: .3rem; pointer-events: auto; z-index: 2;
  overflow: hidden; margin: 0; box-sizing: border-box; cursor: grab;
  touch-action: none; user-select: none;
  display: flex; flex-direction: column; justify-content: flex-start;
  padding: .28rem .55rem .28rem .4rem;
  background: var(--sked, #1d4e89); color: var(--sked-fg, #fff); border-color: transparent;
}
.sked-item__badge {
  align-self: flex-start; flex: none; max-width: calc(100% - .2rem);
  margin: 0 0 .15rem; padding: .1rem .32rem;
  font-size: .58rem; letter-spacing: .03em; line-height: 1.15;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sked-item.is-dragging {
  z-index: 6; cursor: grabbing;
  box-shadow: 0 8px 22px rgba(15, 23, 32, .28);
}
.sked-item--task {
  flex-direction: row; align-items: center; gap: .3rem;
  padding: .3rem .75rem .3rem .4rem;
  background: var(--sked-soft, #f7f4ea); color: #2a2418; border-color: var(--sked, #c9b48a);
}
.sked-item__icon { display: inline-flex; flex: none; opacity: .85; }
.sked-item__note {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: .78rem; font-weight: 650; line-height: 1.25; opacity: 1;
}
.sked-item__resize {
  position: absolute; top: 0; right: 0; width: 12px; height: 100%; cursor: ew-resize;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.35));
}
.sked-item--task .sked-item__resize { background: linear-gradient(90deg, transparent, rgba(0,0,0,.12)); }

.sked-scrim { position: fixed; inset: 0; background: rgba(15, 23, 32, .45); z-index: 80; }
.sked-drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(26rem, 100%);
  background: #eef3ee; z-index: 85; padding: 0; overflow: auto;
  box-shadow: -12px 0 32px rgba(15, 23, 32, .18);
}
.sked-drawer__head {
  display: flex; align-items: flex-start; gap: .75rem;
  padding: 1.1rem 1.15rem 1rem; background: #1b4332; color: #d8f3dc;
}
.sked-drawer__head h2 { margin: .3rem 0 0; flex: 1; font-size: 1.12rem; color: #fff; line-height: 1.3; }
.sked-drawer__head .iconbtn { color: #fff; }
.sked-drawer__head .iconbtn:hover { background: rgba(255,255,255,.12); }
.sked-drawer__badge {
  display: inline-block; margin: 0; padding: .15rem .5rem;
  border-radius: 999px; background: #d8f3dc; color: #1b4332;
  font-size: .68rem; font-weight: 750; letter-spacing: .04em; text-transform: uppercase;
}
.sked-drawer__fields { margin: 0; padding: .9rem 1.1rem 0; }
.sked-drawer__fields dt {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .05em;
  color: #5c7a6a; font-weight: 750; margin: 0;
}
.sked-drawer__fields dd {
  margin: .25rem 0 .75rem; padding: .6rem .7rem;
  background: #fff; border: 1px solid #d5e4d8; border-radius: 8px;
  white-space: pre-wrap; color: #1b2a22; font-size: .95rem; line-height: 1.45;
}
.sked-drawer__actions { display: flex; flex-wrap: wrap; gap: .5rem; padding: .35rem 1.1rem 1.25rem; }
.sked-drawer__status {
  margin: .85rem 1.1rem 0; padding: .7rem .75rem .8rem;
  background: #fff; border: 1px solid #d5e4d8; border-radius: 8px;
}
.sked-drawer__status .label { margin-bottom: .35rem; }
.sked-drawer__status .select { width: 100%; }
.sked-drawer__plan {
  margin: .85rem 1.1rem 0; padding: .75rem .75rem .85rem;
  background: #fff; border: 1px solid #d5e4d8; border-radius: 8px;
}
.sked-drawer__plan > .label { margin: .15rem 0 .35rem; }
.sked-visit {
  display: grid; grid-template-columns: 1fr 1fr; gap: .4rem .6rem;
  padding: .55rem 0 .65rem; border-top: 1px solid #e4eee6;
}
.sked-visit:first-of-type { border-top: 0; padding-top: .1rem; }
.sked-visit__who { grid-column: 1 / -1; margin: 0; font-weight: 700; display: flex; align-items: center; gap: .45rem; }
.sked-picks { display: flex; flex-wrap: wrap; gap: .45rem .55rem; }
.sked-pick { display: inline-flex; align-items: center; gap: .28rem; margin: 0; cursor: pointer; }
.sked-pick input { accent-color: #1b4332; width: 1rem; height: 1rem; }
.sked-pick input:disabled { cursor: default; }
.sked-pick:has(input:disabled) { cursor: default; }
.sked-pick__add { margin-top: .55rem; }
.sked-visit .field { margin: 0; }
.sked-visit .label { margin-bottom: .2rem; }
.sked-visit .input { width: 100%; }
.sked-visit__save { grid-column: 1 / -1; justify-self: start; }
.sked-time-error { grid-column: 1 / -1; margin: 0; color: var(--bad); font-size: .78rem; }
.sked-drawer__plan .hint { margin: .55rem 0 0; }

.sked-leg {
  margin-top: .85rem; padding: .85rem .9rem .95rem;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r);
}
.sked-leg__head { margin-bottom: .65rem; }
.sked-leg__head h2 { margin: 0; font-size: .95rem; }
.sked-leg__head p {
  margin: .3rem 0 0; font-size: .78rem; color: var(--muted); line-height: 1.4; max-width: 46rem;
}
.sked-leg__scroll { overflow-x: auto; }
.sked-leg__table { width: 100%; border-collapse: collapse; font-size: .84rem; }
.sked-leg__table th, .sked-leg__table td {
  padding: .5rem .55rem; text-align: left; white-space: nowrap; vertical-align: middle;
}
.sked-leg__table thead th {
  font-size: .68rem; font-weight: 750; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); border-bottom: 1px solid var(--line);
}
.sked-leg__table tbody th {
  font-weight: 750; color: var(--sked, var(--ink));
  border-left: 4px solid var(--sked, var(--line)); padding-left: .45rem;
}
.sked-leg__name { display: flex; align-items: center; gap: .45rem; }
.sked-leg__who { min-width: 0; }
.sked-leg__table tbody td { font-variant-numeric: tabular-nums; color: var(--ink); }
.sked-leg__table tbody tr { border-bottom: 1px solid var(--line-soft); }
.sked-leg__table tbody tr:last-child { border-bottom: 0; }
.sked-leg__total { font-weight: 750; }
.sked-leg__table tr.is-long .sked-leg__total,
.sked-leg__table tr.is-long .sked-leg__ot {
  color: #9a3412; background: #fff7ed; border-radius: 6px;
}

.res-status { display: flex; align-items: center; gap: .4rem; margin: 0 0 0 auto; }
.res-status__select { min-width: 11rem; font-weight: 650; }
.res-pill {
  display: inline-flex; align-items: center;
  padding: .2rem .5rem; border-radius: 4px;
  font-size: .68rem; font-weight: 750; letter-spacing: .03em;
  text-transform: uppercase; line-height: 1.2; white-space: nowrap;
  color: #fff;
}
.res-pill--unassigned { background: #dc2626; color: #fff; }
.res-pill--scheduled { background: #1d4ed8; color: #fff; }
.res-pill--in_progress { background: #ea580c; color: #fff; }
.res-pill--awaiting_parts { background: #334155; color: #fff; }
.res-pill--on_hold { background: #7c3aed; color: #fff; }
.res-pill--to_invoice { background: #0f766e; color: #fff; }
.res-pill--complete { background: #15803d; color: #fff; }
.res-pill--cancelled { background: #3f3f46; color: #fff; }

.res-job--task { cursor: default; background: #f7f4ea; }
.res-add-system { margin-top: .85rem; padding-top: .85rem; border-top: 1px solid var(--line); }
.res-add-system__btn { width: 100%; min-height: 48px; margin-top: .75rem; }
.res-add-system__unit {
  grid-column: 1 / -1; margin: .55rem 0 0;
  font-size: .72rem; font-weight: 750; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted);
}
[data-single-system],
.res-multi { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 1rem; }
.res-multi[hidden],
[data-single-system][hidden] { display: none; }
.res-multi > .hint { grid-column: 1 / -1; margin: .35rem 0 .15rem; }
.res-indoor {
  grid-column: 1 / -1; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 1rem; margin-top: .35rem; padding-top: .35rem; border-top: 1px solid var(--line-soft);
}
.res-indoor__head { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.res-indoor__head .res-add-system__unit { margin: 0; }
.res-indoor-add { grid-column: 1 / -1; justify-self: start; margin-top: .35rem; }
.res-system-list { list-style: none; padding: 0; margin: 0 0 .5rem; display: grid; gap: .4rem; }
.res-system-row {
  display: flex; align-items: flex-start; justify-content: space-between; gap: .6rem;
  padding: .55rem .65rem; border: 1px solid var(--line-soft); border-radius: var(--r-sm);
  background: var(--surface);
}
.res-system-row__meta { min-width: 0; display: flex; flex-direction: column; gap: .15rem; }
.res-system-row__meta strong { font-size: .92rem; }
.res-system-plates {
  display: block; font-weight: 500; font-size: .78rem; color: var(--muted); line-height: 1.35; white-space: pre-line;
}
.res-system-row .btn { flex-shrink: 0; min-height: 40px; }
.res-lookup-add, .res-lookup-rename { display: flex; gap: .45rem; align-items: center; flex-wrap: wrap; }
.res-lookup-add .input, .res-lookup-rename .input { flex: 1; min-width: 8rem; }
.res-lookup-add .select, .res-lookup-rename .select { flex: 1; min-width: 10rem; }
.res-type-attach {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: .4rem 1.25rem; margin-top: .75rem;
}
.res-type-attach .checkline { margin: 0; }
.res-type-attach .checkline.is-muted { opacity: .55; }
form.inline { display: inline; }

@media (max-width: 960px) {
  .sked { grid-template-columns: minmax(0, 1fr); }
  .sked-pool { position: static; max-width: 100%; }
  .sked-board { min-width: 0; max-width: 100%; }
}

.res-copy { margin-bottom: 1.25rem; }
.res-copy__from { margin: 0 0 .35rem; font-size: 1.02rem; }
.res-copy .input { max-width: 16rem; }

.res-pick { display: flex; flex-direction: column; gap: .35rem; margin-top: .4rem; }
.res-pick button {
  display: flex; flex-direction: column; gap: .12rem;
  text-align: left; border: 1px solid var(--line); background: var(--surface);
  color: var(--ink); border-radius: var(--r-sm); padding: .65rem .7rem;
  font: inherit; font-size: .88rem; cursor: pointer;
}
.res-pick button:hover { border-color: #9cc5a8; background: #f4faf5; }
.res-pick__title { font-weight: 650; }
.res-pick__addr, .res-pick__meta { font-size: .78rem; color: var(--muted); }
.res-preview {
  margin-top: .5rem; padding: .55rem .7rem; background: var(--canvas-alt);
  border-radius: var(--r-sm); font-size: .88rem; color: var(--ink-soft);
  white-space: pre-line;
}
.res-photos img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--r-sm); }

@media (max-width: 640px) {
  .res-banner { padding: .45rem max(1rem, env(safe-area-inset-right)) .45rem max(1rem, env(safe-area-inset-left)); }
  .res-banner__hint { display: none; }
}

/* --------------------------------------------------------------------------
   Print
   -------------------------------------------------------------------------- */
@media print {
  .sidebar, .topbar, .foot, .actionbar, .btn, .no-print, .lightbox { display: none !important; }
  body { background: #fff; }
  .main { padding: 0; max-width: none; }
  .card { box-shadow: none; border-color: #ccc; break-inside: avoid; }
}
