/* ═══════════════════════════════════════════════════════════════════════════
   Recoatly — interface styles

   The surface is built the way Apple builds one: a quiet grey canvas, white
   cards that float a hairline above it, one confident blue for the thing you
   are meant to press, and generous air so the content is the interface.

   Three rules hold the whole thing together:

     1. Depth comes from elevation, not from borders. A card is separated from
        the canvas by a shadow and a radius, never by a heavy rule.
     2. Motion explains causality. Everything that appears arrives from where
        it came from, on a spring, in under 400ms — and nothing moves at all
        for somebody who has asked their system to stop animating.
     3. Colour is information. Grey is the entire interface; a colour means a
        state, a status or an action, and never decoration.

   Light and dark are both first-class. Every colour below is declared twice.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* SF Pro on Apple hardware, the closest well-drawn neighbour everywhere else.
     Nothing is fetched: the stack resolves to whatever the device already has. */
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
    "Inter", "Segoe UI Variable Display", "Segoe UI", Roboto, system-ui, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;

  /* Surfaces */
  --canvas: #F5F5F7;
  --paper: #FFFFFF;
  --sunken: #F5F5F7;
  --raised: #FFFFFF;
  --rail: rgba(250, 250, 252, 0.72);
  --rail-solid: #FAFAFC;
  --rail-hover: rgba(120, 120, 128, 0.10);
  --rail-on: rgba(0, 113, 227, 0.11);
  --veil: rgba(255, 255, 255, 0.72);

  /* Ink */
  --ink: #1D1D1F;
  --ink-2: #6E6E73;
  --ink-3: #6E6E73;
  --ink-4: #8E8E93;
  --ink-invert: #F5F5F7;
  --ink-invert-2: #AEAEB2;

  /* Lines — hairlines, never rules */
  --line: rgba(0, 0, 0, 0.07);
  --line-2: rgba(0, 0, 0, 0.14);
  --line-rail: rgba(0, 0, 0, 0.07);
  --fill: rgba(120, 120, 128, 0.10);
  --fill-2: rgba(120, 120, 128, 0.16);

  /* Accent — the one blue */
  --accent: #0071E3;
  --accent-press: #0062C4;
  --accent-soft: rgba(0, 113, 227, 0.10);
  --accent-ring: rgba(0, 113, 227, 0.28);
  --link: #0071E3;

  /* Status */
  --good: #137333;
  --good-bg: rgba(48, 209, 88, 0.14);
  --good-solid: #30D158;
  --info: #0071E3;
  --info-bg: rgba(0, 113, 227, 0.10);
  --warn: #9A5B00;
  --warn-bg: rgba(255, 159, 10, 0.16);
  --warn-solid: #FF9F0A;
  --bad: #CE2A21;
  --bad-bg: rgba(255, 59, 48, 0.11);
  --bad-solid: #FF3B30;
  --neutral: #6E6E73;
  --neutral-bg: rgba(120, 120, 128, 0.12);
  --active-tone: #4F4DD4;
  --active-bg: rgba(94, 92, 230, 0.12);

  /* Elevation */
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.04), 0 0 0 0.5px rgba(0, 0, 0, 0.045);
  --shadow-lift: 0 8px 24px rgba(0, 0, 0, 0.09), 0 0 0 0.5px rgba(0, 0, 0, 0.045);
  --shadow-pop: 0 28px 70px rgba(0, 0, 0, 0.20), 0 4px 14px rgba(0, 0, 0, 0.07), 0 0 0 0.5px rgba(0, 0, 0, 0.06);

  /* Geometry */
  --r-xs: 5px;
  --r-sm: 8px;
  --r: 11px;
  --r-lg: 16px;
  --r-xl: 22px;
  --pill: 980px;

  /* Motion. The spring is Apple's sheet curve; everything large uses it. */
  --spring: cubic-bezier(0.32, 0.72, 0, 1);
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --fast: 140ms;
  --mid: 260ms;
  --slow: 420ms;

  --rail-w: 244px;
  --top-h: 56px;

  color-scheme: light;
}

/* Dark is a full second skin, not a filter over the first: every token above
   is redeclared, so nothing is left to a browser's own inversion. It applies
   either because the person chose it, or because their system did. */

[data-theme='dark'] {
  color-scheme: dark;

  --canvas: #000000;
  --paper: #1C1C1E;
  --sunken: #2C2C2E;
  --raised: #242426;
  --rail: rgba(28, 28, 30, 0.72);
  --rail-solid: #1C1C1E;
  --rail-hover: rgba(120, 120, 128, 0.20);
  --rail-on: rgba(10, 132, 255, 0.22);
  --veil: rgba(28, 28, 30, 0.74);

  --ink: #F5F5F7;
  --ink-2: #AEAEB2;
  --ink-3: #8E8E93;
  --ink-4: #85858A;
  --ink-invert: #1D1D1F;
  --ink-invert-2: #6E6E73;

  --line: rgba(255, 255, 255, 0.09);
  --line-2: rgba(255, 255, 255, 0.17);
  --line-rail: rgba(255, 255, 255, 0.08);
  --fill: rgba(120, 120, 128, 0.20);
  --fill-2: rgba(120, 120, 128, 0.30);

  --accent: #0A84FF;
  --accent-press: #3D9BFF;
  --accent-soft: rgba(10, 132, 255, 0.18);
  --accent-ring: rgba(10, 132, 255, 0.40);
  --link: #4DA3FF;

  --good: #55D97A;
  --good-bg: rgba(48, 209, 88, 0.18);
  --info: #4DA3FF;
  --info-bg: rgba(10, 132, 255, 0.18);
  --warn: #FFB340;
  --warn-bg: rgba(255, 159, 10, 0.20);
  --bad: #FF6961;
  --bad-bg: rgba(255, 69, 58, 0.18);
  --neutral: #98989D;
  --neutral-bg: rgba(120, 120, 128, 0.24);
  --active-tone: #A5A3FF;
  --active-bg: rgba(94, 92, 230, 0.24);

  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.5), 0 0 0 0.5px rgba(255, 255, 255, 0.07);
  --shadow-lift: 0 10px 28px rgba(0, 0, 0, 0.55), 0 0 0 0.5px rgba(255, 255, 255, 0.08);
  --shadow-pop: 0 30px 80px rgba(0, 0, 0, 0.7), 0 4px 14px rgba(0, 0, 0, 0.4), 0 0 0 0.5px rgba(255, 255, 255, 0.09);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;

    --canvas: #000000;
    --paper: #1C1C1E;
    --sunken: #2C2C2E;
    --raised: #242426;
    --rail: rgba(28, 28, 30, 0.72);
    --rail-solid: #1C1C1E;
    --rail-hover: rgba(120, 120, 128, 0.20);
    --rail-on: rgba(10, 132, 255, 0.22);
    --veil: rgba(28, 28, 30, 0.74);

    --ink: #F5F5F7;
    --ink-2: #AEAEB2;
    --ink-3: #8E8E93;
    --ink-4: #636366;
    --ink-invert: #1D1D1F;
    --ink-invert-2: #6E6E73;

    --line: rgba(255, 255, 255, 0.09);
    --line-2: rgba(255, 255, 255, 0.17);
    --line-rail: rgba(255, 255, 255, 0.08);
    --fill: rgba(120, 120, 128, 0.20);
    --fill-2: rgba(120, 120, 128, 0.30);

    --accent: #0A84FF;
    --accent-press: #3D9BFF;
    --accent-soft: rgba(10, 132, 255, 0.18);
    --accent-ring: rgba(10, 132, 255, 0.40);
    --link: #4DA3FF;

    --good: #55D97A;
    --good-bg: rgba(48, 209, 88, 0.18);
    --info: #4DA3FF;
    --info-bg: rgba(10, 132, 255, 0.18);
    --warn: #FFB340;
    --warn-bg: rgba(255, 159, 10, 0.20);
    --bad: #FF6961;
    --bad-bg: rgba(255, 69, 58, 0.18);
    --neutral: #98989D;
    --neutral-bg: rgba(120, 120, 128, 0.24);
    --active-tone: #A5A3FF;
    --active-bg: rgba(94, 92, 230, 0.24);

    --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.5), 0 0 0 0.5px rgba(255, 255, 255, 0.07);
    --shadow-lift: 0 10px 28px rgba(0, 0, 0, 0.55), 0 0 0 0.5px rgba(255, 255, 255, 0.08);
    --shadow-pop: 0 30px 80px rgba(0, 0, 0, 0.7), 0 4px 14px rgba(0, 0, 0, 0.4), 0 0 0 0.5px rgba(255, 255, 255, 0.09);
  }
}

* { box-sizing: border-box; }

html, body { margin: 0; height: 100%; }

body {
  font-family: var(--font-sans);
  font-size: 13.5px;
  line-height: 1.47;
  color: var(--ink);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.006em;
  accent-color: var(--accent);
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; }
h1 { font-size: 26px; line-height: 1.12; letter-spacing: -0.022em; }
h2 { font-size: 16px; letter-spacing: -0.014em; }
h3 { font-size: 14px; letter-spacing: -0.01em; }
p { margin: 0 0 10px; }
a { color: var(--link); text-decoration: none; transition: opacity var(--fast) var(--ease); }
a:hover { text-decoration: none; opacity: 0.68; }
button { font: inherit; letter-spacing: inherit; }
::selection { background: var(--accent-soft); }

.mono { font-family: var(--font-mono); font-size: 0.9em; letter-spacing: -0.01em; }
.num { font-variant-numeric: tabular-nums; }
.muted { color: var(--ink-3); }
.dim { color: var(--ink-2); }
.tiny { font-size: 11.5px; letter-spacing: 0; }
.small { font-size: 12.5px; letter-spacing: -0.003em; }
.strong { font-weight: 600; }
.right { text-align: right; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hidden { display: none !important; }
.grow { flex: 1; }
.gap-s { gap: 6px; }
.row { display: flex; align-items: center; gap: 10px; }
.col { display: flex; flex-direction: column; }
.wrap { flex-wrap: wrap; }
.stack > * + * { margin-top: 14px; }
.stack-s > * + * { margin-top: 8px; }

.eyebrow {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ── Motion primitives ───────────────────────────────────────────────────── */

@keyframes rise { from { opacity: 0; transform: translate3d(0, 10px, 0); } }
@keyframes fade { from { opacity: 0; } }
@keyframes sheet { from { opacity: 0; transform: scale(0.94) translate3d(0, 16px, 0); } }
@keyframes slidein { from { transform: translate3d(28px, 0, 0); opacity: 0; } }
@keyframes toastin { from { transform: translate3d(0, 16px, 0) scale(0.96); opacity: 0; } }
@keyframes pop { from { transform: scale(0.96); opacity: 0; } }
@keyframes shimmer { to { background-position: -100% 0; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse-ring {
  0% { box-shadow: 0 0 0 0 var(--accent-ring); }
  70% { box-shadow: 0 0 0 7px rgba(0, 113, 227, 0); }
  100% { box-shadow: 0 0 0 0 rgba(0, 113, 227, 0); }
}

/* Anything that enters the page does so from just below it. */
.page { animation: rise var(--slow) var(--spring) both; }

/* ── App shell ───────────────────────────────────────────────────────────── */

.shell { display: grid; grid-template-columns: var(--rail-w) 1fr; min-height: 100vh; }

.rail {
  background: var(--rail);
  -webkit-backdrop-filter: saturate(180%) blur(22px);
  backdrop-filter: saturate(180%) blur(22px);
  color: var(--ink);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  border-right: 1px solid var(--line-rail);
  z-index: 50;
}
@supports not (backdrop-filter: blur(1px)) {
  .rail { background: var(--rail-solid); }
}

.rail-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 18px;
  height: var(--top-h);
  flex-shrink: 0;
}
/* The mark and the name are ink, in one colour, never the accent. */
.rail-mark { width: 13px; height: 24px; flex-shrink: 0; color: var(--ink); }
.rail-word { font-size: 16px; font-weight: 500; letter-spacing: -0.02em; color: var(--ink); }

.rail-scroll { flex: 1; overflow-y: auto; padding: 4px 10px 18px; overscroll-behavior: contain; }
.rail-scroll::-webkit-scrollbar { width: 8px; }
.rail-scroll::-webkit-scrollbar-thumb { background: var(--fill-2); border-radius: 4px; border: 2px solid transparent; background-clip: content-box; }

.rail-group { padding: 12px 0 2px; }
.rail-group-label {
  padding: 0 10px 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-3);
}

.rail-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  margin-bottom: 1px;
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-size: 13.5px;
  font-weight: 450;
  cursor: pointer;
  user-select: none;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease),
    transform var(--fast) var(--spring);
}
.rail-link:hover { background: var(--rail-hover); color: var(--ink); text-decoration: none; }
.rail-link:active { transform: scale(0.985); }
.rail-link.on { background: var(--rail-on); color: var(--accent); font-weight: 590; }
.rail-link svg { width: 17px; height: 17px; flex-shrink: 0; opacity: 0.75; transition: opacity var(--fast) var(--ease); }
.rail-link:hover svg, .rail-link.on svg { opacity: 1; }

.rail-badge {
  margin-left: auto;
  background: var(--bad-solid);
  color: #FFF;
  font-size: 11px;
  font-weight: 600;
  line-height: 17px;
  padding: 0 6px;
  border-radius: var(--pill);
  min-width: 18px;
  text-align: center;
  letter-spacing: 0;
  animation: pop var(--mid) var(--spring) both;
}
.rail-badge.quiet { background: var(--fill-2); color: var(--ink-2); }

.rail-foot { padding: 10px; flex-shrink: 0; border-top: 1px solid var(--line-rail); }
.rail-user {
  display: flex; align-items: center; gap: 10px; padding: 7px 8px;
  border-radius: var(--r-sm); cursor: pointer; width: 100%; text-align: left;
  background: none; border: 0; color: var(--ink);
  transition: background var(--fast) var(--ease), transform var(--fast) var(--spring);
}
.rail-user:hover { background: var(--rail-hover); }
.rail-user:active { transform: scale(0.985); }
.rail-user-name { font-size: 13px; font-weight: 550; color: var(--ink); }
.rail-user-role { font-size: 11.5px; color: var(--ink-3); }

/* ── Top bar ─────────────────────────────────────────────────────────────── */

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

.topbar {
  height: var(--top-h);
  background: var(--veil);
  -webkit-backdrop-filter: saturate(180%) blur(22px);
  backdrop-filter: saturate(180%) blur(22px);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 22px;
  position: sticky;
  top: 0;
  z-index: 40;
}

.searchbtn {
  display: flex; align-items: center; gap: 8px;
  height: 34px; padding: 0 13px;
  border: 0; border-radius: var(--pill);
  background: var(--fill); color: var(--ink-3);
  cursor: pointer; font-size: 13px; min-width: 300px;
  transition: background var(--fast) var(--ease), transform var(--fast) var(--spring);
}
.searchbtn:hover { background: var(--fill-2); color: var(--ink-2); }
.searchbtn:active { transform: scale(0.99); }
.searchbtn kbd {
  margin-left: auto; font-family: var(--font-sans); font-size: 11px; font-weight: 500;
  border-radius: var(--r-xs); padding: 1px 5px;
  color: var(--ink-3); background: var(--paper);
}

.iconbtn {
  width: 34px; height: 34px; display: grid; place-items: center;
  border: 0; border-radius: 50%;
  background: none; cursor: pointer; color: var(--ink-2); position: relative;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease),
    transform var(--fast) var(--spring);
}
.iconbtn:hover { background: var(--fill); color: var(--ink); }
.iconbtn:active { transform: scale(0.92); }
.iconbtn svg { width: 17px; height: 17px; }
.iconbtn.sm { width: 27px; height: 27px; }
.iconbtn.sm svg { width: 14px; height: 14px; }
.iconbtn .dot {
  position: absolute; top: 6px; right: 7px; width: 7px; height: 7px;
  border-radius: 50%; background: var(--bad-solid); border: 1.5px solid var(--paper);
  animation: pop var(--mid) var(--spring) both;
}

/* ── Page ────────────────────────────────────────────────────────────────── */

.page { padding: 26px 26px 72px; flex: 1; min-width: 0; }
.page-wide { padding: 0; }

.page-head {
  display: flex; align-items: flex-start; gap: 18px;
  margin-bottom: 22px; flex-wrap: wrap;
}
/* Keep the title readable: actions wrap to their own line before the heading
   is allowed to squash into a column. */
.page-head .titles { flex: 1; min-width: 260px; }
.page-head h1 { display: flex; align-items: center; gap: 10px; }
.page-sub { color: var(--ink-3); font-size: 14px; margin-top: 5px; letter-spacing: -0.008em; }
.page-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

.breadcrumb { display: flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--ink-3); margin-bottom: 7px; }
.breadcrumb a { color: var(--ink-3); }
.breadcrumb a:hover { color: var(--accent); opacity: 1; }

/* ── Buttons ─────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 34px; padding: 0 15px;
  border: 0; border-radius: var(--pill);
  background: var(--fill); color: var(--ink);
  font-size: 13px; font-weight: 550; cursor: pointer; white-space: nowrap;
  letter-spacing: -0.008em;
  transition: background var(--fast) var(--ease), transform var(--fast) var(--spring),
    box-shadow var(--fast) var(--ease), opacity var(--fast) var(--ease);
}
.btn:hover { background: var(--fill-2); }
.btn:active { transform: scale(0.96); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; transform: none; }
.btn svg { width: 15px; height: 15px; }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--accent-ring); }

.btn-primary { background: var(--accent); color: #FFF; }
.btn-primary:hover { background: var(--accent-press); }
.btn-primary:active { background: var(--accent-press); }

/* Apple Pay's button: pure black, pure white, nothing else. Reserved for the
   single most consequential action on a screen. */
.btn-dark { background: #1D1D1F; color: #FFF; }
.btn-dark:hover { background: #333336; }
[data-theme='dark'] .btn-dark { background: #F5F5F7; color: #1D1D1F; }
[data-theme='dark'] .btn-dark:hover { background: #FFFFFF; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .btn-dark { background: #F5F5F7; color: #1D1D1F; }
  :root:not([data-theme='light']) .btn-dark:hover { background: #FFFFFF; }
}

.btn-ghost { background: transparent; color: var(--ink-2); }
.btn-ghost:hover { background: var(--fill); color: var(--ink); }

.btn-danger { color: var(--bad); background: var(--bad-bg); }
.btn-danger:hover { background: var(--bad-bg); filter: brightness(0.96); }

.btn-sm { height: 28px; padding: 0 11px; font-size: 12.5px; }
.btn-sm svg { width: 13px; height: 13px; }
.btn-lg { height: 44px; padding: 0 24px; font-size: 15px; font-weight: 500; }
.btn-lg svg { width: 17px; height: 17px; }
.btn-block { width: 100%; }

.btn-group { display: inline-flex; background: var(--fill); border-radius: var(--pill); padding: 2px; gap: 2px; }
.btn-group .btn { border-radius: var(--pill); background: transparent; height: 28px; }
.btn-group .btn:first-child { border-radius: var(--pill); }
.btn-group .btn:last-child { border-radius: var(--pill); }
.btn-group .btn:hover { background: var(--fill); }
.btn-group .btn.on { background: var(--paper); color: var(--ink); box-shadow: var(--shadow-card); z-index: 1; }

/* ── Panels ──────────────────────────────────────────────────────────────── */

.panel {
  background: var(--paper);
  border: 0;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  transition: box-shadow var(--mid) var(--ease);
}
.panel-head {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 18px 12px;
  min-height: 46px;
}
.panel-head h2 { font-size: 15px; letter-spacing: -0.014em; }
.panel-head .spacer { flex: 1; }
.panel-body { padding: 4px 18px 18px; }
.panel-head + .panel-body { padding-top: 0; }
.panel > .panel-body:first-child { padding-top: 18px; }
.panel-body.tight { padding: 0; }
.panel-foot { padding: 13px 18px; border-top: 1px solid var(--line); background: var(--sunken); }

.grid { display: grid; gap: 16px; }
.g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.split { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 16px; align-items: start; }
.split-wide { grid-template-columns: minmax(0, 1fr) 400px; }
@media (max-width: 1180px) {
  .split, .split-wide { grid-template-columns: minmax(0, 1fr); }
  .g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
  .g2, .g3, .g4 { grid-template-columns: minmax(0, 1fr); }
}

/* ── Stat strip ──────────────────────────────────────────────────────────── */
/* Separate cards rather than one ruled block — each number is its own object,
   and they arrive one after another so the eye reads them in order. */

/* Cards wrap onto a second row rather than squeezing: a clipped "$7,545.78"
   is worse than two rows of three. */
.stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
  gap: 12px; background: none; border: 0; overflow: visible;
}
.stat {
  padding: 15px 17px; min-width: 0;
  background: var(--paper); border-radius: var(--r-lg); box-shadow: var(--shadow-card);
  transition: transform var(--mid) var(--spring), box-shadow var(--mid) var(--ease);
  animation: rise var(--slow) var(--spring) both;
}
.stat:nth-child(1) { animation-delay: 20ms; }
.stat:nth-child(2) { animation-delay: 70ms; }
.stat:nth-child(3) { animation-delay: 120ms; }
.stat:nth-child(4) { animation-delay: 170ms; }
.stat:nth-child(5) { animation-delay: 220ms; }
.stat[style*='cursor']:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.stat-label { font-size: 12.5px; color: var(--ink-3); font-weight: 500; letter-spacing: -0.004em; }
.stat-value {
  font-size: clamp(23px, 2.1vw, 30px); font-weight: 600; letter-spacing: -0.032em;
  margin-top: 5px; line-height: 1.08;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.stat-value.sm { font-size: clamp(19px, 1.6vw, 23px); letter-spacing: -0.026em; }
.stat-meta { font-size: 12px; margin-top: 5px; color: var(--ink-3); display: flex; align-items: center; gap: 5px; }
.delta { font-weight: 600; }
.delta.up { color: var(--good); }
.delta.down { color: var(--bad); }
@media (max-width: 560px) {
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── Tables ──────────────────────────────────────────────────────────────── */

.tablewrap { overflow-x: auto; }
/* Dense tables scroll rather than squash: a wrapped customer name over three
   lines is harder to scan than a horizontal scrollbar. */
table.data { width: 100%; min-width: 1040px; border-collapse: collapse; font-size: 13px; }
table.data th {
  text-align: left; font-weight: 500; font-size: 12px; color: var(--ink-3);
  letter-spacing: -0.003em;
  padding: 10px 16px; border-bottom: 1px solid var(--line);
  background: var(--paper); white-space: nowrap; position: sticky; top: 0; z-index: 2;
}
table.data td { padding: 12px 16px; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data tbody tr { transition: background var(--fast) var(--ease); }
table.data tbody tr.clickable { cursor: pointer; }
table.data tbody tr.clickable:hover { background: var(--fill); }
table.data tbody tr.on { background: var(--accent-soft); }
table.data th.r, table.data td.r { text-align: right; }
table.data td.money { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Secondary lines stay on one line — a wrapped address turns a scannable row
   into a three-line block and destroys the rhythm of the table. */
table.data .cell-main { font-weight: 550; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
table.data .cell-sub { font-size: 12px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 1px; }
table.data th.sortable { cursor: pointer; user-select: none; }
table.data th.sortable:hover { color: var(--ink); }

/* ── Chips ───────────────────────────────────────────────────────────────── */

.chip {
  display: inline-flex; align-items: center; gap: 5px;
  height: 22px; padding: 0 9px;
  font-size: 12px; font-weight: 550; border-radius: var(--pill);
  background: var(--neutral-bg); color: var(--neutral);
  white-space: nowrap; letter-spacing: -0.003em;
}
.chip.good { background: var(--good-bg); color: var(--good); }
.chip.info { background: var(--info-bg); color: var(--info); }
.chip.warn { background: var(--warn-bg); color: var(--warn); }
.chip.bad { background: var(--bad-bg); color: var(--bad); }
.chip.active { background: var(--active-bg); color: var(--active-tone); }
.chip.neutral { background: var(--neutral-bg); color: var(--neutral); }

.tag {
  display: inline-flex; align-items: center; height: 21px; padding: 0 9px;
  font-size: 12px; border-radius: var(--pill); background: var(--fill);
  border: 0; color: var(--ink-2); white-space: nowrap;
}
.tag.amber { background: var(--warn-bg); color: var(--warn); }
.tag.blue, .tag.teal { background: var(--info-bg); color: var(--info); }
.tag.green { background: var(--good-bg); color: var(--good); }
.tag.red { background: var(--bad-bg); color: var(--bad); }
.tag.plum { background: var(--active-bg); color: var(--active-tone); }

.avatar {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center; color: #FFF;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.01em;
}
.avatar.sm { width: 22px; height: 22px; font-size: 9.5px; }
.avatar.lg { width: 38px; height: 38px; font-size: 13px; }
.avatar-stack { display: flex; }
.avatar-stack .avatar { margin-left: -7px; border: 2px solid var(--paper); }
.avatar-stack .avatar:first-child { margin-left: 0; }

/* ── Forms ───────────────────────────────────────────────────────────────── */

.field { display: block; margin-bottom: 14px; }
.field > label, .flabel {
  display: block; font-size: 12.5px; font-weight: 550; color: var(--ink-2); margin-bottom: 6px;
  letter-spacing: -0.004em;
}
.field .hint { font-size: 12px; color: var(--ink-3); margin-top: 5px; }
.field .err { font-size: 12px; color: var(--bad); margin-top: 5px; }

/* Matched by exclusion rather than by listing types. `h('input', {…})` with no
   type is the common case in this codebase, and an allow-list silently leaves
   those unstyled — which is how half a form ends up looking like 1998. */
input:not([type="checkbox"], [type="radio"], [type="file"], [type="range"],
            [type="color"], [type="submit"], [type="button"], [type="image"], [type="reset"]),
select, textarea {
  width: 100%; font: inherit; font-size: 13.5px; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line-2); border-radius: var(--r-sm);
  padding: 0 11px; height: 34px; outline: none;
  transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease),
    background var(--fast) var(--ease);
}
textarea { height: auto; padding: 9px 11px; min-height: 78px; resize: vertical; line-height: 1.55; }
select { appearance: none; padding-right: 30px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%2386868B' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center; }
input:not([type="checkbox"], [type="radio"]):focus, select:focus, textarea:focus {
  border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-ring);
}
input.invalid, select.invalid, textarea.invalid { border-color: var(--bad); }
input::placeholder, textarea::placeholder { color: var(--ink-4); }
input:disabled, select:disabled, textarea:disabled { background: var(--sunken); color: var(--ink-3); cursor: not-allowed; }

.inline-fields { display: grid; gap: 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.inline-fields.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.inline-fields .field { margin-bottom: 0; }

.input-affix { position: relative; }
.input-affix .prefix {
  position: absolute; left: 11px; top: 0; height: 34px; display: grid; place-items: center;
  color: var(--ink-3); font-size: 13.5px; pointer-events: none;
}
.input-affix.has-prefix input { padding-left: 25px; }
.input-affix .suffix {
  position: absolute; right: 11px; top: 0; height: 34px; display: grid; place-items: center;
  color: var(--ink-3); font-size: 12.5px; pointer-events: none;
}

.check { display: flex; align-items: flex-start; gap: 9px; cursor: pointer; font-size: 13.5px; }
.check input { width: 16px; height: 16px; margin: 1px 0 0; accent-color: var(--accent); flex-shrink: 0; cursor: pointer; }
.check .check-sub { font-size: 12.5px; color: var(--ink-3); }

/* The iOS switch, down to the travel of the knob. */
.switch { display: inline-flex; align-items: flex-start; gap: 11px; cursor: pointer; }
.switch input { position: absolute; opacity: 0; pointer-events: none; }
.switch .track {
  width: 44px; height: 26px; border-radius: var(--pill); background: var(--fill-2);
  position: relative; flex-shrink: 0; margin-top: 1px;
  transition: background var(--mid) var(--spring);
}
.switch .track::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 22px; height: 22px;
  border-radius: 50%; background: #FFF;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.18), 0 0 0 0.5px rgba(0, 0, 0, 0.05);
  transition: transform var(--mid) var(--spring), width var(--fast) var(--ease);
}
.switch:active .track::after { width: 26px; }
.switch input:checked + .track { background: var(--good-solid); }
.switch input:checked + .track::after { transform: translateX(18px); }
.switch:active input:checked + .track::after { transform: translateX(14px); }
.switch input:focus-visible + .track { box-shadow: 0 0 0 4px var(--accent-ring); }

/* The iOS segmented control. */
.seg { display: inline-flex; background: var(--fill); border: 0; border-radius: var(--r-sm); padding: 2px; gap: 2px; }
.seg button {
  height: 28px; padding: 0 13px; border: 0; background: none; border-radius: 6px;
  font-size: 13px; color: var(--ink-2); cursor: pointer; font-weight: 550;
  letter-spacing: -0.006em;
  transition: background var(--mid) var(--spring), color var(--fast) var(--ease),
    box-shadow var(--mid) var(--ease), transform var(--fast) var(--spring);
}
.seg button:active { transform: scale(0.96); }
.seg button.on { background: var(--paper); color: var(--ink); box-shadow: var(--shadow-card); }

/* ── Tabs ────────────────────────────────────────────────────────────────── */

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 18px; overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.board::-webkit-scrollbar, .tablewrap::-webkit-scrollbar { height: 9px; }
.board::-webkit-scrollbar-thumb, .tablewrap::-webkit-scrollbar-thumb { background: var(--fill-2); border-radius: var(--pill); }
.tabs button {
  border: 0; background: none; padding: 9px 13px 11px; font-size: 13.5px; font-weight: 550;
  color: var(--ink-3); cursor: pointer; border-bottom: 2px solid transparent;
  margin-bottom: -1px; white-space: nowrap; display: flex; align-items: center; gap: 7px;
  letter-spacing: -0.008em;
  transition: color var(--fast) var(--ease), border-color var(--mid) var(--spring);
}
.tabs button:hover { color: var(--ink); }
.tabs button.on { color: var(--accent); border-bottom-color: var(--accent); }
.tabs .count {
  font-size: 11.5px; background: var(--fill); color: var(--ink-3);
  padding: 1px 7px; border-radius: var(--pill); font-weight: 600;
}
.tabs button.on .count { background: var(--accent-soft); color: var(--accent); }

.filterbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 14px;
}
.filterbar input[type="search"], .filterbar select, .filterbar input[type="date"] {
  height: 32px; width: auto; min-width: 140px; font-size: 13px;
  border-radius: var(--pill); background: var(--fill); border-color: transparent;
}
.filterbar input[type="search"]:focus, .filterbar select:focus, .filterbar input[type="date"]:focus {
  background: var(--paper); border-color: var(--accent);
}
.filterbar .searchfield { min-width: 250px; flex: 0 1 320px; }

/* ── Modals & drawers ────────────────────────────────────────────────────── */

.scrim {
  position: fixed; inset: 0; background: rgba(0, 0, 0, 0.32);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  /* Above a drawer: a dialog opened from one (change a visit, confirm a removal) covers it. */
  z-index: 102; display: flex; align-items: flex-start; justify-content: center;
  padding: 7vh 20px 20px; overflow-y: auto;
  animation: fade var(--mid) var(--ease);
}

.modal {
  background: var(--paper); border-radius: var(--r-xl); box-shadow: var(--shadow-pop);
  width: 100%; max-width: 540px; overflow: hidden;
  animation: sheet var(--slow) var(--spring) both;
}
.modal.wide { max-width: 800px; }
.modal.xwide { max-width: 1020px; }
.modal-head {
  display: flex; align-items: center; gap: 10px; padding: 18px 20px 14px;
}
.modal-head h2 { flex: 1; font-size: 18px; letter-spacing: -0.018em; }
.modal-body { padding: 0 20px 20px; max-height: 66vh; overflow-y: auto; }
.modal-foot {
  display: flex; align-items: center; gap: 9px; justify-content: flex-end;
  padding: 14px 20px; border-top: 1px solid var(--line); background: var(--sunken);
}
.modal-foot .left { margin-right: auto; }

/* ── Say it (voice capture) ──────────────────────────────────────────────────
   One sheet in three moments: listening, checking what will be made, done.
   The microphone is red only while it is listening: red means recording. */

.vc .callout { margin-bottom: 10px; }
.vc-capture { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.vc-capture .grow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }
.vc-mic {
  width: 56px; height: 56px; flex-shrink: 0; border: 0; border-radius: 50%; cursor: pointer;
  display: grid; place-items: center; background: var(--accent); color: #FFF;
  transition: background var(--fast) var(--ease), transform var(--fast) var(--spring);
}
.vc-mic:hover { background: var(--accent-press); }
.vc-mic:active { transform: scale(0.94); }
.vc-mic:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--accent-ring); }
.vc-mic.on { background: var(--bad-solid); animation: vc-listening 1.6s var(--ease) infinite; }
@keyframes vc-listening {
  0% { box-shadow: 0 0 0 0 rgba(255, 59, 48, 0.42); }
  70% { box-shadow: 0 0 0 12px rgba(255, 59, 48, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 59, 48, 0); }
}
.vc-status { flex: 1 1 220px; font-size: 13.5px; line-height: 1.45; }
.vc-problem { color: var(--bad); }
.vc-lang { width: auto; max-width: 210px; height: 30px; font-size: 12.5px; border-radius: var(--pill); background-color: var(--fill); border-color: transparent; }
.vc-transcript { font-size: 15px; line-height: 1.55; min-height: 120px; }
.vc-hint { font-size: 12.5px; color: var(--ink-3); margin: 10px 0 0; line-height: 1.5; }
.vc-working { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 48px 0; color: var(--ink-2); font-size: 14px; }

.callout.vc-warn { background: var(--warn-bg); }
.callout.vc-warn svg { color: var(--warn); }
.vc-summary { font-size: 14px; color: var(--ink-2); margin: 0 0 12px; line-height: 1.5; }
.vc-cards { display: grid; gap: 10px; }
.vc-card {
  background: var(--sunken); border-radius: var(--r); padding: 12px 14px;
  animation: rise var(--slow) var(--spring) both;
}
.vc-card.off { opacity: 0.62; }
.vc-card-head { display: flex; align-items: center; gap: 10px; }
.vc-card-head input[type="checkbox"] { width: 17px; height: 17px; margin: 0; accent-color: var(--accent); flex-shrink: 0; cursor: pointer; }
.vc-card-icon {
  width: 28px; height: 28px; border-radius: var(--r-sm); flex-shrink: 0;
  display: grid; place-items: center; background: var(--paper); color: var(--ink-2); box-shadow: var(--shadow-card);
}
.vc-card-title { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }
.vc-card-sub { font-size: 12.5px; color: var(--ink-3); margin-top: 1px; }
.vc-card-body { margin-top: 12px; }
.vc-card-body .field { margin-bottom: 10px; }
.vc-card-body .inline-fields { margin-bottom: 10px; }
.vc-card-body .inline-fields .field { margin-bottom: 0; }
.vc-seg { margin-bottom: 10px; }
.vc-keep { margin-top: 4px; font-size: 13px; }
.vc-candidates { display: grid; gap: 8px; margin-bottom: 10px; }
.vc-issue {
  display: flex; align-items: flex-start; gap: 7px; margin-top: 8px;
  font-size: 12.5px; line-height: 1.45; color: var(--ink-2);
}
.vc-issue svg { flex-shrink: 0; margin-top: 2px; color: var(--info); }
.vc-issue.warn svg { color: var(--warn); }
.vc-issue.bad { color: var(--bad); }
.vc-issue.bad svg { color: var(--bad); }
.vc-lines { display: grid; gap: 2px; margin-bottom: 10px; background: var(--paper); border-radius: var(--r-sm); padding: 4px 4px 4px 12px; }
.vc-line { display: flex; align-items: center; gap: 10px; font-size: 13px; padding: 6px 0; }
.vc-line + .vc-line { border-top: 1px solid var(--line); }
.vc-line-total { font-variant-numeric: tabular-nums; white-space: nowrap; }
.vc-charge { display: grid; grid-template-columns: minmax(0, 1fr) 132px auto; gap: 10px; align-items: end; margin-bottom: 10px; }
.vc-card-body .vc-charge .field { margin-bottom: 0; }
.vc-charge .iconbtn { margin-bottom: 5px; }
.vc-total { display: flex; justify-content: space-between; gap: 10px; margin: 12px 0 10px; padding-top: 10px; border-top: 1px solid var(--line); font-size: 13px; font-variant-numeric: tabular-nums; }
.vc-said { margin-top: 14px; font-size: 13px; color: var(--ink-3); }
.vc-said summary { cursor: pointer; font-weight: 550; }
.vc-said p { margin: 8px 0 0; line-height: 1.55; white-space: pre-wrap; }

.vc-done { display: flex; align-items: center; gap: 9px; font-size: 15px; margin-bottom: 12px; color: var(--good); }
.vc-done strong { color: var(--ink); }
.vc-created { display: grid; gap: 6px; }
.vc-created-row {
  display: flex; align-items: center; gap: 10px; padding: 11px 12px;
  border-radius: var(--r-sm); background: var(--fill); color: var(--ink); font-size: 13.5px;
  transition: background var(--fast) var(--ease);
}
.vc-created-row:hover { background: var(--fill-2); opacity: 1; }
.vc-created-row svg { color: var(--ink-3); flex-shrink: 0; }
@media (max-width: 860px) {
  /* Short fields stay side by side on a phone, so a card is not a page long. */
  .vc-card-body .inline-fields.vc-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .vc-card-body .inline-fields.three.vc-cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .vc-mic { width: 52px; height: 52px; }
  .vc-lang { max-width: 100%; }
}

.drawer-scrim {
  position: fixed; inset: 0; background: rgba(0, 0, 0, 0.28);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  z-index: 100; animation: fade var(--mid) var(--ease);
}
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(580px, 94vw);
  background: var(--paper); box-shadow: var(--shadow-pop); z-index: 101;
  display: flex; flex-direction: column; animation: slidein var(--slow) var(--spring) both;
}
.drawer-head { padding: 18px 20px 14px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 10px; }
.drawer-body { flex: 1; overflow-y: auto; padding: 18px 20px; }
.drawer-foot { padding: 14px 20px; border-top: 1px solid var(--line); background: var(--sunken); display: flex; gap: 9px; justify-content: flex-end; }

/* ── Menus ───────────────────────────────────────────────────────────────── */

.menu {
  position: absolute; z-index: 120; min-width: 212px; padding: 6px;
  background: var(--paper); border: 0; border-radius: var(--r);
  box-shadow: var(--shadow-pop);
  animation: pop 180ms var(--spring) both;
  transform-origin: top right;
}
.menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 7px 10px; border: 0; background: none; border-radius: var(--r-xs);
  font-size: 13.5px; color: var(--ink); cursor: pointer; text-align: left;
  transition: background var(--fast) var(--ease);
}
.menu-item:hover { background: var(--accent); color: #FFF; }
.menu-item:hover svg { color: #FFF; }
.menu-item.danger { color: var(--bad); }
.menu-item.danger:hover { background: var(--bad-solid); color: #FFF; }
.menu-item svg { width: 15px; height: 15px; color: var(--ink-3); transition: color var(--fast) var(--ease); }
.menu-sep { height: 1px; background: var(--line); margin: 6px 4px; }
.menu-label { padding: 7px 10px 4px; font-size: 11.5px; font-weight: 600; letter-spacing: 0.03em; color: var(--ink-4); }

/* ── Command palette ─────────────────────────────────────────────────────── */

.cmdk {
  max-width: 620px; width: 100%; background: var(--paper); border-radius: var(--r-xl);
  box-shadow: var(--shadow-pop); overflow: hidden;
  animation: sheet var(--slow) var(--spring) both;
}
.cmdk input {
  border: 0; border-bottom: 1px solid var(--line); border-radius: 0;
  height: 56px; font-size: 17px; padding: 0 20px; letter-spacing: -0.015em;
}
.cmdk input:focus { box-shadow: none; border-color: var(--line); }
.cmdk-list { max-height: 400px; overflow-y: auto; padding: 7px; }
.cmdk-item {
  display: flex; align-items: center; gap: 11px; padding: 9px 12px;
  border-radius: var(--r-sm); cursor: pointer;
  transition: background var(--fast) var(--ease);
}
.cmdk-item.on { background: var(--accent); color: #FFF; }
.cmdk-item.on .cmdk-kind, .cmdk-item.on .cmdk-sub { color: rgba(255, 255, 255, 0.76); }
.cmdk-kind {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600;
  color: var(--ink-4); width: 66px; flex-shrink: 0;
}
.cmdk-title { font-size: 14px; font-weight: 550; letter-spacing: -0.01em; }
.cmdk-sub { font-size: 12.5px; color: var(--ink-3); margin-left: auto; }
.cmdk-empty { padding: 30px; text-align: center; color: var(--ink-3); font-size: 13.5px; }

/* ── Toasts ──────────────────────────────────────────────────────────────── */

.toasts { position: fixed; bottom: 22px; right: 22px; z-index: 200; display: flex; flex-direction: column; gap: 9px; align-items: flex-end; }
.toast {
  display: flex; align-items: flex-start; gap: 10px; max-width: 400px;
  background: rgba(29, 29, 31, 0.86); color: #FFF; padding: 13px 16px; border-radius: var(--r);
  -webkit-backdrop-filter: saturate(180%) blur(20px); backdrop-filter: saturate(180%) blur(20px);
  box-shadow: var(--shadow-pop); font-size: 13.5px;
  animation: toastin var(--slow) var(--spring) both;
}
.toast.bad { background: rgba(206, 42, 33, 0.9); }
.toast.good { background: rgba(19, 115, 51, 0.9); }
.toast svg { width: 17px; height: 17px; flex-shrink: 0; margin-top: 1px; }
.toast .toast-body { flex: 1; }
.toast .toast-title { font-weight: 600; letter-spacing: -0.008em; }
.toast .toast-sub { opacity: 0.8; margin-top: 2px; font-size: 12.5px; }

/* ── Empty & loading states ──────────────────────────────────────────────── */

.empty { padding: 54px 24px; text-align: center; color: var(--ink-3); }
.empty svg { width: 30px; height: 30px; opacity: 0.32; margin-bottom: 14px; }
.empty h3 { font-size: 16px; color: var(--ink); margin-bottom: 6px; letter-spacing: -0.014em; }
.empty p { font-size: 13.5px; max-width: 400px; margin: 0 auto 18px; line-height: 1.5; }

.skeleton {
  background: linear-gradient(90deg, var(--fill) 25%, var(--fill-2) 50%, var(--fill) 75%);
  background-size: 400% 100%; animation: shimmer 1.4s var(--ease) infinite; border-radius: var(--r-xs);
}
.skel-row { height: 13px; margin: 14px 18px; }

.spinner {
  width: 15px; height: 15px; border: 2px solid rgba(255, 255, 255, 0.3);
  border-top-color: #FFF; border-radius: 50%; animation: spin 640ms linear infinite;
}
.spinner.dark { border-color: var(--fill-2); border-top-color: var(--ink); }

/* ── Charts ──────────────────────────────────────────────────────────────── */

.chart { width: 100%; display: block; }
.chart .grid-line { stroke: var(--line); stroke-width: 1; }
.chart .grid-line.zero { stroke: var(--line-2); }
.chart .axis-text { font-size: 11px; fill: var(--ink-4); font-family: var(--font-sans); }
.chart .fade-from { stop-color: var(--accent); stop-opacity: 0.22; }
.chart .fade-to { stop-color: var(--accent); stop-opacity: 0; }
.chart .line { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart .crosshair { stroke: var(--line-2); stroke-width: 1; }
.chart .marker { fill: var(--accent); stroke: var(--paper); stroke-width: 2; }
.chart .bar { fill: var(--accent); rx: 4; transition: opacity var(--fast) var(--ease); }
.chart .bar.alt { fill: var(--active-tone); }
.chart .bar:hover { opacity: 0.74; }

/* The line chart is drawn at its real pixel size, so this box is the chart. */
.chart-wrap { position: relative; touch-action: pan-y; border-radius: var(--r-xs); }
.chart-wrap:focus-visible { outline: 2px solid var(--accent-ring); outline-offset: 4px; }
.chart-wrap .chart { overflow: visible; }
.chart-tip {
  position: absolute; top: 0; left: 0; z-index: 2; pointer-events: none;
  display: flex; flex-direction: column; gap: 1px; white-space: nowrap;
  padding: 7px 10px; border-radius: var(--r-sm);
  background: var(--raised); box-shadow: var(--shadow-lift);
  font-size: 12px; line-height: 1.35; color: var(--ink-3);
}
.chart-tip[hidden] { display: none; }
.chart-tip strong { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.chart-note {
  position: absolute; display: grid; place-items: center; padding: 0 12px;
  text-align: center; font-size: 12.5px; color: var(--ink-3);
}

.legend { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12.5px; color: var(--ink-2); }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }

.meter { height: 6px; background: var(--fill); border-radius: var(--pill); overflow: hidden; }
.meter i { display: block; height: 100%; background: var(--ink-2); border-radius: var(--pill); transition: width var(--slow) var(--spring); }
.meter.good i { background: var(--good-solid); }
.meter.warn i { background: var(--warn-solid); }
.meter.bad i { background: var(--bad-solid); }

.sparkbars { display: flex; align-items: flex-end; gap: 3px; height: 30px; }
.sparkbars i { flex: 1; background: var(--fill-2); border-radius: 2px 2px 0 0; min-height: 2px; transition: height var(--slow) var(--spring); }
.sparkbars i.hot { background: var(--accent); }

/* ── Kanban / board ──────────────────────────────────────────────────────── */

.board { display: flex; gap: 14px; overflow-x: auto; padding-bottom: 14px; align-items: flex-start; }
.board-col { flex: 0 0 286px; background: var(--fill); border: 0; border-radius: var(--r-lg); transition: background var(--mid) var(--ease); }
.board-col.drop { background: var(--accent-soft); box-shadow: inset 0 0 0 2px var(--accent); }
.board-col-head { padding: 11px 14px; display: flex; align-items: center; gap: 8px; }
.board-col-head .n { font-size: 12px; color: var(--ink-3); }
.board-col-head .v { margin-left: auto; font-size: 12.5px; font-weight: 600; }
.board-list { padding: 0 8px 8px; display: flex; flex-direction: column; gap: 8px; min-height: 60px; max-height: calc(100vh - 280px); overflow-y: auto; }
.board-card {
  background: var(--paper); border: 0; border-radius: var(--r);
  padding: 12px 13px; cursor: pointer; box-shadow: var(--shadow-card);
  transition: transform var(--mid) var(--spring), box-shadow var(--mid) var(--ease), opacity var(--fast) var(--ease);
}
.board-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.board-card:active { transform: scale(0.985); }
.board-card.dragging { opacity: 0.4; transform: rotate(1.5deg) scale(1.02); }
.board-card .t { font-size: 13.5px; font-weight: 550; margin-bottom: 3px; letter-spacing: -0.008em; }
.board-card .s { font-size: 12.5px; color: var(--ink-3); }
.board-card .f { display: flex; align-items: center; gap: 7px; margin-top: 9px; }

/* ── Calendar ────────────────────────────────────────────────────────────── */

.cal-month { border: 0; border-radius: var(--r-lg); overflow: hidden; background: var(--paper); box-shadow: var(--shadow-card); }
.cal-dow { display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid var(--line); }
.cal-dow div { padding: 10px 12px; font-size: 12px; font-weight: 600; letter-spacing: 0.02em; color: var(--ink-3); }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); grid-auto-rows: minmax(110px, auto); }
.cal-cell { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 7px; min-width: 0; transition: background var(--fast) var(--ease); }
.cal-cell:nth-child(7n) { border-right: 0; }
.cal-cell.dim { background: var(--sunken); }
.cal-cell.today .cal-date { background: var(--bad-solid); color: #FFF; }
.cal-date { font-size: 12.5px; font-weight: 600; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 50%; margin-bottom: 5px; }
.cal-ev {
  font-size: 11.5px; padding: 3px 8px; border-radius: var(--r-xs); margin-bottom: 3px;
  background: var(--info-bg); color: var(--info); border: 0; font-weight: 500;
  cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: transform var(--fast) var(--spring);
}
.cal-ev:hover { transform: translateX(2px); }
.cal-ev.good { background: var(--good-bg); color: var(--good); }
.cal-ev.warn { background: var(--warn-bg); color: var(--warn); }
.cal-ev.bad { background: var(--bad-bg); color: var(--bad); }
.cal-ev.est { background: var(--active-bg); color: var(--active-tone); }
.cal-more { font-size: 11.5px; color: var(--ink-3); padding-left: 6px; cursor: pointer; }

.cal-week { display: grid; grid-template-columns: 58px repeat(var(--days, 7), minmax(0, 1fr)); border: 0; border-radius: var(--r-lg); overflow: hidden; background: var(--paper); box-shadow: var(--shadow-card); }
.cal-week-head { display: contents; }
.cal-week-head > div { background: var(--paper); border-bottom: 1px solid var(--line); border-right: 1px solid var(--line); padding: 9px 11px; font-size: 12.5px; position: sticky; top: var(--top-h); z-index: 3; }
.cal-hour-label { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); font-size: 11.5px; color: var(--ink-4); padding: 3px 8px; text-align: right; height: 50px; }
.cal-slot { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); height: 50px; position: relative; transition: background var(--fast) var(--ease); }
.cal-slot:hover { background: var(--fill); }
.cal-block {
  position: absolute; left: 3px; right: 3px; border-radius: var(--r-xs); padding: 4px 7px;
  font-size: 11.5px; overflow: hidden; cursor: pointer; z-index: 2;
  background: var(--info-bg); border: 0; color: var(--info);
  transition: transform var(--fast) var(--spring), box-shadow var(--fast) var(--ease);
}
.cal-block:hover { transform: scale(1.015); box-shadow: var(--shadow-card); }
.cal-block .bt { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-block.good { background: var(--good-bg); color: var(--good); }
.cal-block.warn { background: var(--warn-bg); color: var(--warn); }
.cal-block.est { background: var(--active-bg); color: var(--active-tone); }

/* ── Timeline ────────────────────────────────────────────────────────────── */

.timeline { position: relative; padding-left: 24px; }
.timeline::before { content: ''; position: absolute; left: 5px; top: 7px; bottom: 7px; width: 2px; background: var(--line); border-radius: var(--pill); }
.tl-item { position: relative; padding: 0 0 18px; }
.tl-item::before {
  content: ''; position: absolute; left: -22px; top: 5px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--ink-4);
  box-shadow: 0 0 0 3px var(--paper);
}
.tl-item.accent::before { background: var(--accent); }
.tl-item.good::before { background: var(--good-solid); }
.tl-head { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.tl-title { font-size: 13.5px; font-weight: 550; letter-spacing: -0.008em; }
.tl-time { font-size: 11.5px; color: var(--ink-4); margin-left: auto; }
.tl-body { font-size: 13.5px; color: var(--ink-2); margin-top: 4px; white-space: pre-wrap; }

/* ── Document (estimate/invoice) ─────────────────────────────────────────── */

.doc { background: var(--paper); border: 0; border-radius: var(--r-xl); box-shadow: var(--shadow-card); overflow: hidden; }
.doc-head { padding: 30px 34px 26px; border-bottom: 1px solid var(--line); display: flex; gap: 26px; align-items: flex-start; }
.doc-title { font-size: 28px; font-weight: 600; letter-spacing: -0.028em; line-height: 1.12; }
.doc-meta { margin-left: auto; text-align: right; font-size: 13px; color: var(--ink-2); }
.doc-body { padding: 28px 34px; }
.doc-parties { display: grid; grid-template-columns: repeat(2, 1fr); gap: 28px; margin-bottom: 26px; }
.doc-party .eyebrow { margin-bottom: 6px; }
.doc-total-row { display: flex; justify-content: space-between; padding: 6px 0; font-size: 13.5px; }
.doc-total-row.grand { border-top: 1px solid var(--line-2); margin-top: 9px; padding-top: 12px; font-size: 19px; font-weight: 600; letter-spacing: -0.018em; }
.doc-totals { margin-left: auto; width: 300px; }
.doc-foot { padding: 20px 34px; border-top: 1px solid var(--line); font-size: 12.5px; color: var(--ink-3); background: var(--sunken); white-space: pre-wrap; }

.lineitems { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.lineitems th { text-align: left; font-size: 12px; letter-spacing: -0.003em; color: var(--ink-3); padding: 0 10px 9px; border-bottom: 1px solid var(--line-2); font-weight: 550; }
.lineitems td { padding: 12px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
.lineitems .desc { font-size: 12.5px; color: var(--ink-3); margin-top: 3px; }
.lineitems th.r, .lineitems td.r { text-align: right; }
/* On a phone, quantity and price move under the item ("36 squares × $45.00")
   and the table keeps two columns: what it is, and what it costs. */
.lineitems .item-math { display: none; }
@media (max-width: 600px) {
  .lineitems .col-qty, .lineitems .col-rate { display: none; }
  .lineitems .item-math { display: block; }
  .lineitems th:first-child, .lineitems td:first-child { padding-left: 0; }
  .lineitems th:last-child, .lineitems td:last-child { padding-right: 0; white-space: nowrap; }
  .lineitems td:first-child { overflow-wrap: anywhere; }
}

/* ── Editor rows (estimate/invoice builder) ──────────────────────────────── */

.itemrow { display: grid; grid-template-columns: 1fr 82px 104px 108px 110px 32px; gap: 8px; align-items: start; padding: 9px 0; border-bottom: 1px solid var(--line); }
.itemrow.head { border-bottom: 1px solid var(--line-2); padding-bottom: 7px; }
.itemrow.head > div { font-size: 12px; letter-spacing: -0.003em; color: var(--ink-3); font-weight: 550; }
.itemrow input, .itemrow select { height: 32px; font-size: 13px; }
.itemrow textarea { min-height: 32px; font-size: 13px; }
.itemrow .rowtotal { height: 32px; display: flex; align-items: center; justify-content: flex-end; font-weight: 600; font-size: 13.5px; }
.itemrow .del { height: 32px; }
/* Narrow screens: each line becomes a small form. What it is runs across the
   top beside the remove button, then quantity, unit and price share a row,
   and the line's amount closes it on the right.
   Children, in order: item, quantity, unit, price, amount, remove. */
@media (max-width: 900px) {
  .itemrow {
    grid-template-columns: minmax(0, 0.75fr) minmax(0, 1.35fr) minmax(0, 0.9fr) auto;
    gap: 8px; padding: 14px 0;
  }
  .itemrow.head { display: none; }
  /* "Linear Ft" fits beside its arrow. */
  .itemrow > select { padding-right: 26px; background-position: right 9px center; }
  .itemrow > :nth-child(1) { grid-column: 1 / 4; }
  .itemrow > :nth-child(4) { grid-column: 3 / -1; }
  .itemrow > :nth-child(5) { grid-column: 1 / -1; grid-row: 3; }
  .itemrow > :nth-child(6) { grid-column: 4; grid-row: 1; }
}

/* ── Gallery ─────────────────────────────────────────────────────────────── */

.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; }
.gal-item {
  border: 0; border-radius: var(--r); overflow: hidden; background: var(--paper); cursor: pointer;
  box-shadow: var(--shadow-card);
  transition: transform var(--mid) var(--spring), box-shadow var(--mid) var(--ease);
}
.gal-item:hover { transform: translateY(-3px) scale(1.012); box-shadow: var(--shadow-lift); }
.gal-item:active { transform: scale(0.99); }
.gal-thumb { aspect-ratio: 4/3; background: var(--sunken); display: block; width: 100%; object-fit: cover; }
.gal-meta { padding: 9px 11px; font-size: 12.5px; }
.gal-meta .n { font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gal-meta .s { color: var(--ink-3); font-size: 11.5px; }

.lightbox { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.94); z-index: 150; display: flex; flex-direction: column; animation: fade var(--mid) var(--ease); }
.lightbox img { max-width: 92vw; max-height: 78vh; object-fit: contain; margin: auto; border-radius: var(--r-sm); animation: pop var(--slow) var(--spring) both; }
.lightbox-bar { padding: 16px 22px; color: #E5E5EA; display: flex; align-items: center; gap: 14px; font-size: 13.5px; }

/* ── Map ─────────────────────────────────────────────────────────────────── */

.mapwrap { position: relative; border: 0; border-radius: var(--r-lg); overflow: hidden; background: var(--sunken); box-shadow: var(--shadow-card); }
.mapcanvas { display: block; width: 100%; height: 100%; cursor: crosshair; }
.map-tools { position: absolute; top: 12px; left: 12px; display: flex; flex-direction: column; gap: 6px; }
.map-legend { position: absolute; bottom: 12px; left: 12px; background: var(--veil); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px); border-radius: var(--r-sm); padding: 9px 11px; font-size: 12.5px; box-shadow: var(--shadow-card); }
.map-scale { position: absolute; bottom: 12px; right: 12px; background: var(--veil); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px); border-radius: var(--r-sm); padding: 6px 10px; font-size: 12px; color: var(--ink-2); box-shadow: var(--shadow-card); }

/* ── Signature ───────────────────────────────────────────────────────────── */

.sigpad { border: 1.5px dashed var(--line-2); border-radius: var(--r-sm); background: var(--sunken); cursor: crosshair; display: block; width: 100%; touch-action: none; }

/* ── Assistant ───────────────────────────────────────────────────────────── */

.chat { display: flex; flex-direction: column; gap: 16px; }
.chat-msg { display: flex; gap: 11px; }
.chat-msg .who { width: 28px; flex-shrink: 0; }
.chat-bubble { font-size: 14px; line-height: 1.6; white-space: pre-wrap; letter-spacing: -0.008em; }
.chat-msg.user .chat-bubble { background: var(--accent); color: #FFF; border: 0; border-radius: var(--r-lg); padding: 11px 15px; }
.chat-ctx { font-size: 11.5px; color: var(--ink-4); margin-top: 8px; display: flex; gap: 6px; flex-wrap: wrap; }
.chat-composer { display: flex; gap: 9px; align-items: flex-end; border-top: 1px solid var(--line); padding-top: 14px; }
.chat-composer textarea { min-height: 42px; max-height: 150px; border-radius: var(--r-lg); }

.suggest { display: flex; flex-wrap: wrap; gap: 7px; }
.suggest button {
  border: 0; background: var(--fill); border-radius: var(--pill);
  padding: 7px 14px; font-size: 13px; color: var(--ink-2); cursor: pointer;
  transition: background var(--fast) var(--ease), transform var(--fast) var(--spring), color var(--fast) var(--ease);
}
.suggest button:hover { background: var(--fill-2); color: var(--ink); }
.suggest button:active { transform: scale(0.96); }

.insight { display: flex; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--line); }
.insight:last-child { border-bottom: 0; }
.insight .sev { width: 4px; border-radius: var(--pill); flex-shrink: 0; background: var(--neutral); }
.insight.high .sev { background: var(--bad-solid); }
.insight.medium .sev { background: var(--warn-solid); }
.insight.low .sev { background: var(--good-solid); }
.insight h4 { font-size: 13.5px; font-weight: 600; margin-bottom: 3px; letter-spacing: -0.008em; }
.insight p { font-size: 13px; color: var(--ink-2); margin: 0 0 8px; }

/* ── Auth & portal ───────────────────────────────────────────────────────── */

.auth-wrap { min-height: 100vh; display: grid; grid-template-columns: 1fr 520px; }
.auth-aside {
  background: linear-gradient(170deg, #1D1D1F 0%, #000000 100%);
  color: var(--ink-invert); padding: 56px 58px;
  display: flex; flex-direction: column; justify-content: space-between;
}
/* After .auth-aside, or its display: flex wins and a phone opens on a
   screenful of pitch with the sign-in form below the fold. */
@media (max-width: 940px) { .auth-wrap { grid-template-columns: 1fr; } .auth-aside { display: none; } }
.auth-aside h2 { font-size: 40px; letter-spacing: -0.03em; color: #FFF; line-height: 1.1; max-width: 540px; }
.auth-aside p { color: #A1A1A6; font-size: 16px; max-width: 480px; line-height: 1.55; letter-spacing: -0.01em; }
/* The panel is dark in both appearances, so the brand is pinned light on it. */
.auth-aside .rail-mark, .auth-aside .rail-word { color: #F5F5F7; }
.auth-flow { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 32px; }
.auth-flow span {
  font-size: 12.5px; padding: 5px 12px; border: 0; border-radius: var(--pill);
  background: rgba(255, 255, 255, 0.09); color: #C7C7CC;
}
.auth-flow span.hot { background: var(--accent); color: #FFF; }
.auth-main { background: var(--paper); padding: 48px 56px; display: flex; flex-direction: column; justify-content: center; }
.auth-form { width: 100%; max-width: 360px; margin: 0 auto; }
.auth-demo {
  margin-top: 22px; padding: 14px 16px; background: var(--sunken);
  border: 0; border-radius: var(--r); font-size: 13px; color: var(--ink-2);
}

.portal { max-width: 980px; margin: 0 auto; padding: 32px 22px 80px; }
.portal-head { display: flex; align-items: center; gap: 14px; padding: 16px 0 24px; border-bottom: 1px solid var(--line); margin-bottom: 26px; }
.portal-logo { font-size: 19px; font-weight: 600; letter-spacing: -0.022em; }
.doc-page { max-width: 860px; margin: 0 auto; padding: 32px 22px 80px; animation: rise var(--slow) var(--spring) both; }
.doc-actionbar {
  position: sticky; bottom: 16px; background: var(--veil);
  -webkit-backdrop-filter: saturate(180%) blur(22px); backdrop-filter: saturate(180%) blur(22px);
  border: 0; border-radius: var(--r-xl); padding: 16px 20px; margin-top: 20px;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; box-shadow: var(--shadow-lift);
}

/* ── Small screens ───────────────────────────────────────────────────────────
   Technicians work from a phone in a van. Below 860px the rail slides away
   behind a toggle and every two-column layout collapses to one. */

.menu-toggle { display: none; }

@media (max-width: 860px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .rail {
    position: fixed; left: 0; top: 0; bottom: 0; width: 272px; z-index: 92;
    transform: translateX(-100%); transition: transform var(--slow) var(--spring);
    background: var(--rail-solid);
  }
  .rail.open { transform: none; box-shadow: var(--shadow-pop); }
  .rail-scrim { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.3); z-index: 91; -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); animation: fade var(--mid) var(--ease); }
  .menu-toggle { display: grid; }

  .topbar { padding: 0 14px; gap: 7px; }
  .searchbtn { min-width: 0; flex: 1; }
  .searchbtn span { display: none; }
  .searchbtn kbd { display: none; }

  .page { padding: 18px 16px 72px; }
  .page-head { gap: 12px; }
  .page-head h1 { font-size: 23px; }
  .page-head .titles { min-width: 100%; }
  .page-actions { width: 100%; flex-wrap: wrap; }

  .split, .split-wide, .g2, .g3, .g4 { grid-template-columns: minmax(0, 1fr); }
  .stat-value { font-size: 25px; }

  .doc-head { flex-direction: column; gap: 16px; padding: 22px; }
  .doc-title { font-size: 23px; }
  .doc-meta { margin-left: 0; text-align: left; }
  .doc-body { padding: 22px; }
  .doc-parties { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .doc-totals { width: 100%; }
  .doc-page, .portal { padding: 20px 15px 72px; }

  /* A modal on a phone is an iOS sheet: it comes up from the bottom edge. */
  .scrim { padding: 0; align-items: flex-end; }
  .modal, .modal.wide, .modal.xwide {
    max-width: 100%; border-radius: var(--r-xl) var(--r-xl) 0 0;
    animation: sheetup var(--slow) var(--spring) both;
  }
  @keyframes sheetup { from { transform: translate3d(0, 100%, 0); } }
  .modal-body { max-height: 60vh; }
  .inline-fields, .inline-fields.three { grid-template-columns: minmax(0, 1fr); }

  .cal-grid { grid-auto-rows: minmax(82px, auto); }
  .board-col { flex-basis: 256px; }
}

/* A phone's top bar holds six controls. Search becomes a round button there
   instead of a pill squeezed until its icon disappears. */
.searchbtn svg { flex-shrink: 0; }
@media (max-width: 480px) {
  .topbar { gap: 4px; padding: 0 10px; }
  .searchbtn { flex: 0 0 40px; height: 40px; padding: 0; justify-content: center; }
}

/* ── Reduced motion ──────────────────────────────────────────────────────────
   Somebody who has asked their system to stop animating means it. Nothing here
   is load-bearing, so all of it goes. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Print ───────────────────────────────────────────────────────────────── */

@media print {
  .rail, .topbar, .page-actions, .doc-actionbar, .toasts, .tabs { display: none !important; }
  .shell { grid-template-columns: 1fr; }
  body { background: #FFF; }
  .panel, .doc { border: 0; box-shadow: none; }
  .page { padding: 0; animation: none; }
}

/* ── Utility spacing ─────────────────────────────────────────────────────── */

.mt-0 { margin-top: 0; } .mt-1 { margin-top: 6px; } .mt-2 { margin-top: 12px; } .mt-3 { margin-top: 18px; } .mt-4 { margin-top: 26px; }
.mb-1 { margin-bottom: 6px; } .mb-2 { margin-bottom: 12px; } .mb-3 { margin-bottom: 18px; }
.pad { padding: 16px; }
.divider { height: 1px; background: var(--line); margin: 16px 0; }
.kv { display: grid; grid-template-columns: 136px minmax(0, 1fr); gap: 7px 14px; font-size: 13.5px; }
.kv dt { color: var(--ink-3); }
/* An email address or a link is one long word: it breaks rather than
   pushing the value out past the card's edge. */
.kv dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 520px) { .kv { grid-template-columns: 112px minmax(0, 1fr); gap: 7px 12px; } }

/* ── Layout helpers ──────────────────────────────────────────────────────── */

.gap-xs { gap: 5px; }
.stack-xs > * + * { margin-top: 8px; }
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 14px; }
.grid-main { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 16px; align-items: start; }

.callout {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 11px 14px; margin-bottom: 14px;
  background: var(--info-bg); border: 0; border-radius: var(--r-sm);
  color: var(--ink-2); font-size: 13px;
}
.callout svg { flex-shrink: 0; margin-top: 1px; color: var(--info); }

.pickrow { padding: 10px 12px; border: 0; border-radius: var(--r-sm); background: var(--fill); transition: background var(--fast) var(--ease); }
.pickrow:hover { background: var(--fill-2); }

.panel.warn-panel { box-shadow: var(--shadow-card), inset 0 0 0 1.5px var(--warn-solid); }
.panel.warn-panel .panel-head { background: var(--warn-bg); }

@media (max-width: 1100px) { .grid-main { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 640px) { .grid-2 { grid-template-columns: minmax(0, 1fr); } }

/* ── Tasks ───────────────────────────────────────────────────────────────── */

.tasklist > * + * { border-top: 1px solid var(--line); }

.taskrow { display: flex; align-items: flex-start; gap: 12px; padding: 12px 18px; transition: background var(--fast) var(--ease); }
.taskrow:hover { background: var(--fill); }
.taskrow .task-title { font-size: 13.5px; letter-spacing: -0.008em; }

/* The meta line wraps as whole phrases. Letting "7w ago overdue" break across
   two lines reads as two separate facts, which it is not. */
.taskmeta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px;
  margin-top: 3px; font-size: 11.5px; color: var(--ink-3);
}
.taskmeta > * { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.taskrow.done .task-title { text-decoration: line-through; color: var(--ink-4); }
.taskrow.late .task-title { color: var(--bad); }

.taskcheck {
  width: 20px; height: 20px; margin-top: 1px; flex-shrink: 0;
  border: 1.5px solid var(--line-2); border-radius: 50%; background: transparent;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; color: transparent; padding: 0;
  transition: background var(--mid) var(--spring), border-color var(--fast) var(--ease),
    transform var(--fast) var(--spring);
}
.taskcheck:hover { border-color: var(--accent); }
.taskcheck:active { transform: scale(0.88); }
.taskcheck.on { background: var(--good-solid); border-color: var(--good-solid); color: #FFF; }
.taskcheck svg { width: 12px; height: 12px; }

/* ── Getting started ─────────────────────────────────────────────────────── */

.setup-bar { height: 6px; background: var(--fill); border-radius: var(--pill); overflow: hidden; margin-bottom: 14px; }
.setup-bar i { display: block; height: 100%; background: var(--good-solid); border-radius: var(--pill); transition: width 900ms var(--spring); }

.setup-list > * + * { margin-top: 2px; }
.setup-step {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 10px; margin: 0 -10px; border-radius: var(--r-sm);
  color: var(--ink); text-decoration: none;
  transition: background var(--fast) var(--ease), transform var(--fast) var(--spring);
}
.setup-step:hover { background: var(--fill); opacity: 1; }
.setup-step:active { transform: scale(0.99); }
.setup-step svg { color: var(--ink-4); flex-shrink: 0; }
.setup-dot {
  width: 16px; height: 16px; flex-shrink: 0; border-radius: 50%;
  border: 1.5px dashed var(--line-2);
}

/* ── Inventory ───────────────────────────────────────────────────────────── */

.lowstock > * + * { border-top: 1px solid var(--line); }
.lowstock-row { display: flex; align-items: center; gap: 14px; padding: 12px 18px; }

/* ── Contracts ───────────────────────────────────────────────────────────── */

.contract-preview,
.contract-text {
  font-family: var(--font-sans);
  font-size: 13.5px; line-height: 1.68; color: var(--ink-2);
  white-space: pre-wrap; word-break: break-word; margin: 0;
}
.contract-preview {
  max-height: 280px; overflow-y: auto;
  background: var(--sunken); border: 0; border-radius: var(--r-sm); padding: 14px 16px;
}
.contract-text { font-size: 14px; color: var(--ink); }

/* ── Crew tracking ───────────────────────────────────────────────────────── */

.crewlist > * + * { border-top: 1px solid var(--line); }
.crewrow {
  display: flex; align-items: center; gap: 12px; padding: 12px 18px;
  color: var(--ink); text-decoration: none;
  transition: background var(--fast) var(--ease);
}
.crewrow:hover { background: var(--fill); opacity: 1; }

.trailwrap { background: var(--sunken); border: 0; border-radius: var(--r-sm); padding: 12px; }
.trail { width: 100%; height: auto; display: block; }

/* ── Team chat ───────────────────────────────────────────────────────────── */

.chat-shell {
  display: grid; grid-template-columns: 232px minmax(0, 1fr);
  border: 0; border-radius: var(--r-lg); background: var(--paper);
  box-shadow: var(--shadow-card);
  height: calc(100vh - 210px); min-height: 480px; overflow: hidden;
}
.chat-side { border-right: 1px solid var(--line); background: var(--sunken); overflow-y: auto; padding-bottom: 16px; }
.chat-side-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 14px 8px; }

.chat-group { margin-top: 12px; }
.chat-group-label {
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.03em;
  color: var(--ink-4); padding: 0 14px 5px;
}
.chat-channel {
  display: flex; align-items: center; gap: 8px; width: calc(100% - 16px);
  margin: 0 8px; padding: 6px 10px; background: none; border: 0; border-radius: var(--r-sm);
  cursor: pointer; font-size: 13.5px; color: var(--ink-2); text-align: left;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.chat-channel:hover { background: var(--fill); color: var(--ink); }
.chat-channel.on { background: var(--accent); color: #FFF; font-weight: 550; }
.chat-channel .rail-badge { background: var(--bad-solid); }
.chat-channel.on .rail-badge { background: rgba(255, 255, 255, 0.25); color: #FFF; }

.chat-pane { display: flex; flex-direction: column; min-height: 0; }
.chat-head { display: flex; align-items: center; gap: 12px; padding: 14px 20px; border-bottom: 1px solid var(--line); }
.chat-head h2 { font-size: 16px; }

.chat-log { flex: 1; overflow-y: auto; padding: 18px 20px; }
.chat-msg.grouped { padding-top: 0; }
.chat-msg-gutter { width: 22px; flex-shrink: 0; }
.chat-body { font-size: 14px; line-height: 1.55; white-space: pre-wrap; word-break: break-word; letter-spacing: -0.008em; }
.mention { color: var(--accent); font-weight: 600; }

.chat-composer { padding: 14px 20px; background: var(--sunken); }

@media (max-width: 800px) {
  .chat-shell { grid-template-columns: minmax(0, 1fr); height: auto; }
  .chat-side { border-right: 0; border-bottom: 1px solid var(--line); max-height: 230px; }
  .chat-log { max-height: 55vh; }
}

/* ── Instant quote ───────────────────────────────────────────────────────── */

.quote-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-bottom: 1px solid var(--line);
}
.quote-row:last-child { border-bottom: 0; }

/* ── Hosted website ──────────────────────────────────────────────────────────
   The public site is its own visual language: wider measure, display type, and
   a palette the contractor picks rather than one we impose. */

/* The contractor picks this theme, so it renders the same for every visitor.
   A homeowner browsing in dark mode must not be shown a half-inverted version
   of somebody else's brand, so the app tokens are pinned back to light here. */
.site {
  max-width: none; margin: 0; padding: 0;
  --site-ink: #1D1D1F; --site-bg: #FFFFFF; --site-alt: #F5F5F7; --site-accent: #0071E3;

  --paper: #FFFFFF;
  --sunken: #F5F5F7;
  --ink: #1D1D1F;
  --ink-2: #6E6E73;
  --ink-3: #86868B;
  --ink-4: #AEAEB2;
  --line: rgba(0, 0, 0, 0.07);
  --line-2: rgba(0, 0, 0, 0.14);
  --fill: rgba(120, 120, 128, 0.10);
  --fill-2: rgba(120, 120, 128, 0.16);
  --accent: #0071E3;
  --accent-press: #0062C4;
  --accent-soft: rgba(0, 113, 227, 0.10);
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.04), 0 0 0 0.5px rgba(0, 0, 0, 0.045);
  --shadow-lift: 0 8px 24px rgba(0, 0, 0, 0.09), 0 0 0 0.5px rgba(0, 0, 0, 0.045);
  color-scheme: light;
}
[data-site-theme='slate'] .site { --site-ink: #16202A; --site-alt: #EEF1F5; --site-accent: #0071E3; --accent: #0071E3; }
[data-site-theme='forest'] .site { --site-ink: #0F2318; --site-alt: #EAF2EC; --site-accent: #137333; --accent: #137333; --accent-press: #0F5C28; }
[data-site-theme='clay'] .site { --site-ink: #241813; --site-bg: #FFFDFC; --site-alt: #F7EFE9; --site-accent: #BC5A2E; --accent: #BC5A2E; --accent-press: #9F4823; }

.site { background: var(--site-bg); color: var(--site-ink); }
.site-inner { max-width: 940px; margin: 0 auto; padding: 0 26px; }

.site-hero { background: var(--site-alt); padding: 86px 0 74px; text-align: center; }
.site-hero-inner { max-width: 820px; margin: 0 auto; padding: 0 26px; animation: rise 700ms var(--spring) both; }
.site-brand { font-size: 13px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 22px; }
.site-hero h1 { font-size: 54px; line-height: 1.06; letter-spacing: -0.032em; margin: 0; }
.site-sub { font-size: 21px; color: var(--ink-2); margin: 18px auto 0; max-width: 620px; line-height: 1.42; letter-spacing: -0.014em; }
.site-rating { margin-top: 22px; font-size: 14px; color: var(--ink-2); }

.site-section { padding: 68px 0; }
.site-section.alt { background: var(--site-alt); }
.site-section.cta { background: var(--site-ink); color: #FFF; text-align: center; }
.site-section.cta .site-prose { color: rgba(255, 255, 255, 0.78); margin-left: auto; margin-right: auto; }
.site-section h2 { font-size: 34px; letter-spacing: -0.026em; margin: 0 0 24px; line-height: 1.12; }
.site-prose { font-size: 17px; line-height: 1.6; color: var(--ink-2); max-width: 660px; white-space: pre-wrap; letter-spacing: -0.01em; }

.site-services { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(258px, 100%), 1fr)); gap: 14px; }
.site-service {
  background: var(--site-bg); border: 0; border-radius: var(--r-lg); padding: 20px;
  box-shadow: var(--shadow-card);
  transition: transform var(--mid) var(--spring), box-shadow var(--mid) var(--ease);
}
.site-service:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
.site-price { margin-top: 12px; font-size: 15px; font-weight: 600; color: var(--site-accent); letter-spacing: -0.012em; }

.site-list, .site-steps { font-size: 17px; line-height: 1.85; color: var(--ink-2); padding-left: 24px; max-width: 660px; letter-spacing: -0.01em; }
.site-faq details { border-bottom: 1px solid var(--line); padding: 18px 0; max-width: 760px; }
.site-faq summary { font-size: 17px; font-weight: 550; cursor: pointer; letter-spacing: -0.012em; list-style: none; }
.site-faq summary::-webkit-details-marker { display: none; }
.site-faq summary::after { content: '+'; float: right; color: var(--ink-3); font-weight: 400; transition: transform var(--mid) var(--spring); }
.site-faq details[open] summary::after { transform: rotate(45deg); }
.site-faq p { font-size: 16px; line-height: 1.62; color: var(--ink-2); margin: 12px 0 0; letter-spacing: -0.008em; }

/* min(): on a 320px phone one column is narrower than 300px. */
.site-reviews { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap: 14px; }
.site-review { background: var(--site-bg); border: 0; border-radius: var(--r-lg); padding: 22px; margin: 0; box-shadow: var(--shadow-card); }
.site-review blockquote { font-size: 16px; line-height: 1.6; margin: 10px 0 14px; letter-spacing: -0.01em; }
.site-review figcaption { font-size: 13px; color: var(--ink-3); }
.site-stars { color: #FF9F0A; letter-spacing: 3px; font-size: 13px; }

.site-foot { background: var(--site-ink); color: rgba(255, 255, 255, 0.68); padding: 36px 0; }
.site-foot .strong { color: #FFF; font-size: 16px; }

@media (max-width: 640px) {
  .site-hero { padding: 50px 0 44px; }
  .site-hero h1 { font-size: 34px; }
  .site-sub { font-size: 17px; }
  .site-section { padding: 44px 0; }
  .site-section h2 { font-size: 26px; }
  .site-prose, .site-list, .site-steps { font-size: 16px; }
}

/* ── Plan & billing ──────────────────────────────────────────────────────────
   The banner is one line under the top bar. Its colour carries the urgency:
   blue is a trial counting down, amber a card that failed, red a locked
   account. */

.billing-banner {
  display: flex; align-items: center; gap: 10px;
  margin: 14px 26px 0; padding: 8px 8px 8px 14px;
  border-radius: var(--r);
  background: var(--info-bg); color: var(--ink-2);
  font-size: 13px; letter-spacing: -0.004em;
  animation: rise var(--slow) var(--spring) both;
}
.billing-banner > svg { flex-shrink: 0; color: var(--info); }
.billing-banner .btn { flex-shrink: 0; }
.billing-banner.info { background: var(--info-bg); }
.billing-banner.warn { background: var(--warn-bg); }
.billing-banner.warn > svg { color: var(--warn); }
.billing-banner.bad { background: var(--bad-bg); color: var(--ink); }
.billing-banner.bad > svg { color: var(--bad); }

.plan-head { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.plan-name { font-size: 22px; font-weight: 600; letter-spacing: -0.024em; line-height: 1.15; margin-bottom: 3px; }
.plan-price { display: flex; align-items: baseline; gap: 5px; white-space: nowrap; }
.plan-amount { font-size: 34px; font-weight: 600; letter-spacing: -0.034em; line-height: 1; }
.plan-interval { font-size: 14px; color: var(--ink-3); }
.plan-status { margin: 16px 0; font-size: 14px; line-height: 1.55; color: var(--ink-2); max-width: 580px; }
.plan-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.plan-actions:empty { display: none; }
.plan-choices { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; margin: 0 0 16px; }
.plan-choice {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  padding: 14px 16px 16px; border: 1px solid var(--line-2); border-radius: var(--r);
}
.plan-choice .btn { margin-top: 4px; }
.plan-choice-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 14px; }
.plan-note { margin: -4px 0 16px; }
.plan-features { display: grid; gap: 20px; }

.checklist { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.checklist li { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; line-height: 1.45; color: var(--ink-2); }
.checklist svg { flex-shrink: 0; margin-top: 2px; color: var(--good); }

.billing-history > * + * { border-top: 1px solid var(--line); }
.billing-row { display: flex; align-items: center; gap: 12px; padding: 11px 18px; font-size: 13px; }

.auth-terms { font-size: 12.5px; color: var(--ink-3); text-align: center; margin: 12px 0 0; line-height: 1.5; }
.auth-terms:empty { display: none; }

@media (max-width: 860px) {
  .billing-banner { margin: 12px 16px 0; padding: 10px 12px; flex-wrap: wrap; row-gap: 8px; }
  /* The message gets the full width; the button drops under it, in line with the text. */
  .billing-banner > .grow { flex-basis: calc(100% - 26px); }
  .billing-banner .btn { margin-left: 25px; }
}

/* ── Public pricing page ─────────────────────────────────────────────────────
   Recoatly's own shop window. It uses the app's tokens rather than the
   hosted-site palette, so it follows the visitor's light or dark preference
   and looks like the product they are about to sign up for. */

.pricing { min-height: 100vh; background: var(--canvas); padding-bottom: 8px; }

.pricing-nav {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; gap: 8px;
  height: var(--top-h); padding: 0 clamp(16px, 4vw, 40px);
  background: var(--veil);
  -webkit-backdrop-filter: saturate(180%) blur(22px); backdrop-filter: saturate(180%) blur(22px);
  border-bottom: 1px solid var(--line);
}
.pricing-brand { display: flex; align-items: center; gap: 9px; color: var(--ink); }
.pricing-brand:hover { opacity: 1; }

.pricing-hero {
  max-width: 780px; margin: 0 auto; padding: 76px 24px 30px; text-align: center;
  animation: rise 700ms var(--spring) both;
}
.pricing-hero .eyebrow { color: var(--accent); margin-bottom: 14px; }
.pricing-hero h1 { font-size: 52px; line-height: 1.06; letter-spacing: -0.034em; }
.pricing-lede { font-size: 19px; line-height: 1.45; color: var(--ink-2); margin: 18px auto 0; max-width: 610px; letter-spacing: -0.014em; }

.pricing-card {
  width: calc(100% - 32px); max-width: 440px; margin: 16px auto 0; padding: 30px 30px 28px;
  background: var(--paper); border-radius: var(--r-xl); box-shadow: var(--shadow-lift);
  animation: rise 700ms var(--spring) 80ms both;
}
.pricing-plan { font-size: 15px; font-weight: 600; color: var(--accent); letter-spacing: -0.01em; }
.pricing-amount { display: flex; align-items: baseline; gap: 8px; margin-top: 8px; }
.pricing-value { font-size: 64px; font-weight: 600; letter-spacing: -0.045em; line-height: 1; }
.pricing-per { font-size: 16px; color: var(--ink-3); }
.pricing-terms { font-size: 13.5px; color: var(--ink-3); margin: 12px 0 22px; }
.pricing-fine { font-size: 12.5px; color: var(--ink-3); text-align: center; margin: 10px 0 0; }
.pricing-included {
  list-style: none; margin: 22px 0 0; padding: 20px 0 0;
  border-top: 1px solid var(--line); display: grid; gap: 10px;
}

.pricing-included li, .pricing-group li {
  display: flex; align-items: flex-start; gap: 9px;
  font-size: 14px; line-height: 1.45; color: var(--ink-2);
}
.pricing-included svg, .pricing-group svg { flex-shrink: 0; margin-top: 3px; color: var(--good); }

.pricing-section { max-width: 1000px; margin: 0 auto; padding: 84px 24px 0; }
.pricing-section h2 { font-size: 34px; line-height: 1.12; letter-spacing: -0.028em; text-align: center; }
.pricing-sub { font-size: 17px; color: var(--ink-2); text-align: center; margin: 12px auto 0; max-width: 560px; letter-spacing: -0.01em; }

.pricing-features { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-top: 36px; }
.pricing-group { background: var(--paper); border-radius: var(--r-lg); box-shadow: var(--shadow-card); padding: 20px; }
.pricing-group h3 { font-size: 15px; margin-bottom: 14px; }
.pricing-group ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.pricing-group li { font-size: 13.5px; }

.pricing-faq { max-width: 720px; margin: 28px auto 0; }
.pricing-faq details { border-bottom: 1px solid var(--line); padding: 18px 0; }
.pricing-faq summary {
  display: flex; gap: 12px; cursor: pointer; list-style: none;
  font-size: 16px; font-weight: 550; letter-spacing: -0.012em;
}
.pricing-faq summary::-webkit-details-marker { display: none; }
.pricing-faq summary::after {
  content: '+'; margin-left: auto; color: var(--ink-3); font-weight: 400;
  transition: transform var(--mid) var(--spring);
}
.pricing-faq details[open] summary::after { transform: rotate(45deg); }
.pricing-faq p { font-size: 15px; line-height: 1.6; color: var(--ink-2); margin: 10px 0 0; letter-spacing: -0.008em; }

.pricing-cta {
  width: calc(100% - 32px); max-width: 952px; margin: 84px auto 0; padding: 56px 24px;
  text-align: center; background: var(--paper); border-radius: var(--r-xl); box-shadow: var(--shadow-card);
}
.pricing-cta h2 { font-size: 30px; letter-spacing: -0.026em; }
.pricing-cta p { font-size: 16px; line-height: 1.55; color: var(--ink-2); max-width: 520px; margin: 12px auto 24px; }

.pricing-foot {
  display: flex; align-items: center; gap: 18px;
  max-width: 1000px; margin: 0 auto; padding: 48px 24px 32px;
  font-size: 13px; color: var(--ink-3);
}
.pricing-foot a { color: var(--ink-2); }

@media (max-width: 960px) {
  .pricing-features { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .pricing-hero { padding: 48px 20px 22px; }
  .pricing-hero h1 { font-size: 36px; }
  .pricing-lede { font-size: 17px; }
  .pricing-card { padding: 24px 20px; }
  .pricing-value { font-size: 54px; }
  .pricing-section { padding: 60px 16px 0; }
  .pricing-section h2 { font-size: 27px; }
  .pricing-features { grid-template-columns: minmax(0, 1fr); }
  .pricing-cta { margin-top: 60px; padding: 40px 20px; }
  .pricing-cta h2 { font-size: 24px; }
}

/* ── Launch additions: core ─────────────────────────────────────────────── */

/* Suggestion lists float on <body> so no card or dialog can clip them. */
.typeahead-menu {
  position: fixed; z-index: 1200; overflow-y: auto; margin: 0;
  display: block; min-width: 220px;
}
.typeahead-menu .menu-item.on { background: var(--accent); color: #FFF; }
.typeahead-menu .menu-item.on .muted, .typeahead-menu .menu-item.on svg { color: rgba(255, 255, 255, 0.85); }
.typeahead-menu .menu-item:hover .muted { color: rgba(255, 255, 255, 0.85); }

/* First paint while the app shell loads. */
.boot-splash { min-height: 100vh; background: var(--canvas); }

/* Server-rendered error pages (404, 429, 500). */
.error-page { min-height: 100vh; display: grid; place-items: center; padding: 24px 16px; background: var(--canvas); }
.error-card {
  max-width: 440px; width: 100%; background: var(--paper); border-radius: var(--r-xl);
  box-shadow: var(--shadow-card); padding: 36px 28px; text-align: center;
}
.error-card h1 { font-size: 24px; letter-spacing: -0.02em; margin: 0 0 10px; }
.error-card p { color: var(--ink-2); margin: 0 0 18px; line-height: 1.5; }

/* Account banners (verify your email, read-only) under the top bar. */
.notice-banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 12px 24px 0; padding: 10px 14px; border-radius: var(--r);
  background: var(--accent-soft); color: var(--ink); font-size: 13.5px;
}
.notice-banner .grow { min-width: 200px; }
.notice-banner.warn { background: var(--warn-soft, rgba(255, 159, 10, 0.14)); }
@media (max-width: 860px) { .notice-banner { margin: 10px 12px 0; } }

/* Inline field errors next to the input that caused them. */
.field-error { color: var(--bad); font-size: 12.5px; margin-top: 4px; }
.field.invalid input, .field.invalid select, .field.invalid textarea { box-shadow: 0 0 0 1.5px var(--bad) inset; }

/* Visually hidden but read by screen readers. */
.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Honeypot fields: present for bots, invisible for people. */
.hp-field { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

/* Subscribe sheet shown when a write is refused because the plan lapsed. */
.paywall { text-align: center; padding: 8px 4px 4px; }
.paywall h3 { font-size: 20px; letter-spacing: -0.02em; margin: 6px 0 8px; }
.paywall p { color: var(--ink-2); line-height: 1.5; margin: 0 auto 16px; max-width: 380px; }
.paywall .price { font-size: 34px; font-weight: 600; letter-spacing: -0.03em; }

/* Inbox: conversation list beside the open thread; stacked on phones. */
.inbox-grid { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 14px; align-items: start; }
@media (max-width: 860px) { .inbox-grid { grid-template-columns: minmax(0, 1fr); } }

/* Getting-started checklist: finished steps stay visible, ticked. */
.setup-step.done .setup-dot { border: 0; background: var(--good-solid); display: grid; place-items: center; }
.setup-step.done .setup-dot::after { content: ''; width: 7px; height: 4px; border: 1.6px solid #FFF; border-top: 0; border-right: 0; transform: translateY(-1px) rotate(-45deg); }
.setup-step.done .strong { color: var(--ink-3); font-weight: 500; }

/* ── Launch additions: mobile & touch ───────────────────────────────────── */
/* Crews run Recoatly from a phone in a van: one hand, bright sun, sometimes
   gloves. Everything here is additive — the desktop layout is untouched. */

/* A camera button only where there is a camera worth opening. */
@media (hover: hover) and (pointer: fine) {
  .only-touch { display: none !important; }
}

/* A spinner in the button's own ink, so it shows on every button in both themes. */
@supports (color: color-mix(in srgb, red 50%, transparent)) {
  .btn .spinner, .btn .spinner.dark {
    border-color: color-mix(in srgb, currentColor 28%, transparent);
    border-top-color: currentColor;
  }
}

/* ── My day ─────────────────────────────────────────────────────────────── */

.myday { max-width: 720px; width: 100%; margin: 0 auto; padding-bottom: calc(112px + env(safe-area-inset-bottom)); }
.md-body { min-width: 0; }
.md-head { margin-bottom: 16px; }
.md-head h1 { margin-top: 5px; overflow-wrap: anywhere; }
.md-section { margin-top: 22px; }
.md-section-title {
  font-size: 13px; font-weight: 600; letter-spacing: 0.005em; color: var(--ink-3);
  margin: 0 4px 9px;
}
.md-card {
  background: var(--paper); border-radius: var(--r-lg); box-shadow: var(--shadow-card);
  padding: 14px 16px; min-width: 0;
}
.md-wrap { overflow-wrap: anywhere; }
.md-clock { display: flex; align-items: center; gap: 12px; margin-top: 4px; }
.md-clock.on { box-shadow: var(--shadow-card), inset 0 0 0 1.5px var(--good-solid); }
.md-clock-list { margin-top: 4px; }
.md-clock-list > * + * { margin-top: 10px; }
.md-clock .btn { flex-shrink: 0; }
.md-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--ink-4); flex-shrink: 0; }
.md-dot.on { background: var(--good-solid); animation: md-pulse 2.2s ease-out infinite; }
@keyframes md-pulse {
  0% { box-shadow: 0 0 0 0 rgba(48, 209, 88, 0.45); }
  70% { box-shadow: 0 0 0 8px rgba(48, 209, 88, 0); }
  100% { box-shadow: 0 0 0 0 rgba(48, 209, 88, 0); }
}

.md-stops { display: flex; flex-direction: column; gap: 10px; }
.stop {
  background: var(--paper); border-radius: var(--r-lg); box-shadow: var(--shadow-card);
  padding: 14px 16px 13px; min-width: 0; cursor: pointer; overflow-wrap: anywhere;
  -webkit-tap-highlight-color: transparent;
  transition: box-shadow var(--mid) var(--ease), transform var(--fast) var(--spring), opacity var(--mid) var(--ease);
}
.stop:active { transform: scale(0.995); }
.stop.is-current { box-shadow: var(--shadow-lift), inset 0 0 0 2px var(--accent); }
.stop.is-done { opacity: 0.6; }
.stop-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 5px; }
.stop-time { font-size: 13.5px; font-weight: 600; color: var(--ink-2); margin-right: auto; font-variant-numeric: tabular-nums; }
.stop-badge {
  font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: #FFF; background: var(--accent); border-radius: var(--pill); padding: 2px 9px;
}
.stop-name { font-size: 18px; font-weight: 600; letter-spacing: -0.016em; line-height: 1.25; }
.stop-sub { font-size: 13.5px; color: var(--ink-3); margin-top: 2px; }
.stop-sub:empty { display: none; }
.stop-line { display: flex; align-items: flex-start; gap: 9px; margin-top: 9px; font-size: 14.5px; line-height: 1.42; }
.stop-line svg { flex-shrink: 0; margin-top: 2px; color: var(--ink-3); }
.stop-line > span { min-width: 0; }
.stop-gate { background: var(--warn-bg); border-radius: var(--r-sm); padding: 8px 10px; }
.stop-gate svg { color: var(--warn); }
.stop-gate strong { font-size: 16px; letter-spacing: 0.08em; font-variant-numeric: tabular-nums; }
.stop-note { color: var(--ink-2); }
.stop-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 13px; }
.stop-actions .btn { flex: 1 1 auto; }
.stop-actions .stop-open { flex: 0 0 auto; width: 44px; padding: 0; }

.md-next { display: flex; align-items: center; gap: 12px; color: var(--ink); }
.md-next:hover { opacity: 1; box-shadow: var(--shadow-lift); }
.md-next > svg { color: var(--ink-4); flex-shrink: 0; }

.md-tasks { padding: 4px 0; }
.md-task {
  display: flex; align-items: center; gap: 12px; padding: 11px 16px; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background var(--fast) var(--ease), opacity var(--mid) var(--ease);
}
.md-task + .md-task { border-top: 1px solid var(--line); }
.md-task:active { background: var(--fill); }
.md-task > svg { color: var(--ink-4); flex-shrink: 0; }
.md-task-title { font-size: 14.5px; overflow-wrap: anywhere; }
.md-task.late .md-task-title { color: var(--bad); }
.md-task.done { opacity: 0.55; }
.md-task.done .md-task-title { text-decoration: line-through; color: var(--ink-4); }
.md-location .switch { width: 100%; }

/* The "+" that adds a photo or a note to the job in hand. */
.fab {
  position: fixed; z-index: 60;
  right: calc(18px + env(safe-area-inset-right)); bottom: calc(20px + env(safe-area-inset-bottom));
  width: 58px; height: 58px; border: 0; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: var(--accent); color: #FFF;
  box-shadow: 0 10px 26px rgba(0, 113, 227, 0.34), 0 2px 6px rgba(0, 0, 0, 0.14);
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--fast) var(--spring), background var(--fast) var(--ease);
  animation: pop var(--slow) var(--spring) both;
}
.fab:hover { background: var(--accent-press); }
.fab:active { transform: scale(0.92); }
.fab:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--accent-ring); }
.fab svg { width: 24px; height: 24px; }

.sheet-actions { display: flex; flex-direction: column; gap: 8px; }
.sheet-btn {
  display: flex; align-items: center; gap: 14px; width: 100%; min-height: 60px;
  padding: 10px 16px; border: 0; border-radius: var(--r); background: var(--fill);
  color: var(--ink); font: inherit; text-align: left; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background var(--fast) var(--ease), transform var(--fast) var(--spring);
}
.sheet-btn:hover { background: var(--fill-2); }
.sheet-btn:active { transform: scale(0.985); }
.sheet-btn svg { color: var(--accent); flex-shrink: 0; }
.sheet-btn span { display: flex; flex-direction: column; min-width: 0; }
.sheet-btn strong { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.sheet-btn small { font-size: 12.5px; color: var(--ink-3); }

/* A page that pins something to the screen edge fades in rather than rising:
   a transformed page would become the box its "fixed" children stick to. */
.page.myday, .page.has-actionbar { animation: fade var(--slow) var(--ease) both; }

/* ── Job page: the next action within thumb reach ───────────────────────── */

.actionbar { display: none; }
.board-card .board-move { margin-right: -4px; color: var(--ink-3); flex-shrink: 0; }
.photo-actions { justify-content: center; flex-wrap: wrap; }
/* An empty state's big faded glyph is for the state, not for the buttons in it. */
.empty .btn svg { width: 15px; height: 15px; opacity: 1; margin: 0; }
.empty .btn-sm svg { width: 13px; height: 13px; }
.receipt-label { overflow-wrap: anywhere; }

/* "Shared with customer" on every photo card and in the lightbox. */
.gal-link { display: block; color: inherit; }
.gal-link:hover { opacity: 1; }
.gal-share { padding: 0 11px 10px; }
.share-toggle { font-size: 12.5px; gap: 9px; align-items: center; line-height: 1.3; }
.share-toggle .track { margin-top: 0; }
.share-state { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-3); }
.share-state::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--ink-4); flex-shrink: 0; }
.share-state.on { color: var(--good); }
.share-state.on::before { background: var(--good-solid); }
.lightbox-share { display: flex; align-items: center; }
.lightbox-share .share-state { color: #E5E5EA; }

@media (max-width: 860px) {
  .actionbar {
    display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
    padding: 10px max(14px, env(safe-area-inset-right)) calc(10px + env(safe-area-inset-bottom)) max(14px, env(safe-area-inset-left));
    background: var(--veil);
    -webkit-backdrop-filter: saturate(180%) blur(22px); backdrop-filter: saturate(180%) blur(22px);
    border-top: 1px solid var(--line);
    animation: actionbar-in var(--slow) var(--spring) both;
  }
  .actionbar-status { display: flex; align-items: center; gap: 8px; margin: 0 2px 8px; font-size: 12.5px; color: var(--ink-2); }
  .actionbar-row { display: flex; gap: 10px; }
  .actionbar-row .btn { flex: 1 1 0; min-width: 0; height: 48px; font-size: 15px; }
  .page.has-actionbar { padding-bottom: calc(136px + env(safe-area-inset-bottom)); }
  .page.has-actionbar .head-primary { display: none; }
  /* Toasts sit above whatever is pinned to the bottom edge. */
  body:has(.actionbar) .toasts { bottom: calc(100px + env(safe-area-inset-bottom)); }
  body:has(.fab:not(.hidden)) .toasts { bottom: calc(92px + env(safe-area-inset-bottom)); }
}
@supports not (backdrop-filter: blur(1px)) {
  .actionbar { background: var(--paper); }
}
@keyframes actionbar-in { from { transform: translate3d(0, 100%, 0); } }

/* ── Inspections: answers that save themselves ──────────────────────────── */

.autosave-wrap { display: inline-flex; margin-left: 10px; }
.autosave { font-size: 12.5px; color: var(--ink-3); }
.autosave.good { color: var(--good); }
.autosave.bad { color: var(--bad); font-weight: 550; }
.inspect-item { padding: 12px 0; border-bottom: 1px solid var(--line); }
.inspect-q { display: flex; align-items: flex-start; gap: 14px; }
.inspect-control { flex-shrink: 0; max-width: 100%; }
@media (max-width: 640px) {
  .autosave-wrap { display: flex; margin: 4px 0 0; }
  .inspect-q { flex-direction: column; align-items: stretch; gap: 9px; }
  .inspect-control { flex-shrink: 1; }
  .inspect-control .answer-group { display: flex; width: 100%; }
  .inspect-control .answer-group .btn { flex: 1 1 0; }
  .inspect-control input[type="number"] { max-width: none !important; }
}

/* ── Schedule on a phone ────────────────────────────────────────────────── */

.unscheduled-list { max-height: 420px; overflow-y: auto; }
.unscheduled-card { padding: 10px 14px; border-bottom: 1px solid var(--line); }
.unscheduled-card:last-child { border-bottom: 0; }
.cal-scroll { -webkit-overflow-scrolling: touch; }
@media (max-width: 759.98px) {
  /* Seven columns do not fit a phone; the week scrolls sideways instead of squashing. */
  .cal-scroll-week { overflow-x: auto; border-radius: var(--r-lg); }
  .cal-scroll-week > .cal-week { min-width: 640px; }
  .cal-week.cal-day { grid-template-columns: 50px minmax(0, 1fr); }
  .cal-hour-label { padding: 3px 6px; font-size: 11px; }
  .schedule-page .page-actions { gap: 8px; }
  .schedule-page .page-actions select { flex: 1 1 140px; width: auto; }
  .cal-block { padding: 5px 8px; font-size: 12px; }
}
/* A month on a phone is an overview. A seventh of the screen holds no name,
   so each visit is a bar in its colour, and tapping the day opens it in the
   day view (schedule.js). */
@media (max-width: 560px) {
  .cal-dow div { padding: 8px 0; text-align: center; font-size: 11.5px; }
  .cal-grid { grid-auto-rows: minmax(68px, auto); }
  .cal-cell { padding: 5px 4px 6px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
  .cal-cell:active { background: var(--fill); }
  .cal-date { margin: 0 auto 6px; font-size: 13px; }
  /* .cal-cell in front outranks the touch padding further down. */
  .cal-cell .cal-ev {
    height: 5px; padding: 0; margin: 0 2px 3px; border-radius: var(--pill);
    font-size: 0; pointer-events: none; background: var(--info);
  }
  .cal-cell .cal-ev.good { background: var(--good-solid); }
  .cal-cell .cal-ev.warn { background: var(--warn-solid); }
  .cal-cell .cal-ev.bad { background: var(--bad-solid); }
  .cal-cell .cal-ev.est { background: var(--active-tone); }
  .cal-cell .cal-more { padding: 0; font-size: 10.5px; text-align: center; pointer-events: none; }
}

/* ── Data tables become cards on a phone ────────────────────────────────── */
/* And on a touch tablet up to an 11" iPad on its side: a 1040px table would
   otherwise scroll sideways there, which nobody discovers with a finger. */

@media (max-width: 759.98px), (pointer: coarse) and (max-width: 1194px) {
  .tablewrap { overflow-x: visible; }
  table.data { min-width: 0; display: block; font-size: 14px; }
  table.data thead { display: none; }
  table.data tbody { display: block; }
  table.data tbody tr {
    display: flex; flex-direction: column; gap: 4px; position: relative;
    padding: 13px 16px; border-bottom: 1px solid var(--line);
  }
  table.data tbody tr:last-child { border-bottom: 0; }
  table.data tbody tr.clickable:active { background: var(--fill); }
  table.data td {
    display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
    padding: 0; border: 0; min-width: 0; text-align: right; overflow-wrap: anywhere;
  }
  table.data td[data-label]::before {
    content: attr(data-label); flex: 0 0 auto; max-width: 45%;
    font-size: 12.5px; color: var(--ink-3); text-align: left;
  }
  table.data td > * { min-width: 0; max-width: 100%; }
  table.data td.cell-primary { order: -1; display: block; padding-bottom: 3px; text-align: left; font-size: 15px; }
  table.data td.cell-primary .cell-main { white-space: normal; }
  table.data .cell-sub { white-space: normal; }
  table.data td.cell-empty, table.data td.cell-mobile-hide { display: none; }
  table.data tbody tr.has-select { padding-left: 54px; }
  table.data td.cell-select { position: absolute; left: 4px; top: 4px; display: block; width: 44px; height: 44px; }
  table.data td.cell-select > .cell-check { display: flex; width: 44px; height: 44px; min-width: 44px; max-width: none; margin: 0; }
  table.data td.cell-action { position: absolute; right: 6px; top: 6px; display: block; }
  table.data tbody tr.has-action td.cell-primary { padding-right: 46px; }
  /* Keep "select all" when the header goes. */
  table.data.selectable thead { display: block; }
  table.data.selectable thead tr { display: flex; align-items: center; padding: 2px 16px 2px 4px; border-bottom: 1px solid var(--line); }
  table.data.selectable thead th { display: none; }
  table.data.selectable thead th.cell-select {
    display: flex; align-items: center; position: static; width: auto !important;
    padding: 0; border: 0; background: none; font-size: 13px; font-weight: 500; color: var(--ink-2);
  }
  table.data.selectable thead th.cell-select::after { content: 'Select all'; margin-left: 6px; }
  /* Lined up with the boxes on the cards below, not pulled past the panel's edge. */
  table.data.selectable thead th.cell-select > .cell-check { margin: 0; }
}
/* A tablet has room for the cards two abreast. */
@media (pointer: coarse) and (min-width: 760px) and (max-width: 1194px) {
  table.data tbody { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  table.data tbody tr:nth-child(odd):not(:last-child) { border-right: 1px solid var(--line); }
  table.data tbody tr:nth-last-child(2):nth-child(odd) { border-bottom: 0; }
}
.cell-check { display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }

/* Filters on a phone: search across the top, the pickers two to a row. */
@media (max-width: 759.98px) {
  .filterbar .searchfield { flex: 1 1 100%; min-width: 0; }
  .filterbar > select, .filterbar > input[type="date"] { flex: 1 1 calc(50% - 4px); min-width: 0; }
}

/* ── Touch: targets a thumb can hit, inputs iOS will not zoom into ──────── */

@media (pointer: coarse), (max-width: 860px) {
  .btn { height: 44px; padding: 0 17px; font-size: 14px; }
  .btn-sm { height: 36px; min-width: 40px; padding: 0 13px; font-size: 13px; }
  .btn-lg { height: 50px; }
  .btn-group .btn { height: 36px; min-width: 44px; }
  .seg button { height: 36px; padding: 0 14px; }
  .iconbtn { width: 44px; height: 44px; }
  .iconbtn.sm { width: 36px; height: 36px; }
  .taskcheck { width: 26px; height: 26px; }
  /* Visually compact controls still take a 44px tap. */
  .btn-sm, .btn-group .btn, .seg button, .iconbtn.sm, .taskcheck, .cell-check { position: relative; }
  .btn-sm::after, .btn-group .btn::after, .seg button::after, .iconbtn.sm::after { content: ''; position: absolute; inset: -4px; }
  .taskcheck::after { content: ''; position: absolute; inset: -9px; }
  .cell-check { min-width: 44px; min-height: 44px; margin: -12px; }
  .cell-check input { width: 18px !important; height: 18px !important; }
  .check { padding: 9px 0; align-items: center; }
  .check input { width: 20px; height: 20px; margin: 0; }
  .switch { min-height: 44px; align-items: center; }
  .switch .track { margin-top: 0; }
  .tabs button { min-height: 44px; }
  .menu-item { min-height: 44px; font-size: 14.5px; }
  .rail-link { min-height: 44px; }
  .cal-ev { padding: 5px 8px; }

  input:not([type="checkbox"], [type="radio"], [type="file"], [type="range"],
            [type="color"], [type="submit"], [type="button"], [type="image"], [type="reset"]),
  select, textarea { font-size: 16px !important; }
  input:not([type="checkbox"], [type="radio"], [type="file"], [type="range"],
            [type="color"], [type="submit"], [type="button"], [type="image"], [type="reset"]),
  select { min-height: 44px; }
  .input-affix .prefix, .input-affix .suffix { height: 100%; font-size: 15px; }
  .input-affix.has-prefix input { padding-left: 27px; }
  .itemrow .rowtotal, .itemrow .del { height: 44px; }
}

@media (max-width: 860px) {
  /* Nothing on a page may push it wider than the screen. */
  .main { overflow-x: clip; }
  .page { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
  .myday { padding-bottom: calc(112px + env(safe-area-inset-bottom)); }
  .md-head h1 { font-size: 24px; }

  .toasts { left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom)); align-items: stretch; }
  .toast { max-width: none; }

  .modal-foot { flex-wrap: wrap; padding-bottom: calc(14px + env(safe-area-inset-bottom)); }
  .drawer { width: 100vw; }
  .drawer-foot { padding-bottom: calc(14px + env(safe-area-inset-bottom)); }
  .lightbox-bar { flex-wrap: wrap; padding: max(12px, env(safe-area-inset-top)) 14px 12px; }
}

/* ── The shell on a phone, at home on the screen ────────────────────────────
   app.html asks for the whole screen (viewport-fit=cover), so the notch, the
   status bar and the home indicator are the page's to keep clear: in Safari
   on its side, from the home screen, and inside the App Store and Play Store
   builds. Every env() below is 0 on a computer. */

.topbar {
  height: calc(var(--top-h) + env(safe-area-inset-top));
  padding-top: env(safe-area-inset-top);
  padding-right: max(22px, env(safe-area-inset-right));
}
@media screen { .page { padding-right: max(26px, env(safe-area-inset-right)); } }
.cal-week-head > div { top: calc(var(--top-h) + env(safe-area-inset-top)); }
/* 100vh on a phone or a tablet is the screen behind Safari's toolbars; the
   rail's foot (who is signed in) belongs above them. */
.rail {
  height: 100vh; height: 100dvh;
  padding-top: env(safe-area-inset-top); padding-left: env(safe-area-inset-left);
}
.rail-foot { padding-bottom: calc(10px + env(safe-area-inset-bottom)); }

/* The app has its own pressed states (every button scales a little), so the
   browser's tap flash, a blue box on Android, only says "web page". */
body { -webkit-tap-highlight-color: transparent; }

@media (max-width: 860px) {
  .topbar {
    padding-left: max(14px, env(safe-area-inset-left));
    padding-right: max(14px, env(safe-area-inset-right));
  }
  .page {
    padding-left: max(16px, env(safe-area-inset-left));
    padding-right: max(16px, env(safe-area-inset-right));
  }
  .scrim { padding-top: env(safe-area-inset-top); }
  .drawer-head { padding-top: calc(18px + env(safe-area-inset-top)); }

  /* Page actions share their row evenly, so a wrapped row reads as a set of
     buttons rather than leftovers… */
  .page-actions > .btn:not(.head-more) { flex: 1 1 auto; }
  /* …and "More actions" moves up beside the breadcrumb, where a phone keeps
     it, instead of wrapping onto a line of its own. */
  .page-head:has(.head-more) { position: relative; }
  .page-head:has(.head-more) .breadcrumb { padding-right: 48px; }
  .page-head .head-more { position: absolute; top: -9px; right: 0; width: 36px; height: 36px; padding: 0; }
  .page-head .head-more::after { content: ''; position: absolute; inset: -4px; }

  /* Columns of a board settle one at a time under a swipe. */
  .board { scroll-snap-type: x mandatory; }
  .board-col { scroll-snap-align: start; }
}
@media (max-width: 560px) {
  /* Two numbers to a row: an odd last one gets the whole row, not half. */
  .stats > .stat:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (max-width: 480px) {
  .topbar {
    padding-left: max(10px, env(safe-area-inset-left));
    padding-right: max(10px, env(safe-area-inset-right));
  }
}

/* Links under an address: Maps, measure, delete. A thumb needs more than
   the 17px a line of small text gives it. */
.addr-links { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 6px; }
.addr-links .link-danger { border: 0; background: none; color: var(--bad); cursor: pointer; padding: 0; }
@media (pointer: coarse), (max-width: 860px) {
  .addr-links { gap: 0 18px; margin-top: 0; }
  .addr-links > * { display: inline-flex; align-items: center; min-height: 40px; }
}

/* ── Settings & account (agent) ───────────────────────────────────────────
   Settings and My profile. Everything is prefixed set- (acct- for the few
   pieces only My profile uses), so none of it reaches another page. */

/* A reading-width column for tabs that are mostly text. */
.set-narrow { max-width: 780px; }

/* Rows of fields in one form get the same spacing as single fields. */
.set-form .inline-fields { margin-bottom: 14px; }
.set-hint { font-size: 12px; line-height: 1.45; color: var(--ink-3); margin-top: 8px; }
.set-hint:empty { display: none; }
.set-hint.warn { color: var(--warn); margin-top: 6px; }
.set-gap { margin: 14px 0 0; }
.set-break { overflow-wrap: anywhere; word-break: break-word; }

/* A value shown where an input would be, for people who can look but not change. */
.set-value { min-height: 34px; padding: 7px 0; font-size: 14px; line-height: 1.45; color: var(--ink); overflow-wrap: anywhere; }
.set-value.multiline { white-space: pre-wrap; }
.set-value.is-blank { color: var(--ink-4); }

/* Facts: long values wrap, and on a phone each label sits above its value. */
.set-kv dd { min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 520px) {
  .set-kv { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .set-kv dt { font-size: 12.5px; }
  .set-kv dd { margin-bottom: 10px; }
  .set-kv dd:last-child { margin-bottom: 0; }
}

/* Notes: one sentence of context with an icon, toned like the chips. */
.set-note {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 14px; margin-bottom: 14px; border-radius: var(--r-sm);
  background: var(--fill); color: var(--ink-2); font-size: 13px; line-height: 1.5;
}
.set-note > svg { flex-shrink: 0; margin-top: 2px; color: var(--ink-3); }
.set-note > div { flex: 1; min-width: 0; }
.set-note .strong { color: var(--ink); }
.set-note.info { background: var(--info-bg); }
.set-note.info > svg { color: var(--info); }
.set-note.warn { background: var(--warn-bg); }
.set-note.warn > svg { color: var(--warn); }
.set-note.good { background: var(--good-bg); }
.set-note.good > svg { color: var(--good); }
.panel-body .set-note:last-child { margin-bottom: 0; }

/* Lists of rows: connections, features, devices, webhooks, alerts. */
.set-list > * + * { border-top: 1px solid var(--line); }
.set-list-top { border-top: 1px solid var(--line); }
.set-row { display: flex; align-items: flex-start; gap: 14px; padding: 14px 18px; }
.set-row > .switch { flex: 1; min-width: 0; }
.set-row > .switch > span > div:first-child { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); }
.set-row > .switch .tiny.muted { margin-top: 2px; font-size: 12.5px; line-height: 1.45; }
.set-row-main { flex: 1; min-width: 0; }
.set-row-title {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px;
  font-size: 14px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink);
}
.set-row-sub { margin-top: 3px; font-size: 13px; line-height: 1.5; color: var(--ink-2); }
.set-row-meta { margin-top: 3px; font-size: 12.5px; color: var(--ink-3); overflow-wrap: anywhere; }
.set-row-icon {
  width: 34px; height: 34px; flex-shrink: 0; display: grid; place-items: center;
  border-radius: var(--r-sm); background: var(--fill); color: var(--ink-2);
}
.set-row-end { flex-shrink: 0; display: flex; align-items: center; gap: 8px; align-self: center; }
.set-row-link { display: inline-flex; align-items: center; gap: 3px; margin-top: 8px; font-size: 13px; font-weight: 500; }
.set-flag-note { color: var(--ink-3); }
.set-intro { margin: 0; padding: 0 18px 14px; font-size: 13px; line-height: 1.5; color: var(--ink-2); }

/* Yes or no, as two cards; the picked one is outlined in the accent. */
.set-question-field { margin-bottom: 4px; }
.set-question { font-size: 15px; font-weight: 600; letter-spacing: -0.012em; color: var(--ink); }
.set-choices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 10px; }
.set-choice {
  display: flex; align-items: flex-start; gap: 10px; padding: 13px 14px;
  border-radius: var(--r); background: var(--fill); cursor: pointer;
  box-shadow: inset 0 0 0 1.5px transparent;
  transition: background var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.set-choice:hover { background: var(--fill-2); }
.set-choice.is-picked { background: var(--accent-soft); box-shadow: inset 0 0 0 1.5px var(--accent); }
.set-choice:has(input:focus-visible) { box-shadow: inset 0 0 0 1.5px var(--accent), 0 0 0 4px var(--accent-ring); }
.set-choice input { width: 18px; height: 18px; margin: 1px 0 0; flex-shrink: 0; accent-color: var(--accent); cursor: pointer; }
.set-choice-title { display: block; font-size: 14px; font-weight: 600; color: var(--ink); }
.set-choice-sub { display: block; margin-top: 2px; font-size: 12.5px; line-height: 1.45; color: var(--ink-2); }
@media (max-width: 560px) { .set-choices { grid-template-columns: minmax(0, 1fr); } }

/* A status card: a round icon, a headline, a few lines and the next step. */
.set-status { display: flex; align-items: flex-start; gap: 14px; }
.set-status-icon {
  width: 42px; height: 42px; flex-shrink: 0; display: grid; place-items: center;
  border-radius: 50%; background: var(--fill); color: var(--ink-2);
}
.set-status-icon.good { background: var(--good-bg); color: var(--good); }
.set-status-icon.warn { background: var(--warn-bg); color: var(--warn); }
.set-status-icon.info { background: var(--info-bg); color: var(--info); }
.set-status-title { font-size: 16px; font-weight: 600; line-height: 1.3; letter-spacing: -0.016em; color: var(--ink); }
.set-status-text { margin: 6px 0 0; max-width: 620px; font-size: 13.5px; line-height: 1.55; color: var(--ink-2); }
.set-status-text.set-flush { margin: 0; }
.set-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 14px; }
@media (max-width: 520px) {
  .set-status { gap: 12px; }
  .set-status-icon { width: 36px; height: 36px; }
}

/* Logo and brand color. */
.set-logo { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; }
.set-logo-box {
  width: 168px; height: 84px; flex-shrink: 0; display: grid; place-items: center; padding: 10px;
  border-radius: var(--r-sm); background: var(--sunken); box-shadow: inset 0 0 0 1px var(--line);
  color: var(--ink-3); font-size: 12.5px; text-align: center; overflow: hidden;
}
/* Logos are drawn for white paper, so they are previewed on white in both themes. */
.set-logo-box.has-logo { background: #FFFFFF; box-shadow: inset 0 0 0 1px var(--line-2); }
.set-logo-box img { display: block; max-width: 100%; max-height: 100%; object-fit: contain; }
.set-logo-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.set-color { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.set-color input[type="color"] {
  width: 48px; height: 34px; padding: 3px; cursor: pointer;
  border: 1px solid var(--line-2); border-radius: var(--r-sm); background: var(--paper);
}
.set-swatch { width: 24px; height: 24px; flex-shrink: 0; border-radius: 6px; box-shadow: inset 0 0 0 1px var(--line-2); }

/* Sending hours: two short time fields side by side, even on a phone. */
.set-times { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; max-width: 400px; }
.set-times .field { margin-bottom: 0; }

.set-bullets { display: grid; gap: 9px; margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.5; color: var(--ink-2); }
.set-code {
  margin: 0; padding: 12px 14px; border-radius: var(--r-sm); background: var(--sunken);
  font-family: var(--font-mono); font-size: 11.5px; line-height: 1.6; color: var(--ink-2);
  white-space: pre; overflow-x: auto;
}
.set-secret { display: flex; align-items: center; gap: 8px; }
.set-secret input { min-width: 0; font-family: var(--font-mono); font-size: 12.5px; }
.set-events { max-height: 200px; overflow-y: auto; margin-top: 8px; padding-left: 4px; }
.set-events.is-off { opacity: 0.5; }

/* My profile. */
.acct-who { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.acct-email { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: 15px; }

@media (pointer: coarse), (max-width: 860px) {
  .set-color input[type="color"] { width: 56px; height: 44px; }
  .set-choice { padding: 15px 14px; }
  .set-choice input { width: 20px; height: 20px; }
}
@media (max-width: 860px) {
  .set-row { padding: 14px 16px; }
  .set-intro { padding: 0 16px 14px; }
  .set-secret { flex-wrap: wrap; }
  .set-secret .btn { flex: 1; }
}

/* ── Auth screens (agent) ── */
/* Sign in, sign up, password reset, email confirmation and invitations
   (public/js/auth.js). The two-panel layout under "Auth & portal" stays; this
   adds the form details, the status screens and the phone layout. */

.auth-wrap { min-height: 100vh; min-height: 100dvh; }
.auth-main { justify-content: flex-start; gap: 28px; padding: 32px 56px 24px; }
.auth-center { flex: 1; display: flex; flex-direction: column; justify-content: center; }
.auth-top { display: none; }
.auth-foot { display: flex; justify-content: center; flex-wrap: wrap; gap: 6px 20px; font-size: 12.5px; }
.auth-foot a { color: var(--ink-3); }
.auth-foot a:hover { color: var(--ink); opacity: 1; }

/* The dark panel stays in view while a long form scrolls past it. */
@media (min-width: 941px) {
  .auth-aside { position: sticky; top: 0; align-self: start; height: 100vh; height: 100dvh; overflow-y: auto; }
}

/* The logo is ink on paper and white on the dark panel, never the accent. */
.auth-brand { display: inline-flex; align-items: center; gap: 9px; color: var(--ink); }
.auth-brand:hover { opacity: 0.8; }
.auth-brand .rail-word { font-size: 15px; }
.auth-aside .auth-brand { color: #F5F5F7; }
.auth-aside .auth-pitch {
  font-size: 40px; font-weight: 600; line-height: 1.1; letter-spacing: -0.03em;
  color: #FFF; max-width: 540px; margin: 0 0 16px;
}
.auth-aside .auth-aside-note { font-size: 12.5px; color: #8E8E93; margin: 0; }

.auth-form { max-width: 380px; animation: rise var(--mid) var(--ease-out) both; }
.auth-form.wide { max-width: 400px; }
.auth-title { font-size: 26px; line-height: 1.15; letter-spacing: -0.024em; margin: 0 0 6px; overflow-wrap: anywhere; }
.auth-title:focus { outline: none; }
.auth-lede { font-size: 14px; line-height: 1.5; color: var(--ink-2); margin: 0 0 24px; overflow-wrap: anywhere; }
.auth-lede + .auth-lede { margin-top: -14px; }
.auth-lede strong, .auth-note strong { color: var(--ink); font-weight: 600; }

/* Fields */
.auth-form .field { margin-bottom: 16px; }
.auth-form input:not([type="checkbox"]):not([type="radio"]), .auth-form select { height: 40px; font-size: 14px; }
.auth-form input[readonly] { background: var(--sunken); color: var(--ink-2); }
.auth-form .field-error:empty { margin: 0; }
.auth-form .field-error a { font-weight: 550; }
.auth-form .field.invalid input, .auth-form .field.invalid select { border-color: var(--bad); box-shadow: none; }
.auth-form .field.invalid input:focus, .auth-form .field.invalid select:focus {
  border-color: var(--bad);
  box-shadow: 0 0 0 4px var(--bad-bg);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--bad) 26%, transparent);
}
.auth-form .field.invalid input[type="checkbox"] { outline: 2px solid var(--bad); outline-offset: 2px; }
.auth-form .check { color: var(--ink-2); line-height: 1.45; }
.auth-form .check a { font-weight: 550; }
.auth-optional { font-weight: 400; color: var(--ink-3); }

/* Password with a Show/Hide switch inside the field. */
.auth-pw { position: relative; }
.auth-pw input { padding-right: 70px; }
.auth-reveal {
  position: absolute; top: 50%; right: 5px; transform: translateY(-50%);
  height: 30px; padding: 0 11px; border: 0; border-radius: var(--pill);
  background: transparent; color: var(--ink-2); font-size: 12.5px; font-weight: 550; cursor: pointer;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.auth-reveal:hover { background: var(--fill); color: var(--ink); }
.auth-reveal:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.auth-reveal::after { content: ''; position: absolute; inset: -7px -3px; }

/* Strength: three segments that fill as a new password gets harder to guess. */
.auth-meter { display: flex; gap: 4px; margin-top: 8px; }
.auth-meter span { flex: 1; height: 4px; border-radius: var(--pill); background: var(--fill-2); transition: background-color var(--mid) var(--ease); }
.auth-meter[data-level="1"] span:first-child { background: var(--bad-solid); }
.auth-meter[data-level="2"] span:nth-child(-n+2) { background: var(--warn-solid); }
.auth-meter[data-level="3"] span { background: var(--good-solid); }

/* Time zone: a small select under the country, prefilled from the browser. */
.auth-tz { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; margin-top: 8px; font-size: 12.5px; }
.auth-tz label { font-weight: 550; color: var(--ink-2); }
.auth-form .auth-tz select {
  width: auto; max-width: 100%; height: 30px; padding: 0 28px 0 11px;
  border-radius: var(--pill); font-size: 12.5px; background-position: right 10px center;
}

.auth-forgot { margin: -6px 0 18px; text-align: right; font-size: 13px; }

/* Messages above a form. The live region stays in the page while empty, so
   screen readers are already listening when a message arrives. */
.auth-live:empty { display: block; height: 0; }
.auth-note {
  display: flex; align-items: flex-start; gap: 10px;
  margin: 0 0 18px; padding: 11px 14px; border-radius: var(--r);
  background: var(--fill); color: var(--ink); font-size: 13.5px; line-height: 1.45;
  animation: rise var(--mid) var(--ease-out) both;
}
.auth-note svg { flex-shrink: 0; margin-top: 2px; }
.auth-note a { font-weight: 550; }
.auth-note.bad { background: var(--bad-bg); }
.auth-note.bad svg { color: var(--bad); }
.auth-note.good { background: var(--good-bg); }
.auth-note.good svg { color: var(--good); }
.auth-note.info { background: var(--info-bg); }
.auth-note.info svg { color: var(--info); }

.auth-switch { margin: 22px 0 0; text-align: center; font-size: 13.5px; color: var(--ink-2); }
.auth-fine { margin: 12px 0 0; text-align: center; font-size: 12.5px; line-height: 1.5; color: var(--ink-3); }
.auth-fine:empty { display: none; }
.auth-linkbtn {
  padding: 0; border: 0; background: none; color: var(--link); font: inherit; cursor: pointer;
  transition: opacity var(--fast) var(--ease);
}
.auth-linkbtn:hover { opacity: 0.68; }
.auth-linkbtn:focus-visible { outline: 2px solid var(--accent-ring); outline-offset: 2px; border-radius: 4px; }

/* Confirmations and dead links: an icon, a heading, a line or two, one next step. */
.auth-badge {
  width: 48px; height: 48px; border-radius: 50%; display: grid; place-items: center;
  margin-bottom: 18px; background: var(--fill); color: var(--ink-2);
}
.auth-badge svg { width: 22px; height: 22px; }
.auth-badge.good { background: var(--good-bg); color: var(--good); }
.auth-badge.warn { background: var(--warn-bg); color: var(--warn); }
.auth-badge.bad { background: var(--bad-bg); color: var(--bad); }
.auth-badge.info { background: var(--info-bg); color: var(--info); }
.auth-actions { display: grid; gap: 10px; }
.auth-loading { display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 180px; color: var(--ink-3); font-size: 13.5px; }

/* Development only: the demo company's sign-in. */
.auth-demo-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; color: var(--ink); }
.auth-demo-cred { display: flex; justify-content: space-between; gap: 12px; padding: 2px 0; }
.auth-demo-cred .mono { color: var(--ink); text-align: right; overflow-wrap: anywhere; }
.auth-demo-note { margin: 8px 0 0; line-height: 1.45; }

/* Tablets and phones: the dark panel goes and the logo sits above the form.
   The env() insets keep it clear of the notch and the home indicator when the
   page has the whole screen (from the home screen, or inside the store apps). */
@media (max-width: 940px) {
  .auth-top { display: flex; width: 100%; max-width: 400px; margin: 0 auto; }
  .auth-main {
    min-height: 100vh; min-height: 100dvh;
    padding: calc(24px + env(safe-area-inset-top)) 24px calc(20px + env(safe-area-inset-bottom));
  }
}
@media (max-width: 600px) {
  .auth-main {
    gap: 26px;
    padding: calc(16px + env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
      calc(20px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  }
  .auth-center { justify-content: flex-start; }
  .auth-title { font-size: 24px; }
  .auth-lede { margin-bottom: 20px; }
  .auth-reveal { height: 36px; }
}

/* ── Customer pages (agent) ── */
/* What a contractor's customers open from an email: estimates, invoices,
   agreements, reviews, unsubscribe, reports, forms, the account, the hosted
   site and the instant quote (public/js/portal.js). Built on the document,
   panel and form styles above; everything new is prefixed cp-. */

/* The contractor's colour. portal.js computes light and dark variants as
   --cp-* on <html>; the page swaps them in for the accent tokens. */
body.cp-branded {
  --accent: var(--cp-accent);
  --accent-press: var(--cp-accent-press);
  --accent-ring: var(--cp-accent-ring);
  --accent-soft: var(--cp-accent-soft);
  --accent-ink: var(--cp-accent-ink);
  --link: var(--cp-link);
}
[data-theme='dark'] body.cp-branded {
  --accent: var(--cp-accent-d);
  --accent-press: var(--cp-accent-press-d);
  --accent-ring: var(--cp-accent-ring-d);
  --accent-soft: var(--cp-accent-soft-d);
  --accent-ink: var(--cp-accent-ink-d);
  --link: var(--cp-link-d);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) body.cp-branded {
    --accent: var(--cp-accent-d);
    --accent-press: var(--cp-accent-press-d);
    --accent-ring: var(--cp-accent-ring-d);
    --accent-soft: var(--cp-accent-soft-d);
    --accent-ink: var(--cp-accent-ink-d);
    --link: var(--cp-link-d);
  }
}
/* The hosted site is pinned to light, so it keeps the light variants. */
body.cp-branded .site {
  --accent: var(--cp-accent);
  --accent-press: var(--cp-accent-press);
  --accent-ring: var(--cp-accent-ring);
  --accent-soft: var(--cp-accent-soft);
  --accent-ink: var(--cp-accent-ink);
  --link: var(--cp-link);
}
body.cp-branded .btn-primary { color: var(--accent-ink, #FFF); }
.cp .chip.info, .cp-sheet-form .chip.info { background: var(--accent-soft); color: var(--link); }

/* Frame */
.doc-page.cp { padding-bottom: calc(84px + env(safe-area-inset-bottom)); }
.doc-page.cp-narrow { max-width: 580px; }
.cp [hidden], .cp-sheet-form [hidden] { display: none !important; }
.cp a:not(.btn):focus-visible, .cp-sheet-form a:not(.btn):focus-visible, .cp summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px;
}
.cp .check input:focus-visible, .cp-sheet-form .check input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cp-print-only { display: none; }

.cp-head { margin-bottom: 22px; }
.cp-head .cp-name { min-width: 0; overflow-wrap: anywhere; line-height: 1.2; }
.cp-logo { display: block; width: auto; height: auto; max-height: 44px; max-width: min(220px, 55vw); object-fit: contain; }
.cp-head-meta { margin-left: auto; flex-shrink: 0; display: flex; flex-direction: column; align-items: flex-end; gap: 3px; text-align: right; }
.cp-head-sub { font-size: 13px; font-weight: 600; letter-spacing: -0.01em; }
.cp-head-phone { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--ink-2); }
.cp-head-phone svg { color: var(--ink-3); }
/* A logo drawn for white paper stays legible on a dark page. */
[data-theme='dark'] .cp-logo { background: #FFF; padding: 5px 9px; border-radius: 9px; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .cp-logo { background: #FFF; padding: 5px 9px; border-radius: 9px; }
}

.cp-banner {
  display: flex; align-items: flex-start; gap: 10px;
  margin: 0 0 16px; padding: 12px 14px; border-radius: var(--r);
  background: var(--warn-bg); box-shadow: inset 0 0 0 1px rgba(255, 159, 10, 0.4);
  color: var(--ink); font-size: 13.5px; line-height: 1.45;
}
.cp-banner svg { flex-shrink: 0; margin-top: 2px; color: var(--warn); }
.cp-banner p { margin: 0; }

.cp-notice {
  --cp-tone: var(--link); --cp-tone-bg: var(--accent-soft);
  display: flex; align-items: flex-start; gap: 12px;
  margin: 0 0 14px; padding: 15px 16px; border-radius: var(--r-lg);
  background: var(--paper); box-shadow: var(--shadow-card), inset 3px 0 0 var(--cp-tone);
  animation: rise var(--slow) var(--spring) both;
}
.cp-notice:focus { outline: none; }
.cp-notice:focus-visible { box-shadow: var(--shadow-card), inset 3px 0 0 var(--cp-tone), 0 0 0 3px var(--accent-ring); }
.cp-notice.good { --cp-tone: var(--good); --cp-tone-bg: var(--good-bg); }
.cp-notice.warn { --cp-tone: var(--warn); --cp-tone-bg: var(--warn-bg); }
.cp-notice.bad { --cp-tone: var(--bad); --cp-tone-bg: var(--bad-bg); }
.cp-notice-icon {
  width: 30px; height: 30px; flex-shrink: 0; border-radius: 50%;
  display: grid; place-items: center; background: var(--cp-tone-bg); color: var(--cp-tone);
}
.cp-notice-main { flex: 1; min-width: 0; }
.cp-notice-title { padding-top: 4px; font-size: 15px; font-weight: 600; line-height: 1.35; letter-spacing: -0.012em; }
.cp-notice-body { margin: 4px 0 0; font-size: 13.5px; line-height: 1.5; color: var(--ink-2); }
.cp-notice-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }

.cp-loading { display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 42vh; color: var(--ink-3); font-size: 14px; }
.cp-card-body { padding: 26px 24px; }
.cp-panel-title { font-size: 17px; letter-spacing: -0.014em; }
.cp-empty { padding: 44px 22px; }
.cp-empty-title { margin: 0 0 8px; font-size: 19px; letter-spacing: -0.016em; color: var(--ink); }

.cp-foot {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  margin-top: 34px; padding-top: 18px; border-top: 1px solid var(--line);
  text-align: center; font-size: 12.5px; color: var(--ink-3);
}
.cp-foot-name { font-weight: 600; color: var(--ink-2); }
.cp-foot-contact { overflow-wrap: anywhere; }
.cp-foot-contact a { color: var(--ink-2); }
/* Recoatly, once, small and in the page's own grey. */
.cp-powered { display: inline-flex; align-items: center; gap: 6px; margin-top: 14px; font-size: 11px; letter-spacing: 0.01em; color: var(--ink-4); }
.cp-powered svg { width: 7px; height: 12px; flex-shrink: 0; color: currentColor; }
.cp-site-powered { color: rgba(255, 255, 255, 0.5); margin-top: 18px; }

.cp-toolbar { display: flex; justify-content: flex-end; gap: 8px; margin: 0 0 10px; }
.cp-print-btn svg { opacity: 0.8; }
.cp-card .panel-head + .cp-card-body { padding-top: 6px; }
.cp-list .panel-head { padding-bottom: 10px; }
.cp-stats { margin-bottom: 6px; }

/* Documents */
.cp-doc-lead { flex: 1; min-width: 0; }
.cp-doc .doc-title { overflow-wrap: anywhere; }
.cp-doc-sub { margin-top: 6px; }
.cp-meta { flex-shrink: 0; }
.cp-meta-number { margin: 2px 0 6px; font-size: 17px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); }
.cp-meta-chip { margin: 0 0 6px; }
.cp-doc .doc-party .small { margin-top: 2px; overflow-wrap: anywhere; }
.cp-message { margin: 0 0 22px; white-space: pre-wrap; overflow-wrap: anywhere; font-size: 14px; line-height: 1.6; color: var(--ink-2); }
.cp-items td:first-child { overflow-wrap: anywhere; }
.cp-items td.r { white-space: nowrap; }
.cp-item-name { font-weight: 600; }
.cp-item-math { display: none; }
.cp-amount { font-weight: 600; }
.cp-totals-note { margin: 8px 0 0; font-size: 12px; line-height: 1.4; color: var(--ink-3); text-align: right; }
.cp-deposit-row { margin-top: 6px; padding-top: 10px; border-top: 1px dashed var(--line-2); }
.cp-balance-row { margin-top: 4px; font-size: 15px; font-weight: 600; }
.cp-tip-row { font-size: 12.5px; }

.cp-extras { min-width: 0; margin: 26px 0 0; padding: 0; border: 0; }
.cp-extras legend { padding: 0; margin-bottom: 6px; }
.cp-extras-hint { margin: 0 0 10px; }
.cp-extra { align-items: flex-start; margin-bottom: 8px; padding: 12px 14px; border-radius: var(--r); background: var(--sunken); }
.cp-extra:has(input:checked) { background: var(--accent-soft); box-shadow: inset 0 0 0 1.5px var(--accent); }
.cp-extra-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cp-extra-price { font-weight: 600; white-space: nowrap; }

.cp-payments { margin-top: 26px; }
.cp-payments .eyebrow { margin: 0 0 4px; }
.cp-pay-list { list-style: none; margin: 0; padding: 0; }
.cp-pay-item { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.cp-pay-item:last-child { border-bottom: 0; }
.cp-pay-when { color: var(--ink-2); }
.cp-pay-amount { font-weight: 600; text-align: right; white-space: nowrap; }
.cp-pay-tip { font-weight: 400; color: var(--ink-3); }

.cp-howto { margin-bottom: 14px; }
.cp-instructions { margin: 0 0 10px; white-space: pre-wrap; overflow-wrap: anywhere; font-size: 14px; line-height: 1.55; }
.cp-print-howto { margin-top: 22px; }
.cp-howto-ways { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }

.cp-photos .gallery, .cp-docs { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
.cp-file-thumb { display: grid; place-items: center; color: var(--ink-3); }

/* The bar that follows you down the page: approve, sign, pay. */
.cp-actionbar { bottom: max(12px, env(safe-area-inset-bottom)); z-index: 20; }
.cp-actionbar-text { flex: 1 1 220px; min-width: 0; }
.cp-actionbar-buttons { display: flex; flex-wrap: wrap; gap: 8px; }

/* Sheets: approve, decline, sign, pay, request */
.cp-sheet-lead { margin: 0 0 14px; font-size: 14px; line-height: 1.5; }
.cp-opt { font-weight: 400; color: var(--ink-3); }
.cp-form-error {
  margin: 4px 0 14px; padding: 10px 12px; border-radius: var(--r-sm);
  background: var(--bad-bg); color: var(--bad); font-size: 13px; font-weight: 550; line-height: 1.45;
}
.cp-form-error:focus { outline: none; }
.cp-money-input input { font-weight: 600; font-size: 16px; letter-spacing: -0.01em; }

.cp-tips { min-width: 0; margin: 0 0 14px; padding: 0; border: 0; }
.cp-tips legend { padding: 0; }
.cp-tips .field { margin: 10px 0 0; }
.cp-seg { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
.cp-seg-item { position: relative; display: block; cursor: pointer; }
.cp-seg-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.cp-seg-label {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  min-height: 48px; padding: 6px 2px; border-radius: var(--r-sm);
  background: var(--fill); font-size: 13.5px; font-weight: 600; text-align: center;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.cp-seg-sub { font-size: 11px; font-weight: 500; color: var(--ink-3); }
.cp-seg-item:hover .cp-seg-label { background: var(--fill-2); }
.cp-seg-input:checked + .cp-seg-label { background: var(--accent); color: var(--accent-ink, #FFF); }
.cp-seg-input:checked + .cp-seg-label .cp-seg-sub { color: inherit; opacity: 0.85; }
.cp-seg-input:focus-visible + .cp-seg-label { box-shadow: 0 0 0 3px var(--accent-ring); }

.cp-pay-sum { margin: 4px 0 14px; padding: 12px 14px; border-radius: var(--r); background: var(--sunken); }
.cp-sum-row { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; font-size: 13.5px; }
.cp-sum-row dt { color: var(--ink-2); }
.cp-sum-row dd { margin: 0; }
.cp-sum-total { margin-top: 6px; padding-top: 9px; border-top: 1px solid var(--line-2); font-size: 16px; font-weight: 600; }
.cp-sum-total dt { color: var(--ink); }
.cp-secure { display: flex; align-items: center; gap: 6px; margin: 12px 0 0; font-size: 12px; color: var(--ink-3); }
.cp-secure svg { flex-shrink: 0; }
.cp-unavailable { margin-top: 12px; padding: 12px 14px; border-radius: var(--r); background: var(--warn-bg); }
.cp-unavailable-lead { margin: 0 0 8px; font-weight: 550; }
.cp-unavailable .cp-instructions { margin: 4px 0 0; }

/* Signatures stay ink on paper, whatever the appearance. */
.cp-sigfield { margin-bottom: 8px; }
.cp-sigpad { height: 140px; background: #FFF; border-color: rgba(0, 0, 0, 0.22); }
.cp-sig-tools { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 30px; margin-top: 6px; }
.cp-sig-state { font-size: 12px; color: var(--ink-3); }
.cp-typed-sig { margin: 0 0 14px; }
.cp-signed { border-top: 1px solid var(--line); }
.cp-sig-img { display: block; max-width: 100%; max-height: 96px; margin: 10px 0 8px; padding: 8px 12px; border-radius: var(--r-sm); background: #FFF; }

.cp-success { padding: 14px 6px 6px; text-align: center; }
.cp-success:focus { outline: none; }
.cp-success-icon {
  width: 52px; height: 52px; margin: 0 auto 14px; border-radius: 50%;
  display: grid; place-items: center; background: var(--good-bg); color: var(--good);
  animation: pop var(--slow) var(--spring) both;
}
.cp-success-title { margin: 0 0 8px; font-size: 20px; letter-spacing: -0.018em; }
.cp-success p { max-width: 420px; margin: 0 auto 8px; font-size: 14px; line-height: 1.55; color: var(--ink-2); }

/* Forms */
.cp-form textarea { min-height: 96px; }
.cp-form-submit { margin-top: 6px; }
.cp-consent { margin: 2px 0 8px; }
.cp-consent .field { margin-bottom: 6px; }
.cp-consent .check { font-size: 13px; line-height: 1.45; color: var(--ink-2); }
.cp-signin-title { margin: 0 0 6px; font-size: 24px; letter-spacing: -0.022em; }
.cp-signin .cp-notice { margin: 14px 0; }

/* Review */
.cp-review-title { margin: 4px 0 8px; font-size: 22px; line-height: 1.25; letter-spacing: -0.02em; text-align: center; overflow-wrap: anywhere; }
.cp-review-lead { max-width: 420px; margin: 0 auto 4px; text-align: center; }
.cp-review-form .field { text-align: left; }
.cp-stars-field { min-width: 0; margin: 16px 0 14px; padding: 0; border: 0; text-align: center; }
.cp-stars { display: inline-flex; gap: 2px; }
.cp-star-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.cp-star { display: grid; place-items: center; width: 50px; height: 50px; border-radius: 12px; cursor: pointer; }
.cp-star-glyph { font-size: 38px; line-height: 1; color: var(--ink-4); opacity: 0.45; transition: color var(--fast) var(--ease), opacity var(--fast) var(--ease), transform var(--fast) var(--spring); }
.cp-star.on .cp-star-glyph { color: #FF9F0A; opacity: 1; }
.cp-star:active .cp-star-glyph { transform: scale(0.9); }
.cp-star-input:focus-visible + .cp-star { box-shadow: 0 0 0 3px var(--accent-ring); }
.cp-stars-caption { min-height: 19px; margin-top: 4px; font-size: 13px; color: var(--ink-3); }
.cp-preview-hint { margin: 10px 0 0; }
.cp-share { display: flex; flex-direction: column; align-items: center; gap: 10px; margin-top: 18px; padding-top: 20px; border-top: 1px solid var(--line); text-align: center; }
.cp-share-lead { max-width: 360px; margin: 0; font-size: 15px; font-weight: 550; line-height: 1.45; }
.cp-copy { margin-top: 2px; }

/* Unsubscribe */
.cp-unsub { text-align: center; }
.cp-unsub .cp-notice { text-align: left; }
.cp-unsub-icon {
  width: 52px; height: 52px; margin: 6px auto 14px; border-radius: 50%;
  display: grid; place-items: center; background: var(--accent-soft); color: var(--link);
}
.cp-unsub-title { margin: 0 0 10px; font-size: 21px; line-height: 1.25; letter-spacing: -0.02em; overflow-wrap: anywhere; }
.cp-unsub-email { margin: 0 0 10px; color: var(--ink-2); overflow-wrap: anywhere; }
.cp-unsub p.muted { max-width: 400px; margin: 0 auto 18px; }
.cp-unsub-actions { display: flex; justify-content: center; margin-top: 8px; }
.cp-unsub .cp-form-error { margin-top: 14px; }

/* Inspection report */
.cp-score { margin: 2px 0; font-size: 26px; font-weight: 600; letter-spacing: -0.02em; }
.cp-score.good { color: var(--good); }
.cp-score.warn { color: var(--warn); }
.cp-check-section { margin-bottom: 22px; }
.cp-check-section .eyebrow { margin: 0 0 4px; }
.cp-checks { list-style: none; margin: 0; padding: 0; }
.cp-check { display: flex; align-items: flex-start; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 13.5px; }
.cp-check:last-child { border-bottom: 0; }
.cp-check-text { flex: 1; min-width: 0; }
.cp-check .chip { flex-shrink: 0; }
.cp-check-value { flex-shrink: 0; max-width: 45%; font-weight: 600; text-align: right; overflow-wrap: anywhere; }

/* Account */
.cp-portal-hero { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.cp-portal-title { margin: 0 0 4px; font-size: 26px; letter-spacing: -0.024em; }
.cp-portal-hello p { margin: 0; }
.cp-portal-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.cp-rows { list-style: none; margin: 0; padding: 0; }
.cp-row { display: flex; align-items: center; gap: 12px; padding: 12px 18px; border-top: 1px solid var(--line); }
.cp-row-main { flex: 1; min-width: 0; }
.cp-row-title { font-size: 14px; font-weight: 600; overflow-wrap: anywhere; }
.cp-row-sub { margin-top: 2px; font-size: 12.5px; color: var(--ink-3); overflow-wrap: anywhere; }
.cp-row-side { flex-shrink: 0; }
.cp-row-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }

/* Instant quote */
.cp-quote-intro { margin: 4px 0 6px; }
.cp-quote-title { margin: 0 0 8px; font-size: 28px; line-height: 1.15; letter-spacing: -0.026em; }
.cp-quote-intro p { max-width: 620px; margin: 0; }
.cp-quote-list { display: flex; flex-direction: column; }
.cp-quote-row { gap: 14px; }
.cp-quote-label { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; cursor: pointer; }
.cp-qty-wrap { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.cp-qty-wrap .tiny { min-width: 44px; }
.cp input.cp-qty { width: 96px; text-align: right; }
.cp-quote-totals { width: 100%; max-width: 440px; }
.cp-quote-empty { margin: 0; }

/* Hosted website */
.cp-site-ctas { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 24px; }
.cp-site-call { background: transparent; box-shadow: inset 0 0 0 1.5px var(--line-2); }
.cp-site-call:hover { background: var(--fill); }
.cp-site-logo { display: block; max-height: 48px; max-width: 220px; margin: 0 auto; object-fit: contain; }
.cp-site-hero-media { max-width: 940px; margin: 40px auto 0; padding: 0 26px; }
.cp-site-hero-media img { display: block; width: 100%; max-height: 460px; object-fit: cover; border-radius: var(--r-xl); box-shadow: var(--shadow-lift); }
.cp-site-service-name { margin: 0 0 4px; font-size: 16px; letter-spacing: -0.012em; }
.cp-site-form { max-width: 640px; }
.cp-site-form-lead { margin: -10px 0 22px; }
.cp-site-contact { margin-top: 4px; }
.cp-site-contact a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.cp-star-off { color: rgba(0, 0, 0, 0.14); }

/* Phones */
@media (max-width: 600px) {
  .cp-head { padding: 8px 0 16px; margin-bottom: 16px; }
  .cp-head .portal-logo { font-size: 17px; }
  .cp-doc .doc-title { font-size: 22px; }
  .cp-col-qty, .cp-col-rate { display: none; }
  .cp-item-math { display: block; }
  .cp-doc .lineitems th:first-child, .cp-doc .lineitems td:first-child { padding-left: 0; }
  .cp-doc .lineitems th:last-child, .cp-doc .lineitems td:last-child { padding-right: 0; }
  .cp-notice { padding: 13px 14px; }
  .cp-card-body { padding: 22px 18px; }
  .cp-actionbar { padding: 12px; gap: 10px; border-radius: var(--r-lg); }
  .cp-actionbar-buttons { width: 100%; }
  .cp-actionbar-buttons .btn { flex: 1 1 0; min-width: 0; }
  .cp-actionbar-buttons .btn-lg { flex: 2 1 0; }
  .cp-row { flex-wrap: wrap; padding: 12px 14px; }
  .cp-row-side { width: 100%; }
  .cp-row-actions { justify-content: space-between; }
  .cp-portal-actions { width: 100%; }
  .cp-portal-actions .btn { flex: 1 1 auto; }
  .cp-quote-row { flex-wrap: wrap; }
  .cp-quote-title, .cp-portal-title { font-size: 24px; }
  .cp-site-hero-media { margin-top: 28px; padding: 0 16px; }
  .cp-site-ctas .btn { flex: 1 1 100%; }
}
@media (max-width: 360px) {
  .cp-seg { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Print and "Download PDF": a clean letterhead document on white, A4 or
   Letter, whatever the screen's appearance. */
@media print {
  @page { size: auto; margin: 14mm 12mm; }
  :root {
    --canvas: #FFF !important; --paper: #FFF !important; --sunken: #F5F5F7 !important;
    --ink: #1D1D1F !important; --ink-2: #3A3A3C !important; --ink-3: #6E6E73 !important; --ink-4: #8E8E93 !important;
    --line: rgba(0, 0, 0, 0.12) !important; --line-2: rgba(0, 0, 0, 0.26) !important;
    --good: #137333 !important; --warn: #9A5B00 !important; --bad: #CE2A21 !important; --info: #1D1D1F !important;
    --good-bg: transparent !important; --warn-bg: transparent !important; --bad-bg: transparent !important;
    --info-bg: transparent !important; --neutral-bg: transparent !important;
    color-scheme: light;
  }
  body.cp-branded { --link: #1D1D1F !important; --accent-soft: transparent !important; }
  html, body { background: #FFF !important; }
  .cp-banner, .cp-notice, .cp-toolbar, .cp-actionbar, .cp-howto, .cp-photos, .cp-foot,
  .cp .btn, .toasts, .scrim, .cp-extras-hint { display: none !important; }
  .cp-print-only { display: block !important; }
  .doc-page, .doc-page.cp { max-width: none; margin: 0; padding: 0; animation: none; }
  .cp-head { padding: 0 0 12pt; margin-bottom: 16pt; border-bottom: 1px solid rgba(0, 0, 0, 0.2); }
  .cp-logo { background: none !important; padding: 0 !important; max-height: 52px; }
  .cp-head-phone svg { display: none; }
  .cp a { color: inherit !important; }
  .cp-doc, .doc { box-shadow: none !important; border-radius: 0 !important; overflow: visible !important; background: #FFF !important; }
  .cp-doc .doc-head { flex-direction: row !important; gap: 20pt; padding: 0 0 12pt !important; }
  .cp-doc .doc-title { font-size: 20pt !important; }
  .cp-doc .doc-meta { margin-left: auto !important; text-align: right !important; }
  .cp-doc .doc-body { padding: 14pt 0 !important; }
  .cp-doc .doc-parties { grid-template-columns: 1fr 1fr !important; gap: 20pt; }
  .cp-doc .doc-totals { width: 260px !important; margin-left: auto; break-inside: avoid; }
  .cp-doc .doc-foot { padding: 12pt 0 0 !important; background: none !important; break-inside: avoid; }
  .cp-col-qty, .cp-col-rate { display: table-cell !important; }
  .cp-item-math { display: none !important; }
  .lineitems thead { display: table-header-group; }
  .lineitems tr, .cp-check, .cp-pay-item { break-inside: avoid; }
  .cp-extra { padding: 4pt 0; background: none !important; box-shadow: none !important; }
  .cp .chip { padding: 0 6px; border: 1px solid currentColor; background: none !important; }
  .cp-sig-img { padding: 0; }
  .cp *, .cp *::before, .cp *::after { animation: none !important; transition: none !important; }
}
