/* ═══════════════════════════════════════════════════════════════════════════
   HYDRATECH — CLEAR WATER
   Saturated hero, rounded cards, circular icon badges, big tabular numbers.
   Tokens live in theme.css.
   ═══════════════════════════════════════════════════════════════════════════ */

.hidden { display: none !important; }
.error  { color: var(--bad); font-size: .84rem; margin-top: 8px; font-weight: 600; }
.n      { font-variant-numeric: tabular-nums; }
svg.ico { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.1;
          stroke-linecap: round; stroke-linejoin: round; flex: none; }

/* Icon badge — the coloured rounded square used everywhere */
.badge { width: 40px; height: 40px; border-radius: 13px; flex: none; display: grid; place-items: center; }
/* Without fill/stroke the sprite falls back to SVG's default — solid black
   fill, no stroke — which rendered every badge as a dark blob. */
.badge svg {
  width: 19px; height: 19px;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.badge-sm { width: 34px; height: 34px; border-radius: 11px; }
.badge-sm svg { width: 17px; height: 17px; }
.c-blue   { background: var(--tint-brand);  color: var(--brand); }
.c-teal   { background: var(--tint-ok);     color: var(--ok); }
.c-violet { background: var(--tint-violet); color: var(--violet); }
.c-amber  { background: var(--tint-warn);   color: var(--warn); }
.c-red    { background: var(--tint-bad);    color: var(--bad); }

/* ══════════════════════════ LOGIN ══════════════════════════ */
#screen-login {
  position: fixed; inset: 0; z-index: 400; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(165deg, #00A6E6 0%, #0075B8 48%, #003E6B 100%);
}
#screen-login::before, #screen-login::after,
#screen-login .login-glow {
  content: ''; position: absolute; border-radius: 50%; filter: blur(60px); opacity: .5;
}
#screen-login::before { width: 62vw; aspect-ratio: 1; background: #6FE3FF; top: -12%; left: -18%;
  animation: lg-float 15s ease-in-out infinite; }
#screen-login::after  { width: 55vw; aspect-ratio: 1; background: #00D4C7; bottom: -14%; right: -16%;
  animation: lg-float 19s ease-in-out infinite reverse; }
@keyframes lg-float { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(9%,-11%) scale(1.2); } }

.login-box {
  position: relative; z-index: 3; width: min(88vw, 372px);
  background: var(--surface); border-radius: 28px; padding: 34px 26px 28px;
  box-shadow: 0 30px 70px rgba(0,30,60,.36);
  animation: lb-lift .7s cubic-bezier(.2,.9,.3,1.05) backwards;
}
@keyframes lb-lift { from { opacity: 0; transform: translateY(34px) scale(.94); } }
.login-box > *, .login-box form > * { animation: lb-up .55s cubic-bezier(.2,.9,.3,1) backwards; }
.login-box > *:nth-child(1) { animation-delay: .10s; }
.login-box > *:nth-child(2) { animation-delay: .16s; }
.login-box form > *:nth-child(1) { animation-delay: .22s; }
.login-box form > *:nth-child(2) { animation-delay: .27s; }
.login-box form > *:nth-child(3) { animation-delay: .32s; }
.login-box form > *:nth-child(4) { animation-delay: .37s; }
@keyframes lb-up { from { opacity: 0; transform: translateY(14px); } }

.login-subtitle {
  text-align: center; color: var(--text-muted); font-size: .84rem;
  font-weight: 600; margin-bottom: 24px;
}
/* Not selected by type: the show-password toggle switches the field to
   type="text", and a type-based selector drops every style the moment it
   does — padding, border, background and all. */
#form-login input:not([type="checkbox"]) {
  width: 100%; padding: 15px 16px; margin-bottom: 11px; border-radius: 15px;
  background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .95rem; font-weight: 500;
}
#form-login input::placeholder { color: var(--text-muted); }
#form-login input:focus { outline: none; border-color: var(--brand); background: var(--surface); }
.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 46px !important; }
.pw-toggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 34px; height: 34px; margin-top: -5px; border: none; background: none;
  color: var(--text-muted); cursor: pointer; display: grid; place-items: center; border-radius: 9px;
}
.remember-label {
  display: flex; align-items: center; gap: 8px; margin: 4px 0 14px;
  font-size: .82rem; color: var(--text-muted); font-weight: 600; cursor: pointer;
}
.remember-label input { width: 17px; height: 17px; accent-color: var(--brand); }
#btn-login {
  width: 100%; padding: 16px; border: none; border-radius: 15px;
  background: linear-gradient(135deg, var(--brand), var(--brand-2)); color: #fff;
  font-family: inherit; font-size: 1rem; font-weight: 700; cursor: pointer;
  box-shadow: var(--sh-fab); transition: transform .12s;
}
#btn-login:active { transform: scale(.97); }
#btn-login:disabled { opacity: .65; }

/* ══════════════════════════ HERO HEADER ══════════════════════════ */
/* ══════════════ THE HEADER — a pool surface ══════════════
   The card reads as water seen from above: light gathering at the top left the
   way it does on a surface, deepening towards the bottom, and a waterline
   instead of a ruled edge. All CSS — no image to load and nothing to animate,
   because this is a phone in someone's pocket all day. */
#nav {
  position: relative; overflow: hidden;
  /* Deeper towards the bottom, the way water is. */
  background:
    radial-gradient(120% 80% at 12% -20%,
      rgba(255,255,255,var(--rail-sheen)) 0%, rgba(255,255,255,0) 58%),
    linear-gradient(165deg, var(--rail-1) 0%, var(--rail-2) 72%, var(--rail-2) 100%);
  padding: calc(18px + env(safe-area-inset-top)) 18px 40px;
  box-shadow: var(--sh-l); margin-bottom: 4px;
}

/* Caustics — the bright net of light that moves across the bottom of a pool.
   Two soft bands crossing at a shallow angle, kept faint enough to read as
   texture rather than pattern. */
#nav::before {
  content: ''; position: absolute; inset: 0; pointer-events: none; opacity: var(--rail-caustics);
  background-image:
    repeating-linear-gradient(102deg, transparent 0 34px, rgba(255,255,255,.10) 34px 37px, transparent 37px 46px),
    repeating-linear-gradient(78deg,  transparent 0 44px, rgba(255,255,255,.07) 44px 46px, transparent 46px 58px),
    radial-gradient(60% 50% at 78% 12%, rgba(255,255,255,.16), transparent 70%);
  -webkit-mask-image: linear-gradient(160deg, #000 10%, rgba(0,0,0,.35) 70%, transparent 100%);
          mask-image: linear-gradient(160deg, #000 10%, rgba(0,0,0,.35) 70%, transparent 100%);
}

/* The waterline. A shallow double wave in the page colour, so the header ends
   at a surface rather than at a rounded rectangle. */
#nav::after {
  content: ''; position: absolute; left: -2px; right: -2px; bottom: -1px;
  height: 26px; background: var(--bg); pointer-events: none;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 60' preserveAspectRatio='none'%3E%3Cpath d='M0,30 C210,60 430,2 700,20 C955,37 1205,4 1440,28 L1440,60 L0,60 Z' fill='%23fff'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 60' preserveAspectRatio='none'%3E%3Cpath d='M0,30 C210,60 430,2 700,20 C955,37 1205,4 1440,28 L1440,60 L0,60 Z' fill='%23fff'/%3E%3C/svg%3E");
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}

.hero-inner { position: relative; z-index: 1; max-width: 620px; margin: 0 auto; }
.hero-top { display: flex; justify-content: space-between; align-items: center; gap: 12px; }

/* The way into your own profile — face, name, role, one tap. Frosted glass on
   the water rather than a button drawn in a box. */
.nav-me {
  display: flex; align-items: center; gap: 11px; min-width: 0; cursor: pointer;
  padding: 5px 12px 5px 5px; margin-left: -5px; border-radius: 999px;
  background: rgba(255,255,255,.16); border: 1.5px solid rgba(255,255,255,.28);
  box-shadow: 0 2px 10px rgba(0,0,0,.10), inset 0 1px 0 rgba(255,255,255,.30);
  font-family: inherit; text-align: left;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  transition: background .15s, transform .12s;
}
.nav-me:active { transform: scale(.97); background: rgba(255,255,255,.26); }
.nav-me-av {
  width: 40px; height: 40px; border-radius: 50%; flex: none; overflow: hidden;
  display: grid; place-items: center;
  background: rgba(255,255,255,.26); border: 2px solid rgba(255,255,255,.55);
  box-shadow: 0 2px 8px rgba(0,0,0,.16);
  color: #fff; font-size: .84rem; font-weight: 800; letter-spacing: -.01em;
}
.nav-me-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero-who { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.hero-who small {
  display: block; color: rgba(255,255,255,.72); font-size: .6rem;
  font-weight: 800; letter-spacing: .09em; text-transform: uppercase; line-height: 1;
}
#nav-user {
  color: #fff; font-size: .88rem; font-weight: 800; letter-spacing: -.015em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  display: block; max-width: 40vw; line-height: 1.25;
}
.nav-me-go {
  width: 15px; height: 15px; flex: none; fill: none; stroke: rgba(255,255,255,.65);
  stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
}

/* Round, to sit with the avatar rather than argue with it. */
.nav-right { display: flex; gap: 8px; flex: none; }
.nav-right button {
  width: 38px; height: 38px; border-radius: 50%; border: 1.5px solid rgba(255,255,255,.30);
  background: rgba(255,255,255,.15); color: #fff; cursor: pointer;
  display: grid; place-items: center; font-size: .95rem;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.25);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  transition: background .15s, transform .12s;
}
.nav-right button:hover { background: rgba(255,255,255,.24); }
.nav-right button:active { transform: scale(.93); }
.btn-label { display: none; }

.greet { color: #fff; margin-top: 20px; text-shadow: 0 1px 12px rgba(0,0,0,.14); }
.greet .greet-hi {
  font-size: .74rem; font-weight: 700; letter-spacing: .10em; text-transform: uppercase;
  opacity: .78;
}
.greet h1 {
  font-size: clamp(1.6rem, 7.4vw, 2.1rem); font-weight: 800;
  letter-spacing: -.03em; line-height: 1.1; margin-top: 5px;
}
.greet .greet-meta {
  margin-top: 7px; font-size: .76rem; font-weight: 600; opacity: .8;
  display: inline-flex; align-items: center; gap: 7px;
}
/* A small bead of light before the date, echoing the water above. */
.greet .greet-meta::before {
  content: ''; width: 5px; height: 5px; border-radius: 50%;
  background: rgba(255,255,255,.75); flex: none;
}

@media (prefers-reduced-motion: reduce) {
  .nav-me, .nav-right button { transition: none; }
}

/* Desktop link row, hidden on phones where the bottom bar takes over */
.nav-links { display: none; gap: 4px; margin-top: 18px; flex-wrap: wrap; }
.nav-links a {
  padding: 8px 14px; border-radius: 11px; text-decoration: none; color: rgba(255,255,255,.8);
  font-size: .82rem; font-weight: 700; border: 1.5px solid transparent;
}
.nav-links a:hover { background: rgba(255,255,255,.14); color: #fff; }
.nav-links a.active { background: var(--rail-active-bg); color: var(--rail-active-ink); }

/* ══════════════════════════ SCREENS ══════════════════════════ */
.screen { min-height: 40vh; }
.container { max-width: 620px; margin: 0 auto; padding: 20px 16px 0; }
.screen-header { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.screen-header h2 { font-size: 1.15rem; font-weight: 800; letter-spacing: -.02em;
  display: flex; align-items: center; gap: 9px; }
.last-updated { color: var(--text-muted); font-size: .74rem; font-weight: 600; }

.section-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.section-header h3 { margin-bottom: 0; }

.empty-state {
  text-align: center; color: var(--text-muted); font-size: .88rem; font-weight: 600;
  padding: 34px 16px; background: var(--surface); border: 1.5px dashed var(--border); border-radius: var(--radius);
}

/* ══════════════════════════ BUTTONS ══════════════════════════ */
.btn-primary, .btn-secondary, .btn-danger {
  border: none; border-radius: 13px; padding: 10px 16px; cursor: pointer;
  font-family: inherit; font-size: .85rem; font-weight: 700; transition: transform .12s, filter .15s;
}
.btn-primary { background: linear-gradient(135deg, var(--brand), var(--brand-2)); color: #fff; box-shadow: var(--sh-s); }
.btn-secondary { background: var(--surface-2); color: var(--text-2); border: 1.5px solid var(--border); }
.btn-danger { background: color-mix(in srgb, var(--bad) 14%, transparent); color: var(--bad); }
.btn-primary:active, .btn-secondary:active, .btn-danger:active { transform: scale(.96); }
.btn-primary:disabled { opacity: .6; }

/* The "+ Add" button above a list. On a phone it is a bar across the thumb's
   path, which is right. On a monitor the same bar is a metre of blue gradient
   shouting over the list it is supposed to sit above, so it goes back to being
   a button — see the desktop block at the foot of this file. */
.add-bar { width: 100%; padding: 13px; margin-bottom: 14px; }

/* ══════════════════════════ INVENTORY ══════════════════════════ */
/* Search scrolls with the list. It was sticky, but a bar that stays put while
   rows slide underneath reads as the page coming apart — and rows were being
   clipped mid-height against its edges. */
.inv-search {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: 15px; padding: 0 12px; margin-bottom: 16px;
  box-shadow: var(--sh-s);
}
.inv-search:focus-within { border-color: var(--brand); }
.inv-search-icon { width: 19px; height: 19px; flex: none; fill: none;
  stroke: var(--text-muted); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.inv-search:focus-within .inv-search-icon { stroke: var(--brand); }
.inv-search input {
  flex: 1; min-width: 0; border: none; background: none; color: var(--text);
  font-family: inherit; font-size: .95rem; font-weight: 600; padding: 13px 0;
}
.inv-search input:focus { outline: none; }
.inv-search input::placeholder { color: var(--text-muted); font-weight: 500; }
/* kill the browser's own clear button — we render our own */
.inv-search input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
/* Every search box has one of these. It was styled by id, so only Inventory
   ever got the styling — the clear buttons on Reports, Customers and
   Commercial Pools un-hid as raw native buttons, which iOS draws as a big
   light-grey slab over the page. Matched on the container instead, so any
   search added later is covered too. */
.inv-search > button {
  flex: none; width: 28px; height: 28px; padding: 0; border: none; border-radius: 9px;
  cursor: pointer; background: var(--surface-2); color: var(--text-muted);
  display: grid; place-items: center; font: inherit; -webkit-appearance: none; appearance: none;
}
.inv-search > button svg { width: 15px; height: 15px; fill: none; stroke: currentColor;
  stroke-width: 2.6; stroke-linecap: round; }
.inv-search > button:active { transform: scale(.9); }


.chem-group { margin-bottom: 22px; }
.chem-group-header {
  font-size: 1rem; font-weight: 800; letter-spacing: -.015em; margin-bottom: 11px;
  display: flex; align-items: center; gap: 9px;
}
.chem-group-body { display: flex; flex-direction: column; gap: 9px; }

.chem-row {
  display: grid; grid-template-columns: 1fr auto auto auto; align-items: center; gap: 10px;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius);
  padding: 11px 12px; box-shadow: var(--sh-s); transition: transform .13s, border-color .2s;
}
.chem-row:active { transform: scale(.985); }
.chem-row.stock-low  { border-color: color-mix(in srgb, var(--warn) 40%, var(--border)); }
.chem-row.stock-crit { border-color: color-mix(in srgb, var(--bad) 45%, var(--border));
  background: linear-gradient(100deg, color-mix(in srgb, var(--bad) 7%, var(--surface)), var(--surface) 60%); }
.chem-name { font-size: .92rem; font-weight: 700; letter-spacing: -.01em; min-width: 0; line-height: 1.25; }
.chem-unit { display: block; font-size: .69rem; color: var(--text-muted); font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em; margin-top: 2px; }
.chem-count {
  font-size: 1.45rem; font-weight: 800; letter-spacing: -.03em; line-height: 1;
  min-width: 46px; text-align: center; font-variant-numeric: tabular-nums;
}
.chem-count.stock-ok   { color: var(--text); }
.chem-count.stock-low  { color: var(--warn); }
.chem-count.stock-crit { color: var(--bad); }

.btn-take, .btn-restock {
  width: 42px; height: 42px; border-radius: 13px; border: none; cursor: pointer;
  font-size: 1.35rem; font-weight: 700; line-height: 1; display: grid; place-items: center;
  transition: transform .12s;
}
.btn-take    { background: color-mix(in srgb, var(--bad) 13%, transparent); color: var(--bad); }
.btn-restock { background: color-mix(in srgb, var(--ok) 14%, transparent);  color: var(--ok); }
.btn-take:active, .btn-restock:active { transform: scale(.9); }

/* Low-stock banner */

/* ══════════════════════════ ACTIVITY LOG ══════════════════════════ */
.log-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.log-filters input, .log-filters select {
  padding: 11px 13px; border-radius: 13px; background: var(--input-bg);
  border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .86rem; font-weight: 600;
}
.log-filters select { flex: 1; min-width: 130px; }
.log-filters input:focus, .log-filters select:focus { outline: none; border-color: var(--brand); }

.week-block { margin-bottom: 12px; }
.week-header {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; cursor: pointer;
  list-style: none; padding: 13px 15px; border-radius: var(--radius);
  background: var(--surface); border: 1.5px solid var(--border); box-shadow: var(--sh-s);
}
.week-header::-webkit-details-marker { display: none; }
.week-label { font-size: .87rem; font-weight: 700; }
.week-count { font-size: .7rem; font-weight: 700; color: var(--brand);
  background: var(--brand-soft); padding: 4px 9px; border-radius: 8px; }
.week-entries { padding: 10px 0 2px; display: flex; flex-direction: column; gap: 8px; }
.log-entry {
  background: var(--surface); border: 1.5px solid var(--border); border-radius: 15px;
  padding: 12px 14px; display: flex; gap: 11px; align-items: flex-start;
}
.log-body { flex: 1; min-width: 0; }
.log-av {
  width: 34px; height: 34px; border-radius: 50%; flex: none; object-fit: cover; display: block;
  background: var(--surface-2); border: 1.5px solid var(--border);
}
.log-av.is-initials {
  display: grid; place-items: center; font-size: .7rem; font-weight: 800;
  color: var(--brand); background: var(--tint-brand); border-color: transparent;
}
.log-entry-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.log-action { font-size: .87rem; font-weight: 700; }
.log-action.took      { color: var(--bad); }
.log-action.restocked { color: var(--ok); }
.log-timestamp { font-size: .7rem; color: var(--text-muted); font-weight: 600; flex: none; }
.log-detail { font-size: .78rem; color: var(--text-muted); margin-top: 3px; font-weight: 500; }
.log-note { font-size: .78rem; color: var(--text-2); margin-top: 6px; font-style: italic;
  padding-left: 10px; border-left: 2.5px solid var(--border); }

/* ══════════════════════════ BIBLE ══════════════════════════ */
.bible-search-bar { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.bible-search-bar input { flex: 1 1 100%; padding: 12px 14px; border-radius: 13px;
  background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .9rem; font-weight: 500; }
.bible-search-bar select { flex: 1; padding: 11px 12px; border-radius: 13px;
  background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .84rem; font-weight: 600; }
.bible-search-bar input:focus, .bible-search-bar select:focus { outline: none; border-color: var(--brand); }

.bible-card { background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-lg);
  padding: 16px; margin-bottom: 12px; box-shadow: var(--sh-s); }
.bible-card-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.bible-badge { font-size: .66rem; font-weight: 800; padding: 5px 10px; border-radius: 8px;
  border: 1.5px solid; text-transform: uppercase; letter-spacing: .05em; }
.bible-card-actions { display: flex; gap: 6px; }
.bible-card-actions button { border: none; background: var(--surface-2); color: var(--text-2);
  border-radius: 9px; padding: 6px 11px; font-family: inherit; font-size: .74rem; font-weight: 700; cursor: pointer; }
.bible-card-actions .btn-danger { background: color-mix(in srgb, var(--bad) 13%, transparent); color: var(--bad); }
.bible-card-title { font-size: 1rem; font-weight: 800; letter-spacing: -.015em; margin-bottom: 8px; }
.bible-card-img { width: 100%; border-radius: 14px; margin-bottom: 10px; }
.bible-card-preview { font-size: .85rem; color: var(--text-2); line-height: 1.6; font-weight: 500; }
.bible-card-full { font-size: .88rem; color: var(--text-2); line-height: 1.7; margin-top: 8px; }
.bible-card-full h1, .bible-card-full h2, .bible-card-full h3 { margin: 14px 0 6px; font-weight: 800; color: var(--text); }
.bible-card-full ul, .bible-card-full ol { padding-left: 20px; margin: 8px 0; }
.bible-card-full li { margin-bottom: 4px; }
.bible-expand-btn { margin-top: 11px; border: none; background: var(--brand-soft); color: var(--brand);
  border-radius: 10px; padding: 8px 14px; font-family: inherit; font-size: .78rem; font-weight: 700; cursor: pointer; }

/* ══════════════════════════ INSPECTION ══════════════════════════ */
.insp-tab-bar { display: flex; gap: 4px; background: var(--surface-2); border: 1.5px solid var(--border);
  border-radius: 15px; padding: 4px; margin-bottom: 16px; }
.insp-tab-btn { flex: 1; padding: 10px; border: none; border-radius: 11px; background: none; cursor: pointer;
  font-family: inherit; font-size: .84rem; font-weight: 700; color: var(--text-muted); transition: .18s; }
.insp-tab-btn.active { background: var(--text); color: var(--surface); box-shadow: var(--sh-s); }

.insp-section { background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-lg);
  padding: 17px; margin-bottom: 13px; box-shadow: var(--sh-s); }
.insp-section-title { font-size: .95rem; font-weight: 800; letter-spacing: -.015em;
  margin-bottom: 14px; padding-bottom: 10px; border-bottom: 1.5px solid var(--border); }
.insp-label { display: block; font-size: .69rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-muted); font-weight: 700; margin-bottom: 6px; }
.insp-equip-label { font-size: .8rem; font-weight: 800; color: var(--brand);
  margin: 16px 0 9px; letter-spacing: .01em; }
.insp-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; margin-bottom: 12px; }
.insp-row-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 11px; margin-bottom: 12px; }
.insp-col-2 { grid-column: span 2; }
.insp-compliance-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; margin-bottom: 12px; }
.insp-chem-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 11px; }
.insp-section input[type="text"], .insp-section input[type="number"], .insp-section input[type="date"],
.insp-section select, .insp-section textarea {
  width: 100%; padding: 11px 12px; border-radius: 12px; background: var(--input-bg);
  border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .9rem; font-weight: 600; margin-bottom: 10px;
}
.insp-section textarea { resize: vertical; line-height: 1.5; font-weight: 500; }
.insp-section input:focus, .insp-section select:focus, .insp-section textarea:focus {
  outline: none; border-color: var(--brand); }

#insp-form-panel { position: fixed; inset: 0; z-index: 90; background: var(--bg); overflow-y: auto; }
.insp-form-header { position: sticky; top: 0; z-index: 5; display: flex; align-items: center; gap: 10px;
  justify-content: space-between; background: var(--bg); padding: 14px 0; border-bottom: 1.5px solid var(--border); margin-bottom: 16px; }
.insp-form-header h3 { font-size: .98rem; font-weight: 800; }
.insp-form-header-btns { display: flex; gap: 7px; }
.insp-form-footer { display: flex; gap: 9px; justify-content: flex-end; padding: 6px 0 30px; }

.insp-report-card { display: flex; align-items: center; gap: 12px; background: var(--surface);
  border: 1.5px solid var(--border); border-radius: var(--radius); padding: 13px 14px;
  margin-bottom: 10px; box-shadow: var(--sh-s); }
.insp-report-left { flex: 1; min-width: 0; }
.insp-report-client { font-size: .92rem; font-weight: 700; }
.insp-report-address { font-size: .77rem; color: var(--text-muted); font-weight: 500; margin-top: 2px; }
.insp-report-meta { font-size: .72rem; color: var(--text-muted); font-weight: 600; margin-top: 3px; }
.insp-report-right { display: flex; align-items: center; gap: 8px; flex: none; }
.insp-status-badge { font-size: .63rem; font-weight: 800; padding: 4px 9px; border-radius: 7px;
  text-transform: uppercase; letter-spacing: .05em; }
.insp-badge-draft { background: color-mix(in srgb, var(--warn) 16%, transparent); color: var(--warn); }
.insp-badge-done  { background: color-mix(in srgb, var(--ok) 16%, transparent);   color: var(--ok); }
.insp-rating-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.insp-open-btn { border: none; background: var(--brand-soft); color: var(--brand); border-radius: 10px;
  padding: 7px 12px; font-family: inherit; font-size: .76rem; font-weight: 700; cursor: pointer; }

.insp-accordion { background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius); margin-bottom: 10px; overflow: hidden; box-shadow: var(--sh-s); }
.insp-accordion-summary { display: flex; align-items: center; gap: 11px; cursor: pointer;
  list-style: none; padding: 14px 15px; }
.insp-accordion-summary::-webkit-details-marker { display: none; }
.insp-acc-icon { font-size: 1.15rem; line-height: 1; flex: none; }
.insp-acc-title { flex: 1; font-size: .9rem; font-weight: 700; }
.insp-acc-chevron { color: var(--text-muted); transition: transform .2s; flex: none; }
.insp-accordion[open] .insp-acc-chevron { transform: rotate(90deg); }
.insp-accordion-body { padding: 0 15px 15px; font-size: .86rem; color: var(--text-2); line-height: 1.65; }
.insp-accordion-body ul, .insp-accordion-body ol { padding-left: 19px; margin: 7px 0; }
.insp-accordion-body li { margin-bottom: 4px; }
.insp-accordion-body strong { color: var(--text); }
.insp-photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); gap: 8px; margin-top: 10px; }
.insp-photo-item { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 11px; }

/* ══════════════════════════ POOL CALCULATOR ══════════════════════════ */
.calc-card { background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-lg);
  padding: 18px; margin-bottom: 13px; box-shadow: var(--sh-s); }
.calc-card-title { display: flex; align-items: center; gap: 10px; font-size: .97rem; font-weight: 800;
  letter-spacing: -.015em; margin-bottom: 15px; }
.calc-label { display: block; font-size: .74rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--text); font-weight: 800; margin-bottom: 7px; }
.calc-sub { display: block; font-size: .73rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text); font-weight: 800; margin-bottom: 5px; }
.calc-hint { font-size: .79rem; color: var(--text-2); margin-top: 8px; font-weight: 600; line-height: 1.5; }
.calc-hint-warn { color: var(--warn); font-weight: 700; }
.calc-footnote { font-size: .79rem; color: var(--text-2); line-height: 1.6;
  text-align: center; padding: 4px 10px 0; font-weight: 600; }
.calc-row { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; margin-bottom: 13px; }
.calc-card input[type="number"] {
  width: 100%; padding: 12px 13px; border-radius: 13px; background: var(--input-bg);
  border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .97rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.calc-card input[type="number"]:focus { outline: none; border-color: var(--brand); }
.calc-shapes, .calc-bagsize { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 15px; }
.calc-chip { flex: 1 1 calc(50% - 4px); padding: 11px 12px; border-radius: 13px; cursor: pointer;
  background: var(--input-bg); border: 1.5px solid var(--border); color: var(--text-2);
  font-family: inherit; font-size: .83rem; font-weight: 700; text-align: center; transition: .15s; }
.calc-chip.active { background: var(--brand); border-color: var(--brand); color: #fff; }

.calc-result { border-radius: 17px; padding: 19px 16px; text-align: center; color: #fff;
  background: linear-gradient(135deg, var(--brand), var(--brand-2)); box-shadow: var(--sh-l);
  display: flex; flex-direction: column; gap: 3px; }
.calc-result-label { font-size: .7rem; letter-spacing: .1em; text-transform: uppercase; font-weight: 800; opacity: 1; }
.calc-result-value { font-size: 2.3rem; font-weight: 800; letter-spacing: -.035em; line-height: 1.1;
  font-variant-numeric: tabular-nums; }
.calc-result-value.calc-value-sm { font-size: 1.25rem; }
.calc-result-sub { font-size: .8rem; opacity: .95; font-weight: 600; }
.calc-result-salt { background: linear-gradient(135deg, var(--ok), #0E9F6E); }
:root[data-theme="dark"] .calc-result-salt { background: linear-gradient(135deg, #10B981, #047857); }

.calc-override { display: flex; align-items: center; gap: 9px; font-size: .86rem;
  color: var(--text); margin-top: 14px; cursor: pointer; font-weight: 700; }
.calc-override input { width: 17px; height: 17px; accent-color: var(--brand); }
#calc-known { margin-top: 10px; }
.calc-warn { background: color-mix(in srgb, var(--warn) 12%, var(--surface));
  border: 1.5px solid color-mix(in srgb, var(--warn) 35%, transparent); border-radius: 14px;
  padding: 13px 14px; margin-top: 12px; font-size: .83rem; line-height: 1.55; color: var(--text-2); font-weight: 500; }
.calc-warn strong { color: var(--text); }
.calc-warn-inline { color: var(--warn); font-size: .82rem; margin-top: 10px; font-weight: 600; }

.calc-log { margin-top: 16px; padding-top: 16px; border-top: 1.5px solid var(--border); }
.calc-log.calc-log-idle { opacity: .42; pointer-events: none; }
.calc-log-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 13px; }
.calc-log-label { font-size: .85rem; font-weight: 700; }
.calc-stepper { display: flex; align-items: center; gap: 8px; }
.calc-stepper button { width: 40px; height: 40px; border-radius: 13px; border: none; cursor: pointer;
  font-size: 1.25rem; font-weight: 800; line-height: 1; display: grid; place-items: center; }
#calc-bag-minus { background: color-mix(in srgb, var(--bad) 13%, transparent); color: var(--bad); }
#calc-bag-plus  { background: color-mix(in srgb, var(--ok) 14%, transparent);  color: var(--ok); }
.calc-stepper input { width: 74px; text-align: center; }
#btn-calc-log-salt { width: 100%; padding: 14px; font-size: .95rem; }

/* ══════════════════════════ STOCK AUDIT ══════════════════════════ */
.audit-help, .audit-footnote { color: var(--text-muted); font-size: .8rem; line-height: 1.55;
  margin-bottom: 14px; font-weight: 500; }
.audit-footnote { margin: 16px 0 0; text-align: center; }
.audit-actions { display: flex; gap: 8px; justify-content: flex-end; margin-bottom: 16px; }

/* Email report — recipients saved on this device, sent via the email app */
.audit-report {
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-lg);
  padding: 16px; margin-bottom: 16px;
}
.audit-report-title { margin: 0 0 4px; font-size: .95rem; }
.audit-report-help { color: var(--text-muted); font-size: .78rem; line-height: 1.5; margin: 0 0 12px; }
.audit-report-emails { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 10px; }
.audit-report-emails:empty { display: none; }
.audit-email-chip {
  display: flex; align-items: center; gap: 6px; padding: 7px 8px 7px 13px; border-radius: 20px;
  background: color-mix(in srgb, var(--brand) 10%, transparent); border: 1.5px solid var(--border);
  font-size: .8rem; font-weight: 600; color: var(--text-2);
}
.audit-email-chip button {
  width: 20px; height: 20px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--surface-2); color: var(--text-muted); font-size: .8rem; line-height: 1;
  display: grid; place-items: center; padding: 0;
}
.audit-report-add { display: flex; gap: 8px; margin-bottom: 12px; }
.audit-report-add input {
  flex: 1; min-width: 0; padding: 12px 13px; border-radius: 13px; background: var(--input-bg);
  border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .9rem; font-weight: 600;
}
.audit-report-add input:focus { outline: none; border-color: var(--brand); }
.audit-report-add .btn-secondary { flex: none; }
#btn-audit-report-send { width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; }
.audit-report-fallback-text {
  width: 100%; box-sizing: border-box; margin-top: 7px; padding: 9px 11px; resize: vertical;
  border-radius: 10px; background: var(--input-bg); border: 1.5px solid var(--input-border);
  color: var(--text-2); font-family: ui-monospace, Menlo, monospace; font-size: .72rem; line-height: 1.5;
}

/* Headline widget — what the whole shelf is worth */
.audit-total {
  border-radius: var(--radius-lg); padding: 20px 18px; margin-bottom: 14px; color: #fff;
  background: linear-gradient(140deg, var(--brand), var(--brand-2)); box-shadow: var(--sh-l);
  position: relative; overflow: hidden;
}
.audit-total::before {
  content: ''; position: absolute; inset: 0; opacity: .13; pointer-events: none;
  background-image:
    repeating-linear-gradient(115deg, transparent 0 26px, rgba(255,255,255,.85) 26px 29px),
    repeating-linear-gradient(65deg,  transparent 0 26px, rgba(255,255,255,.5) 26px 28px);
  -webkit-mask-image: linear-gradient(115deg, transparent 30%, #000 100%);
          mask-image: linear-gradient(115deg, transparent 30%, #000 100%);
}
.audit-total.is-short { background: linear-gradient(140deg, #F97316, #C2410C); }
.audit-total-main { position: relative; display: flex; flex-direction: column; gap: 3px; }
.audit-total-label { font-size: .67rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; opacity: .84; }
.audit-total-value { font-size: 2.35rem; font-weight: 800; letter-spacing: -.035em;
  line-height: 1.1; font-variant-numeric: tabular-nums; }
.audit-total-sub { font-size: .77rem; opacity: .85; font-weight: 500; }
.audit-total-split {
  position: relative; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 16px;
  padding-top: 15px; border-top: 1.5px solid rgba(255,255,255,.25);
}
.audit-total-split > div { display: flex; flex-direction: column; gap: 2px; }
.audit-total-k { font-size: .64rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; opacity: .82; }
.audit-total-v { font-size: 1.15rem; font-weight: 800; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; }
/* On the coloured card the red/green tokens would vanish — use white-on-tint */
.audit-total-v.audit-neg, .audit-total-v.audit-pos { color: #fff; }

.audit-summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 18px; }
.audit-tile { background: var(--surface); border: 1.5px solid var(--border); border-radius: 16px;
  padding: 13px; display: flex; flex-direction: column; gap: 3px; box-shadow: var(--sh-s); }
.audit-tile-label { color: var(--text-muted); font-size: .64rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .06em; }
.audit-tile-value { font-size: 1.3rem; font-weight: 800; letter-spacing: -.025em;
  line-height: 1.15; font-variant-numeric: tabular-nums; }
.audit-tile-sub { color: var(--text-muted); font-size: .69rem; font-weight: 600; }
.audit-tile-missing { border-color: color-mix(in srgb, var(--bad) 38%, transparent); }
.audit-tile-missing .audit-tile-value { color: var(--bad); }
.audit-tile-over { border-color: color-mix(in srgb, var(--ok) 38%, transparent); }
.audit-tile-over .audit-tile-value { color: var(--ok); }

/* Missing-by-group breakdown — makes the headline shortfall traceable */
.audit-bd {
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius-lg); padding: 15px 16px; margin-bottom: 18px; box-shadow: var(--sh-s);
}
.audit-bd-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding-bottom: 11px; margin-bottom: 4px; border-bottom: 1.5px solid var(--border);
  font-size: .72rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-muted);
}
.audit-bd-total { color: var(--bad); font-size: .95rem; letter-spacing: -.01em; }
.audit-bd-row {
  display: grid; grid-template-columns: auto minmax(0,1fr) 74px auto;
  align-items: center; gap: 11px; padding: 10px 0;
  border-bottom: 1.5px solid var(--border);
}
.audit-bd-row:last-child { border-bottom: none; }
.audit-bd-info { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.audit-bd-name { font-size: .88rem; font-weight: 700; }
.audit-bd-sub { font-size: .71rem; color: var(--text-muted); font-weight: 600; }
.audit-bd-bar { background: var(--surface-2); border-radius: 4px; height: 7px; overflow: hidden; }
.audit-bd-bar i { display: block; height: 100%; background: var(--bad); border-radius: 4px; transition: width .35s; }
.audit-bd-val {
  font-size: 1rem; font-weight: 800; color: var(--bad);
  letter-spacing: -.02em; font-variant-numeric: tabular-nums; white-space: nowrap;
}

.audit-group { margin-bottom: 18px; }
.audit-group-header { font-size: .92rem; font-weight: 800; letter-spacing: -.01em; margin-bottom: 9px; }
.audit-group-body { display: flex; flex-direction: column; gap: 8px; }
.audit-row {
  display: grid; grid-template-columns: minmax(0,1fr) 58px 82px 66px 82px 88px;
  align-items: center; gap: 8px; background: var(--surface); border: 1.5px solid var(--border);
  border-radius: 15px; padding: 10px 12px; font-size: .84rem; box-shadow: var(--sh-s);
}
.audit-row-short { border-color: color-mix(in srgb, var(--bad) 40%, transparent);
  background: color-mix(in srgb, var(--bad) 5%, var(--surface)); }
.audit-row-over  { border-color: color-mix(in srgb, var(--ok) 40%, transparent);
  background: color-mix(in srgb, var(--ok) 5%, var(--surface)); }
.audit-name { font-weight: 700; min-width: 0; }
.audit-unit { color: var(--text-muted); font-size: .68rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .05em; }
.audit-cell { display: flex; flex-direction: column; gap: 3px; text-align: center; }
.audit-cell-label { display: none; color: var(--text-muted); font-size: .62rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .05em; }
.audit-system { color: var(--text-muted); font-variant-numeric: tabular-nums; font-weight: 700; }
.audit-diff, .audit-value { font-weight: 800; font-variant-numeric: tabular-nums; }
.audit-neg { color: var(--bad); } .audit-pos { color: var(--ok); }
.audit-row input[type="number"] {
  width: 100%; background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  padding: 7px 6px; border-radius: 10px; font-family: inherit; font-size: .85rem; font-weight: 700;
  text-align: center; font-variant-numeric: tabular-nums;
}
.audit-row input:focus { outline: none; border-color: var(--brand); }
.audit-row input.audit-price { color: var(--text-muted); }
.audit-confirm-list { margin: 10px 0 0; padding-left: 18px; font-size: .84rem;
  line-height: 1.75; max-height: 240px; overflow-y: auto; }

/* ══════════════════════════ CLIENT SEASONAL DATA ══════════════════════════ */
.szn-row {
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-lg);
  margin-bottom: 10px; overflow: hidden;
}
.szn-summary {
  display: grid; grid-template-columns: 1.6fr .8fr 1fr 1fr 1fr; gap: 10px; align-items: center;
  padding: 14px 16px; cursor: pointer; list-style: none;
}
.szn-summary::-webkit-details-marker { display: none; }
.szn-name { font-weight: 700; }
.szn-visits { color: var(--text-muted); font-size: .8rem; }
.szn-money { font-variant-numeric: tabular-nums; color: var(--text-2); }
.szn-profit { font-weight: 800; font-variant-numeric: tabular-nums; text-align: right; }
.szn-visit-list { border-top: 1.5px solid var(--border); padding: 6px 16px 12px; }
.szn-visit-row {
  display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 10px;
  padding: 7px 0; border-bottom: 1px solid var(--border); font-size: .82rem;
  font-variant-numeric: tabular-nums;
}
.szn-visit-row:last-child { border-bottom: none; }

/* The column names, on the same tracks as the rows beneath them. Money in a
   column is unreadable without them: three figures in a line say nothing about
   which is takings and which is cost. */
.szn-head {
  display: grid; grid-template-columns: 1.6fr .8fr 1fr 1fr 1fr; gap: 10px;
  padding: 0 16px 7px; font-size: .62rem; font-weight: 800;
  letter-spacing: .09em; text-transform: uppercase; color: var(--text-muted);
}
.szn-h-end { text-align: right; }
.szn-visit-head {
  font-size: .6rem; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-muted); padding-top: 2px;
}

/* The season's own line. Reads as a sum rather than another customer: no
   border, heavier rule above it, and it does not open. */
.szn-total {
  display: grid; grid-template-columns: 1.6fr .8fr 1fr 1fr 1fr; gap: 10px;
  align-items: center; padding: 13px 16px; margin-top: 2px;
  border-top: 2.5px solid var(--border); font-weight: 800;
}

@media (max-width: 640px) {
  .szn-summary, .szn-total { grid-template-columns: 1fr 1fr; row-gap: 4px; }
  .szn-visit-row { grid-template-columns: 1fr 1fr; row-gap: 2px; }
  /* A header row cannot follow its columns once they wrap, so each figure
     carries its own name instead — otherwise the phone is back to three
     unlabelled numbers, which is the thing being fixed. */
  .szn-head, .szn-visit-head { display: none; }
  .szn-money[data-l]::before, .szn-profit[data-l]::before {
    content: attr(data-l) " ";
    font-size: .58rem; font-weight: 800; letter-spacing: .07em;
    text-transform: uppercase; color: var(--text-muted);
  }
  .szn-profit { text-align: left; }
}

/* ══════════════════════════ TODAY / SCHEDULE ══════════════════════════ */
.today-bar { display: grid; grid-template-columns: auto minmax(0,1fr) auto; gap: 8px; margin-bottom: 12px; }
/* The Schedule's bar carries a fourth control — "This week" — so it gets a
   fourth track rather than squeezing one into the date box's. */
#screen-schedule .today-bar,
#screen-billing  .today-bar { grid-template-columns: auto minmax(0,1fr) auto auto; }
/* Four across a phone clipped the date down to "Thu, Sep 17, 202". Below the
   fold of a narrow screen it takes a row of its own. */
@media (max-width: 640px) {
  #screen-schedule .today-bar,
  #screen-billing  .today-bar { grid-template-columns: auto minmax(0,1fr) auto; }
  #btn-sch-today, #btn-bill-now { grid-column: 1 / -1; }
}
.today-bar button { display: grid; place-items: center; padding: 0 14px; }
/* flatpickr swaps the native box for a text one it draws itself (see dayPicker
   in js/app.js), so this styles the input whichever of the two is standing. */
.today-bar input {
  -webkit-appearance: none; appearance: none; box-sizing: border-box;
  width: 100%; min-width: 0; padding: 11px 12px; border-radius: 13px;
  background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .9rem; font-weight: 700; text-align: center;
}
.today-bar input:focus { outline: none; border-color: var(--brand); }
:root[data-theme="dark"] .today-bar input::-webkit-calendar-picker-indicator {
  filter: invert(1) opacity(.65);
}

/* End-of-day reminder switch */
.push-row {
  display: flex; align-items: center; gap: 12px; margin-bottom: 10px;
  padding: 12px 13px; border-radius: 14px;
  background: var(--surface-2); border: 1.5px solid var(--border);
}
.push-row.is-blocked { opacity: .72; }
.push-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.push-k { font-size: .84rem; font-weight: 800; letter-spacing: -.01em; }
.push-sub { font-size: .72rem; font-weight: 600; color: var(--text-muted); line-height: 1.35; }
.push-sw {
  flex: none; width: 46px; height: 27px; border-radius: 999px; cursor: pointer;
  border: none; padding: 3px; background: var(--input-border);
  transition: background .18s ease;
}
.push-sw span {
  display: block; width: 21px; height: 21px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,.3); transition: transform .18s ease;
}
.push-sw.is-on { background: var(--ok); }
.push-sw.is-on span { transform: translateX(19px); }
.push-sw:disabled { opacity: .5; }
/* A standing note about a phone setting, not an alarm. It was bare orange text
   across the width of the screen, shouting every day at someone who has
   already decided they do not want the reminders. It keeps the warning colour
   on a rule down its side, and says its piece quietly. */
.push-note {
  font-size: .72rem; line-height: 1.5; color: var(--text-2); font-weight: 600;
  margin: -2px 0 12px; padding: 7px 10px;
  border-left: 3px solid var(--warn); border-radius: 0 9px 9px 0;
  background: var(--tint-warn);
}
@media (prefers-reduced-motion: reduce) {
  .push-sw, .push-sw span { transition: none; }
}

.map-pick { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.map-pick-k { font-size: .68rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-muted); }
.map-pick-opts { display: flex; gap: 6px; flex-wrap: wrap; }
.map-chip {
  padding: 6px 11px; border-radius: 20px; cursor: pointer; font-family: inherit;
  background: var(--surface); border: 1.5px solid var(--border); color: var(--text-2);
  font-size: .74rem; font-weight: 700;
}
.map-chip.active { background: var(--brand); border-color: var(--brand); color: #fff; }

.today-prog {
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius);
  padding: 13px 15px; margin-bottom: 14px; box-shadow: var(--sh-s);
}
.today-prog-top { display: flex; justify-content: space-between; align-items: baseline;
  gap: 10px; margin-bottom: 9px; }
.bar { height: 7px; border-radius: 4px; background: var(--surface-2); overflow: hidden; }
.bar i { display: block; height: 100%; border-radius: 4px; transition: width .4s; }
.today-prog-k { font-size: .88rem; font-weight: 800; }
.today-prog-v { font-size: .76rem; font-weight: 700; color: var(--text-muted); }

/* One stop on the run */
.stop {
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-lg);
  padding: 14px; margin-bottom: 11px; box-shadow: var(--sh-s);
}
.stop.is-done { opacity: .62; }
.stop.is-done .stop-n { background: var(--ok); color: #fff; }
.stop-head { display: flex; align-items: flex-start; gap: 12px; }
.stop-n {
  width: 32px; height: 32px; flex: none; border-radius: 10px; display: grid; place-items: center;
  background: var(--brand-soft); color: var(--brand);
  font-size: .9rem; font-weight: 800; font-variant-numeric: tabular-nums;
}
.stop-n svg { width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.stop-id { flex: 1; min-width: 0; }
.stop-name { display: block; font-size: 1rem; font-weight: 800; letter-spacing: -.015em; }
.stop-meta { display: flex; align-items: center; gap: 7px; margin-top: 4px; flex-wrap: wrap; }
.stop-type { padding: 3px 8px; border-radius: 7px; font-size: .62rem;
  font-weight: 800; text-transform: uppercase; letter-spacing: .05em; }
.stop-status { font-size: .7rem; font-weight: 700; color: var(--text-muted); }
.stop-addr { font-size: .84rem; color: var(--text-2); font-weight: 600; margin: 10px 0 0; }
.stop-gate { font-size: .77rem; color: var(--warn); font-weight: 700; margin-top: 4px; }
.stop-note { font-size: .8rem; color: var(--text-2); margin-top: 6px; font-style: italic; }

.stop-actions { display: flex; gap: 7px; margin-top: 12px; flex-wrap: wrap; }
.stop-btn {
  flex: 1; min-width: 92px; display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 10px; border-radius: 12px; text-decoration: none; cursor: pointer;
  background: var(--surface-2); border: 1.5px solid var(--border); color: var(--text);
  font-family: inherit; font-size: .8rem; font-weight: 700;
}
.stop-btn svg { width: 15px; height: 15px; fill: none; stroke: var(--brand);
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.stop-btn:active { transform: scale(.96); }
.stop-btn.is-history svg { stroke: var(--violet); }
.stop-go { display: flex; gap: 8px; margin-top: 10px; }
.stop-go .btn-primary, .stop-go .btn-secondary { flex: 1; padding: 12px; }
.stop-go .btn-danger { flex: none; display: grid; place-items: center; padding: 12px 14px; }

/* Client history rows */
.hist-row {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; cursor: pointer;
  background: none; border: none; border-bottom: 1.5px solid var(--border);
  padding: 11px 0; font-family: inherit; color: var(--text);
}
.hist-row:last-child { border-bottom: none; }
.hist-left { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.hist-date { font-size: .87rem; font-weight: 700; }
.hist-tech { font-size: .73rem; color: var(--text-muted); font-weight: 600; }

/* The note that never leaves the company */
.comm-sec.rep-private {
  border-color: color-mix(in srgb, var(--bad) 35%, transparent);
  background: color-mix(in srgb, var(--bad) 4%, var(--surface));
}
.rep-private-tag {
  margin-left: auto; padding: 3px 8px; border-radius: 7px;
  background: color-mix(in srgb, var(--bad) 15%, transparent); color: var(--bad);
  font-size: .58rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
}

@media (max-width: 640px) {
  .stop-btn { min-width: 0; font-size: .76rem; padding: 11px 6px; }
  .map-pick { gap: 7px; }
}

/* ══════════════════════════ COVER CHECK ══════════════════════════ */
.cov-head {
  display: grid; grid-template-columns: 30px minmax(0,1fr) minmax(0,1fr) 34px;
  gap: 8px; padding: 0 0 7px;
  font-size: .64rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-muted); text-align: center;
}
.cov-row {
  display: grid; grid-template-columns: 30px minmax(0,1fr) minmax(0,1fr) 34px;
  gap: 8px; align-items: center; margin-bottom: 7px;
}
.cov-n {
  font-size: .78rem; font-weight: 800; color: var(--text-muted);
  text-align: center; font-variant-numeric: tabular-nums;
}
.cov-row input {
  -webkit-appearance: none; appearance: none; box-sizing: border-box;
  width: 100%; min-width: 0; padding: 10px 10px; border-radius: 11px;
  background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .92rem; font-weight: 700; text-align: center;
  font-variant-numeric: tabular-nums;
}
.cov-a, .cov-b { min-width: 0; }
.cov-row input:focus { outline: none; border-color: var(--brand); }
.cov-row.is-ok input  { border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.cov-row.is-bad input { border-color: var(--bad); color: var(--bad); }
.cov-row.is-bad .cov-n { color: var(--bad); }
.cov-x {
  width: 34px; height: 34px; border: none; border-radius: 10px; cursor: pointer;
  background: color-mix(in srgb, var(--bad) 12%, transparent); color: var(--bad);
  display: grid; place-items: center;
}
.cov-x svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.6; }
/* Lengths & widths — the sheet's own point-to-point checks */
/* Four columns, not five: the verdict column is gone. See renderCoverForm. */
.cov-xhead {
  display: grid; grid-template-columns: 56px 56px minmax(0,1fr) 34px;
  gap: 7px; padding: 0 0 7px;
  font-size: .62rem; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-muted); text-align: center;
}
.cov-xrow {
  display: grid; grid-template-columns: 56px 56px minmax(0,1fr) 34px;
  gap: 7px; align-items: center; margin-bottom: 7px;
}
.cov-xrow input {
  -webkit-appearance: none; appearance: none; box-sizing: border-box;
  width: 100%; min-width: 0; padding: 9px 6px; border-radius: 10px;
  background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .88rem; font-weight: 700; text-align: center;
  font-variant-numeric: tabular-nums;
}
.cov-xrow input:focus { outline: none; border-color: var(--brand); }
/* the check lines drawn across the pool */
.cov-cross { stroke-width: 1.5; stroke-dasharray: 9 6; vector-effect: non-scaling-stroke; fill: none; }
.cov-cross.ok    { stroke: var(--ok); }
.cov-cross.close { stroke: var(--warn); }
.cov-cross.off   { stroke: var(--bad); stroke-width: 2.5; }

.cov-count-tag {
  margin-left: auto; font-size: .64rem; font-weight: 800; letter-spacing: .05em;
  color: var(--text-muted); text-transform: none;
}

/* The drawing */
.cov-plot {
  width: 100%; height: auto; max-height: 420px; display: block;
  background: var(--input-bg); border: 1.5px solid var(--border); border-radius: 14px;
}
/* color-mix() is not a valid SVG paint value — it falls back to black.
   fill-opacity gives the same look and actually works. */
.cov-shape { fill: var(--brand); fill-opacity: .18;
  stroke: var(--brand); stroke-width: 2.5; vector-effect: non-scaling-stroke;
  stroke-linejoin: round; }
.cov-ab { stroke: var(--text-muted); stroke-width: 1.5; stroke-dasharray: 6 5;
  vector-effect: non-scaling-stroke; }
.cov-pt circle { fill: var(--brand); }
.cov-pt text { fill: var(--text-muted); text-anchor: middle; font-weight: 700;
  font-family: 'Plus Jakarta Sans', sans-serif; }
.cov-ref circle { fill: var(--warn); }
.cov-ref text { fill: var(--warn); text-anchor: middle; font-weight: 800;
  font-family: 'Plus Jakarta Sans', sans-serif; }
.cov-plot-empty {
  padding: 34px 16px; text-align: center; color: var(--text-muted);
  font-size: .86rem; font-weight: 600;
  background: var(--input-bg); border: 1.5px dashed var(--border); border-radius: 14px;
}
.cov-plot-note { font-size: .78rem; color: var(--bad); font-weight: 700; margin-top: 9px; text-align: center; }

.cov-stats { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 8px; margin-top: 12px; }
.cov-stats > div { background: var(--surface-2); border: 1.5px solid var(--border);
  border-radius: 12px; padding: 10px 8px; text-align: center;
  display: flex; flex-direction: column; gap: 2px; }
.cov-s-k { font-size: .6rem; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-muted); }
.cov-s-v { font-size: .95rem; font-weight: 800; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; }
.cov-s-v small { font-size: .58rem; font-weight: 700; color: var(--text-muted); }

.cov-issues { display: flex; flex-direction: column; gap: 8px; }
.cov-issue {
  display: flex; gap: 10px; align-items: flex-start; padding: 11px 12px; border-radius: 12px;
  font-size: .84rem; line-height: 1.45; font-weight: 500;
}
.cov-issue svg { width: 16px; height: 16px; flex: none; margin-top: 2px;
  fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.cov-issue.error { background: color-mix(in srgb, var(--bad) 11%, transparent); color: var(--bad); }
.cov-issue.warn  { background: color-mix(in srgb, var(--warn) 12%, transparent); color: var(--warn); }
.cov-issue strong { font-weight: 800; }
.cov-ok { font-size: .86rem; color: var(--ok); font-weight: 700; }

/* Optional extras, folded away so the simple path stays simple */
.cov-extra > summary { cursor: pointer; list-style: none; margin-bottom: 0; }
.cov-extra[open] > summary { margin-bottom: 13px; }
.cov-extra > summary::-webkit-details-marker { display: none; }
.cov-extra > summary::after {
  content: '+'; margin-left: auto; font-size: 1.1rem; font-weight: 700;
  color: var(--text-muted); line-height: 1;
}
.cov-extra[open] > summary::after { content: '−'; }

@media (max-width: 640px) {
  .cov-stats { grid-template-columns: repeat(2, minmax(0,1fr)); }
}

/* ══════════════ THE FINISHED REPORT ══════════════
   Reads like the paper report: centred headings, label-and-value rows.
   Same bones as before, just legible. */
.fr { padding-bottom: 8px; }

.fr-head { text-align: center; padding: 18px 4px 20px; border-bottom: 2px solid var(--border); margin-bottom: 4px; }
.fr-client { font-size: 1.35rem; font-weight: 800; letter-spacing: -.025em; line-height: 1.2; }
.fr-addr {
  display: inline-block; margin-top: 5px; color: var(--text-2);
  font-size: .88rem; font-weight: 600; text-decoration: none; line-height: 1.4;
}
.fr-addr:hover { color: var(--brand); }
.fr-meta { display: flex; align-items: center; justify-content: center; gap: 10px;
  flex-wrap: wrap; margin-top: 14px; }
.fr-when { display: inline-flex; align-items: center; gap: 7px;
  font-size: .84rem; font-weight: 700; color: var(--text-2); }
.fr-when .ico { width: 16px; height: 16px; stroke: var(--text-muted); }
.fr-job {
  padding: 7px 13px; border-radius: 11px; font-size: .78rem; font-weight: 800;
  border: 1.5px solid currentColor; line-height: 1.25; max-width: 190px;
}
.fr-by { margin-top: 12px; font-size: .84rem; color: var(--text-muted); font-weight: 500; }
.fr-by strong { color: var(--text); font-weight: 700; }
.fr-by .rep-status { margin-left: 8px; }

.fr-sec { padding: 20px 0 4px; }
.fr-h {
  text-align: center; font-size: .96rem; font-weight: 800; letter-spacing: -.01em;
  color: var(--brand); margin-bottom: 14px;
}
.fr-sec.is-warn .fr-h { color: var(--bad); }
.fr-sec.is-private .fr-h { color: var(--bad); display: flex; align-items: center;
  justify-content: center; gap: 9px; }

/* label : value rows */
.fr-rows { display: flex; flex-direction: column; }
.fr-row {
  display: flex; align-items: baseline; gap: 12px; padding: 9px 2px;
  border-bottom: 1px solid var(--border);
}
.fr-row:last-child { border-bottom: none; }
.fr-k { flex: 1; min-width: 0; font-size: .88rem; color: var(--text-2); font-weight: 600; line-height: 1.4; }
.fr-row.is-warn .fr-k { color: var(--bad); font-weight: 700; }
.fr-tick { flex: none; display: grid; place-items: center; }
.fr-tick svg { width: 17px; height: 17px; fill: none; stroke: var(--ok);
  stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.fr-row.is-warn .fr-tick svg { stroke: var(--bad); stroke-width: 2.2; }
.fr-v { flex: none; font-size: .95rem; font-weight: 800; color: var(--text);
  font-variant-numeric: tabular-nums; }
.fr-v small { font-size: .68rem; font-weight: 700; color: var(--text-muted);
  text-transform: uppercase; margin-left: 2px; }

.fr-msg {
  font-size: .92rem; line-height: 1.65; color: var(--text); font-weight: 500;
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius); padding: 14px 16px; white-space: pre-wrap;
}
.fr-sec.is-warn .fr-msg { border-color: color-mix(in srgb, var(--bad) 35%, transparent);
  background: color-mix(in srgb, var(--bad) 5%, var(--surface)); }
.fr-sec.is-private .fr-msg { border-color: color-mix(in srgb, var(--bad) 35%, transparent);
  background: color-mix(in srgb, var(--bad) 5%, var(--surface)); }

.fr-pics { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.fr-pics img {
  width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 12px; display: block;
  border: 1.5px solid var(--border);
}

.fr-meas { display: grid; grid-template-columns: repeat(auto-fit, minmax(104px, 1fr)); gap: 9px; }
.fr-m {
  background: var(--surface); border: 1.5px solid var(--border); border-radius: 14px;
  padding: 12px 10px; text-align: center; display: flex; flex-direction: column; gap: 3px;
}
.fr-m-k { font-size: .66rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-muted); }
.fr-m-v { font-size: 1.3rem; font-weight: 800; letter-spacing: -.025em;
  font-variant-numeric: tabular-nums; }
.fr-m-v small { font-size: .58rem; font-weight: 700; opacity: .65; margin-left: 2px; }
.fr-m-range { font-size: .64rem; font-weight: 600; color: var(--text-muted); }
.fr-m.is-ok   { border-color: color-mix(in srgb, var(--ok) 40%, transparent); }
.fr-m.is-ok   .fr-m-v { color: var(--ok); }
.fr-m.is-low  { border-color: color-mix(in srgb, var(--warn) 48%, transparent);
  background: color-mix(in srgb, var(--warn) 7%, var(--surface)); }
.fr-m.is-low  .fr-m-v { color: var(--warn); }
.fr-m.is-high { border-color: color-mix(in srgb, var(--bad) 48%, transparent);
  background: color-mix(in srgb, var(--bad) 7%, var(--surface)); }
.fr-m.is-high .fr-m-v { color: var(--bad); }

@media (max-width: 400px) {
  .fr-pics { grid-template-columns: repeat(2, 1fr); }
  .fr-client { font-size: 1.2rem; }
}

/* ══════════════════════════ SERVICE REPORTS ══════════════════════════ */
.rep-card {
  display: block; width: 100%; text-align: left; cursor: pointer; font-family: inherit;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius);
  padding: 13px 14px; margin-bottom: 10px; box-shadow: var(--sh-s);
  color: var(--text); transition: transform .13s;
}
.rep-card:active { transform: scale(.985); }
.rep-card-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.rep-site { font-size: .95rem; font-weight: 700; letter-spacing: -.01em; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rep-status {
  flex: none; padding: 3px 9px; border-radius: 7px; font-size: .62rem;
  font-weight: 800; text-transform: uppercase; letter-spacing: .05em;
}
.rep-card-meta { font-size: .76rem; color: var(--text-muted); font-weight: 600; margin-top: 3px; }
.rep-card-bits { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.rep-bit {
  display: flex; align-items: center; gap: 5px; padding: 4px 9px; border-radius: 8px;
  background: var(--surface-2); color: var(--text-2);
  font-size: .7rem; font-weight: 700;
}
.rep-bit svg { width: 12px; height: 12px; fill: none; stroke: currentColor;
  stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.rep-bit.is-warn { background: color-mix(in srgb, var(--warn) 15%, transparent); color: var(--warn); }
.rep-sub { font-size: .82rem; color: var(--text-muted); font-weight: 600; margin-bottom: 10px; }

/* Readings — colour tells you at a glance what is out of range */
.rep-readings { display: grid; grid-template-columns: repeat(auto-fit, minmax(86px, 1fr)); gap: 8px; }
.rep-reading {
  background: var(--surface-2); border: 1.5px solid var(--border);
  border-radius: 12px; padding: 10px 8px; text-align: center;
  display: flex; flex-direction: column; gap: 2px;
}
.rep-r-label { font-size: .64rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-muted); }
.rep-r-value { font-size: 1.15rem; font-weight: 800; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; }
.rep-r-value small { font-size: .6rem; font-weight: 700; opacity: .7; margin-left: 2px; }
.rep-reading.is-ok   { border-color: color-mix(in srgb, var(--ok) 40%, transparent); }
.rep-reading.is-ok   .rep-r-value { color: var(--ok); }
.rep-reading.is-low  { border-color: color-mix(in srgb, var(--warn) 45%, transparent);
  background: color-mix(in srgb, var(--warn) 8%, var(--surface-2)); }
.rep-reading.is-low  .rep-r-value { color: var(--warn); }
.rep-reading.is-high { border-color: color-mix(in srgb, var(--bad) 45%, transparent);
  background: color-mix(in srgb, var(--bad) 8%, var(--surface-2)); }
.rep-reading.is-high .rep-r-value { color: var(--bad); }
.rep-legend { font-size: .7rem; color: var(--text-muted); font-weight: 600; margin-top: 10px; text-align: center; }

.rep-reading-grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 10px; }
.rep-readings { grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); }
.rep-reading-grid input.is-ok   { border-color: color-mix(in srgb, var(--ok) 50%, transparent); }
.rep-reading-grid input.is-low  { border-color: var(--warn); color: var(--warn); }
.rep-reading-grid input.is-high { border-color: var(--bad); color: var(--bad); }


/* A labelled number with its unit — the building block of every chemical
   section. Measurements get a heavier treatment than the products dosed. */
.rep-lines { display: flex; flex-direction: column; gap: 2px; }
.rep-line {
  display: grid; grid-template-columns: minmax(0,1fr) 92px 42px;
  align-items: center; gap: 10px; padding: 9px 0;
  border-bottom: 1.5px solid var(--border);
}
.rep-line:last-child { border-bottom: none; }
.rep-line-label { font-size: .86rem; font-weight: 600; color: var(--text-2); min-width: 0; line-height: 1.3; }
.rep-line.is-measure .rep-line-label { font-weight: 800; color: var(--text); }
.rep-line input[type="number"] {
  -webkit-appearance: none; appearance: none; box-sizing: border-box;
  width: 100%; min-width: 0; padding: 10px 11px; border-radius: 11px;
  background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .95rem; font-weight: 700;
  font-variant-numeric: tabular-nums; text-align: right;
}
.rep-line input[type="number"]:focus { outline: none; border-color: var(--brand); }
.rep-line.is-measure input[type="number"] { border-width: 2px; }
.rep-line input.is-ok   { border-color: color-mix(in srgb, var(--ok) 55%, transparent); }
.rep-line input.is-low  { border-color: var(--warn); color: var(--warn); }
.rep-line input.is-high { border-color: var(--bad);  color: var(--bad); }
.rep-line-unit {
  font-size: .68rem; font-weight: 800; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .02em; white-space: nowrap; line-height: 1.2;
}

/* Warnings read as warnings, in the form and on the report */
.rep-task.is-warn { border-color: color-mix(in srgb, var(--bad) 30%, var(--border)); }
.rep-task.is-warn.on {
  border-color: var(--bad); background: color-mix(in srgb, var(--bad) 10%, transparent); color: var(--text);
}
.rep-tasks.is-warn-list { grid-template-columns: minmax(0,1fr); }
.rep-task-done.is-warn {
  background: color-mix(in srgb, var(--bad) 12%, transparent); color: var(--bad);
}

/* Work-done checklist */
.rep-tasks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.rep-task {
  display: flex; align-items: center; gap: 10px; cursor: pointer; padding: 12px;
  border-radius: 12px; background: var(--input-bg); border: 1.5px solid var(--border);
  font-size: .82rem; font-weight: 600; color: var(--text-2); transition: .15s;
  line-height: 1.3; min-width: 0;
}
.rep-task input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--brand); flex: none; margin: 0; }
.rep-task span { flex: 1; min-width: 0; }
.rep-task.on { border-color: var(--brand); background: var(--brand-soft); color: var(--text); font-weight: 700; }
.rep-tasks-done { display: flex; flex-wrap: wrap; gap: 7px; }
.rep-task-done {
  display: flex; align-items: center; gap: 6px; padding: 7px 11px; border-radius: 10px;
  background: color-mix(in srgb, var(--ok) 12%, transparent); color: var(--ok);
  font-size: .8rem; font-weight: 700;
}
.rep-task-done svg { width: 13px; height: 13px; fill: none; stroke: currentColor;
  stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }

.comm-sec.rep-issues { border-color: color-mix(in srgb, var(--bad) 35%, transparent); }
.comm-sec select {
  width: 100%; min-width: 0; box-sizing: border-box; padding: 11px 12px; border-radius: 12px;
  background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .92rem; font-weight: 600;
}
.comm-sec select:focus { outline: none; border-color: var(--brand); }
.comm-sec input:disabled { opacity: .6; }

@media (max-width: 640px) {
  .rep-reading-grid { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .rep-line { grid-template-columns: minmax(0,1fr) 78px 38px; gap: 8px; }
}

/* ══════════════════════════ COMMERCIAL INFO ══════════════════════════ */
.comm-card {
  display: flex; align-items: center; gap: 13px; width: 100%; text-align: left;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius);
  padding: 10px; margin-bottom: 10px; cursor: pointer; box-shadow: var(--sh-s);
  font-family: inherit; color: var(--text); transition: transform .13s;
}
.comm-card:active { transform: scale(.985); }
.comm-thumb {
  position: relative; width: 66px; height: 66px; flex: none; border-radius: 13px;
  overflow: hidden; background: var(--surface-2); display: grid; place-items: center;
}
.comm-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.comm-thumb-ph { width: 26px; height: 26px; fill: none; stroke: var(--text-muted);
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.comm-thumb-n {
  position: absolute; right: 4px; bottom: 4px; padding: 1px 6px; border-radius: 6px;
  background: rgba(0,0,0,.62); color: #fff; font-size: .62rem; font-weight: 800;
}
.comm-card-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.comm-card-name { font-size: .95rem; font-weight: 700; letter-spacing: -.01em; }
.comm-card-sub { font-size: .74rem; color: var(--brand); font-weight: 700; }
.comm-card-addr {
  font-size: .74rem; color: var(--text-muted); font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.comm-card-go { width: 18px; height: 18px; flex: none; fill: none; stroke: var(--text-muted);
  stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }

/* Detail / edit panel */
/* Every detail/edit panel covers the screen it came from. Only the commercial
   one used to carry these rules, so adding a client, a cover measurement or a
   report dropped the form at the foot of the page instead of opening it. A
   shared class rather than a list of ids, so the next panel cannot miss out. */
.panel { position: fixed; inset: 0; z-index: 90; background: var(--bg);
  overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; }
.panel > .container { padding-bottom: calc(90px + var(--nav-lift)); }
.comm-panel-head {
  position: sticky; top: 0; z-index: 5; display: flex; align-items: center;
  justify-content: space-between; gap: 10px; background: var(--bg);
  padding: calc(12px + env(safe-area-inset-top)) 0 12px; border-bottom: 1.5px solid var(--border);
}
.comm-panel-head .btn-secondary { display: flex; align-items: center; gap: 5px; }
.comm-panel-actions { display: flex; gap: 7px; }
.comm-panel-actions button { display: grid; place-items: center; padding: 9px 13px; }

.comm-title { font-size: 1.3rem; font-weight: 800; letter-spacing: -.025em; margin: 16px 0 10px; }
.comm-link {
  display: flex; align-items: center; gap: 8px; padding: 11px 13px; margin-bottom: 8px;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: 13px;
  color: var(--text); text-decoration: none; font-size: .86rem; font-weight: 600;
}
.comm-link .ico { stroke: var(--brand); width: 17px; height: 17px; }

.comm-gallery {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 8px; margin: 14px 0;
}
.comm-gallery img {
  width: 100%; aspect-ratio: 4/3; object-fit: cover; border-radius: 12px; display: block;
  border: 1.5px solid var(--border);
}
.comm-photo-slot { position: relative; }
.comm-photo-x {
  position: absolute; top: 5px; right: 5px; width: 26px; height: 26px; border: none;
  border-radius: 8px; background: rgba(0,0,0,.66); color: #fff; cursor: pointer;
  display: grid; place-items: center;
}
.comm-photo-x svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.6; }
.comm-upload {
  display: flex; align-items: center; justify-content: center; gap: 9px; cursor: pointer;
  padding: 14px; border-radius: 14px; border: 1.5px dashed var(--border);
  background: var(--surface-2); color: var(--text-2); font-size: .88rem; font-weight: 700;
}
.comm-upload .ico { stroke: var(--brand); }

.comm-sec {
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius-lg); padding: 16px; margin-bottom: 12px; box-shadow: var(--sh-s);
}
.comm-sec-title {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  font-size: .7rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-muted); margin-bottom: 12px; padding-bottom: 9px;
  border-bottom: 1.5px solid var(--border);
}
/* the on/off switch for a body of water */
.comm-switch {
  margin-left: auto; display: flex; align-items: center; gap: 7px; cursor: pointer;
  font-size: .68rem; font-weight: 700; letter-spacing: .02em; text-transform: none;
  color: var(--text-2);
}
.comm-switch input[type="checkbox"] { width: 17px; height: 17px; accent-color: var(--brand); flex: none; margin: 0; }
.comm-empty-note { font-size: .82rem; color: var(--text-muted); font-weight: 500; }

/* Pool / Spa pills on the detail header */
.comm-kinds { display: flex; gap: 7px; margin-bottom: 12px; }
.comm-kind {
  padding: 5px 12px; border-radius: 20px; font-size: .74rem; font-weight: 800;
  background: color-mix(in srgb, var(--brand) 14%, transparent);
  color: var(--brand); border: 1.5px solid color-mix(in srgb, var(--brand) 32%, transparent);
}
.comm-kind.is-baby {
  background: color-mix(in srgb, var(--ok) 14%, transparent);
  color: var(--ok); border-color: color-mix(in srgb, var(--ok) 32%, transparent);
}
.comm-kv {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 8px 0; border-bottom: 1.5px solid var(--border);
}
.comm-kv:last-child { border-bottom: none; padding-bottom: 0; }
.comm-k { font-size: .78rem; color: var(--text-muted); font-weight: 600; flex: none; }
.comm-v { font-size: .89rem; font-weight: 700; text-align: right; min-width: 0; word-break: break-word; }
/* Lifeguard staffing is a safety requirement, not a spec — it reads red so a
   tech scanning the page cannot miss it. */
.comm-kv.is-alert .comm-k { color: var(--bad); }
.comm-kv.is-alert .comm-v { color: var(--bad); font-weight: 800; }
.comm-form-grid .is-alert .calc-sub { color: var(--bad); }
.comm-form-grid .is-alert input {
  border-color: color-mix(in srgb, var(--bad) 45%, var(--input-border));
  background: color-mix(in srgb, var(--bad) 7%, var(--input-bg));
  color: var(--bad); font-weight: 800;
}
.comm-form-grid .is-alert input:focus { border-color: var(--bad); }

.comm-notes { font-size: .87rem; line-height: 1.6; color: var(--text-2); font-weight: 500; white-space: pre-wrap; }

.comm-form-grid { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 11px; }
.comm-span { grid-column: 1 / -1; }
.comm-sec input:not([type="checkbox"]), .comm-sec textarea {
  width: 100%; min-width: 0; box-sizing: border-box; padding: 11px 12px; border-radius: 12px;
  background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .92rem; font-weight: 600;
}
.comm-sec textarea { resize: vertical; line-height: 1.55; font-weight: 500; }
.comm-sec input:not([type="checkbox"]):focus, .comm-sec textarea:focus { outline: none; border-color: var(--brand); }
.comm-form-footer { display: flex; gap: 9px; justify-content: flex-end; padding: 4px 0 30px; }

@media (max-width: 640px) {
  .comm-form-grid { grid-template-columns: minmax(0,1fr); }
  .comm-form-footer { flex-direction: column-reverse; }
  .comm-form-footer button { width: 100%; padding: 14px; }
  .comm-kv { flex-direction: column; gap: 2px; align-items: flex-start; }
  .comm-v { text-align: left; }
}

/* ══════════════════════════ WEEKLY USAGE ══════════════════════════ */
/* Range picker — presets plus an exact from/to */
.rng { margin-bottom: 16px; }
.rng-presets { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 11px; }
/* Shown only on the desktop rail's behalf — see the 1024px block. */
.web-tabs { display: none; }
.rng-chip {
  padding: 9px 13px; border-radius: 12px; cursor: pointer;
  background: var(--surface); border: 1.5px solid var(--border); color: var(--text-2);
  font-family: inherit; font-size: .8rem; font-weight: 700; white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s;
}
.rng-chip.active { background: var(--brand); border-color: var(--brand); color: #fff; }
.rng-chip[hidden] { display: none; }

.rng-custom {
  display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr) auto; gap: 10px; align-items: end;
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: 15px; padding: 12px; box-shadow: var(--sh-s);
  max-width: 100%; overflow: hidden;
}
.rng-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.rng-lbl {
  font-size: .66rem; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-muted);
}
.rng-custom input {
  -webkit-appearance: none; appearance: none;
  display: block; box-sizing: border-box;
  width: 100%; min-width: 0; max-width: 100%;
  padding: 10px 11px; border-radius: 11px;
  background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .87rem; font-weight: 600;
}
/* Safari lays the date out as inline segments that can spill; pin them inside. */
.rng-custom input::-webkit-date-and-time-value { text-align: left; margin: 0; }
.rng-custom input::-webkit-datetime-edit { padding: 0; overflow: hidden; }
.rng-custom input:focus { outline: none; border-color: var(--brand); }
/* the native picker glyph is near-invisible on the dark theme */
:root[data-theme="dark"] .rng-custom input::-webkit-calendar-picker-indicator {
  filter: invert(1) opacity(.65);
}
#wk-apply { padding: 11px 16px; }

@media (max-width: 640px) {
  .rng-custom { grid-template-columns: minmax(0,1fr); gap: 12px; }
  #wk-apply { width: 100%; padding: 13px; }
}

.weekly-empty { color: var(--text-muted); padding: 14px 0; font-size: .86rem; font-weight: 600; }
.weekly-table { width: 100%; border-collapse: collapse; font-size: .86rem; }
.weekly-table thead tr { border-bottom: 1.5px solid var(--border); }
.weekly-table th { padding: 0 5px 11px; color: var(--text-muted); font-weight: 800;
  text-align: center; white-space: nowrap; font-size: .64rem;
  text-transform: uppercase; letter-spacing: .07em; }
.weekly-table th.wk-used { color: var(--bad); } .weekly-table th.wk-restocked { color: var(--ok); }
.weekly-table tbody tr { border-bottom: 1.5px solid var(--border); }
.weekly-table tbody tr:last-child { border-bottom: none; }
.weekly-table td { padding: 12px 5px; text-align: center; font-variant-numeric: tabular-nums; }
.weekly-table .wk-name { text-align: left; padding-left: 0; font-weight: 700; }
.weekly-table td.wk-used, .weekly-table td.wk-restocked, .weekly-table td.wk-left {
  font-size: 1.08rem; font-weight: 800; letter-spacing: -.02em; }
.weekly-table td.wk-used { color: var(--bad); } .weekly-table td.wk-restocked { color: var(--ok); }
.wk-left .stock-ok { color: var(--text); } .wk-left .stock-low { color: var(--warn); } .wk-left .stock-crit { color: var(--bad); }
.wk-unit { display: block; color: var(--text-muted); font-size: .6rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; }
.wk-left-unknown { color: var(--text-muted); font-weight: 600; }
.weekly-table tr.wk-row-quiet td.wk-used, .weekly-table tr.wk-row-quiet td.wk-restocked {
  color: var(--text-muted); font-weight: 600; }
.wk-badge { display: inline-block; margin-top: 4px; padding: 3px 8px; border-radius: 7px;
  background: color-mix(in srgb, var(--warn) 15%, transparent); color: var(--warn);
  font-size: .58rem; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; }
.weekly-table .wk-bar { min-width: 100px; padding-right: 0; }
.wk-bar-track { background: var(--surface-2); border-radius: 4px; height: 7px; overflow: hidden; }
.wk-bar-fill { background: var(--bad); height: 100%; border-radius: 4px; transition: width .4s; }

/* ══════════════════════════ ADMIN ══════════════════════════ */
.admin-section { background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius-lg); padding: 18px; margin-bottom: 14px; box-shadow: var(--sh-s); }
.admin-section h3 { font-size: .97rem; font-weight: 800; letter-spacing: -.015em; margin-bottom: 15px;
  display: flex; align-items: center; gap: 9px; }

.admin-chem-row { display: flex; align-items: center; gap: 8px; padding: 9px 0;
  border-bottom: 1.5px solid var(--border); font-size: .85rem; }
.admin-chem-row:last-child { border-bottom: none; }
.admin-chem-name { flex: 1; font-weight: 600; }
.admin-chem-group { margin-bottom: 14px; }
.admin-chem-group-h { font-size: .78rem; font-weight: 700; color: var(--text-muted); margin: 10px 0 6px; }
.admin-chem-row input[type="number"] { width: 62px; background: var(--input-bg);
  border: 1.5px solid var(--input-border); color: var(--text); padding: 7px 8px;
  border-radius: 10px; font-family: inherit; font-size: .84rem; font-weight: 700; text-align: center; }
.admin-chem-row input:focus { outline: none; border-color: var(--brand); }

/* Company Setup text fields. The admin-chem-row layout only ever styled number
   inputs, so text/tel/email boxes came out unstyled and cramped beside their
   label. These stack the same way every other form in the app does. */
.co-field { margin-bottom: 12px; }
.co-field label { display: block; font-size: .7rem; text-transform: uppercase;
  letter-spacing: .08em; color: var(--text-muted); font-weight: 700; margin: 0 0 6px; }
.co-field input { width: 100%; padding: 12px 13px; border-radius: 13px;
  background: var(--input-bg); border: 1.5px solid var(--input-border);
  color: var(--text); font-family: inherit; font-size: .95rem; font-weight: 600; }
.co-field input:focus { outline: none; border-color: var(--brand); }

/* One chemical's price and packaging. A card per chemical rather than a flex
   row: five number boxes, a toggle and a button never fit on one line on a
   phone, and wrapped into an unreadable pile. */
.chem-cfg { padding: 12px 0; border-bottom: 1.5px solid var(--border); }
.chem-cfg:last-child { border-bottom: none; }
.chem-cfg-name { font-weight: 700; font-size: .9rem; margin-bottom: 9px; }
.chem-cfg-unit { color: var(--text-muted); font-weight: 600; font-size: .76rem; }
/* A retired chemical or visit type stays listed so it can be switched back on,
   but reads as inactive. */
.chem-cfg.is-off { opacity: .5; }
.chem-cfg-head { display: flex; gap: 7px; margin-bottom: 9px; }
.chem-cfg-nm, .chem-cfg-un { background: var(--input-bg); border: 1.5px solid var(--input-border);
  color: var(--text); padding: 9px 10px; border-radius: 10px; font-family: inherit;
  font-size: .88rem; font-weight: 700; min-width: 0; }
.chem-cfg-nm { flex: 1 1 auto; }
.chem-cfg-un { flex: 0 0 82px; font-weight: 600; font-size: .8rem; }
.chem-cfg-nm:focus, .chem-cfg-un:focus { outline: none; border-color: var(--brand); }
.chem-cfg-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(78px, 1fr));
  gap: 8px; align-items: end; }
.chem-cfg-f { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.chem-cfg-f span { font-size: .62rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--text-muted); font-weight: 700; }
.chem-cfg-f input[type="number"] { width: 100%; background: var(--input-bg);
  border: 1.5px solid var(--input-border); color: var(--text); padding: 9px 8px;
  border-radius: 10px; font-family: inherit; font-size: .88rem; font-weight: 700;
  text-align: center; }
.chem-cfg-f input:focus { outline: none; border-color: var(--brand); }
.chem-cfg-foot { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-top: 10px; }
.chem-cfg-half { display: flex; align-items: center; gap: 7px; font-size: .8rem;
  font-weight: 600; color: var(--text-2); cursor: pointer; }
.chem-cfg-half input { width: 18px; height: 18px; accent-color: var(--brand); }

.btn-save-threshold, .btn-reset-stock { border: none; border-radius: 10px; padding: 7px 12px;
  font-family: inherit; font-size: .76rem; font-weight: 700; cursor: pointer; }
.btn-save-threshold { background: var(--brand-soft); color: var(--brand); }
.btn-reset-stock { background: var(--surface-2); color: var(--text-2); border: 1.5px solid var(--border); }

.user-row { display: flex; align-items: center; gap: 10px; padding: 11px 0; border-bottom: 1.5px solid var(--border); }
.user-row:last-child { border-bottom: none; }
.user-info { flex: 1; min-width: 0; }
.user-name { font-size: .9rem; font-weight: 700; }
.user-email { color: var(--text-muted); font-size: .76rem; font-weight: 500; }
.user-role { font-size: .64rem; font-weight: 800; padding: 4px 9px; border-radius: 7px;
  background: var(--brand-soft); color: var(--brand); text-transform: uppercase; letter-spacing: .05em; }

.supplier-cards { display: flex; flex-direction: column; gap: 10px; }
.supplier-card { background: var(--surface-2); border: 1.5px solid var(--border);
  border-radius: 15px; padding: 14px; }
.supplier-name { font-size: .89rem; font-weight: 800; margin-bottom: 5px; }
.supplier-meta { font-size: .77rem; color: var(--text-muted); font-weight: 500; line-height: 1.5; }
.supplier-phone { display: inline-block; margin-top: 9px; padding: 8px 14px; border-radius: 11px;
  background: var(--brand-soft); color: var(--brand); text-decoration: none;
  font-size: .84rem; font-weight: 800; }

.order-row { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 0; border-bottom: 1.5px solid var(--border); }
.order-row:last-child { border-bottom: none; }
.order-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.order-name { font-weight: 700; font-size: .9rem; }
.order-stock { font-size: .77rem; font-weight: 700; }
.order-stock.stock-low { color: var(--warn); } .order-stock.stock-crit { color: var(--bad); }
.order-tag { background: color-mix(in srgb, var(--bad) 11%, transparent);
  border: 1.5px solid color-mix(in srgb, var(--bad) 30%, transparent); color: var(--bad);
  padding: 6px 11px; border-radius: 20px; font-size: .72rem; font-weight: 800; white-space: nowrap; flex: none; }

/* ══════════════════════════ MODAL ══════════════════════════ */
#modal-overlay { position: fixed; inset: 0; z-index: 200; background: rgba(4,22,38,.55);
  display: flex; align-items: center; justify-content: center; padding: 20px;
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); animation: m-fade .18s;
  overscroll-behavior: contain; }
@keyframes m-fade { from { opacity: 0; } }
#modal { background: var(--modal-bg); border: 1.5px solid var(--border); border-radius: 24px;
  padding: 22px; width: 100%; max-width: 420px; max-height: 86svh;
  box-sizing: border-box; overflow-y: auto; overflow-x: hidden;
  overscroll-behavior: contain;
  box-shadow: 0 26px 60px rgba(0,20,40,.4); animation: m-pop .22s cubic-bezier(.2,.9,.3,1.1); }
@keyframes m-pop { from { opacity: 0; transform: translateY(16px) scale(.96); } }
#modal-title { font-size: 1.05rem; font-weight: 800; letter-spacing: -.02em; margin-bottom: 14px; }
#modal-body label { display: block; font-size: .7rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-muted); font-weight: 700; margin: 12px 0 6px; }
#modal-body p { font-size: .88rem; color: var(--text-2); line-height: 1.6; font-weight: 500; }
#modal-body input, #modal-body select, #modal-body textarea {
  /* Without border-box these were 100% PLUS 26px padding and 3px of border, so
     every field sat wider than the modal and the whole card could be dragged
     sideways. */
  width: 100%; box-sizing: border-box; max-width: 100%;
  padding: 12px 13px; border-radius: 13px; background: var(--input-bg);
  border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .95rem; font-weight: 600; }
#modal-body input:focus, #modal-body select:focus, #modal-body textarea:focus {
  outline: none; border-color: var(--brand); }
.modal-actions { display: flex; gap: 9px; justify-content: flex-end; margin-top: 20px; }
.modal-actions button { padding: 12px 20px; }

.qty-row { display: flex; gap: 7px; flex-wrap: wrap; margin: 10px 0; }
.btn-half, .btn-pallet, .btn-bottle, .btn-frac {
  flex: 1; min-width: 74px; padding: 11px 8px; border-radius: 12px; cursor: pointer;
  background: var(--surface-2); border: 1.5px solid var(--border); color: var(--text);
  font-family: inherit; font-size: .82rem; font-weight: 700; }
.btn-half:active, .btn-pallet:active, .btn-bottle:active, .btn-frac:active {
  background: var(--brand); border-color: var(--brand); color: #fff; }
.bottle-row { display: flex; align-items: center; gap: 9px; margin: 10px 0; }
.bottle-row-label { font-size: .8rem; color: var(--text-muted); font-weight: 700; }

/* ══════════════════════════ BOTTOM NAV ══════════════════════════ */
#bottom-nav {
  display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 100;
  background: var(--nav-bg); border-top: 1.5px solid var(--border);
  padding: 0 4px var(--nav-lift); box-shadow: var(--sh-nav);
  align-items: flex-end;
}
.bn-item {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  color: var(--text-muted); text-decoration: none; padding: 10px 2px 11px;
  cursor: pointer; background: none; border: none; font-family: inherit; position: relative;
}
.bn-icon { display: grid; place-items: center; }
.bn-icon svg { width: 21px; height: 21px; fill: none; stroke: currentColor; stroke-width: 2.1;
  stroke-linecap: round; stroke-linejoin: round; transition: transform .2s; }
.bn-label { font-size: .59rem; font-weight: 700; letter-spacing: .02em; }
.bn-item.active { color: var(--brand); }
.bn-item.active .bn-icon svg { transform: translateY(-2px) scale(1.1); }

.bn-fab-slot { flex: 0 0 68px; display: flex; justify-content: center; align-items: flex-start; }
#bn-fab {
  width: 54px; height: 54px; margin-top: -22px; border-radius: 19px; border: none; cursor: pointer;
  /* Split down the diagonal — green on one half, the brand blue on the other.
     A hard stop rather than a blend, so it reads as two halves and not as a
     muddy teal. */
  background: linear-gradient(135deg,
    var(--brand) 0%, var(--brand-2) 50%,
    var(--fab-green) 50%, var(--fab-green) 100%);
  display: grid; place-items: center; box-shadow: var(--sh-fab); transition: transform .15s;
}
#bn-fab:active { transform: scale(.92); }
#bn-fab svg { width: 24px; height: 24px; fill: none; stroke: #fff; stroke-width: 2.3;
  stroke-linecap: round; stroke-linejoin: round; }

/* More sheet */
#bn-more-backdrop { position: fixed; inset: 0; background: rgba(4,22,38,.5); z-index: 110;
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); animation: m-fade .16s;
  touch-action: none; }

/* While the sheet is open the page underneath is frozen. overflow:hidden alone
   is ignored by iOS Safari for touch scrolling, so the body is pinned and its
   scroll position restored on close — otherwise the screen behind jumps to the
   top when the menu shuts. */
body.sheet-open { position: fixed; left: 0; right: 0; width: 100%; overflow: hidden; }
#bn-more-menu {
  position: fixed; left: 12px; right: 12px; bottom: calc(88px + var(--nav-lift));
  z-index: 120; max-width: 400px; margin: 0 auto;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: 24px;
  overflow-y: auto; max-height: min(72vh, 580px); box-shadow: var(--sh-l);
  /* Stop a flick that reaches the end of this list from carrying on into the
     screen behind it. */
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  animation: sheet-pop .22s cubic-bezier(.2,.9,.3,1.15);
}
@keyframes sheet-pop { from { opacity: 0; transform: translateY(16px) scale(.96); } }
/* Grouped rows rather than one long list. An admin sees ten destinations in
   here; as a flat column they all looked alike and nothing could be found at a
   glance. Each group is one card of full-width rows, so the eye lands on the
   group first and the item second, long names never wrap, and the chevron
   makes it obvious these go somewhere. */
.bn-grp { padding: 13px 13px 3px; }
.bn-grp:last-child { padding-bottom: 13px; }
.bn-grp-h { font-size: .61rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-muted); font-weight: 800; padding: 0 2px 8px; }
.bn-card { background: var(--surface-2); border: 1.5px solid var(--border);
  border-radius: 15px; overflow: hidden; }
.bn-more-item { display: flex; align-items: center; gap: 12px; padding: 11px 13px;
  color: var(--text); text-decoration: none; }
.bn-more-item + .bn-more-item { border-top: 1.5px solid var(--border); }
.bn-more-item:active { background: var(--brand-soft); }
.bn-more-item.active { background: var(--brand-soft); }
.bn-more-chev { width: 15px; height: 15px; flex: none; color: var(--text-muted);
  fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round; }
.bn-more-icon { display: grid; place-items: center; }
/* Menu icons sit lighter than the badges elsewhere — thinner stroke and a
   softer tile, so the list reads as navigation rather than five loud chips. */
/* One colour per group, so the tile says which part of the app you are in
   before you read the label. The tints sit on --surface-2 inside the cards
   rather than on the page, so they need more strength than they did as a flat
   list or they come out muddy. */
#bn-more-menu .bn-more-icon svg { stroke-width: 2; }
#bn-more-menu .bn-more-icon.c-blue   { background: color-mix(in srgb, var(--brand) 20%, transparent);  color: var(--brand); }
#bn-more-menu .bn-more-icon.c-teal   { background: color-mix(in srgb, var(--ok) 20%, transparent);     color: var(--ok); }
#bn-more-menu .bn-more-icon.c-violet { background: color-mix(in srgb, var(--violet) 22%, transparent); color: var(--violet); }
#bn-more-menu .bn-more-icon.c-amber  { background: color-mix(in srgb, var(--warn) 24%, transparent);   color: var(--warn); }
#bn-more-menu .bn-more-icon.c-red    { background: color-mix(in srgb, var(--bad) 20%, transparent);    color: var(--bad); }
.bn-more-text { font-size: .88rem; font-weight: 700; flex: 1; min-width: 0; }

/* ══════════════════════════ ODDS AND ENDS ══════════════════════════ */
/* Small wrappers and variants that carry their own class in the markup. */
.audit-cell-value { text-align: center; }
.audit-count:focus { border-color: var(--brand) !important; }
.btn-bible-edit { background: var(--surface-2); color: var(--text-2); }
.btn-bible-delete { background: color-mix(in srgb, var(--bad) 13%, transparent); color: var(--bad); }
.insp-comp-item { display: flex; flex-direction: column; min-width: 0; }
.insp-comp-item select, .insp-comp-item input { margin-bottom: 0; }
.insp-tab-panel { animation: pg-in .28s cubic-bezier(.2,.9,.3,1); }
@keyframes pg-in { from { opacity: 0; transform: translateY(8px); } }
/* Bible entries author their own markup; give FAQ blocks a sane default. */
.faq-item { padding: 11px 0; border-bottom: 1.5px solid var(--border); }
.faq-item:last-child { border-bottom: none; }

/* ══════════════════════════ FLATPICKR ══════════════════════════ */
.flatpickr-calendar { background: var(--modal-bg) !important; border: 1.5px solid var(--border) !important;
  border-radius: 18px !important; box-shadow: var(--sh-l) !important; font-family: inherit !important; }
.flatpickr-months, .flatpickr-month, .flatpickr-current-month { color: var(--text) !important; fill: var(--text) !important; }
.flatpickr-weekday { color: var(--text-muted) !important; font-weight: 700 !important; }
.flatpickr-day { color: var(--text) !important; border-radius: 10px !important; font-weight: 600 !important; }
.flatpickr-day:hover { background: var(--surface-2) !important; border-color: transparent !important; }
.flatpickr-day.selected, .flatpickr-day.today {
  background: var(--brand) !important; border-color: var(--brand) !important; color: #fff !important; }
.flatpickr-prev-month, .flatpickr-next-month { fill: var(--text) !important; }
.numInputWrapper span { border-color: var(--border) !important; }
.cur-month, .cur-year { color: var(--text) !important; }

/* ══════════════════════════ RESPONSIVE ══════════════════════════ */
@media (min-width: 641px) {
  .nav-links { display: flex; }
  #bn-more-menu, #bn-more-backdrop { display: none !important; }
  .btn-label { display: inline; }
  /* grid-auto-flow, because the base rule is a one-column grid: without it the
     icon sits on top of its own label and the label spills out of the pill. */
  .nav-right button {
    width: auto; padding: 0 13px; height: 38px; font-size: .82rem; font-weight: 700;
    gap: 6px; grid-auto-flow: column; white-space: nowrap;
  }
}

@media (max-width: 640px) {
  #bottom-nav.active { display: flex; }

  /* Every screen clears the bottom bar. This was a hand-kept list of screen
     ids, so half the app was missing from it and each new screen started life
     with its save button hidden under the menu. Login has no .container and
     hides the bar anyway. */
  .screen > .container,
  #insp-form-panel > .container {
    padding-bottom: calc(84px + var(--nav-lift));
  }

  .insp-row-2, .insp-compliance-grid { grid-template-columns: 1fr; }
  .insp-row-3 { grid-template-columns: 1fr 1fr; }
  .insp-col-2 { grid-column: span 2; }
  .insp-chem-grid { grid-template-columns: 1fr 1fr; }
  .insp-form-header h3 { font-size: .9rem; }
  .insp-form-footer { flex-direction: column; }
  .insp-form-footer button { width: 100%; padding: 13px; }
  .insp-report-card { flex-wrap: wrap; }
  .insp-report-right { width: 100%; justify-content: flex-end; }

  .admin-section { padding: 15px; }
  .section-header { flex-direction: column; align-items: stretch; gap: 10px; }
  .section-header .btn-primary { width: 100%; padding: 12px; }
  .admin-chem-row { flex-wrap: wrap; gap: 8px; padding: 12px 0; }
  .admin-chem-name { width: 100%; flex: none; font-size: .9rem; }
  .admin-chem-row input[type="number"] { flex: 1; width: auto; font-size: .95rem; padding: 10px; }
  .user-row { flex-wrap: wrap; }
  .order-row { flex-wrap: wrap; gap: 8px; }

  .audit-bd-row { grid-template-columns: auto minmax(0,1fr) auto; }
  .audit-bd-bar { display: none; }
  .audit-summary { grid-template-columns: 1fr 1fr; }
  .audit-actions button { flex: 1; padding: 12px; }
  .audit-row { grid-template-columns: repeat(5, 1fr); gap: 6px; padding: 13px 10px; }
  .audit-name { grid-column: 1 / -1; font-size: .9rem; margin-bottom: 3px; }
  .audit-cell-label { display: block; }
  .audit-row input[type="number"] { padding: 9px 4px; font-size: .92rem; }

  .weekly-table .wk-bar { display: none; }
  .weekly-table th, .weekly-table td { padding-left: 3px; padding-right: 3px; }

  .calc-card { padding: 16px; }
  .calc-result-value { font-size: 2rem; }

  #modal-overlay { align-items: flex-end; padding: 0; }
  #modal { border-radius: 26px 26px 0 0; max-width: 100%; max-height: 90svh;
    padding: 22px 20px calc(22px + var(--nav-lift));
    animation: m-slide .26s cubic-bezier(.2,.9,.3,1); }
  @keyframes m-slide { from { transform: translateY(100%); } }
  .modal-actions { flex-direction: column-reverse; }
  .modal-actions button { width: 100%; padding: 14px; }
}

.push-test {
  width: 100%; margin: -4px 0 12px; padding: 9px 12px; border-radius: 11px;
  border: 1.5px dashed var(--border); background: transparent; color: var(--text-muted);
  font-family: inherit; font-size: .76rem; font-weight: 700; cursor: pointer;
}
.push-test:active { transform: scale(.98); }
.push-test:disabled { opacity: .6; }

/* ══════════════ MY PROFILE ══════════════ */
.prof-top { display: flex; gap: 15px; align-items: center; }
.prof-avatar-wrap { position: relative; flex: none; }
.prof-avatar {
  width: 74px; height: 74px; border-radius: 24px; object-fit: cover; display: block;
  background: var(--surface-2); border: 1.5px solid var(--border);
}
.prof-initials {
  display: grid; place-items: center; font-size: 1.5rem; font-weight: 800;
  color: var(--brand); background: var(--tint-brand); letter-spacing: -.02em;
}
.prof-avatar-btn {
  position: absolute; right: -5px; bottom: -5px; width: 30px; height: 30px;
  border-radius: 50%; display: grid; place-items: center; cursor: pointer;
  background: var(--brand); color: var(--brand-ink); box-shadow: var(--sh-s);
  border: 2.5px solid var(--surface);
}
.prof-avatar-btn svg { width: 14px; height: 14px; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.prof-who { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.prof-name { font-size: 1.12rem; font-weight: 800; letter-spacing: -.025em; }
.prof-role {
  align-self: flex-start; font-size: .62rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--brand);
  background: var(--tint-brand); padding: 3px 9px; border-radius: 999px;
}
.prof-email { font-size: .76rem; color: var(--text-muted); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; }
.prof-cert { font-size: .8rem; font-weight: 700; margin-top: 11px; }
.prof-cert.ok   { color: var(--ok); }
.prof-cert.warn { color: var(--warn); }
.prof-cert.bad  { color: var(--bad); }
#prof-notes {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 120px;
  padding: 11px 12px; border-radius: 12px;
  background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .88rem; line-height: 1.55;
}
#prof-notes:focus { outline: none; border-color: var(--brand); }

/* ══════════════ FIELD HANDBOOK ══════════════
   Search sits above everything: at a pool you already know the word. */
.hb-search { position: relative; margin-bottom: 12px; }
.hb-search input {
  width: 100%; box-sizing: border-box; padding: 12px 38px 12px 40px; border-radius: 14px;
  background: var(--surface); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .92rem; font-weight: 600;
}
.hb-search input:focus { outline: none; border-color: var(--brand); }
.hb-search-i {
  position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
  width: 17px; height: 17px; fill: none; stroke: var(--text-muted); stroke-width: 2.2;
  stroke-linecap: round; pointer-events: none;
}
#hb-q-clear {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  width: 26px; height: 26px; border: none; border-radius: 50%; cursor: pointer;
  background: var(--surface-2); color: var(--text-muted); display: grid; place-items: center;
}
#hb-q-clear svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2.6; }
.hb-found { font-size: .76rem; font-weight: 700; color: var(--text-muted); margin-bottom: 10px; }

.hb-tabs { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 7px; margin-bottom: 9px; }
.hb-tab {
  display: flex; flex-direction: column; align-items: center; gap: 5px; cursor: pointer;
  padding: 11px 5px; border-radius: 13px; font-family: inherit;
  font-size: .68rem; font-weight: 800; letter-spacing: -.01em;
  background: var(--surface); border: 1.5px solid var(--border); color: var(--text-muted);
}
.hb-tab svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; }
.hb-tab.is-on { background: var(--tint-brand); border-color: transparent; color: var(--brand); }
.hb-blurb { font-size: .78rem; color: var(--text-muted); font-weight: 500; margin-bottom: 13px; }

.hb-drafts {
  display: flex; gap: 9px; align-items: center; margin-bottom: 12px;
  padding: 11px 12px; border-radius: 12px;
  background: var(--tint-warn); color: var(--warn);
  font-size: .8rem; font-weight: 700; line-height: 1.4;
}
.hb-drafts svg { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

.hb-group { margin-bottom: 18px; }
.hb-group-h {
  font-size: .66rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-muted); margin-bottom: 8px; padding-left: 3px;
}
.hb-list { display: flex; flex-direction: column; gap: 9px; }
.hb-group .hb-card { margin-bottom: 8px; }
.hb-card {
  display: flex; gap: 12px; align-items: flex-start; width: 100%; text-align: left;
  padding: 13px; border-radius: 16px; cursor: pointer; font-family: inherit;
  background: var(--surface); border: 1.5px solid var(--border); color: var(--text);
}
.hb-card:active { transform: scale(.99); }
.hb-card.is-draft { border-style: dashed; border-color: color-mix(in srgb, var(--warn) 55%, transparent); }
.hb-thumb { width: 58px; height: 58px; border-radius: 12px; object-fit: cover; flex: none; }
.hb-card-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.hb-kicker { font-size: .62rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--brand); }
.hb-kicker.big { font-size: .72rem; margin-bottom: 10px; }
.hb-title { font-size: .93rem; font-weight: 800; letter-spacing: -.02em; line-height: 1.3; }
.hb-sum { font-size: .78rem; color: var(--text-2); font-weight: 500; line-height: 1.4; }
.hb-meta { display: flex; gap: 9px; flex-wrap: wrap; margin-top: 3px;
  font-size: .66rem; font-weight: 700; color: var(--text-muted); }
.hb-flag { color: var(--warn); }

.hb-lead { font-size: .92rem; font-weight: 600; color: var(--text-2); line-height: 1.5; margin-bottom: 14px; }
.hb-shots { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px,1fr)); gap: 8px; margin-bottom: 14px; }
.hb-shots img { width: 100%; aspect-ratio: 4/3; object-fit: cover; border-radius: 13px; display: block; }
.hb-vids { display: flex; flex-direction: column; gap: 9px; margin-bottom: 15px; }
.hb-vid {
  position: relative; display: block; border-radius: 14px; overflow: hidden;
  background: var(--surface-2); border: 1.5px solid var(--border); text-decoration: none;
}
.hb-vid img { width: 100%; display: block; aspect-ratio: 16/9; object-fit: cover; }
.hb-vid-play {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);
  width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(0,0,0,.62); color: #fff;
}
.hb-vid-play svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.6; margin-left: 3px; }
.hb-vid-t { display: block; padding: 9px 12px; font-size: .8rem; font-weight: 700; color: var(--text); }
.hb-body { font-size: .9rem; line-height: 1.65; color: var(--text); }
.hb-by { font-size: .72rem; color: var(--text-muted); font-weight: 600; margin-top: 16px; }

.hb-vid-row { display: grid; grid-template-columns: minmax(0,1.2fr) minmax(0,1fr) 34px; gap: 7px; margin-bottom: 7px; }

/* Customers — the clients / commercial switch */
.cust-toggle {
  display: grid; grid-template-columns: 1fr 1fr; gap: 7px; margin-bottom: 13px;
  padding: 5px; border-radius: 15px; background: var(--surface-2);
  border: 1.5px solid var(--border);
}
.cust-tab {
  display: flex; align-items: center; justify-content: center; gap: 7px; cursor: pointer;
  padding: 10px 6px; border-radius: 11px; border: none; background: transparent;
  font-family: inherit; font-size: .82rem; font-weight: 800; letter-spacing: -.01em;
  color: var(--text-muted); transition: background .15s, color .15s;
}
.cust-tab svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.1;
  stroke-linecap: round; stroke-linejoin: round; }
.cust-tab.is-on { background: var(--surface); color: var(--brand); box-shadow: var(--sh-s); }
@media (prefers-reduced-motion: reduce) { .cust-tab { transition: none; } }

.cov-addrow { display: grid; grid-template-columns: 78px minmax(0,1fr); gap: 8px; margin-top: 9px; }
.cov-addrow input {
  -webkit-appearance: none; appearance: none; box-sizing: border-box;
  width: 100%; min-width: 0; padding: 10px; border-radius: 11px; text-align: center;
  background: var(--input-bg); border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .92rem; font-weight: 800; font-variant-numeric: tabular-nums;
}
.cov-addrow input:focus { outline: none; border-color: var(--brand); }
.cov-addrow button { width: 100%; }

/* Low stock — a warning light rather than a banner. What to order lives on the
   Admin page; this says the light is on and takes you there. */
.lowdot {
  display: flex; align-items: center; gap: 10px; width: 100%; cursor: pointer;
  margin-bottom: 12px; padding: 10px 13px; border-radius: 13px;
  background: var(--surface); border: 1.5px solid var(--border);
  font-family: inherit; text-align: left; color: var(--text-2);
  box-shadow: var(--sh-s);
  transition: transform .12s;
}
.lowdot:active { transform: scale(.99); }
.lowdot-led {
  width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--bad);
  box-shadow: 0 0 0 3.5px color-mix(in srgb, var(--bad) 18%, transparent),
              0 0 9px color-mix(in srgb, var(--bad) 65%, transparent);
  animation: lowdot-pulse 2.6s ease-in-out infinite;
}
@keyframes lowdot-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .45; }
}
.lowdot-txt { flex: 1; min-width: 0; font-size: .8rem; font-weight: 600; line-height: 1.35; }
.lowdot-txt strong { color: var(--bad); font-weight: 800; }
.lowdot-go {
  width: 15px; height: 15px; flex: none; fill: none; stroke: var(--text-muted);
  stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
}
@media (prefers-reduced-motion: reduce) {
  .lowdot { transition: none; }
  .lowdot-led { animation: none; }
}

/* ── The rest of the Meyco form ── */
.cov-steps { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 9px; }
.cov-steps li { font-size: .84rem; line-height: 1.55; color: var(--text-2); font-weight: 500; }
.cov-steps li::marker { color: var(--brand); font-weight: 800; }

.obs-head {
  display: grid; grid-template-columns: minmax(0,1fr) 62px 62px 34px; gap: 7px; padding: 0 0 7px;
  font-size: .62rem; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-muted); text-align: center;
}
.obs-head span:first-child { text-align: left; }
.obs-row { display: grid; grid-template-columns: minmax(0,1fr) 62px 62px 34px; gap: 7px;
  align-items: center; margin-bottom: 7px; }
.obs-row input, .obs-row select {
  -webkit-appearance: none; appearance: none; box-sizing: border-box; width: 100%; min-width: 0;
  padding: 10px 9px; border-radius: 11px; background: var(--input-bg);
  border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .84rem; font-weight: 700;
}
.obs-row input { text-align: center; font-variant-numeric: tabular-nums; }
.obs-row input:focus, .obs-row select:focus { outline: none; border-color: var(--brand); }

.cf-sec { margin-bottom: 18px; }
.cf-sec:last-child { margin-bottom: 0; }
.cf-sec-h {
  font-size: .64rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-muted); margin-bottom: 10px;
}
.cf-row { display: flex; align-items: center; gap: 12px; margin-bottom: 9px; }
.cf-q { flex: 1; min-width: 0; font-size: .85rem; font-weight: 600; line-height: 1.35; }
.cf-yn { display: flex; gap: 5px; flex: none; }
.cf-yn button {
  min-width: 48px; padding: 8px 12px; border-radius: 10px; cursor: pointer;
  border: 1.5px solid var(--input-border); background: var(--input-bg); color: var(--text-muted);
  font-family: inherit; font-size: .78rem; font-weight: 800;
}
.cf-yn button.is-on { background: var(--brand); border-color: transparent; color: var(--brand-ink); }
.cf-block { margin-bottom: 11px; }
.cf-block .calc-sub, .cf-block .cf-q { display: block; margin-bottom: 6px; }
.cf-block input {
  -webkit-appearance: none; appearance: none; box-sizing: border-box; width: 100%;
  padding: 10px 11px; border-radius: 11px; background: var(--input-bg);
  border: 1.5px solid var(--input-border); color: var(--text);
  font-family: inherit; font-size: .88rem; font-weight: 600;
}
.cf-block input:focus { outline: none; border-color: var(--brand); }
.cf-opts { display: flex; flex-wrap: wrap; gap: 6px; }
.cf-opt {
  padding: 8px 12px; border-radius: 10px; cursor: pointer; font-family: inherit;
  border: 1.5px solid var(--input-border); background: var(--input-bg); color: var(--text-2);
  font-size: .77rem; font-weight: 700; text-align: left; line-height: 1.3;
}
.cf-opt.is-on { background: var(--tint-brand); border-color: var(--brand); color: var(--brand); }
.cf-note { font-size: .74rem; color: var(--text-muted); font-weight: 500;
  line-height: 1.45; margin: -3px 0 10px; }
.cov-check { display: flex; align-items: center; gap: 9px; margin-top: 10px;
  font-size: .84rem; font-weight: 600; cursor: pointer; }
.cov-check input[type="checkbox"] { width: 19px; height: 19px; flex: none; accent-color: var(--brand); }

/* ── Coping profiles ── */
.cope-grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 8px; }
.cope-card {
  display: flex; flex-direction: column; gap: 0; cursor: pointer; padding: 0; overflow: hidden;
  border-radius: 13px; border: 2px solid var(--border); background: var(--surface);
  font-family: inherit; transition: border-color .15s, transform .12s;
}
.cope-card:active { transform: scale(.97); }
.cope-card.is-on { border-color: var(--brand); box-shadow: 0 0 0 3px var(--tint-brand); }
.cope-svg { display: block; width: 100%; height: 78px; background: #EFEAE1; }
.cope-name {
  padding: 7px 5px; font-size: .64rem; font-weight: 800; line-height: 1.25;
  color: var(--text-2); text-align: center;
}
.cope-card.is-on .cope-name { color: var(--brand); }
@media (max-width: 380px) { .cope-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (prefers-reduced-motion: reduce) { .cope-card { transition: none; } }

/* Full-size photo viewer — one for the whole app */
#photo-view {
  position: fixed; inset: 0; z-index: 300; display: flex;
  flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  padding: 24px; background: rgba(6, 20, 33, .88); cursor: zoom-out;
  overscroll-behavior: contain;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  animation: pv-in .16s ease-out;
}
@keyframes pv-in { from { opacity: 0; } to { opacity: 1; } }
#photo-view-img {
  max-width: min(100%, 520px); max-height: 70vh; border-radius: 20px;
  object-fit: contain; display: block;
  box-shadow: 0 24px 60px rgba(0,0,0,.5);
  background: rgba(255,255,255,.06);
}
#photo-view-cap {
  color: #fff; font-size: .92rem; font-weight: 700; letter-spacing: -.01em;
  text-align: center; text-shadow: 0 1px 10px rgba(0,0,0,.4);
}
#photo-close {
  position: absolute; top: calc(14px + env(safe-area-inset-top)); right: 14px;
  width: 40px; height: 40px; border-radius: 50%; cursor: pointer;
  border: 1.5px solid rgba(255,255,255,.45); background: rgba(255,255,255,.22);
  color: #fff; display: grid; place-items: center;
  box-shadow: 0 2px 12px rgba(0,0,0,.35);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
#photo-close svg { width: 17px; height: 17px; fill: none; stroke: currentColor;
  stroke-width: 2.6; stroke-linecap: round; }
.log-av.is-tappable { cursor: zoom-in; transition: transform .12s; }
.log-av.is-tappable:active { transform: scale(.9); }
@media (prefers-reduced-motion: reduce) {
  #photo-view { animation: none; }
  .log-av.is-tappable { transition: none; }
}

/* ══════════════ DESKTOP ══════════════
   Below this width the app is a phone in a pocket: one column, a bottom bar,
   one thing at a time. From here up it is someone at a desk with a mouse and
   a monitor, so the header becomes a standing sidebar — everything one click
   away instead of hidden behind a menu — and the content gets the room it has
   been wasting. */
@media (min-width: 1024px) {

  /* The header stops being a banner and becomes the rail. */
  #nav {
    position: fixed; top: 0; left: 0; bottom: 0; width: 264px; z-index: 60;
    border-radius: 0; margin: 0; overflow-y: auto; overflow-x: hidden;
    padding: 22px 16px calc(16px + env(safe-area-inset-bottom));
    display: flex; flex-direction: column;
    box-shadow: 4px 0 26px rgba(10, 37, 64, .13);
  }
  #nav::after { display: none; }            /* the waterline belongs on a banner */
  #nav::before { opacity: calc(var(--rail-caustics) * .64); }   /* caustics stay, quieter */

  .hero-inner { max-width: none; display: flex; flex-direction: column; flex: 1; }

  /* The chip and the buttons become direct children of the rail, so the
     buttons can be pushed to its bottom — margin-top:auto cannot climb out of
     a wrapper. */
  .hero-top { display: contents; }
  .nav-me { width: 100%; margin-left: 0; padding: 7px 12px 7px 7px; }
  #nav-user { max-width: none; }
  /* Four buttons on one 232px row does not fit, and the rail clips what
     overflows — "Password" and "Logout" were sitting half off the edge of
     every screen in the app. Laid out rather than left to flex: the two icon
     circles keep their size, Password takes what is left of the first row, and
     Logout has the second to itself. */
  .nav-right {
    order: 99; margin-top: auto; padding-top: 16px; gap: 8px;
    border-top: 1px solid rgba(255,255,255,.18);
    display: grid; grid-template-columns: 38px 38px minmax(0, 1fr);
  }
  .nav-right button { border-radius: 12px; min-width: 0; }
  #lang-toggle, #theme-toggle { width: 38px; padding: 0; border-radius: 50%; }
  #btn-change-pass { grid-column: 3; grid-row: 1; }
  #btn-logout      { grid-column: 1 / -1; grid-row: 2; }
  .nav-right .btn-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  .greet { margin: 18px 2px 4px; }
  .greet .greet-hi { font-size: .64rem; }
  .greet h1 { font-size: 1.35rem; }
  .greet .greet-meta { font-size: .7rem; margin-top: 5px; }

  /* The links, now a proper list. */
  .nav-links {
    display: flex; flex-direction: column; gap: 2px; margin-top: 16px;
    padding-top: 16px; border-top: 1px solid rgba(255,255,255,.18);
  }
  .nav-links a {
    display: flex; align-items: center; gap: 11px; padding: 10px 12px;
    border-radius: 11px; font-size: .85rem; font-weight: 700;
    color: rgba(255,255,255,.82); border: none;
  }
  .nav-links a:hover { background: rgba(255,255,255,.15); color: #fff; }
  .nav-links a.active { background: var(--rail-active-bg); color: var(--rail-active-ink); }

  /* The two screens the day is actually run from — the technician's Today and
     the office's Schedule — are picked out of the rail rather than sitting in
     the queue with everything else. */
  #nav-schedule, #nav-today {
    background: rgba(255, 159, 67, .18);
    color: #FFC793;
    box-shadow: inset 0 0 0 1.5px rgba(255, 159, 67, .38);
  }
  #nav-schedule:hover, #nav-today:hover { background: rgba(255, 159, 67, .30); color: #FFE2C9; }
  #nav-schedule.active, #nav-today.active {
    background: #F59034; color: #2A1503; box-shadow: none;
  }
  .nl-i {
    width: 17px; height: 17px; flex: none; fill: none; stroke: currentColor;
    stroke-width: 2.1; stroke-linecap: round; stroke-linejoin: round;
  }

  /* Content takes the rest, and actually uses it. */
  body { padding-left: 264px; }
  .container { max-width: 1080px; padding: 26px 30px 40px; }

  /* Opening a customer used to cover the monitor. On a phone that is right —
     there is only ever one thing on screen. On a desktop it threw away the
     list, the search and the person's place in it, to show one record; and
     checking four customers meant opening and closing four times, each time
     landing back at the top.
     It is a pane down the right now, and the list reflows to sit beside it.
     Still open, still searchable, still scrolled where it was. Click the next
     customer and the pane simply changes. */
  .panel {
    inset: 0 0 0 auto;
    width: min(620px, 52vw);
    padding: 0;
    background: var(--bg);
    border-left: 1.5px solid var(--border);
    box-shadow: -20px 0 56px rgba(0, 0, 0, .30);
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  .panel > .container {
    max-width: none; border-radius: 0; box-shadow: none;
    max-height: none; padding: 18px 26px 44px;
  }
  /* The work makes room for the pane rather than hiding behind it. Set on the
     body so every screen reflows — a two-column list becomes one, and nothing
     is left underneath where it cannot be reached. */
  body.pane-open { padding-right: min(620px, 52vw); }
  body.pane-open #today-list,
  body.pane-open #cl-list, body.pane-open #comm-list,
  body.pane-open #cov-list, body.pane-open #rep-list,
  body.pane-open .hb-list, body.pane-open .chem-group-body {
    grid-template-columns: minmax(0, 1fr);
  }
  /* Seven day columns cannot survive half the width; the week stacks instead. */
  body.pane-open .wk { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  body.pane-open .wk-day.is-empty { display: none; }

  /* Two columns wherever a list is really a set of cards. */
  #cl-list, #comm-list, #cov-list, #rep-list, .hb-list, .week-entries {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px; align-items: start;
  }
  /* Empty states are a sentence, not a card — they span the row. */
  .hb-list > .empty-state, #cl-list > .empty-state, #comm-list > .empty-state,
  #cov-list > .empty-state, #rep-list > .empty-state { grid-column: 1 / -1; }
  .hb-group { grid-column: 1 / -1; }

  /* The schedule is the screen a manager lives on — give it three across. */
  #today-list { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 11px; align-items: start; }
  #today-list > .empty-state { grid-column: 1 / -1; }
  /* A technician's whole day stays together, and spreads across the row. */
  .sched-group { grid-column: 1 / -1; margin-bottom: 8px; }
  /* Today's cards go three across; the office's rows are full-width lines. */
  #today-list .sched-group-list { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 11px; align-items: start; }
  #sch-list .sched-group-list { display: flex; flex-direction: column; gap: 7px; }

  /* Stock is scanned, so more of it on screen at once. It was one row per
     chemical across the full width: the name at one end of the monitor and the
     count at the other, with three-quarters of a metre of nothing between
     them, twenty-nine deep. Two columns puts the number back beside the name
     and the whole store on one screen. */
  .chem-row { padding-left: 14px; padding-right: 14px; }
  .chem-group-body {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px; align-items: start;
  }

  /* ── A shorter rail ──
     Fourteen items in one column is a list to be searched rather than a menu
     to be used, and two of them did not earn their place on a desktop:
       · The Calculator is a poolside tool. On a phone it is the button under
         the technician's thumb; nobody works out salt dosage at an office
         desk.
       · Weekly Usage and Stock Audit both ask questions about the very thing
         the Activity Log records — what was taken, and when — so all three are
         tabs on one screen instead of three separate rows in the menu.
       · The Bible is the field handbook: how to backwash this filter, what
         this pump model wants. It is read standing in front of the equipment,
         on a phone, not at a desk.
       · Client Seasonal Data asks which of these customers is worth keeping,
         so it is a tab on Customers rather than a separate row that has to be
         connected back to them in your head.
     Both are hidden here only. The phone's More sheet still reaches them, and
     neither screen has been removed or changed. */
  .nav-links a[data-screen="calc"],
  .nav-links a[data-screen="handbook"],
  .nav-links a[data-screen="audit"],
  .nav-links a[data-screen="seasonal"],
  .nav-links a[data-screen="weekly"] { display: none; }

  /* The paired tabs that replace the rail entry. Desktop only — on a phone
     the two screens are separate items in the More sheet, which is right
     there. */
  .web-tabs { display: flex; }

  /* An add button is a button again, not a bar across the screen. */
  .add-bar { width: auto; padding: 10px 18px; margin-bottom: 16px; }

  /* Today puts the work first. The clock, the map preference and the reminder
     switch are all things set once and then left alone, and they were stacked
     above the job list pushing the day's actual stops down the screen. On a
     monitor there is room to stand them beside it instead, so the jobs begin
     at the top where they belong. Ordered by grid area rather than by moving
     anything, because the phone's running order is the right one on a phone. */
  #screen-today .container {
    display: grid; align-content: start;
    grid-template-columns: minmax(0, 1fr) 292px;
    column-gap: 20px;
    grid-template-areas:
      "head head"
      "bar  bar"
      "main rail";
  }
  #screen-today .screen-header { grid-area: head; }
  #screen-today .today-bar     { grid-area: bar; }
  /* One area a side, not a row each. A grid item spanning several rows hands
     its height out across all of them, so a tall rail beside a short filter
     row grew the empty rows above the job list and pushed the day's work a
     third of the way down the screen. Two columns, one row, no distribution. */
  #today-main { grid-area: main; min-width: 0; }
  #today-rail {
    grid-area: rail; align-self: start;
    display: flex; flex-direction: column; gap: 12px;
  }
  /* Narrower column, so two across rather than three. */
  #today-list, #today-list .sched-group-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Forms stop being a single column of full-width boxes. */
  .comm-form-grid { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .cope-grid { grid-template-columns: repeat(6, minmax(0,1fr)); }

  /* Measurement rows are narrow by nature — two columns of them. */
  #cov-rows { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 0 14px; }

  /* Hover states worth having once there is a pointer. */
  .hb-card:hover, .cope-card:hover, .lowdot:hover { border-color: var(--brand); }
  .stop:hover { border-color: var(--brand); }
}

/* Wider still — a third column of cards rather than more whitespace. */
@media (min-width: 1500px) {
  .container { max-width: 1320px; }
  #cl-list, #comm-list, #cov-list, #rep-list, .hb-list, .week-entries {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  #today-list, #today-list .sched-group-list { grid-template-columns: repeat(3, minmax(0,1fr)); }
  .chem-group-body { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ── Scrollbars ── */
/* `color-scheme` in theme.css already tells the browser which way to paint
   these, and on its own that was the fix. They are drawn here as well because
   the browser's dark scrollbar is a grey slab against the app's blues, and
   because the rail scrolls too — a light bar down the inside edge of a dark
   rail is exactly where it was first noticed. */
* { scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border); border-radius: 8px;
  border: 3px solid transparent; background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); background-clip: padding-box; }
/* The rail is its own colour, so the bar inside it has to be too — the page's
   border token is invisible against it in one theme and glaring in the other. */
#nav { scrollbar-color: rgba(255,255,255,.22) transparent; }
#nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.22); background-clip: padding-box; }
#nav::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.38); background-clip: padding-box; }

/* ── The upgraded date box ── */
/* flatpickr hides the real <input type="date"> and puts a text box in front of
   it, which no `input[type="date"]` rule can reach — so a styled date box
   turned into a bare white block the moment it was upgraded. That is the same
   unstyled-white-box bug that has bitten this app before, and it is easy to
   miss because it only appears where a rule was written by type.
   `dt-box` is set by upgradeDateBoxes() in js/app.js so there is always
   something to target, and this is the floor: contexts that style their own
   inputs (.today-bar, .rng-custom) still win on specificity. */
.dt-box {
  -webkit-appearance: none; appearance: none; box-sizing: border-box;
  width: 100%; min-width: 0; padding: 10px 11px; border-radius: 11px;
  background: var(--input-bg); border: 1.5px solid var(--input-border);
  color: var(--text); font-family: inherit; font-size: .87rem; font-weight: 600;
}
.dt-box:focus { outline: none; border-color: var(--brand); }

/* ── Admin, one section at a time ── */
/* `is-off` rather than `hidden`, because "Order Needed" already uses `hidden`
   to mean "nothing is low" — one class meaning two things would have the tab
   row fighting the stock check over the same section. */
.admin-tabs { margin-bottom: 14px; }
.admin-section.is-off { display: none; }

/* ══════════════════════════ THE OFFICE'S WEEK ══════════════════════════ */
/* Seven columns, one per day, because the questions asked of this screen are
   about the week and not about a job: which day is empty, which is overloaded,
   and what nobody is driving yet. An empty day keeps its column — a Wednesday
   with no work is the most useful thing on the board. */
.wk {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 8px; align-items: start;
}
.wk-day {
  background: var(--surface); border: 1.5px solid var(--border); border-radius: 14px;
  padding: 8px; display: flex; flex-direction: column; gap: 7px; min-height: 108px;
}
.wk-day.is-today { border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); }
/* Nothing booked reads as an outline rather than a card, so a full day and an
   empty one are told apart before either is read. */
.wk-day.is-empty { background: transparent; border-style: dashed; }

.wk-dh {
  display: flex; align-items: baseline; gap: 6px;
  padding: 1px 3px 7px; border-bottom: 1px solid var(--border);
}
.wk-dn { font-size: .6rem; font-weight: 800; letter-spacing: .09em;
         text-transform: uppercase; color: var(--text-muted); }
.wk-dd { font-size: 1.02rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.wk-day.is-today .wk-dn, .wk-day.is-today .wk-dd { color: var(--brand); }
.wk-dc { margin-left: auto; font-size: .6rem; font-weight: 800; color: var(--text-muted); }
.wk-dc.is-loose { color: var(--warn); }

.wk-jobs { display: flex; flex-direction: column; gap: 5px; }
.wk-job {
  position: relative; display: flex; flex-direction: column; gap: 2px;
  text-align: left; border: none; cursor: pointer; font-family: inherit;
  border-radius: 10px; padding: 7px 8px;
  background: var(--c); color: var(--ink);
  transition: transform .12s, filter .15s;
}
.wk-job:hover  { filter: brightness(1.07); }
.wk-job:active { transform: scale(.97); }
/* A long pool name wraps rather than spilling out of a seventh of the screen. */
.wk-job-t { font-size: .74rem; font-weight: 800; line-height: 1.25; overflow-wrap: anywhere; }
.wk-job-m { display: flex; align-items: center; gap: 6px; font-size: .62rem; font-weight: 700; opacity: .88; }
.wk-who {
  margin-left: auto; flex: none; min-width: 19px; height: 17px; padding: 0 4px;
  border-radius: 7px; display: grid; place-items: center;
  background: rgba(255,255,255,.26); font-size: .58rem; font-weight: 800;
}
/* Nobody driving it. The one thing on this board that needs chasing, so it is
   the one thing outlined. */
.wk-job.is-loose  { box-shadow: inset 0 0 0 2px var(--warn); }
.wk-who.is-none   { background: var(--warn); color: var(--brand-ink); }
/* Finished work steps back, but only its text — the tick stays readable. The
   whole card was faded once and the badge went with it. */
.wk-job.is-done .wk-job-t, .wk-job.is-done .wk-job-m { opacity: .6; }
/* The tick sits over the top-right corner, so the title has to end before it
   rather than running underneath — "Cedar Point HOA✓" was one word. */
.wk-job.is-done .wk-job-t { padding-right: 15px; }
.wk-tick { position: absolute; top: 5px; right: 5px; }
.wk-tick svg { width: 12px; height: 12px; fill: none; stroke: currentColor;
               stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round; }

/* Faint rather than hidden. Something an admin does twenty times a day should
   not have to be discovered by hovering, and a button that only appears on
   hover still reserves its space — which left a hole under the last job of
   every column. */
.wk-add {
  margin-top: auto; border: 1.5px dashed var(--border); background: transparent;
  color: var(--text-muted); border-radius: 9px; padding: 3px 0; cursor: pointer;
  font: inherit; font-size: .82rem; font-weight: 800; line-height: 1.1;
  opacity: .45; transition: opacity .14s, border-color .14s, color .14s;
}
.wk-day:hover .wk-add, .wk-add:focus-visible { opacity: 1; }
.wk-add:hover { border-color: var(--brand); color: var(--brand); opacity: 1; }

/* On a phone the board is the list it always was: the week down the screen,
   and days with nothing on them left out rather than taking a turn each. */
@media (max-width: 1023px) {
  .wk { grid-template-columns: 1fr; gap: 10px; }
  .wk-day.is-empty { display: none; }
  .wk-day { min-height: 0; }
  .wk-dd { font-size: 1.1rem; }
  .wk-job-t { font-size: .84rem; }
  .wk-job-m { font-size: .7rem; }
  .wk-add { opacity: 1; }        /* no hover on a touchscreen */
}

.vf-row { display: grid; grid-template-columns: minmax(0,1fr) 120px; gap: 10px; }

/* ── Scheduling a job ── */
.vf-opt { font-weight: 600; color: var(--text-muted); text-transform: none; letter-spacing: 0; }
.vf-row { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 10px; }
.vf-colors { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.vf-color {
  width: 32px; height: 32px; border-radius: 50%; cursor: pointer; padding: 0;
  background: var(--sw); border: 2.5px solid transparent; box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.35);
}
.vf-color.is-on { border-color: var(--text); transform: scale(1.06); }

/* A job's colour runs down the side of its card, so a day reads at a glance. */
.stop { position: relative; }
.stop[style*="--stop-c"] { border-left: 5px solid var(--stop-c); }
.stop-title {
  display: block; font-size: .68rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--stop-c, var(--brand)); margin-bottom: 2px;
}
.stop-at {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: .68rem; font-weight: 800; color: var(--text);
  background: var(--surface-2); border: 1.5px solid var(--border);
  padding: 2px 7px; border-radius: 999px;
}
.stop-at svg { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 2.4; }

/* Whose day is whose, when the office is handing the work out. */
.sched-group { margin-bottom: 18px; }
.sched-group-h {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  margin-bottom: 9px; padding-bottom: 7px; border-bottom: 1.5px solid var(--border);
  font-size: .8rem; font-weight: 800; letter-spacing: -.01em;
}
.sched-group-n { font-size: .68rem; font-weight: 700; color: var(--text-muted); }
.sched-group-list { display: flex; flex-direction: column; gap: 10px; }

.sch-count { font-size: .8rem; font-weight: 600; color: var(--text-muted); margin-bottom: 12px; }
.sch-count strong { color: var(--warn); font-weight: 800; }

/* ── The office's job row ──
   Solid colour doing the identifying, one line of substance, and nothing a
   technician would need at a pool. A day fits on a screen. */
.job {
  display: flex; align-items: center; gap: 11px; position: relative;
  padding: 9px 11px 9px 0; border-radius: 12px; overflow: hidden;
  background: color-mix(in srgb, var(--job-c) 9%, var(--surface));
  border: 1.5px solid color-mix(in srgb, var(--job-c) 26%, transparent);
}
.job-bar { width: 6px; align-self: stretch; flex: none; background: var(--job-c); }
.job-when {
  flex: none; width: 64px; text-align: center;
  font-size: .78rem; font-weight: 800; color: var(--job-c);
  font-variant-numeric: tabular-nums; line-height: 1.2;
}
.job-when small { font-size: .6rem; font-weight: 700; opacity: .75; }
.job-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.job-title {
  font-size: .84rem; font-weight: 800; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.job-where {
  font-size: .72rem; font-weight: 500; color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.job-acts { display: flex; gap: 5px; flex: none; align-items: center; }
.job-btn {
  width: 30px; height: 30px; border-radius: 9px; cursor: pointer;
  border: 1.5px solid var(--border); background: var(--surface);
  color: var(--text-muted); display: grid; place-items: center;
}
.job-btn:hover { border-color: var(--brand); color: var(--brand); }
.job-btn.is-del:hover { border-color: var(--bad); color: var(--bad); }
.job-btn svg { width: 14px; height: 14px; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.job-done { color: var(--ok); display: grid; place-items: center; padding-right: 3px; }
.job-done svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.6; }
.job.is-done { opacity: .62; }
.job.is-done .job-title { text-decoration: line-through; }

/* ── The agenda ──
   Date, then the day's work as solid blocks. Read by colour first. */
.ag-day { margin-bottom: 20px; }
.ag-date {
  font-size: .82rem; font-weight: 700; color: var(--text-2);
  margin-bottom: 9px; padding-left: 2px;
}
.ag-day.is-today .ag-date { color: var(--brand); font-weight: 800; }
.ag-job {
  display: flex; align-items: center; gap: 11px; width: 100%; cursor: pointer;
  text-align: left; font-family: inherit; border: none;
  padding: 13px 15px; border-radius: 11px; margin-bottom: 8px;
  background: var(--c); color: var(--ink);
  transition: transform .1s, filter .12s;
}
.ag-job:active { transform: scale(.99); }
.ag-job:hover { filter: brightness(1.05); }
.ag-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ag-title {
  font-size: .93rem; font-weight: 800; letter-spacing: -.015em; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ag-when {
  font-size: .78rem; font-weight: 500; opacity: .82;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ag-who {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center; font-size: .68rem; font-weight: 800;
  background: rgba(0,0,0,.28); color: #fff;
}
.ag-who.is-none { background: rgba(0,0,0,.16); }
/* A tick on its own left people unsure whether the job had actually been
   filed, so the word is spelled out — and it is filled solid, because a tinted
   pill on an already-faded card was almost invisible.
   --ok against --brand-ink resolves correctly in both themes: bright green
   with near-black text at night, dark green with white text in daylight. */
.ag-done { flex: none; display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px 4px 8px; border-radius: 20px; font-size: .64rem; font-weight: 800;
  letter-spacing: .05em; text-transform: uppercase; white-space: nowrap;
  background: var(--ok); color: var(--brand-ink); }
.ag-done svg { width: 13px; height: 13px; flex: none; fill: none; stroke: currentColor;
  stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round; }
/* Fade the job's own text, never the whole card — the badge has to stay solid. */
.ag-job.is-done .ag-title,
.ag-job.is-done .ag-when { opacity: .6; }
.ag-job.is-done .ag-title { text-decoration: line-through; }

.js-done { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px;
  padding: 5px 13px 5px 10px; border-radius: 20px; font-size: .72rem; font-weight: 800;
  letter-spacing: .03em; background: var(--ok); color: var(--brand-ink); }
.js-done svg { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor;
  stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round; }

/* The sheet a job opens into */
.js-head { padding: 18px 18px 16px; border-radius: 16px; background: var(--c); color: var(--ink); margin-bottom: 16px; }
.js-title { display: block; font-size: 1.15rem; font-weight: 800; letter-spacing: -.025em; line-height: 1.2; }
.js-when { display: block; font-size: .82rem; font-weight: 600; opacity: .85; margin-top: 4px; }
.js-body { display: flex; flex-direction: column; gap: 9px; margin-bottom: 16px; }
.js-row { display: flex; gap: 12px; font-size: .87rem; font-weight: 600; line-height: 1.4; }
.js-k { flex: none; width: 74px; font-size: .68rem; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-muted); padding-top: 2px; }
.js-note { font-size: .84rem; line-height: 1.5; color: var(--text-2); font-style: italic;
  padding-left: 11px; border-left: 2.5px solid var(--border); margin-top: 3px; }
.js-acts { display: grid; grid-template-columns: repeat(auto-fit, minmax(90px,1fr)); gap: 8px; margin-bottom: 14px; }
.js-foot { display: flex; gap: 8px; }
.js-foot .btn-primary, .js-foot .btn-secondary:first-child { flex: 1; }

/* Dragging the rail into a different order (desktop only — the phone has the
   bottom bar and a drag would fight the scroll). */
@media (min-width: 1024px) {
  .nav-links a { position: relative; }
  .nav-links a::before {
    content: '⠿'; position: absolute; left: -2px; top: 50%; transform: translateY(-50%);
    font-size: .8rem; opacity: 0; color: rgba(255,255,255,.55); transition: opacity .12s;
    pointer-events: none;
  }
  .nav-links a:hover::before { opacity: 1; }
  .nav-links a:hover { padding-left: 18px; }
  .nav-links a.is-dragging { opacity: .4; }
  .nav-links a.is-over { box-shadow: inset 0 2px 0 rgba(255,255,255,.85); }
}

/* ══════════════ THE REPORT A CUSTOMER RECEIVES ══════════════ */
.fr-letter {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding-bottom: 14px; margin-bottom: 16px; border-bottom: 2.5px solid var(--brand);
}
.fr-brand { display: flex; align-items: center; gap: 11px; min-width: 0; }
.fr-logo { width: 40px; height: 40px; object-fit: contain; flex: none; }
.fr-co { display: block; font-size: .9rem; font-weight: 800; letter-spacing: -.02em; line-height: 1.2; }
.fr-co-sub { display: block; font-size: .68rem; font-weight: 600; color: var(--text-muted); margin-top: 2px; }
.fr-doc {
  flex: none; font-size: .6rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--brand); background: var(--tint-brand); padding: 5px 11px; border-radius: 999px;
}

.fr-lead { font-size: .86rem; font-weight: 600; line-height: 1.5; margin-bottom: 13px; }
.fr-lead.is-ok   { color: var(--ok); }
.fr-lead.is-warn { color: var(--warn); }

.fr-tbl { width: 100%; border-collapse: collapse; }
.fr-tbl th {
  text-align: left; font-size: .6rem; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-muted); padding: 0 8px 7px 0;
  border-bottom: 1.5px solid var(--border);
}
.fr-tbl td { padding: 9px 8px 9px 0; border-bottom: 1px solid var(--border); vertical-align: middle; }
.fr-tbl tr:last-child td { border-bottom: none; }
.fr-t-k { font-size: .85rem; font-weight: 700; }
.fr-t-v { font-size: .9rem; font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
.fr-t-v small { font-size: .68rem; font-weight: 700; color: var(--text-muted); }
.fr-t-r { font-size: .74rem; font-weight: 600; color: var(--text-muted); white-space: nowrap; }
.fr-t-s { text-align: right; }
.fr-tbl.is-plain td { border-bottom: 1px solid var(--border); }
.fr-pill {
  display: inline-block; font-size: .62rem; font-weight: 800; letter-spacing: .04em;
  padding: 3px 9px; border-radius: 999px; white-space: nowrap;
}
.fr-pill.is-ok   { background: var(--tint-ok);   color: var(--ok); }
.fr-pill.is-low  { background: var(--tint-warn); color: var(--warn); }
.fr-pill.is-high { background: var(--tint-bad);  color: var(--bad); }

.fr-attn {
  background: var(--tint-warn); border-radius: 14px; padding: 15px 16px;
  border: 1.5px solid color-mix(in srgb, var(--warn) 34%, transparent);
}
.fr-attn .fr-h { color: var(--warn); }

.fr-done { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(190px,1fr)); gap: 7px 16px; }
.fr-done li { display: flex; gap: 8px; align-items: flex-start; font-size: .84rem; font-weight: 600; line-height: 1.4; }
.fr-done li svg { width: 15px; height: 15px; flex: none; margin-top: 2px; color: var(--ok);
  fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.fr-done li.is-warn { color: var(--warn); }
.fr-done li.is-warn svg { color: var(--warn); }

.fr-pics { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px,1fr)); gap: 9px; }
.fr-pics img { width: 100%; aspect-ratio: 4/3; object-fit: cover; border-radius: 12px; display: block; cursor: zoom-in; }

.fr-foot {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px;
  margin-top: 24px; padding-top: 14px; border-top: 1.5px solid var(--border);
  font-size: .7rem; font-weight: 600; color: var(--text-muted);
}

/* Printing is how a report gets sent today, so it has to come out clean. */
@media print {
  #nav, #bottom-nav, .comm-panel-head, .rep-panel-actions,
  .fr-sec.is-private, .lowdot { display: none !important; }
  body { padding: 0 !important; background: #fff !important; }
  .panel { position: static !important; padding: 0 !important; background: none !important; }
  .panel > .container { max-width: none !important; box-shadow: none !important; border-radius: 0 !important; }
  .fr-sec { break-inside: avoid; }
  .fr-pics img { break-inside: avoid; }
}

/* Today on the bottom bar, in the same orange as the rail, so the screen a
   technician opens first is the one their thumb finds without looking. */
#bn-today { color: var(--warn); }
#bn-today.active { color: #F59034; }
#bn-today.active .bn-icon svg { transform: translateY(-2px) scale(1.12); }

.cov-send { border-color: color-mix(in srgb, var(--ok) 32%, var(--border)); }
.cov-shared { font-size: .74rem; color: var(--text-muted); font-weight: 600; margin-top: 9px; }

.cov-link {
  width: 100%; box-sizing: border-box; margin-top: 7px; padding: 9px 11px;
  border-radius: 10px; background: var(--input-bg); border: 1.5px solid var(--input-border);
  color: var(--text-2); font-family: ui-monospace, Menlo, monospace; font-size: .72rem;
}

/* ── The time clock ── */
.clk {
  background: var(--surface); border: 1.5px solid var(--border); border-radius: 16px;
  padding: 14px 15px; margin-bottom: 12px;
}
.clk.is-on { border-color: color-mix(in srgb, var(--ok) 50%, transparent);
  background: color-mix(in srgb, var(--ok) 5%, var(--surface)); }
.clk-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.clk-state { display: flex; align-items: center; gap: 11px; min-width: 0; }
.clk-dot {
  width: 10px; height: 10px; border-radius: 50%; flex: none; background: var(--text-muted);
}
.clk.is-on .clk-dot {
  background: var(--ok);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 20%, transparent);
  animation: clk-beat 2.4s ease-in-out infinite;
}
@keyframes clk-beat { 0%,100% { opacity: 1; } 50% { opacity: .5; } }
.clk-state b { display: block; font-size: .9rem; font-weight: 800; letter-spacing: -.015em; }
.clk-state small { display: block; font-size: .74rem; color: var(--text-muted); font-weight: 600; }
.clk-top button { flex: none; padding: 10px 18px; font-size: .84rem; }
.clk-nums {
  display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 8px;
  margin-top: 13px; padding-top: 13px; border-top: 1.5px solid var(--border);
}
.clk-nums div { text-align: center; }
.clk-nums span {
  display: block; font-size: .6rem; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-muted); margin-bottom: 3px;
}
.clk-nums b { font-size: 1rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.clk-nums .is-over span, .clk-nums .is-over b { color: var(--warn); }
@media (prefers-reduced-motion: reduce) { .clk.is-on .clk-dot { animation: none; } }

/* Everyone's hours */
.tc-nav { display: flex; align-items: center; gap: 8px; }
.tc-nav span { font-size: .78rem; font-weight: 700; color: var(--text-2); min-width: 110px; text-align: center; }
.tc-nav button { width: 32px; height: 32px; padding: 0; }
.tc-tbl { width: 100%; border-collapse: collapse; }
.tc-tbl th {
  text-align: left; font-size: .6rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-muted); padding: 0 8px 8px 0;
  border-bottom: 1.5px solid var(--border);
}
.tc-tbl td { padding: 10px 8px 10px 0; border-bottom: 1px solid var(--border);
  font-size: .86rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.tc-who { font-weight: 800; }
.tc-live {
  font-size: .58rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  color: var(--ok); background: var(--tint-ok); padding: 2px 7px; border-radius: 999px;
  white-space: nowrap;
}
.tc-tot { font-weight: 800; }
.tc-tot small { font-size: .66rem; color: var(--text-muted); font-weight: 700; }
.tc-tbl tr.is-over td { color: var(--warn); }
.tc-tbl tr.is-over .tc-who { color: var(--text); }
.tc-note { font-size: .78rem; font-weight: 600; color: var(--warn); margin-top: 12px; }
.tc-note.quiet { color: var(--text-muted); font-weight: 500; line-height: 1.5; }

/* ── Hours, week by week ── */
.hv-pick { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 13px; align-items: stretch; }
.hv-any {
  display: flex; align-items: center; gap: 6px; padding: 0 11px; border-radius: 11px;
  background: var(--input-bg); border: 1.5px solid var(--input-border);
  font-size: .72rem; font-weight: 700; color: var(--text-muted); cursor: text;
}
.hv-any.is-on { border-color: var(--brand); background: var(--tint-brand); color: var(--brand); }
.hv-any input {
  width: 44px; padding: 7px 0; text-align: center; border: none; background: none;
  color: inherit; font-family: inherit; font-size: .82rem; font-weight: 800;
  font-variant-numeric: tabular-nums; -moz-appearance: textfield;
}
.hv-any input:focus { outline: none; }
.hv-any input::-webkit-outer-spin-button,
.hv-any input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.hv-tab {
  padding: 9px 6px; border-radius: 11px; cursor: pointer; font-family: inherit;
  font-size: .78rem; font-weight: 800; color: var(--text-muted);
  background: var(--input-bg); border: 1.5px solid var(--input-border);
}
.hv-tab.is-on { background: var(--tint-brand); border-color: var(--brand); color: var(--brand); }
.hv-head {
  display: flex; gap: 14px; align-items: center; justify-content: space-between;
  flex-wrap: wrap; padding: 15px 16px; border-radius: 15px;
  background: var(--surface-2); border: 1.5px solid var(--border); margin-bottom: 14px;
}
.hv-big span { display: block; font-size: .62rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-muted); }
.hv-big b { display: block; font-size: 1.55rem; font-weight: 800; letter-spacing: -.03em; line-height: 1.15; }
.hv-big small { display: block; font-size: .72rem; color: var(--text-muted); font-weight: 600; margin-top: 2px; }
.hv-split { display: flex; gap: 18px; }
.hv-split span { display: block; font-size: .6rem; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-muted); }
.hv-split b { font-size: 1rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.hv-split .is-over span, .hv-split .is-over b { color: var(--warn); }
.hv-tbl { width: 100%; border-collapse: collapse; }
.hv-tbl th { text-align: left; font-size: .58rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-muted); padding: 0 6px 7px 0;
  border-bottom: 1.5px solid var(--border); }
.hv-tbl td { padding: 9px 6px 9px 0; border-bottom: 1px solid var(--border);
  font-size: .82rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.hv-w { font-weight: 700; }
.hv-t { font-weight: 800; text-align: right; }
.hv-t small { font-size: .64rem; color: var(--text-muted); }
.hv-tbl tr.is-over td { color: var(--warn); }
.hv-tbl tr.is-over .hv-w { color: var(--text); }

.hv-tbl tr.hv-sum td { border-bottom: none; border-top: 2px solid var(--border);
  font-weight: 800; padding-top: 11px; }

.tc-stuck {
  font-size: .58rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  color: var(--warn); background: var(--tint-warn); padding: 2px 7px; border-radius: 999px;
  white-space: nowrap;
}
.clk.is-stuck { border-color: color-mix(in srgb, var(--warn) 55%, transparent);
  background: color-mix(in srgb, var(--warn) 7%, var(--surface)); }
.clk.is-stuck .clk-dot { background: var(--warn);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--warn) 22%, transparent); }

.weekly-table .wk-adj { text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; }
.wk-note { font-size: .78rem; line-height: 1.5; color: var(--text-muted); font-weight: 500; margin-top: 12px; }
.wk-note strong { color: var(--text-2); font-weight: 800; }

.log-action.is-audit { color: var(--violet); }


/* Who is on the clock right now */
.oc-list { display: flex; flex-direction: column; gap: 7px; margin-bottom: 16px; }
.oc {
  display: flex; align-items: center; gap: 11px; padding: 10px 13px; border-radius: 12px;
  background: color-mix(in srgb, var(--ok) 7%, var(--surface));
  border: 1.5px solid color-mix(in srgb, var(--ok) 34%, transparent);
}
.oc.is-stuck {
  background: color-mix(in srgb, var(--warn) 8%, var(--surface));
  border-color: color-mix(in srgb, var(--warn) 45%, transparent);
}
.oc-dot {
  width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--ok);
  box-shadow: 0 0 0 3.5px color-mix(in srgb, var(--ok) 20%, transparent);
  animation: clk-beat 2.4s ease-in-out infinite;
}
.oc.is-stuck .oc-dot { background: var(--warn);
  box-shadow: 0 0 0 3.5px color-mix(in srgb, var(--warn) 22%, transparent); }
.oc-who { flex: 1; min-width: 0; }
.oc-who b { display: block; font-size: .86rem; font-weight: 800; letter-spacing: -.01em; }
.oc-who small { display: block; font-size: .72rem; color: var(--text-muted); font-weight: 600; }
.oc.is-stuck .oc-who small { color: var(--warn); }
.oc-for { flex: none; font-size: .92rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.oc-none { font-size: .82rem; color: var(--text-muted); font-weight: 600; margin-bottom: 14px; }
@media (prefers-reduced-motion: reduce) { .oc-dot { animation: none; } }

.hrs-head-right { display: flex; align-items: center; gap: 10px; }
.hrs-today-head { font-size: .68rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-muted); margin: 16px 0 8px; }
.hrs-person-row { display: flex; align-items: center; gap: 10px; margin: 18px 0 12px; }
.hrs-person-row .calc-sub { flex: none; }
.hrs-person-row select {
  flex: 1; min-width: 0; padding: 10px 12px; border-radius: 12px; background: var(--input-bg);
  border: 1.5px solid var(--input-border); color: var(--text); font-family: inherit;
  font-size: .88rem; font-weight: 600;
}
.hrs-person-row select:focus { outline: none; border-color: var(--brand); }
#btn-hours-refresh { padding: 7px 12px; height: auto; display: inline-flex; align-items: center; gap: 6px; }
#btn-hours-refresh .ico { width: 15px; height: 15px; }
#btn-hours-refresh.is-spinning .ico { animation: hrs-spin .7s linear infinite; }
@keyframes hrs-spin { to { transform: rotate(360deg); } }
.oc-stamp { font-size: .7rem; color: var(--text-muted); font-weight: 600; }
.oc-stamp-line { margin: -8px 0 16px; }
@media (prefers-reduced-motion: reduce) { #btn-hours-refresh.is-spinning .ico { animation: none; } }

/* ══════════════════════════ OPENING SCREEN ══════════════════════════ */
/* Committed to the deep-water palette in both themes: a splash is a brand
   moment, and it fades to reveal whatever theme the app is actually in.
   Everything here is SVG and CSS — this has to come up in a van on one bar. */
#splash {
  position: fixed; inset: 0; z-index: 9999; background: #0B1A2B;
  opacity: 1; transition: opacity .38s ease; overflow: hidden;
}
#splash.is-gone { opacity: 0; pointer-events: none; }
/* Fills the viewport rather than sitting in it — the SVG's own slice keeps the
   scene centred while the water runs off every edge. */
.sp-stage { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* The name sits low, over open water. It was above the deck line before, which
   put it in exactly the band the technician occupies — he covered it. Below the
   surface there is nothing but water on every screen shape, so the name always
   has clear ground. */
.sp-brand { position: absolute; left: 0; right: 0; bottom: 10%; z-index: 2;
  text-align: center; padding: 0 24px calc(env(safe-area-inset-bottom)); }
.sp-word { font-size: clamp(1.5rem, 7.5vw, 2.1rem); font-weight: 800; letter-spacing: -.03em;
  color: #EAF3FA; opacity: 0; animation: sp-in .5s ease-out .18s forwards; }
.sp-word span { color: #22B8F0; }
.sp-sub { font-size: .78rem; font-weight: 600; color: #9FC0D2; letter-spacing: .05em;
  margin-top: 6px; opacity: 0; animation: sp-in .5s ease-out .34s forwards; }
/* A soft darkening toward the bottom so the name always reads, whatever the
   waves are doing behind it. */
#splash::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: 42%; pointer-events: none; z-index: 1;
  background: linear-gradient(rgba(11,26,43,0), rgba(11,26,43,.55) 45%, rgba(11,26,43,.82)); }
@keyframes sp-in { to { opacity: 1; } }

.sp-w1 { animation: sp-drift1 3.4s linear infinite; }
.sp-w2 { animation: sp-drift2 4.6s linear infinite; }
/* The light net on the pool floor — slow, out of step with the surface, and
   breathing rather than sliding, which is how caustics actually behave. */
.sp-c1 { animation: sp-caust1 9s ease-in-out infinite; }
.sp-c2 { animation: sp-caust2 11s ease-in-out infinite; }
@keyframes sp-caust1 { 0%, 100% { transform: translateX(0);     opacity: .16; }
  50% { transform: translateX(13px); opacity: .25; } }
@keyframes sp-caust2 { 0%, 100% { transform: translateX(0);     opacity: .12; }
  50% { transform: translateX(-11px); opacity: .2; } }

/* The reflection never sits still on real water. */
.sp-refl { animation: sp-sway 5.5s ease-in-out infinite; }
@keyframes sp-sway { 0%, 100% { transform: matrix(1,0,0,-1,0,300); opacity: .15; }
  50% { transform: matrix(1.03,0,0,-1,-2,300); opacity: .09; } }

/* Droplets thrown up by the stream, each on its own arc. */
.sp-d1, .sp-d2, .sp-d3 { opacity: 0; }
.sp-d1 { animation: sp-drop1 2s ease-out .33s infinite; }
.sp-d2 { animation: sp-drop2 2s ease-out .48s infinite; }
.sp-d3 { animation: sp-drop3 2s ease-out .42s infinite; }
@keyframes sp-drop1 { 0% { opacity: 0; transform: translate(0,0); }
  8% { opacity: .9; } 30% { opacity: 0; transform: translate(-9px,-13px); }
  100% { opacity: 0; transform: translate(-9px,-13px); } }
@keyframes sp-drop2 { 0% { opacity: 0; transform: translate(0,0); }
  8% { opacity: .85; } 30% { opacity: 0; transform: translate(10px,-11px); }
  100% { opacity: 0; transform: translate(10px,-11px); } }
@keyframes sp-drop3 { 0% { opacity: 0; transform: translate(0,0); }
  8% { opacity: .75; } 28% { opacity: 0; transform: translate(1px,-16px); }
  100% { opacity: 0; transform: translate(1px,-16px); } }
@keyframes sp-drift1 { to { transform: translateX(-40px); } }
@keyframes sp-drift2 { to { transform: translateX(40px); } }

/* Retimed tighter than the mockup: on a fast connection the whole splash may
   only be up for half a second, so the pour has to start almost at once. */
.sp-jug { transform-box: fill-box; transform-origin: 20% 80%;
  animation: sp-tip 2s ease-in-out infinite; }
@keyframes sp-tip { 0%, 8% { transform: rotate(0); }
  22%, 68% { transform: rotate(-46deg); } 100% { transform: rotate(0); } }

.sp-stream { opacity: 0; animation: sp-pour 2s ease-in-out infinite; }
@keyframes sp-pour { 0%, 16% { opacity: 0; } 26%, 66% { opacity: 1; } 76%, 100% { opacity: 0; } }

.sp-ring { transform-box: fill-box; transform-origin: center; opacity: 0; }
.sp-r1 { animation: sp-ring 2s ease-out .28s infinite; }
.sp-r2 { animation: sp-ring 2s ease-out .52s infinite; }
.sp-r3 { animation: sp-ring 2s ease-out .75s infinite; }
@keyframes sp-ring { 0% { opacity: 0; transform: scale(.2); }
  12% { opacity: .75; } 55%, 100% { opacity: 0; transform: scale(1.9); } }

@media (prefers-reduced-motion: reduce) {
  .sp-jug, .sp-stream, .sp-ring, .sp-w1, .sp-w2, .sp-c1, .sp-c2,
  .sp-refl, .sp-d1, .sp-d2, .sp-d3, .sp-word, .sp-sub { animation: none; }
  .sp-word, .sp-sub { opacity: 1; }
  .sp-jug { transform: rotate(-46deg); }
  .sp-stream, .sp-ring { opacity: .8; }
}

/* Language switch, beside the theme toggle. Shows the language you would get
   by tapping it, not the one you are already in. */
#lang-toggle { font-family: inherit; font-size: .72rem; font-weight: 800;
  letter-spacing: .06em; }

/* ── On the clock, in the header ─────────────────────────────────────────── */
/* The home-screen icon badge is drawn by the operating system and is always a
   red dot — nothing can change that. This is the version we control: green,
   breathing, and impossible to mistake for a notification count. */
.on-clock {
  display: inline-flex; align-items: center; gap: 9px; margin-top: 14px;
  padding: 7px 14px 7px 11px; border-radius: 22px;
  background: rgba(8, 40, 30, .34); border: 1.5px solid rgba(52, 211, 153, .45);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  font-size: .78rem; font-weight: 700; color: #C9FBE8; text-shadow: none;
  box-shadow: 0 2px 16px rgba(6, 30, 22, .28);
}
.on-clock strong { font-weight: 800; color: #fff; font-variant-numeric: tabular-nums; }
.on-clock-dot {
  width: 11px; height: 11px; border-radius: 50%; flex: none; background: #34D399;
  box-shadow: 0 0 0 0 rgba(52, 211, 153, .85), 0 0 12px rgba(52, 211, 153, .9);
  animation: on-clock-pulse 2s ease-out infinite;
}
/* The ring travels outward and fades, the way a live indicator should — a dot
   that merely blinks reads as a fault light rather than "running". */
@keyframes on-clock-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(52,211,153,.8),  0 0 12px rgba(52,211,153,.9); }
  70%  { box-shadow: 0 0 0 11px rgba(52,211,153,0), 0 0 12px rgba(52,211,153,.5); }
  100% { box-shadow: 0 0 0 0 rgba(52,211,153,0),   0 0 12px rgba(52,211,153,.9); }
}
@media (prefers-reduced-motion: reduce) { .on-clock-dot { animation: none; } }

/* Admin corrections on a shift row. Kept tight so the row still reads as data
   rather than a toolbar. */
.hv-fix { white-space: nowrap; text-align: right; }
.hv-fix button { margin-left: 5px; padding: 4px 9px; font-size: .7rem; }
.hv-fix .btn-danger { padding: 4px 7px; }
.hv-fix .ico { width: 13px; height: 13px; }

/* The product mark on the opening screen. Sized off the viewport so it holds
   its proportions from a small phone to a desktop. */
.sp-logo { width: clamp(64px, 19vw, 96px); height: auto; display: block;
  margin: 0 auto 4px; filter: drop-shadow(0 8px 22px rgba(4, 18, 30, .45)); }

/* Sign-in: the product's mark, not a company's. Everyone shares this screen,
   and it is shown before we know which company the person belongs to. */
.login-logo { display: block; width: 78px; height: auto; margin: 0 auto 12px;
  filter: drop-shadow(0 8px 20px rgba(4, 18, 30, .3)); }
.login-word { text-align: center; font-size: 1.75rem; font-weight: 800;
  letter-spacing: -.03em; margin: 0 0 4px; color: var(--text); }
.login-word span { color: var(--brand); }
/* A third element now sits above the form, so the stagger needs one more step. */
.login-box > *:nth-child(3) { animation-delay: .21s; }

/* ══════════════════════════ IMPORTING A CUSTOMER LIST ══════════════════════════ */
/* The preview carries the weight here. It is the only thing standing between a
   spreadsheet nobody has read and a hundred rows in somebody's live account, so
   it has to be read rather than skimmed: what is wrong first, what is already
   there second, and what is about to happen last. */
.imp-pick { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 12px; }
.imp-pick input[type="file"] {
  flex: 1; min-width: 0; font: inherit; font-size: .85rem; color: var(--text-2);
  background: var(--input-bg); border: 1.5px dashed var(--input-border);
  border-radius: 12px; padding: 10px 12px;
}
.imp-pick input[type="file"]::file-selector-button {
  font: inherit; font-size: .82rem; font-weight: 700; cursor: pointer;
  margin-right: 10px; padding: 7px 13px; border-radius: 9px;
  border: 1.5px solid var(--border); background: var(--surface-2); color: var(--text);
}

.imp-sum { display: flex; flex-wrap: wrap; gap: 7px; margin: 14px 0 2px; }
.imp-pill {
  font-size: .72rem; font-weight: 800; padding: 4px 11px; border-radius: 20px;
  letter-spacing: .01em;
}
.imp-pill.is-ok   { background: var(--tint-ok);    color: var(--ok); }
.imp-pill.is-skip { background: var(--surface-2);  color: var(--text-muted); }
.imp-pill.is-bad  { background: var(--tint-bad);   color: var(--bad); }

.imp-note {
  font-size: .86rem; line-height: 1.55; margin: 10px 0;
  padding: 11px 14px; border-radius: 0 11px 11px 0;
  background: var(--surface-2); border-left: 3px solid var(--border); color: var(--text-2);
}
.imp-note.is-bad  { background: var(--tint-bad);  border-left-color: var(--bad); }
.imp-note.is-skip { background: var(--surface-2); border-left-color: var(--text-muted); }
.imp-note strong  { color: var(--text); }
.imp-list { margin: 7px 0 0; padding-left: 18px; }
.imp-list li { margin-bottom: 3px; }

.imp-table { width: 100%; border-collapse: collapse; font-size: .84rem; min-width: 520px; }
.imp-table th {
  text-align: left; font-size: .62rem; font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-muted);
  padding: 0 10px 7px 0; border-bottom: 1.5px solid var(--border);
}
.imp-table td { padding: 8px 10px 8px 0; border-bottom: 1px solid var(--border); }
.imp-table td.n { text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; }
/* A wide table scrolls inside itself; the page never moves sideways. */
.scroller { overflow-x: auto; }

/* ══════════════════════ SCHEDULING A JOB ══════════════════════ */
/* Each field is its own block so the form can go two across without a label
   parting company with its box. One column until there is room for two. */
.vf-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 20px; }
.vf-f { min-width: 0; }
.vf-f.is-wide { grid-column: 1 / -1; }

/* "Tick here if the stop is free."
   It used to read "Billable visit", ticked by default, and the way to make a
   stop free was to untick it — two negatives to hold at once, on the control
   that decides whether somebody gets charged. The box now says what ticking it
   does, and the ordinary case is an empty box.
   The native control is hidden rather than removed: it still holds the state,
   still takes focus, still responds to the keyboard and still reads correctly
   to a screen reader. Only its appearance is ours. */
/* Scoped under #modal-body deliberately. The generic rule there is
   `#modal-body label`, which carries an id and therefore beats any plain class
   — so a bare `.vf-free` lost on `display` and the row rendered as a stacked,
   uppercase, muted caption with the tick adrift above it. Matching that
   selector's weight is the fix; raising it with !important would only move the
   fight somewhere else. */
#modal-body label.vf-free {
  display: flex; align-items: center; gap: 11px; cursor: pointer;
  margin: 0; padding: 11px 13px; border-radius: 13px;
  text-transform: none; letter-spacing: 0; font-size: inherit; color: var(--text);
  background: var(--input-bg); border: 1.5px solid var(--input-border);
  transition: border-color .15s, background .15s;
}
#modal-body label.vf-free:hover { border-color: var(--brand); }
#modal-body .vf-free input { position: absolute; opacity: 0; width: 0; height: 0; }
.vf-tick {
  flex: none; width: 22px; height: 22px; border-radius: 7px;
  border: 1.5px solid var(--input-border); background: var(--surface);
  display: grid; place-items: center;
  transition: background .15s, border-color .15s, transform .12s;
}
.vf-tick svg {
  width: 13px; height: 13px; fill: none; stroke: var(--brand-ink);
  stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round;
  opacity: 0; transform: scale(.6); transition: opacity .13s, transform .13s;
}
#modal-body .vf-free input:checked ~ .vf-tick { background: var(--ok); border-color: var(--ok); }
#modal-body .vf-free input:checked ~ .vf-tick svg { opacity: 1; transform: scale(1); }
/* A keyboard user has to be able to see where they are. */
#modal-body .vf-free input:focus-visible ~ .vf-tick { box-shadow: 0 0 0 3px var(--brand-soft); border-color: var(--brand); }
.vf-free-t { font-size: .9rem; font-weight: 700; color: var(--text); }
/* Ticked, the whole row says so rather than just the little square. */
#modal-body label.vf-free:has(input:checked) { border-color: var(--ok); background: var(--tint-ok); }

@media (min-width: 1024px) {
  /* The job form is a page, not a popup. Ten fields in a 420px box on a
     1440px monitor was the thing that read as confusing — there was room for
     all of it at once and the screen was not using it. */
  #modal-overlay.is-page {
    padding: 0; align-items: stretch; justify-content: stretch;
    background: var(--bg); left: 264px;          /* clear of the rail */
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  #modal-overlay.is-page #modal {
    max-width: none; width: 100%; max-height: none;
    border: none; border-radius: 0; animation: none;
    padding: 30px 34px 40px; overflow-y: auto;
  }
  /* The form itself still stops at a readable width — a two-column form
     stretched across a 27-inch monitor is no easier to fill in. */
  #modal-overlay.is-page #modal-title,
  #modal-overlay.is-page #modal-body,
  #modal-overlay.is-page .modal-actions { max-width: 880px; margin-inline: auto; }
  #modal-overlay.is-page #modal-title { font-size: 1.5rem; margin-bottom: 20px; }
  #modal-overlay.is-page .vf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #modal-overlay.is-page .modal-actions {
    margin-top: 26px; padding-top: 18px; border-top: 1.5px solid var(--border);
  }
}

/* ══════════════════════════ BILLING ══════════════════════════ */
.bill-month {
  display: grid; place-items: center; font-weight: 800; font-size: .95rem;
  background: var(--input-bg); border: 1.5px solid var(--input-border);
  border-radius: 13px; padding: 11px 12px;
}

.bill-sum { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; margin-bottom: 16px; }
.bill-tile {
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius); padding: 14px 16px; box-shadow: var(--sh-s);
}
/* The visits with no price are the point of this screen, so they are coloured
   like a problem rather than listed like a statistic. */
.bill-tile.is-warn { background: var(--tint-warn); border-color: var(--warn); }
.bill-k { display: block; font-size: .62rem; font-weight: 800; letter-spacing: .09em;
          text-transform: uppercase; color: var(--text-muted); }
.bill-tile.is-warn .bill-k { color: var(--warn); }
.bill-v { display: block; font-size: 1.6rem; font-weight: 800; letter-spacing: -.02em;
          font-variant-numeric: tabular-nums; margin-top: 2px; }
.bill-s { display: block; font-size: .78rem; color: var(--text-muted); }

.bill-card {
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius-lg); margin-bottom: 11px; overflow: hidden;
}
.bill-card-h {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; padding: 15px 17px; border-bottom: 1px solid var(--border);
}
.bill-name { display: block; font-weight: 800; font-size: 1rem; }
.bill-meta { display: block; font-size: .78rem; color: var(--text-muted); }
.bill-card-r { display: flex; align-items: center; gap: 14px; }
.bill-total { font-size: 1.25rem; font-weight: 800; font-variant-numeric: tabular-nums; }

.bill-lines { padding: 6px 17px 13px; }
.bill-line {
  display: grid; grid-template-columns: minmax(0,1fr) 54px 96px; gap: 10px;
  padding: 8px 0; border-bottom: 1px solid var(--border); font-size: .9rem;
}
.bill-line:last-child { border-bottom: none; }
.bill-line .n { text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; }
.bill-line.is-total { font-weight: 800; border-top: 2px solid var(--border); border-bottom: none; }

/* Work that happened and has nothing to charge for. Said plainly, with the
   dates, because the only useful response is to go and put a price on it. */
.bill-unpriced {
  margin: 0 17px 15px; padding: 11px 14px; font-size: .84rem; line-height: 1.55;
  background: var(--tint-warn); border-left: 3px solid var(--warn);
  border-radius: 0 11px 11px 0; color: var(--text-2);
}
.bill-unpriced strong { color: var(--text); }
.bill-unpriced ul { margin: 6px 0 0; padding-left: 18px; }

.inv-table { width: 100%; border-collapse: collapse; font-size: .88rem; min-width: 640px; }
.inv-table th {
  text-align: left; font-size: .62rem; font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-muted);
  padding: 0 12px 8px 0; border-bottom: 1.5px solid var(--border);
}
.inv-table td { padding: 11px 12px 11px 0; border-bottom: 1px solid var(--border); }
.inv-table .n { text-align: right; font-variant-numeric: tabular-nums; }
.inv-table tr.is-void-row td { opacity: .5; text-decoration: line-through; }
.inv-pill {
  font-size: .62rem; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
  padding: 3px 9px; border-radius: 20px; white-space: nowrap;
}
.inv-pill.is-draft { background: var(--surface-2);  color: var(--text-muted); }
.inv-pill.is-sent  { background: var(--tint-warn);  color: var(--warn); }
.inv-pill.is-paid  { background: var(--tint-ok);    color: var(--ok); }
.inv-pill.is-void  { background: var(--surface-2);  color: var(--text-muted); }
/* Sent and never opened is the one worth noticing in a list of numbers. */
.inv-unseen { color: var(--text-muted); font-style: italic; font-size: .8rem; }
.inv-open { font-variant-numeric: tabular-nums; font-weight: 700; }
.inv-open-btn { padding: 6px 12px; font-size: .78rem; }

/* ── One invoice ── */
.inv-h { font-size: .66rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
         color: var(--text-muted); margin: 22px 0 8px; }
.inv-doc { padding: 0; margin-top: 14px; }
.inv-link { display: flex; gap: 8px; align-items: center; }
.inv-link input {
  flex: 1; min-width: 0; padding: 10px 12px; border-radius: 12px;
  background: var(--input-bg); border: 1.5px solid var(--input-border);
  color: var(--text-2); font-family: inherit; font-size: .78rem;
}
.inv-events { display: flex; flex-direction: column; }
.inv-ev {
  display: flex; justify-content: space-between; gap: 12px; padding: 8px 0;
  border-bottom: 1px solid var(--border); font-size: .85rem;
}
.inv-ev:last-child { border-bottom: none; }
.inv-ev span:first-child { color: var(--text-muted); font-weight: 700; }
.inv-ev.is-good span:first-child { color: var(--ok); }
.inv-opened { font-size: .92rem; margin: 0; }
/* Sent and never opened is the thing worth noticing on this screen. */
.inv-opened.is-never { color: var(--text-muted); font-style: italic; }
.inv-actions { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 24px; }
.comm-sub { color: var(--text-muted); font-size: .86rem; margin: 2px 0 0; }

/* ── Sending a report ── */
.rep-send-box { margin-top: 26px; padding-top: 20px; border-top: 1.5px solid var(--border); }
.rep-send-box .btn-primary { width: 100%; padding: 13px; }
.rep-sent {
  background: var(--tint-ok); border-left: 3px solid var(--ok);
  border-radius: 0 11px 11px 0; padding: 11px 14px; font-size: .9rem;
  color: var(--text-2); margin-bottom: 10px;
}
.rep-sent strong { color: var(--ok); }
/* A customer with no address is the one thing that stops a send, so it is
   said in the warning colour rather than as a quiet aside. */
.calc-hint.is-warn { color: var(--warn); font-weight: 600; }
@media (min-width: 1024px) { .rep-send-box .btn-primary { width: auto; padding: 11px 20px; } }
