/* ==========================================================================
   Anchor — application design system
   Extends the public site's "Harbour ledger" identity (paper ground, navy
   ink, one signal accent) into a denser, operational UI for the client and
   staff portals. Type: Stack Sans Notch (display) · IBM Plex Sans (text)
   · IBM Plex Mono (labels, ids, statuses).
   ========================================================================== */

@font-face {
  font-family: "Stack Sans Notch";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("assets/fonts/StackSansNotch-Bold.ttf") format("truetype");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/IBMPlexSans-400.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/IBMPlexSans-400-italic.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/IBMPlexSans-500.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("assets/fonts/IBMPlexSans-600.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/IBMPlexMono-400.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/IBMPlexMono-500.woff2") format("woff2");
}

:root {
  /* colour — shared with the public site */
  --paper: #f6f4ef;
  --paper-dim: #edeae1;
  --card: #fbfaf7;          /* slightly lifted surface for panels on paper */
  --ink: #16222e;
  --slate: #4e5c69;
  --navy: #14324d;
  --navy-deep: #0d2236;
  --line: #d9d4c8;
  --line-mid: #b9b2a2;
  --line-ink: #16222e;
  --accent: #bc4318;
  --accent-deep: #9c3512;
  --paper-on-navy: #f6f4ef;
  --line-on-navy: rgba(246, 244, 239, 0.18);
  --slate-on-navy: #9fb0bf;

  /* semantic states (never colour-only — always paired with a label) */
  --ok: #1d6b46;
  --ok-soft: #e2ede5;
  --warn: #8a5a00;
  --warn-soft: #f3ead6;
  --crit: #b3261e;
  --crit-soft: #f4e0dd;
  --info: #14324d;
  --info-soft: #e2e8ed;
  --neutral-soft: #eae7de;

  /* type */
  --font-display: "Stack Sans Notch", "IBM Plex Sans", "Helvetica Neue", Arial, sans-serif;
  --font-text: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* motion (see .agents/skills/emil-design-eng) */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);

  /* rhythm — denser than the marketing site */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;
  --radius: 2px;
  --sidebar-w: 232px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

[hidden] { display: none !important; }

body {
  font-family: var(--font-text);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

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

a { color: inherit; text-decoration: none; }
p a, li a, td a, .prose a {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--line-mid);
  transition: text-decoration-color 150ms ease;
}
p a:hover, li a:hover, td a:hover, .prose a:hover { text-decoration-color: var(--accent); }

a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

::selection { background: var(--navy); color: var(--paper); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); overflow: hidden; white-space: nowrap;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 300;
  background: var(--navy); color: var(--paper); padding: 10px 16px;
  font-weight: 500;
}
.skip-link:focus { left: 0; }

/* Hide until entitlements/session resolved — prevents a flash of nav items
   the current user doesn't own. */
body.js-loading .app-main, body.js-loading .app-sidebar { visibility: hidden; }

/* --------------------------------------------------------------------------
   Type
   -------------------------------------------------------------------------- */
h1, h2 { font-family: var(--font-display); font-weight: 700; line-height: 1.08; letter-spacing: 0.005em; }
h3, h4 { font-family: var(--font-text); font-weight: 600; line-height: 1.3; }

.mono {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--slate);
}
.muted { color: var(--slate); }
.small { font-size: 0.85rem; }

/* mono section eyebrow with trailing rule: "01 — Services" */
.eyebrow {
  display: flex; align-items: center; gap: var(--sp-3);
  font-family: var(--font-mono);
  font-size: 0.72rem; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--slate);
  margin-bottom: var(--sp-4);
}
.eyebrow::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.eyebrow .num { color: var(--accent); }

/* --------------------------------------------------------------------------
   App shell: fixed sidebar on desktop, topbar + drawer on mobile
   -------------------------------------------------------------------------- */
.app { display: flex; min-height: 100vh; }

.app-sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  width: var(--sidebar-w);
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border-right: 1px solid var(--line);
  z-index: 100;
  overflow-y: auto;
}

.side-brand {
  display: flex; align-items: center; gap: 10px;
  padding: 18px 20px 16px;
  border-bottom: 1px solid var(--line);
}
.side-brand .brand-mark { width: 22px; height: 22px; object-fit: contain; }
.side-brand .brand-name {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.15rem; line-height: 1;
  transform: translateY(1px);
}
.side-brand .brand-scope {
  margin-left: auto;
  font-family: var(--font-mono); font-size: 0.6rem; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--slate);
  border: 1px solid var(--line-mid);
  padding: 2px 6px;
  border-radius: var(--radius);
}
/* Beta-environment indicator — injected at runtime (see the
   markBetaEnvironment() call in script.js/staff-script.js) only when the
   page is served from a beta.* hostname, so this exact same build is safe
   to reuse for the eventual production deploy without carrying it over.
   Small and bordered like the existing Client/Staff tag beside it, in the
   accent colour, so it reads as one more label rather than a loud banner. */
.brand-scope.is-beta {
  margin-left: 6px;
  color: var(--accent);
  border-color: var(--accent);
}

.side-nav { flex: 1; padding: var(--sp-4) 0; }
.side-group + .side-group { margin-top: var(--sp-5); }
.side-group-label {
  font-family: var(--font-mono); font-size: 0.62rem; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--slate);
  padding: 0 20px;
  margin-bottom: var(--sp-2);
}
.side-nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 20px;
  font-size: 0.9rem; font-weight: 500;
  color: var(--ink);
  border-left: 2px solid transparent;
  transition: background-color 120ms ease, border-color 120ms ease;
}
.side-nav a:hover { background: var(--paper-dim); }
.side-nav a[aria-current="page"] {
  border-left-color: var(--accent);
  background: var(--paper-dim);
  font-weight: 600;
}
.side-nav a .ext {
  margin-left: auto;
  font-family: var(--font-mono); font-size: 0.72rem;
  color: var(--slate);
}
.side-nav svg { width: 16px; height: 16px; flex: none; color: var(--slate); }
.side-nav a[aria-current="page"] svg { color: var(--accent); }

.side-foot {
  border-top: 1px solid var(--line);
  padding: 14px 20px;
}
.side-user { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.side-user .who { min-width: 0; }
.side-user .who .name { font-weight: 600; font-size: 0.88rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.side-user .who .role {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--slate); margin-top: 1px;
}
.side-user .logout, .side-user .staff-logout {
  flex: none;
  font-size: 0.8rem; font-weight: 500; color: var(--slate);
  border: 1px solid var(--line-mid); border-radius: var(--radius);
  padding: 5px 10px;
  transition: border-color 140ms ease, color 140ms ease;
}
.side-user .logout:hover, .side-user .staff-logout:hover { border-color: var(--crit); color: var(--crit); }

/* mobile topbar */
.app-topbar {
  display: none;
  position: sticky; top: 0; z-index: 120;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  align-items: center; gap: 12px;
  padding: 0 var(--sp-4);
  height: 56px;
}
.app-topbar .side-brand { border: none; padding: 0; flex: 1; }
.nav-toggle {
  display: block;
  background: none; border: none; cursor: pointer; padding: 10px;
  margin-left: -10px;
}
.nav-toggle span {
  display: block; width: 20px; height: 2px; background: var(--ink);
  transition: transform 200ms var(--ease-out), opacity 150ms ease;
}
.nav-toggle span + span { margin-top: 5px; }
body.nav-open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
body.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
body.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.app-main {
  flex: 1;
  margin-left: var(--sidebar-w);
  min-width: 0;
  padding: var(--sp-6) var(--sp-6) var(--sp-8);
}
.main-inner { max-width: 1120px; margin: 0 auto; }

@media (max-width: 900px) {
  .app-sidebar {
    inset: 56px 0 auto 0;
    width: 100%;
    border-right: none;
    border-bottom: 1px solid var(--line);
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    transition: transform 200ms var(--ease-out), opacity 150ms ease;
    max-height: calc(100vh - 56px);
    z-index: 110;
  }
  body.nav-open .app-sidebar { transform: translateY(0); opacity: 1; pointer-events: auto; }
  .app-sidebar .side-brand { display: none; }
  .app-topbar { display: flex; }
  .app-main { margin-left: 0; padding: var(--sp-5) var(--sp-4) var(--sp-7); }
  .side-nav a { padding: 12px 20px; }
}
@media (prefers-reduced-motion: reduce) {
  .app-sidebar, .nav-toggle span { transition: none; }
}

/* --------------------------------------------------------------------------
   Page header
   -------------------------------------------------------------------------- */
.page-head { margin-bottom: var(--sp-6); }
.page-head .crumb {
  font-family: var(--font-mono); font-size: 0.7rem; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--slate);
  margin-bottom: var(--sp-3);
}
.page-head .crumb a:hover { color: var(--accent); }
.page-head .crumb .sep { color: var(--line-mid); margin: 0 6px; }
.page-head h1 { font-size: clamp(1.5rem, 3vw, 2rem); margin-bottom: 6px; }
.page-head .sub { color: var(--slate); max-width: 62ch; }
.page-head-row {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap;
}
.page-head-row .actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-text); font-size: 0.88rem; font-weight: 500;
  padding: 9px 18px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 160ms var(--ease-out), border-color 160ms var(--ease-out),
              color 160ms var(--ease-out), transform 160ms var(--ease-out);
}
.btn:active { transform: scale(0.97); }
.btn[disabled] { opacity: 0.55; cursor: not-allowed; }
.btn[disabled]:active { transform: none; }

.btn-primary { background: var(--navy); color: var(--paper); }
.btn-primary:hover { background: var(--navy-deep); }
.btn-accent { background: var(--accent); color: #fff; }
.btn-accent:hover { background: var(--accent-deep); }
.btn-ghost, .btn-secondary { background: transparent; color: var(--ink); border-color: var(--line-mid); }
.btn-ghost:hover, .btn-secondary:hover { border-color: var(--ink); }
.btn-danger { background: transparent; color: var(--crit); border-color: var(--crit); }
.btn-danger:hover { background: var(--crit); color: #fff; }
.btn-quiet { background: none; border: none; color: var(--slate); padding: 4px 8px; font-size: 0.82rem; }
.btn-quiet:hover { color: var(--accent); }

.btn-small { padding: 5px 12px; font-size: 0.8rem; }
.btn-block { width: 100%; }

/* text link with arrow */
.link-arrow { display: inline-flex; align-items: baseline; gap: 8px; font-weight: 500; color: var(--ink); }
.link-arrow .arr { font-family: var(--font-mono); transition: transform 180ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .link-arrow:hover .arr { transform: translateX(4px); }
  .link-arrow:hover { color: var(--accent); }
}

/* --------------------------------------------------------------------------
   Panels & sections — flat, bordered, ledger-like. Not everything is a card.
   -------------------------------------------------------------------------- */
.panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-5);
  margin-bottom: var(--sp-5);
}
.panel-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); flex-wrap: wrap;
  margin-bottom: var(--sp-4);
}
.panel-head h2 { font-size: 1.05rem; font-family: var(--font-text); font-weight: 600; }
.panel-head .mono { margin-left: auto; }
.panel > :last-child { margin-bottom: 0; }

/* flat section (no box) with top rule, for primary page content */
.sect { padding: var(--sp-5) 0; border-top: 1px solid var(--line-ink); margin-bottom: var(--sp-5); }
.sect .eyebrow { margin-top: calc(-1 * var(--sp-2)); }

/* ledger strip — bordered columns of figures */
.ledger {
  border-top: 1px solid var(--line-ink);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  margin-bottom: var(--sp-5);
}
.ledger > div {
  padding: var(--sp-4) var(--sp-4) var(--sp-4) 0;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  min-width: 0;
}
.ledger > div + div { padding-left: var(--sp-4); }
.ledger > div:last-child { border-right: none; }
.ledger .val {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.45rem; line-height: 1.15;
  overflow-wrap: anywhere;
}
.ledger .val.small-val { font-family: var(--font-text); font-weight: 600; font-size: 1.02rem; }
.ledger .lab {
  font-family: var(--font-mono); font-size: 0.65rem; font-weight: 400;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--slate);
  margin-top: 4px;
}

/* --------------------------------------------------------------------------
   Status badges — small mono chips with a dot; text always carries meaning
   -------------------------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: 0.65rem; font-weight: 500;
  letter-spacing: 0.07em; text-transform: uppercase;
  padding: 2px 8px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  white-space: nowrap;
}
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.badge-ok    { color: var(--ok);   background: var(--ok-soft); }
.badge-warn  { color: var(--warn); background: var(--warn-soft); }
.badge-crit  { color: var(--crit); background: var(--crit-soft); }
.badge-info  { color: var(--info); background: var(--info-soft); }
.badge-off   { color: var(--slate); background: var(--neutral-soft); }
.badge-plain { border-color: var(--line-mid); color: var(--slate); background: none; }
.badge-plain::before { display: none; }

/* --------------------------------------------------------------------------
   Attention list (dashboard "needs attention")
   -------------------------------------------------------------------------- */
.attn-list { border-top: 1px solid var(--line-ink); margin-bottom: var(--sp-5); }
.attn {
  display: flex; align-items: flex-start; gap: var(--sp-4);
  padding: var(--sp-4) 0;
  border-bottom: 1px solid var(--line);
}
.attn .attn-marker {
  flex: none; width: 8px; height: 8px; border-radius: 50%;
  margin-top: 7px;
}
.attn.is-crit .attn-marker { background: var(--crit); }
.attn.is-warn .attn-marker { background: var(--warn); }
.attn.is-info .attn-marker { background: var(--info); }
.attn .attn-body { flex: 1; min-width: 0; }
.attn h3 { font-size: 0.95rem; margin-bottom: 2px; }
.attn p { font-size: 0.88rem; color: var(--slate); }
.attn .attn-action { flex: none; align-self: center; }
.attn-quiet {
  display: flex; align-items: center; gap: 10px;
  padding: var(--sp-4) 0; border-bottom: 1px solid var(--line);
  color: var(--slate); font-size: 0.9rem;
}
.attn-quiet .tick { color: var(--ok); font-family: var(--font-mono); }

/* --------------------------------------------------------------------------
   Tables — hairline ledger style
   -------------------------------------------------------------------------- */
.table-scroll { overflow-x: auto; }
table.tbl {
  width: 100%;
  border-collapse: collapse;
  border-top: 1px solid var(--line-ink);
  font-size: 0.88rem;
}
.tbl th {
  text-align: left;
  font-family: var(--font-mono); font-size: 0.65rem; font-weight: 500;
  letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--slate);
  padding: 10px 14px 8px 0;
  border-bottom: 1px solid var(--line-mid);
  white-space: nowrap;
}
.tbl td {
  padding: 11px 14px 11px 0;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
.tbl tr:hover > td { background: rgba(22, 34, 46, 0.025); }
.tbl .num { text-align: right; font-variant-numeric: tabular-nums; }
.tbl th.num { text-align: right; }
.tbl .actions-cell { text-align: right; white-space: nowrap; }
.tbl .mono-cell { font-family: var(--font-mono); font-size: 0.78rem; letter-spacing: 0.02em; text-transform: none; }
.tbl .empty-row td { color: var(--slate); padding: var(--sp-5) 0; }

/* Stacked-record layout for operational tables on narrow screens — opt-in
   via .tbl-stack (alongside .tbl) so simple tables that already fit at
   375px (Team, Mail domains) can keep the plain scrollable table instead.
   Each <tr> becomes a hairline-bordered record (same border/radius tokens
   as .panel, not a rounded "card"); each <td> keeps its column label,
   using the same mono/uppercase/slate treatment as .ledger .lab and
   .kv-row .k elsewhere in this system, so it reads as the same app rather
   than a bolted-on mobile view. Cells that hold detail/expand content
   (colspan) are left as plain block content, not stacked as a record. */
@media (max-width: 640px) {
  .tbl-stack, .tbl-stack tbody, .tbl-stack tr, .tbl-stack td { display: block; width: 100%; }
  .tbl-stack thead {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    clip: rect(0 0 0 0); overflow: hidden; white-space: nowrap;
  }
  .tbl-stack tbody tr {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: var(--sp-3) var(--sp-4);
    margin-bottom: var(--sp-3);
  }
  .tbl-stack tbody tr:last-child { margin-bottom: 0; }
  .tbl-stack td {
    display: flex; flex-wrap: wrap; align-items: baseline;
    gap: 2px var(--sp-3);
    padding: 7px 0;
    border-bottom: 1px solid var(--line);
  }
  .tbl-stack td:last-child { border-bottom: none; }
  .tbl-stack td::before {
    content: attr(data-label);
    flex: 1 0 100%;
    font-family: var(--font-mono); font-size: 0.65rem; font-weight: 500;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--slate);
  }
  .tbl-stack td.actions-cell {
    justify-content: flex-start;
    text-align: left;
    padding-top: var(--sp-3);
  }
  .tbl-stack td.actions-cell::before { display: none; }
  .tbl-stack td.actions-cell .btn { width: 100%; justify-content: center; }
  /* Inline-editable cells (role/extension on Team, custom-domain add on
     Sites, etc.) carry fixed pixel widths sized for a table column — let
     them use the full stacked-record width instead of staying cramped. */
  .tbl-stack td > select, .tbl-stack td > input { width: 100% !important; flex: 1 0 100%; }
  /* Detail/expand rows (e.g. a file manager under a site row) hold one
     colspan'd cell of non-tabular content — leave those as plain blocks,
     not a labelled "record". */
  .tbl-stack td[colspan] {
    padding: 0; border-bottom: none;
  }
  .tbl-stack td[colspan]::before { display: none; }
  .tbl-stack tr:has(> td[colspan]) { border: none; padding: 0; margin-bottom: var(--sp-3); }
  .tbl-stack .empty-row td { padding: var(--sp-4) 0; }
  /* The table no longer needs a horizontal scroller once it's stacked. */
  .table-scroll:has(.tbl-stack) { overflow-x: visible; }
}

/* --------------------------------------------------------------------------
   Definition rows (key → value)
   -------------------------------------------------------------------------- */
.kv { border-top: 1px solid var(--line-ink); }
.kv-row {
  display: grid; grid-template-columns: minmax(120px, 3fr) minmax(0, 9fr);
  gap: var(--sp-2) var(--sp-5);
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}
.kv-row .k {
  font-family: var(--font-mono); font-size: 0.68rem; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--slate);
}
.kv-row .v { min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 540px) { .kv-row { grid-template-columns: 1fr; gap: 2px; } }

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
.field { margin-bottom: var(--sp-4); }
.field label { display: block; font-weight: 500; font-size: 0.85rem; margin-bottom: 6px; }
.field .hint { font-weight: 400; color: var(--slate); }

input[type="text"], input[type="email"], input[type="password"], input[type="search"],
input[type="tel"], input[type="number"], input[type="file"], select, textarea {
  width: 100%;
  font-family: var(--font-text); font-size: 0.92rem; color: var(--ink);
  background: #fff;
  border: 1px solid var(--line-mid);
  border-radius: var(--radius);
  padding: 9px 12px;
  transition: border-color 150ms ease;
}
input:hover, select:hover, textarea:hover { border-color: var(--slate); }
input:focus, select:focus, textarea:focus { border-color: var(--navy); outline-offset: 0; }
textarea { resize: vertical; min-height: 90px; }
select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--slate) 50%), linear-gradient(135deg, var(--slate) 50%, transparent 50%); background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%; background-size: 5px 5px; background-repeat: no-repeat; padding-right: 30px; }

.field-row { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.field-row > * { flex: 1; min-width: 140px; }

.check-row { display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4); }
.check-row label {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 0.88rem; font-weight: 500; cursor: pointer;
  border: 1px solid var(--line-mid); border-radius: var(--radius);
  padding: 7px 12px;
  transition: border-color 140ms ease, background-color 140ms ease;
}
.check-row label:hover { border-color: var(--slate); }
.check-row label:has(input:checked) { border-color: var(--navy); background: var(--info-soft); }
.check-row input { width: 15px; height: 15px; accent-color: var(--navy); }

.form-error {
  color: var(--crit);
  font-size: 0.85rem;
  margin-top: var(--sp-3);
}
.form-success { color: var(--ok); font-size: 0.85rem; margin-top: var(--sp-3); }
.form-success a { color: inherit; }

/* --------------------------------------------------------------------------
   Login pages
   -------------------------------------------------------------------------- */
.login-page { min-height: 100vh; display: flex; flex-direction: column; }
.login-back { padding: var(--sp-5) var(--sp-5) 0; font-size: 0.88rem; color: var(--slate); }
.login-back a:hover { color: var(--accent); }
.login-center { flex: 1; display: flex; align-items: center; justify-content: center; padding: var(--sp-5); }
.login-card {
  width: 100%; max-width: 400px;
  background: var(--card);
  border: 1px solid var(--ink);
  box-shadow: 6px 6px 0 rgba(22, 34, 46, 0.12);
  border-radius: var(--radius);
  padding: var(--sp-6);
}
.login-card .brand { display: flex; align-items: center; gap: 10px; margin-bottom: var(--sp-5); }
.login-card .brand-mark { width: 24px; height: 24px; object-fit: contain; }
.login-card .brand-name { font-family: var(--font-display); font-weight: 700; font-size: 1.25rem; transform: translateY(1px); }
.login-card .eyebrow { margin-bottom: var(--sp-4); }
.login-card h1 { font-size: 1.35rem; margin-bottom: var(--sp-5); }
.login-foot { margin-top: var(--sp-5); padding-top: var(--sp-4); border-top: 1px solid var(--line); font-size: 0.85rem; color: var(--slate); }
.login-foot a { font-weight: 500; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line-mid); }
.login-foot a:hover { text-decoration-color: var(--accent); }
.login-error { color: var(--crit); font-size: 0.85rem; margin-top: var(--sp-3); }

/* --------------------------------------------------------------------------
   Service rows / cards
   -------------------------------------------------------------------------- */
.svc-list { border-top: 1px solid var(--line-ink); margin-bottom: var(--sp-5); }
.svc-row {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 4fr) auto;
  gap: var(--sp-3) var(--sp-5);
  align-items: center;
  padding: var(--sp-4) 0;
  border-bottom: 1px solid var(--line);
}
.svc-row h3 { font-size: 0.98rem; margin-bottom: 2px; }
.svc-row .svc-kind {
  font-family: var(--font-mono); font-size: 0.65rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--slate);
}
.svc-row .svc-meta { font-size: 0.85rem; color: var(--slate); overflow-wrap: anywhere; }
.svc-row .svc-actions { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 700px) {
  .svc-row { grid-template-columns: 1fr; }
  .svc-row .svc-actions { justify-content: flex-start; }
}

/* framed screenshot plate (shared with the public site) */
.plate {
  border: 1px solid var(--ink);
  background: #fff;
  box-shadow: 4px 4px 0 rgba(22, 34, 46, 0.12);
}
.plate img { width: 100%; height: auto; display: block; }
.plate-bar {
  display: flex; align-items: center; gap: 5px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}
.plate-bar i { width: 7px; height: 7px; border-radius: 50%; background: var(--line-mid); font-style: normal; }
.plate-bar .plate-url {
  margin-left: 6px;
  font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.04em;
  color: var(--slate);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.plate-empty {
  aspect-ratio: 16 / 10;
  display: flex; align-items: center; justify-content: center;
  background: var(--paper-dim);
  font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--slate);
}

.site-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: var(--sp-5);
  margin-bottom: var(--sp-5);
}
.site-card { cursor: pointer; text-align: left; background: none; border: none; padding: 0; font: inherit; color: inherit; }
.site-card .plate { transition: transform 180ms var(--ease-out), box-shadow 180ms var(--ease-out); }
.site-card:hover .plate { transform: translate(-2px, -2px); box-shadow: 6px 6px 0 rgba(22, 34, 46, 0.14); }
.site-card.selected .plate { box-shadow: 4px 4px 0 var(--accent); border-color: var(--accent); }
.site-card .site-name { font-weight: 600; font-size: 0.92rem; margin-top: 10px; }
.site-card .site-domain { font-family: var(--font-mono); font-size: 0.72rem; color: var(--slate); margin-top: 1px; overflow-wrap: anywhere; }
@media (prefers-reduced-motion: reduce) { .site-card .plate { transition: none; } .site-card:hover .plate { transform: none; } }

/* --------------------------------------------------------------------------
   Bar chart (traffic)
   -------------------------------------------------------------------------- */
.chart { display: flex; align-items: flex-end; gap: 10px; height: 150px; padding-top: 8px; }
.chart .bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; gap: 6px; max-width: 64px; }
.chart .bar { width: 100%; max-width: 34px; background: var(--navy); border-radius: 1px 1px 0 0; min-height: 3px; }
.chart .bar-col:first-child .bar { background: var(--accent); }
.chart .bar-label { font-family: var(--font-mono); font-size: 0.68rem; color: var(--slate); text-transform: uppercase; }
.chart .bar-count { font-family: var(--font-mono); font-size: 0.7rem; color: var(--ink); }
.chart-empty { color: var(--slate); font-size: 0.88rem; }

/* --------------------------------------------------------------------------
   Empty & loading states
   -------------------------------------------------------------------------- */
.empty-state {
  border: 1px dashed var(--line-mid);
  border-radius: var(--radius);
  padding: var(--sp-6) var(--sp-5);
  text-align: center;
  color: var(--slate);
  font-size: 0.9rem;
  margin-bottom: var(--sp-5);
}
.empty-state strong { display: block; color: var(--ink); font-weight: 600; margin-bottom: 4px; }

.skel {
  display: inline-block;
  background: linear-gradient(90deg, var(--paper-dim) 25%, var(--line) 50%, var(--paper-dim) 75%);
  background-size: 200% 100%;
  animation: skel-shimmer 1.4s ease infinite;
  border-radius: var(--radius);
  color: transparent !important;
  min-height: 0.9em; min-width: 3ch;
  user-select: none;
}
@keyframes skel-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .skel { animation: none; } }

/* --------------------------------------------------------------------------
   Modal
   -------------------------------------------------------------------------- */
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(13, 34, 54, 0.45);
  display: flex; align-items: center; justify-content: center;
  padding: var(--sp-5);
  z-index: 200;
  animation: modal-fade 160ms ease-out;
}
.modal {
  width: 100%; max-width: 460px;
  max-height: 90vh; overflow-y: auto;
  background: var(--card);
  border: 1px solid var(--ink);
  box-shadow: 6px 6px 0 rgba(22, 34, 46, 0.18);
  border-radius: var(--radius);
  padding: var(--sp-5);
  animation: modal-in 200ms var(--ease-out);
}
.modal .panel-head h2 { font-size: 1.05rem; }
@keyframes modal-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes modal-in { from { opacity: 0; transform: translateY(8px) scale(0.98); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .modal-overlay, .modal { animation: none; } }

/* --------------------------------------------------------------------------
   Toasts (call notifications, confirmations)
   -------------------------------------------------------------------------- */
.toast-stack {
  position: fixed; top: 16px; right: 16px; z-index: 400;
  display: flex; flex-direction: column; gap: 10px;
  max-width: 340px;
}
.toast {
  display: block;
  background: var(--navy-deep); color: var(--paper);
  border: 1px solid var(--navy);
  border-radius: var(--radius);
  box-shadow: 6px 6px 0 rgba(13, 34, 54, 0.25);
  padding: 13px 16px;
  font-size: 0.88rem;
  animation: toast-in 200ms var(--ease-out);
}
.toast .toast-kicker {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--slate-on-navy); margin-bottom: 4px;
}
.toast .toast-title { font-weight: 600; font-size: 0.95rem; }
.toast .toast-meta { font-size: 0.82rem; color: var(--slate-on-navy); margin-top: 2px; }
.toast .toast-code {
  margin-top: 8px; padding: 5px 10px;
  background: rgba(246, 244, 239, 0.12);
  border-radius: var(--radius);
  font-family: var(--font-mono); font-size: 1.05rem; letter-spacing: 0.08em;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }

/* --------------------------------------------------------------------------
   Command palette (staff)
   -------------------------------------------------------------------------- */
.cmdk-overlay {
  position: fixed; inset: 0;
  background: rgba(13, 34, 54, 0.35);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 12vh var(--sp-5) var(--sp-5);
  z-index: 300;
}
.cmdk {
  width: 100%; max-width: 540px;
  background: var(--card);
  border: 1px solid var(--ink);
  box-shadow: 6px 6px 0 rgba(22, 34, 46, 0.18);
  border-radius: var(--radius);
  overflow: hidden;
}
.cmdk input {
  border: none; border-bottom: 1px solid var(--line);
  border-radius: 0;
  padding: 14px 16px;
  font-size: 1rem;
  background: transparent;
}
.cmdk input:focus { outline: none; border-bottom-color: var(--navy); }
.cmdk-results { max-height: 320px; overflow-y: auto; padding: 6px 0; }
.cmdk-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  padding: 9px 16px;
  font: inherit; font-size: 0.9rem; color: var(--ink);
}
.cmdk-item .cmdk-kind {
  font-family: var(--font-mono); font-size: 0.6rem; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--slate);
  border: 1px solid var(--line-mid); border-radius: var(--radius);
  padding: 1px 6px; flex: none; min-width: 52px; text-align: center;
}
.cmdk-item .cmdk-sub { margin-left: auto; font-size: 0.78rem; color: var(--slate); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmdk-item:hover, .cmdk-item.active { background: var(--paper-dim); }
.cmdk-empty { padding: var(--sp-5) 16px; color: var(--slate); font-size: 0.88rem; }
.cmdk-hint {
  border-top: 1px solid var(--line);
  padding: 7px 16px;
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--slate);
}

/* --------------------------------------------------------------------------
   Code editor
   -------------------------------------------------------------------------- */
.editor-grid {
  display: grid; grid-template-columns: 240px minmax(0, 1fr);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  overflow: hidden;
}
.editor-tree { border-right: 1px solid var(--line); overflow-y: auto; max-height: 72vh; }
.editor-tree-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
}
.editor-tree-head strong { font-size: 0.82rem; }
.editor-file {
  display: block; width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  padding: 6px 14px;
  font-family: var(--font-mono); font-size: 0.76rem; color: var(--ink);
  overflow-wrap: anywhere;
}
.editor-file:hover { background: var(--paper-dim); }
.editor-file.active { background: var(--info-soft); color: var(--navy); }
.editor-main { display: flex; flex-direction: column; min-width: 0; }
.editor-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
}
.editor-bar .path { font-family: var(--font-mono); font-size: 0.8rem; overflow-wrap: anywhere; }
.editor-bar .status { font-size: 0.75rem; color: var(--slate); margin-top: 1px; }
.editor-code {
  flex: 1; min-height: 540px; width: 100%;
  border: none; resize: none;
  padding: 14px 16px;
  font-family: var(--font-mono); font-size: 0.82rem; line-height: 1.55;
  background: #fff; color: var(--ink);
}
.editor-code:focus { outline: none; }
@media (max-width: 800px) {
  .editor-grid { grid-template-columns: 1fr; }
  .editor-tree { max-height: 220px; border-right: none; border-bottom: 1px solid var(--line); }
}

/* --------------------------------------------------------------------------
   Pricing calculator
   -------------------------------------------------------------------------- */
.price-total-card {
  position: sticky; top: 12px; z-index: 50;
  display: flex; align-items: baseline; justify-content: space-between;
  background: var(--navy); color: var(--paper);
  border-radius: var(--radius);
  border: 1px solid var(--navy-deep);
  padding: var(--sp-4) var(--sp-5);
  margin-bottom: var(--sp-5);
  box-shadow: 4px 4px 0 rgba(13, 34, 54, 0.2);
}
@media (max-width: 900px) { .price-total-card { top: 68px; } }
.price-total-label {
  font-family: var(--font-mono); font-size: 0.68rem; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--slate-on-navy);
}
.price-total-value {
  font-family: var(--font-display); font-weight: 700; font-size: 1.8rem;
  font-variant-numeric: tabular-nums;
}

.price-option-list { display: flex; flex-direction: column; gap: 6px; }
.price-option {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 14px;
  border: 1px solid var(--line-mid);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color 140ms ease, background-color 140ms ease;
}
.price-option:hover { border-color: var(--slate); }
.price-option:has(input:checked) { border-color: var(--navy); background: var(--info-soft); }
.price-option-main { display: flex; align-items: center; gap: 12px; font-size: 0.9rem; min-width: 0; }
.price-option-main input { flex: none; width: 16px; height: 16px; accent-color: var(--navy); }
.price-option-note { color: var(--slate); font-size: 0.8rem; }
.price-option-cost {
  font-family: var(--font-mono); font-size: 0.78rem; font-weight: 500;
  color: var(--slate); white-space: nowrap; font-variant-numeric: tabular-nums;
}
.price-option:has(input:checked) .price-option-cost { color: var(--navy); }

.quote-summary {
  background: var(--paper-dim);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-4);
  font-family: var(--font-mono); font-size: 0.8rem; line-height: 1.6;
  white-space: pre-wrap;
  margin-bottom: var(--sp-3);
  overflow-x: auto;
}
.copy-confirm { margin-left: 10px; color: var(--ok); font-size: 0.85rem; font-weight: 500; }

/* --------------------------------------------------------------------------
   Misc
   -------------------------------------------------------------------------- */
.support-code-value {
  font-family: var(--font-mono);
  font-size: 2rem; font-weight: 500; letter-spacing: 0.18em;
  color: var(--navy);
}
.tick-rule {
  height: 8px;
  background-image:
    linear-gradient(var(--line-mid), var(--line-mid)),
    repeating-linear-gradient(to right, var(--line-mid) 0 1px, transparent 1px 48px);
  background-size: 100% 1px, 100% 8px;
  background-position: bottom left, bottom left;
  background-repeat: no-repeat;
  margin: var(--sp-5) 0;
}
.divider { border: none; border-top: 1px solid var(--line); margin: var(--sp-5) 0; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-5); align-items: start; }
@media (max-width: 820px) { .grid-2 { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   PWA install / notification banners — same bottom-anchored, hairline-bordered
   treatment as the public site's cookie notice, adapted to the app's denser
   spacing. Two possible cards (install, then notifications) stack via normal
   flex column flow rather than both trying to sit fixed at the same spot.
   -------------------------------------------------------------------------- */
.pwa-banner {
  position: fixed;
  left: var(--sp-4); right: var(--sp-4); bottom: var(--sp-4);
  z-index: 250;
  max-width: 480px;
  margin: 0 auto;
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--ink);
  box-shadow: 6px 6px 0 rgba(22, 34, 46, 0.16);
  border-radius: var(--radius);
  padding: var(--sp-4) var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.pwa-banner + .pwa-banner { margin-bottom: calc(var(--sp-4) + 84px); }
.pwa-banner-text { display: flex; flex-direction: column; gap: 4px; }
.pwa-banner-text strong { font-size: 0.98rem; }
.pwa-banner-text span { color: var(--slate); font-size: 0.88rem; }
.pwa-banner-actions { display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap; }
@media (prefers-reduced-motion: no-preference) {
  .pwa-banner { animation: pwa-banner-in 220ms var(--ease-out); }
}
@keyframes pwa-banner-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

.pwa-steps { list-style: decimal; padding-left: 1.3em; margin: var(--sp-4) 0; }
.pwa-steps li { margin-bottom: 8px; font-size: 0.95rem; }
.pwa-steps li:last-child { margin-bottom: 0; }

/* Inline (non-fixed) variant for the Account/Settings page, where the
   banner concept is embedded in normal page flow rather than floating. */
.pwa-inline-card {
  display: flex; flex-direction: column; gap: var(--sp-3);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-4) var(--sp-5);
}

/* --------------------------------------------------------------------------
   Support-access approval — client portal
   -------------------------------------------------------------------------- */
.access-request {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--sp-5);
  margin-bottom: var(--sp-4);
}
.access-request.is-pending { border-color: var(--accent); }
.access-request-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); margin-bottom: var(--sp-4);
}
.access-request-head h3 { font-size: 1rem; }
.access-request-staff {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 1.05rem; font-weight: 600; margin-bottom: 2px;
}
.access-request-staff .role { font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--slate); font-weight: 500; }
.access-request-meta { color: var(--slate); font-size: 0.85rem; margin-bottom: var(--sp-4); }
.access-request-reason { font-size: 0.92rem; margin-bottom: var(--sp-4); }
.access-request-actions { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.access-request-actions .btn { min-width: 140px; }

.active-grant-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--line);
}
.active-grant-row:last-child { border-bottom: none; }
.active-grant-who { font-weight: 600; font-size: 0.92rem; }
.active-grant-meta { color: var(--slate); font-size: 0.82rem; margin-top: 2px; }
