/* heySec — portal styles. heySec Home's design language (Apple's) brought closer to heysec.com:
   the site's warm ground and night, Inter with tight titles, inset-grouped cards of rows, capsule
   buttons, and glass navigation. Light and dark follow the device, or the person's own choice
   (data-theme on <html>, saved on their account). The CSP allows no inline styles, so every look
   lives here. */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/inter/InterVariable.woff2") format("woff2");
}

:root {
  /* Brand. Yellow for the one main action, the selected place and the armed hero, always with
     ink on it; where yellow must read on the page itself (checks, links, caret) a deeper gold. */
  --accent: #f9ce19;
  --accent-hover: #ffdf58;
  --accent-pressed: #efc000;
  --on-accent: #030107;
  --ink: #030107;
  --tint: #a57f00;
  --on-tint: #ffffff;
  --lens: rgba(249, 206, 25, .32);
  --night: #0e0d0a;
  --on-night: #f5f5f0;
  /* The logo's own colours (the CVI): full colour on light grounds, all white on night. Never the page's ink or yellow. */
  --logo-word: #383637;
  --logo-shield: #fdda27;

  /* Labels, grounds, fills and separators: heysec.com's warm neutrals. */
  --label: #030107;
  --label-2: #5d5d57;
  --label-3: #74746d;
  --label-4: #c4c4be;
  --bg: #f7f7f4;
  --surface: #ffffff;
  --surface-2: #efefe9;
  --surface-hover: #fafaf6;
  --elevated: #ffffff;
  --fill: rgba(3, 1, 7, .06);
  --fill-strong: rgba(3, 1, 7, .11);
  --pressed: #ebebe5;
  --sep: rgba(3, 1, 7, .1);
  --border: rgba(3, 1, 7, .14);
  --hair: 1px;

  /* Glass: the navigation layer, never content. */
  --glass: rgba(255, 255, 255, .72);
  --glass-strong: rgba(250, 250, 247, .94);
  --glass-edge: rgba(3, 1, 7, .08);
  --glass-shine: rgba(255, 255, 255, .8);
  --glass-shadow: 0 12px 32px rgba(3, 1, 7, .08), 0 2px 6px rgba(3, 1, 7, .04);
  --pop-shadow: 0 24px 60px rgba(20, 16, 4, .16), 0 4px 14px rgba(3, 1, 7, .06), 0 0 0 .5px rgba(3, 1, 7, .06);
  --scrim: rgba(3, 1, 7, .22);

  /* States. Text colours read on the page; tints sit behind them. Product colours mark a
     service: yellow for heySec Home, teal for Prompt Firewall (heysec.com's --acc-home, --acc-cloud). */
  --teal: #146c79;
  --green: #18753b;
  --orange: #c4501f;
  --red: #b92f28;
  --teal-tint: rgba(20, 108, 121, .1);
  --green-tint: rgba(24, 117, 59, .11);
  --orange-tint: rgba(216, 92, 46, .12);
  --red-tint: rgba(185, 47, 40, .1);
  --yellow-tint: rgba(249, 206, 25, .22);
  --violet: #5d4aa8;
  --violet-tint: rgba(93, 74, 168, .1);
  --switch-on: #34c759;

  /* Solid fills (tiles, the coloured heroes): strong in both themes, white on top. */
  --solid-neutral: #8e8d86;
  --solid-green: #2e9e57;
  --solid-orange: #d85c2e;
  --solid-red: #d63a31;
  --solid-teal: #146c79;
  --solid-violet: #5d4aa8;

  /* What changes with the theme for single components. */
  --ink-button: #030107;
  --on-ink-button: #ffffff;
  --segment-active: #ffffff;
  --hover-filter: brightness(.96);
  --hero-shield: .26;

  --focus: #146c79;
  --radius-card: 14px;
  --radius-hero: 24px;
  --radius-field: 12px;

  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: var(--font);
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  /* Type: a phone's ramp; a desktop's is below. Headline is Body in semibold. */
  --large-title: 32px; --large-title-lh: 38px;
  --title-3: 20px; --title-3-lh: 25px;
  --body: 16px; --body-lh: 22px;
  --subhead: 14.5px; --subhead-lh: 20px;
  --footnote: 13px; --footnote-lh: 18px;
  /* A dense panel's text (the floor plan's side panel), a segmented control's and a button's label,
     a figure (the hero's state, a stat) and a control's height. */
  --dense-body: 15px; --dense-body-lh: 20px;
  --dense-sub: 13px; --dense-sub-lh: 18px;
  --control-text: 14px; --control-text-lh: 18px;
  --button-text: 15px; --button-text-lh: 20px;
  --figure: 34px; --figure-lh: 40px;
  --control: 44px; --control-sm: 34px; --control-lg: 52px;
  --ease: cubic-bezier(.2, .9, .25, 1);
  --spring: cubic-bezier(.34, 1.56, .64, 1);

  --chevrons: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.6 9.4 L12 5 L16.4 9.4 M7.6 14.6 L12 19 L16.4 14.6' fill='none' stroke='%235d5d57' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6.4 12.6 L10.3 16.4 L17.8 7.8' fill='none' stroke='%23ffffff' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  color-scheme: light;
}

/* The dark theme: heysec.com's warm night. It applies when the device is dark and the person
   has not chosen light, and whenever they chose dark. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --tint: #f9ce19;
    --on-tint: #030107;
    --lens: rgba(249, 206, 25, .22);
    --label: #f5f5f0;
    --label-2: #a8a79f;
    --label-3: #8f8e87;
    --label-4: #4e4d48;
    --bg: #0e0d0a;
    --surface: #1a1915;
    --surface-2: #24231e;
    --surface-hover: #201f1a;
    --elevated: #2a2924;
    --fill: rgba(255, 255, 245, .07);
    --fill-strong: rgba(255, 255, 245, .13);
    --pressed: #26251f;
    --sep: rgba(255, 255, 245, .12);
    --border: rgba(255, 255, 255, .14);
    --glass: rgba(36, 35, 30, .72);
    --glass-strong: rgba(30, 29, 25, .95);
    --glass-edge: rgba(255, 255, 255, .1);
    --glass-shine: rgba(255, 255, 255, .1);
    --glass-shadow: 0 12px 32px rgba(0, 0, 0, .36), 0 2px 6px rgba(0, 0, 0, .2);
    --pop-shadow: 0 24px 60px rgba(0, 0, 0, .55), 0 0 0 .5px rgba(255, 255, 245, .1);
    --scrim: rgba(0, 0, 0, .5);
    --teal: #3fb4c6;
    --green: #3ecf7a;
    --orange: #ff8a3d;
    --red: #f05f59;
    --teal-tint: rgba(63, 180, 198, .16);
    --green-tint: rgba(62, 207, 122, .16);
    --orange-tint: rgba(255, 138, 61, .16);
    --red-tint: rgba(240, 95, 89, .16);
    --yellow-tint: rgba(249, 206, 25, .18);
    --violet: #a99bf0;
    --violet-tint: rgba(169, 155, 240, .16);
    --solid-violet: #7b69cf;
    --switch-on: #30d158;
    --ink-button: #f5f5f0;
    --on-ink-button: #030107;
    --segment-active: #4a4943;
    --hover-filter: brightness(1.12);
    --hero-shield: .12;
    --focus: #3fb4c6;
    --logo-word: #fff;
    --logo-shield: #fff;
    --chevrons: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.6 9.4 L12 5 L16.4 9.4 M7.6 14.6 L12 19 L16.4 14.6' fill='none' stroke='%23a8a79f' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    --check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6.4 12.6 L10.3 16.4 L17.8 7.8' fill='none' stroke='%23030107' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --tint: #f9ce19;
  --on-tint: #030107;
  --lens: rgba(249, 206, 25, .22);
  --label: #f5f5f0;
  --label-2: #a8a79f;
  --label-3: #8f8e87;
  --label-4: #4e4d48;
  --bg: #0e0d0a;
  --surface: #1a1915;
  --surface-2: #24231e;
  --surface-hover: #201f1a;
  --elevated: #2a2924;
  --fill: rgba(255, 255, 245, .07);
  --fill-strong: rgba(255, 255, 245, .13);
  --pressed: #26251f;
  --sep: rgba(255, 255, 245, .12);
  --border: rgba(255, 255, 255, .14);
  --glass: rgba(36, 35, 30, .72);
  --glass-strong: rgba(30, 29, 25, .95);
  --glass-edge: rgba(255, 255, 255, .1);
  --glass-shine: rgba(255, 255, 255, .1);
  --glass-shadow: 0 12px 32px rgba(0, 0, 0, .36), 0 2px 6px rgba(0, 0, 0, .2);
  --pop-shadow: 0 24px 60px rgba(0, 0, 0, .55), 0 0 0 .5px rgba(255, 255, 245, .1);
  --scrim: rgba(0, 0, 0, .5);
  --teal: #3fb4c6;
  --green: #3ecf7a;
  --orange: #ff8a3d;
  --red: #f05f59;
  --teal-tint: rgba(63, 180, 198, .16);
  --green-tint: rgba(62, 207, 122, .16);
  --orange-tint: rgba(255, 138, 61, .16);
  --red-tint: rgba(240, 95, 89, .16);
  --yellow-tint: rgba(249, 206, 25, .18);
  --violet: #a99bf0;
  --violet-tint: rgba(169, 155, 240, .16);
  --solid-violet: #7b69cf;
  --switch-on: #30d158;
  --ink-button: #f5f5f0;
  --on-ink-button: #030107;
  --segment-active: #4a4943;
  --hover-filter: brightness(1.12);
  --hero-shield: .12;
  --focus: #3fb4c6;
  --logo-word: #fff;
  --logo-shield: #fff;
  --chevrons: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.6 9.4 L12 5 L16.4 9.4 M7.6 14.6 L12 19 L16.4 14.6' fill='none' stroke='%23a8a79f' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6.4 12.6 L10.3 16.4 L17.8 7.8' fill='none' stroke='%23030107' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  color-scheme: dark;
}
/* One physical pixel on a sharp screen. */
@media (min-resolution: 2dppx) { :root { --hair: .5px; } }
/* A desktop (the sidebar layout, from 1024px) reads at a Mac window's scale: 14px for what a row
   is, 13px for what it says about itself, 13.5px controls on 38px capsules, a compact title. */
@media (min-width: 1024px) {
  :root {
    --large-title: 28px; --large-title-lh: 34px;
    --title-3: 16px; --title-3-lh: 22px;
    --body: 14px; --body-lh: 20px;
    --subhead: 13px; --subhead-lh: 18px;
    --footnote: 12px; --footnote-lh: 16px;
    --dense-body: var(--body); --dense-body-lh: var(--body-lh);
    --dense-sub: var(--subhead); --dense-sub-lh: var(--subhead-lh);
    --control-text: 13px; --control-text-lh: 18px;
    --button-text: 13.5px; --button-text-lh: 18px;
    --figure: 32px; --figure-lh: 38px;
    --control: 38px; --control-sm: 32px; --control-lg: 44px;
  }
}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
/* Inter, as heysec.com sets it: its alternates for a clearer 1, l and 4; titles tracked tight, body text left as drawn. */
body {
  margin: 0; background: var(--bg); color: var(--label);
  font: 400 var(--body)/var(--body-lh) var(--font); font-feature-settings: "cv02", "cv03", "cv04", "cv11";
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility;
  -webkit-tap-highlight-color: transparent;
}
::selection { background: var(--yellow-tint); }
a { color: var(--tint); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }
img { max-width: 100%; }
h1, h2, h3 { margin: 0; font-family: var(--font-display); }
/* Large Title, Title 3 (a section), Headline. */
h1 { font-size: var(--large-title); line-height: var(--large-title-lh); font-weight: 700; }
h2 { font-size: var(--title-3); line-height: var(--title-3-lh); font-weight: 700; }
h3 { font-size: var(--body); line-height: var(--body-lh); font-weight: 600; font-family: var(--font); }
h1 { letter-spacing: -.03em; }
h2 { letter-spacing: -.015em; }
@media (min-width: 1024px) {
  h1 { font-size: 30px; line-height: 36px; font-weight: 750; letter-spacing: -.034em; }
  h2 { font-weight: 650; }
}
p { margin: 0 0 10px; }
strong { font-weight: 600; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 8px; }
.muted { color: var(--label-2); }
/* Footnote. In a row the second line is a Subheadline (below). */
.small { font-size: var(--footnote); line-height: var(--footnote-lh); }
.mono { font-family: var(--mono); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.sym { display: inline-block; flex: none; vertical-align: middle; }
[hidden] { display: none !important; }
.battery, .num { font-variant-numeric: tabular-nums; }


/* ---------- the frame: a top bar says where, a sidebar what; on a phone the sidebar is a sheet ---------- */
:root { --topbar: 56px; --sidebar: 240px; }
.nav-toggle { position: absolute; opacity: 0; pointer-events: none; }
.nav-scrim, .sidebar-close, .tabbar, .topbar-place, .sheet-head { display: none; }

/* heySec's logo, never under the CVI's 102px wide (26px tall) and never recoloured: --logo-word and --logo-shield
   pick the full-colour or the all-white version for the ground it is on. */
.logo { display: block; height: 26px; width: auto; }
.logo .logo-ink { fill: var(--logo-word); }
.logo .logo-gold { fill: var(--logo-shield); }

/* Who owns it: initials in ink, round for a household, square for an organisation. */
.mark {
  width: 32px; height: 32px; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center;
  background: var(--ink-button); color: var(--on-ink-button); font-size: 11.5px; font-weight: 700; letter-spacing: .02em;
}
.mark-org { border-radius: 9px; }
.mark-sm { width: 26px; height: 26px; font-size: 10px; }
.mark-sm.mark-org { border-radius: 7px; }
.mark-lg { width: 52px; height: 52px; font-size: 17px; }
.mark-lg.mark-org { border-radius: 14px; }
.mark-you { background: var(--fill-strong); color: var(--label); }
/* A symbol's tile in a mark's place (a service, a staff console): the size of the marks beside it. */
.mark-tile { width: 32px; height: 32px; border-radius: 9px; }
.mark-tile-sm { width: 26px; height: 26px; border-radius: 7px; }
.mark-tile-sm .sym { width: 16px; height: 16px; }

/* The top bar: on the page's ground, a hairline under it; the staff consoles' is night, so acting as staff always shows. */
.topbar {
  position: sticky; top: 0; z-index: 40; display: flex; align-items: center; gap: 8px;
  height: calc(var(--topbar) + env(safe-area-inset-top)); padding: env(safe-area-inset-top) max(16px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left));
  background: var(--bg); box-shadow: inset 0 calc(-1 * var(--hair)) 0 var(--sep);
}
.topbar-logo { display: inline-flex; padding: 0 5px 0 2px; flex: none; }
.topbar-logo:hover { text-decoration: none; }
.topbar-slash { color: var(--label-4); font-size: 22px; font-weight: 300; line-height: 1; }
.topbar-gap { flex: 1; }
.area-chip {
  flex: none; padding: 3px 8px; border-radius: 999px; background: var(--accent); color: var(--on-accent);
  font-size: 10.5px; line-height: 14px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}
/* Night carries the all-white logo, the teal focus ring for night and, where the page is night too (dark), a hairline. */
.area-staff .topbar {
  background: var(--night); color: var(--on-night); box-shadow: inset 0 calc(-1 * var(--hair)) 0 rgba(255, 255, 245, .12);
  --logo-word: #fff; --logo-shield: #fff; --focus: #3fb4c6;
}
.area-staff .topbar .topbar-slash { color: rgba(245, 245, 240, .3); }
.area-staff .topbar .switch:hover, .area-staff .topbar details[open] > .switch, .area-staff .topbar .me-button:hover, .area-staff .topbar details[open] > .me-button { background: rgba(255, 255, 245, .1); }
.area-staff .topbar .switch-text small, .area-staff .topbar .switch-chev { color: rgba(245, 245, 240, .6); }
.area-staff .topbar .avatar { background: rgba(255, 255, 245, .14); color: #fff; }

/* Menus that open in place (the switcher, the person's menu): <details data-menu>. */
details[data-menu] { position: relative; flex: none; }
details[data-menu] > summary { list-style: none; cursor: pointer; }
details[data-menu] > summary::-webkit-details-marker { display: none; }
.switch {
  display: flex; align-items: center; gap: 9px; min-width: 0; padding: 5px 9px 5px 5px; border-radius: 10px;
  transition: background-color 160ms ease;
}
.switch:hover, details[open] > .switch { background: var(--fill); }
.switch.is-static, .switch.is-static:hover { background: transparent; }
.switch-text { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.switch-text b { font-size: 14px; font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.switch-text small { font-size: 11.5px; color: var(--label-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.switch .count { flex: none; min-width: 18px; height: 18px; font-size: 11px; padding: 0 5px; }
.switch-chev { color: var(--label-3); flex: none; }
.switcher-top { min-width: 0; max-width: 320px; }
.menu-pop {
  position: absolute; z-index: 60; left: 0; top: calc(100% + 6px); width: max(100%, 300px); max-height: min(72vh, 560px); overflow: auto;
  padding: 8px; border-radius: 16px; background: var(--elevated); box-shadow: var(--pop-shadow); animation: menu-in 160ms var(--ease);
}
.menu-right { left: auto; right: 0; width: 272px; }
@keyframes menu-in { from { opacity: 0; transform: translateY(-4px) scale(.985); } to { opacity: 1; transform: none; } }
.menu-label { display: flex; align-items: center; gap: 7px; font-size: 10.5px; line-height: 14px; font-weight: 650; letter-spacing: .1em; text-transform: uppercase; color: var(--label-3); padding: 10px 10px 4px; }
.menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 10px; border: 0; border-radius: 10px; background: transparent;
  color: var(--label); text-align: left; font: inherit; cursor: pointer; text-decoration: none;
}
.menu-item:hover { background: var(--fill); text-decoration: none; }
.menu-item[aria-current] { background: var(--fill); }
.menu-item .tile { width: 26px; height: 26px; border-radius: 7px; }
.menu-item .count { flex: none; }
.menu-item form { margin: 0; }
.menu-text { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.menu-text b { font-size: 13.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.menu-text small { font-size: 12px; color: var(--label-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.menu-check { color: var(--tint); flex: none; }
.menu-sep { height: var(--hair); background: var(--sep); margin: 6px 8px; }
.menu-who { display: flex; flex-direction: column; padding: 8px 10px 6px; line-height: 1.35; }
.menu-who b { font-size: 13.5px; font-weight: 650; }
.menu-who span { font-size: 12px; color: var(--label-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
form > .menu-item { margin: 0; }

/* Jump to: a field in the top bar, the dialog it opens (public/js/app.js). */
.jump-button {
  display: inline-flex; align-items: center; gap: 8px; flex: 0 1 300px; min-width: 0; height: 34px; padding: 0 7px 0 11px; border: 0; border-radius: 10px;
  background: var(--fill); color: var(--label-2); font: 400 13px/18px var(--font); cursor: pointer; transition: background-color 160ms ease;
}
.jump-button:hover { background: var(--fill-strong); }
.jump-text { flex: 1; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jump-kbd {
  flex: none; margin-left: auto; padding: 0 6px; border-radius: 5px; box-shadow: inset 0 0 0 var(--hair) var(--border);
  font: 500 11px/18px var(--font); color: var(--label-2);
}
.area-staff .jump-button { background: rgba(255, 255, 245, .1); color: rgba(245, 245, 240, .7); }

/* The person: their initials on the right, invitations counted on them. */
.me-button { position: relative; width: 40px; height: 40px; display: grid; place-items: center; border-radius: 50%; transition: background-color 160ms ease; }
.me-button:hover, details[open] > .me-button { background: var(--fill); }
.avatar {
  width: 32px; height: 32px; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface-2); color: var(--label); font-size: 12px; font-weight: 650;
}
.me-count { position: absolute; top: 0; right: -2px; min-width: 18px; height: 18px; padding: 0 5px; font-size: 11px; box-shadow: 0 0 0 2px var(--bg); }
.who { flex: 1; min-width: 0; line-height: 16px; }
.who b, .who span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.who b { font-size: 13px; font-weight: 600; }
.who span { font-size: 12px; color: var(--label-2); }

/* The sidebar: a column on the ground under the top bar, every product a group. */
.sidebar {
  position: fixed; z-index: 30; top: calc(var(--topbar) + env(safe-area-inset-top)); bottom: 0; left: 0; width: var(--sidebar);
  padding: 16px 10px 28px; display: flex; flex-direction: column; gap: 14px; overflow-y: auto; overscroll-behavior: contain;
  background: var(--bg); box-shadow: inset calc(-1 * var(--hair)) 0 0 var(--sep); scrollbar-width: none;
}
.sidebar::-webkit-scrollbar { display: none; }
.area-back {
  display: flex; align-items: center; gap: 4px; flex: none; min-height: 30px; padding: 0 10px 0 6px; border-radius: 8px;
  font-size: 13.5px; font-weight: 500; color: var(--tint); text-decoration: none; width: fit-content;
}
.area-back:hover { background: var(--fill); text-decoration: none; }
.nav-groups { display: flex; flex-direction: column; gap: 20px; }
.nav-group { display: flex; flex-direction: column; gap: 1px; }
.nav-label {
  display: flex; align-items: center; gap: 7px; padding: 0 10px 6px;
  font-size: 10.5px; line-height: 14px; font-weight: 650; letter-spacing: .11em; text-transform: uppercase; color: var(--label-3);
}
.svc-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; display: inline-block; background: var(--label-3); }
.svc-yellow { background: var(--accent); }
.svc-teal { background: var(--teal); }
.svc-violet { background: var(--violet); }
.svc-orange { background: var(--solid-orange); }
.svc-green { background: var(--solid-green); }
.svc-ink { background: var(--label); }
.nav { display: flex; flex-direction: column; gap: 1px; }
.nav a {
  position: relative; display: flex; align-items: center; gap: 10px; min-height: 32px; padding: 0 10px; border-radius: 8px;
  color: var(--label); font-size: 13.5px; line-height: 18px; font-weight: 500; text-decoration: none; transition: background-color 160ms ease;
}
.nav a .sym { color: var(--label-2); }
.nav a:hover { background: var(--fill); text-decoration: none; }
.nav a.active { background: var(--lens); font-weight: 650; }
.nav a.active .sym, .nav a.is-open .sym { color: var(--label); }
.nav a.is-open { font-weight: 650; }
.nav a.is-muted { color: var(--label-2); }
.nav-text { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav .count { min-width: 18px; height: 18px; font-size: 11px; padding: 0 5px; }
/* An open object's pages, indented under it on a hairline; they arrive once, never on every page. */
.nav-sub { display: flex; flex-direction: column; gap: 1px; margin: 2px 0 6px 18px; padding-left: 9px; box-shadow: inset var(--hair) 0 0 var(--sep); }
.nav-sub a { min-height: 29px; color: var(--label-2); font-size: 13px; }
.nav-sub a.active { color: var(--label); }
.nav-sub.is-arriving { animation: nav-open 240ms var(--ease) both; }
@keyframes nav-open { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
/* A location's state beside its name: an alarm sounding, armed, disarmed. */
.state { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.state-alarm { background: var(--solid-red); box-shadow: 0 0 0 3px var(--red-tint); }
.state-armed { background: var(--accent); box-shadow: inset 0 0 0 1.5px var(--accent-pressed); }
.state-disarmed { background: var(--solid-green); }
.count {
  display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: 10px; background: var(--solid-red); color: #fff; font-size: 12px; font-weight: 650;
  font-variant-numeric: tabular-nums;
}

.main { margin-left: var(--sidebar); padding: 28px clamp(24px, 3.4vw, 48px) 96px; max-width: calc(var(--sidebar) + 1300px); }
.main > .flash { margin-bottom: 20px; }
/* A page of wide tables (request logs) takes the room the screen has instead of scrolling sideways. */
.main.is-wide { max-width: none; }

.bar-button {
  width: 40px; height: 40px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; flex: none;
  color: var(--label); cursor: pointer; transition: background-color 160ms ease;
}
.bar-button:hover { background: var(--fill); }

/* Phones and tablets: the title opens the sheet, the open object's pages are the bottom bar. */
@media (max-width: 1023px) {
  :root { --topbar: 52px; }
  .topbar-slash, .switcher-top, .topbar > .switch, .jump-text, .jump-button .jump-kbd, .topbar .area-chip { display: none; }
  .topbar-place {
    display: inline-flex; align-items: center; gap: 7px; min-width: 0; padding: 3px 10px 3px 3px; border-radius: 999px;
    background: var(--fill); cursor: pointer;
  }
  .area-staff .topbar-place { background: rgba(255, 255, 245, .1); }
  .topbar-name { font-size: 14px; font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .topbar-chev { color: var(--label-2); flex: none; }
  .jump-button { flex: none; width: 40px; height: 40px; padding: 0; justify-content: center; border-radius: 50%; background: transparent; color: var(--label); }
  .area-staff .jump-button { background: transparent; color: inherit; }

  .sidebar {
    display: none; top: calc(8px + env(safe-area-inset-top)); left: 8px; right: 8px; bottom: 8px; width: auto; max-width: 420px;
    margin: 0 auto; border-radius: 26px; padding: 12px 12px 20px; background: var(--elevated); z-index: 50; box-shadow: var(--pop-shadow);
  }
  .nav-toggle:checked ~ .shell .sidebar { display: flex; animation: sheet-in 320ms var(--ease); }
  .nav-toggle:checked ~ .nav-scrim { display: block; position: fixed; inset: 0; z-index: 45; background: var(--scrim); animation: fade-in 200ms ease; }
  body:has(.nav-toggle:checked) { overflow: hidden; }
  .sheet-head { display: flex; align-items: flex-start; gap: 8px; }
  .sheet-head > .switcher, .sheet-head > .switch { flex: 1; min-width: 0; }
  .sheet-head .switch { padding: 8px 10px 8px 8px; border-radius: 14px; background: var(--fill); }
  .sheet-head .switch.is-static { background: transparent; }
  .sidebar-close { display: inline-flex; background: var(--fill); }
  /* In the sheet a menu opens in place, pushing what follows down. */
  .sidebar .menu-pop { position: static; width: auto; max-height: none; margin-top: 8px; box-shadow: none; background: var(--fill); animation: none; }
  .nav a { min-height: 42px; font-size: 15px; }
  .nav-sub a { min-height: 38px; font-size: 14.5px; }

  .tabbar {
    display: flex; position: fixed; z-index: 20; left: 12px; right: 12px; margin: 0 auto; max-width: 460px;
    bottom: max(12px, calc(env(safe-area-inset-bottom) - 8px)); height: 62px; padding: 4px; border-radius: 24px;
    background: var(--elevated); box-shadow: 0 0 0 var(--hair) var(--sep), 0 10px 30px rgba(3, 1, 7, .12);
  }
  .tab {
    flex: 1; min-width: 0; position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    border-radius: 20px; color: var(--label-2); text-decoration: none; font-size: 10px; line-height: 12px; font-weight: 600; cursor: pointer;
    transition: background-color 280ms var(--ease), color 200ms;
  }
  .tab:hover { text-decoration: none; }
  .tab.active { background: var(--lens); color: var(--label); }
  .tab .count { position: absolute; top: 3px; left: calc(50% + 6px); min-width: 18px; height: 18px; font-size: 11px; padding: 0 5px; }
  .tab:active .sym { transform: scale(.9); }
  .tab .sym { transition: transform 160ms var(--ease); }

  .main { margin-left: 0; padding: 16px max(16px, env(safe-area-inset-right)) calc(40px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); max-width: 820px; margin-inline: auto; }
  .has-tabbar .main { padding-bottom: calc(112px + env(safe-area-inset-bottom)); }
}
@keyframes sheet-in { from { transform: translateY(24px) scale(.98); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* Jump to's dialog: one field and what matches, keys to move, Enter to open. */
dialog.jump {
  width: min(600px, calc(100% - 32px)); max-height: min(70vh, 560px); margin: 12vh auto auto; padding: 0; border: 0; border-radius: 18px;
  background: var(--elevated); color: var(--label); box-shadow: var(--pop-shadow); overflow: hidden;
}
dialog.jump[open] { display: flex; flex-direction: column; animation: menu-in 180ms var(--ease); }
dialog.jump::backdrop { background: var(--scrim); }
.jump-field { display: flex; align-items: center; gap: 10px; padding: 12px 14px; box-shadow: inset 0 calc(-1 * var(--hair)) 0 var(--sep); color: var(--label-2); }
.jump-field input[type=search] { flex: 1; min-height: 34px; padding: 4px 0; background: transparent; border-radius: 0; font-size: 16px; box-shadow: none; }
.jump-field input[type=search]:focus { box-shadow: none; }
.jump-results { list-style: none; margin: 0; padding: 6px; overflow-y: auto; }
.jump-results li { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 10px; cursor: pointer; }
.jump-results li[aria-selected="true"] { background: var(--fill); }
.jump-results .sym { color: var(--label-2); flex: none; }
.jump-results b { font-weight: 600; font-size: 14px; }
.jump-results small { display: block; font-size: 12px; color: var(--label-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jump-results .grow { min-width: 0; }
.jump-results .jump-kind { flex: none; margin-left: auto; font-size: 11px; color: var(--label-3); }
.jump-empty { margin: 0; padding: 18px; color: var(--label-2); font-size: var(--subhead); }

/* Banners that follow a person: an alarm anywhere they may look, an invitation waiting. */
.banner {
  display: flex; align-items: center; gap: 12px; padding: 10px 10px 10px 14px; border-radius: 16px; margin-bottom: 12px;
  font-size: var(--subhead); line-height: var(--subhead-lh);
}
.banner b { font-weight: 650; }
.banner-alarm { background: var(--solid-red); color: #fff; }
.banner-invite { background: var(--teal-tint); color: var(--label); }
.banner-invite > .sym { color: var(--teal); }
.banner-warn { background: var(--orange-tint); color: var(--label); }
.banner-warn > .sym { color: var(--orange); }
.btn.btn-on-red { background: #fff; color: #8f1d17; }


/* ---------- a page: large title, then sections of grouped cards ---------- */
.page-head { margin: 0 0 22px; }
.back {
  display: inline-flex; align-items: center; gap: 2px; margin: 0 0 6px -7px; min-height: 32px; padding-right: 6px;
  font-size: var(--body); color: var(--tint); text-decoration: none;
}
.back:hover { text-decoration: none; opacity: .72; }
.page-title { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap; }
.page-title h1 { overflow-wrap: anywhere; }
/* The title keeps room for its words: when the actions beside it leave less than this, they wrap under it (never squeeze it
   until its words break). */
.page-title > .grow { flex: 1 1 16rem; }
.eyebrow {
  display: flex; align-items: center; gap: 8px; margin-bottom: 6px;
  font-size: 11.5px; line-height: 14px; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; color: var(--label-2);
}
.page-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-bottom: 2px; }
.search { position: relative; }
.search .sym { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--label-2); pointer-events: none; }
.search input[type=search] { width: min(280px, 100%); min-height: 36px; padding: 7px 12px 7px 36px; border-radius: 10px; font-size: var(--body); }
.lead { font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); max-width: 640px; margin: 6px 0 0; }

.section { margin-top: 30px; }
.section:first-child, .page-head + .section, .page-head + * > .section:first-child { margin-top: 0; }
.section + .grid, .section + .group { margin-top: 30px; }
.section-head { display: flex; align-items: center; gap: 8px; min-height: 30px; padding: 0 4px 10px; }
.section-head h2 { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
/* A section's count is a number, not an alarm: quiet unless the section is about something open. */
.section-head h2 .count { background: var(--fill-strong); color: var(--label-2); }
.section-head > form, .section-head > .pill, .section-head > .btn { margin-left: auto; }
.section-head .aside { margin-left: auto; color: var(--label-2); font-size: var(--subhead); text-align: right; }
.section-link {
  margin-left: auto; display: inline-flex; align-items: center; gap: 2px; font-size: var(--subhead); color: var(--tint);
  text-decoration: none; white-space: nowrap;
}
.section-link:hover { text-decoration: none; opacity: .72; }
.group-label { font-size: var(--footnote); line-height: var(--footnote-lh); text-transform: uppercase; color: var(--label-2); padding: 0 16px 7px; margin-top: 24px; }
.group-label:first-child { margin-top: 0; }
/* On a desktop a label in capitals is the sidebar's: small, spaced, a little heavier. */
@media (min-width: 1024px) { .group-label { font-size: 10px; line-height: 14px; font-weight: 650; letter-spacing: .12em; } }
.group-foot { font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); padding: 8px 16px 0; margin: 0; }
/* A line under a section's title saying where it comes from (a household shared with the person). */
.section-note { font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); margin: -6px 0 12px; padding: 0 4px; }

/* A card: the ground for rows and content, edged with a hairline. Nothing here casts a shadow: only what floats does
   (menus, sheets, dialogs, the phone's bottom bar). */
.group, .card { background: var(--surface); border-radius: var(--radius-card); border: var(--hair) solid var(--sep); }
.group { overflow: hidden; }
.card-pad, .group-pad { padding: 16px; }
@media (min-width: 700px) { .card-pad, .group-pad { padding: 20px; } }

.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 30px 24px; align-items: start; margin-top: 30px; }
.page-head + .columns { margin-top: 0; }
.columns > * { min-width: 0; }
.columns > .section, .columns > * > .section:first-child { margin-top: 0; }
@media (max-width: 1180px) { .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 860px) { .columns { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 640px) { .grid-2, .grid-3 { grid-template-columns: minmax(0, 1fr); } .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; } }
.stack { display: flex; flex-direction: column; gap: 16px; }
.row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.spread { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.grow { flex: 1; min-width: 0; }

/* ---------- rows: iOS's inset-grouped list ---------- */
.list { list-style: none; margin: 0; padding: 0; }
.list > li {
  position: relative; display: flex; align-items: center; gap: 14px; min-height: 48px; padding: 10px 16px;
}
/* Hairlines start where the text does: under the title, past a leading tile. */
.list > li + li::before {
  content: ""; position: absolute; top: 0; right: 0; left: 16px; height: var(--hair); background: var(--sep); pointer-events: none;
}
.list > li:has(> .tile:first-child, > .avatar:first-child) + li::before, .list > li + li:has(> .tile:first-child, > .avatar:first-child)::before { left: 60px; }
/* Where some rows lead with a photo, every row's text starts past the photo's width. */
.list:has(> li > .thumb:first-child, > li > .snap-link:first-child, > li > .media-link-thumb:first-child) > li + li::before { left: 104px; }
.list:has(> li > .thumb:first-child, > li > .snap-link:first-child) > li > .tile:first-child { margin-inline: 22px; }
.list .title { font-size: var(--body); line-height: var(--body-lh); color: var(--label); font-weight: 400; overflow-wrap: anywhere; }
.list a.title { text-decoration: none; }
.list .small, .list .sub { font-size: var(--subhead); line-height: var(--subhead-lh); margin-top: 1px; }
.list .sub { color: var(--label-2); }
@media (min-width: 1024px) { .list .title { font-weight: 500; } }
/* The whole row opens it: the title's link covers the row; controls sit above it. */
.list > li:has(> .grow a.title, > a.title) { cursor: pointer; transition: background-color 240ms ease; }
.list a.title::after { content: ""; position: absolute; inset: 0; }
.list > li:has(a.title):hover { background: var(--pressed); }
.list > li:has(a.title):active { background: var(--pressed); transition: none; }
.list > li :is(form, button, select, input, .btn, details, .pill, .status, .row, img, .snap-link, .media-link-thumb) { position: relative; z-index: 1; }
.list > li.is-active { background: var(--lens); }
.chev { color: var(--label-4); flex: none; margin-left: -4px; }
.list > li > .trail { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.list .row { gap: 8px; }
.list .actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 640px) {
  .list > li.wraps { flex-wrap: wrap; row-gap: 8px; }
  .list > li.wraps > .actions { order: 2; flex-basis: 100%; justify-content: flex-start; padding-left: 44px; }
  .list > li.wraps:not(:has(> .tile, > .avatar)) > .actions { padding-left: 0; }
}
/* A question opened in a row's actions (x-confirm, an edit panel) takes a line of its own, at every width: it never
   squeezes the row's title until its words break. */
.list > li.wraps:has(> .actions details[open]) { flex-wrap: wrap; row-gap: 8px; }
.list > li.wraps:has(> .actions details[open]) > .actions { order: 2; flex-basis: 100%; justify-content: flex-start; padding-left: 44px; }
.list > li.wraps:not(:has(> .tile, > .avatar)):has(> .actions details[open]) > .actions { padding-left: 0; }
.select-sm { width: auto; min-height: 34px; padding: 0 30px 0 12px; border-radius: 10px; font-size: var(--subhead); line-height: var(--subhead-lh); background-position: right 9px center; background-size: 14px; }

/* A symbol on a small continuous-cornered tile: the leading mark of a row. */
.tile {
  width: 30px; height: 30px; border-radius: 8.4px; flex: none; display: inline-flex; align-items: center; justify-content: center;
  background: var(--fill); color: var(--label);
}
.tile .sym [stroke-width="1.6"] { stroke-width: 1.9px; }
.tile-green { background: var(--green-tint); color: var(--green); }
.tile-orange { background: var(--orange-tint); color: var(--orange); }
.tile-red { background: var(--red-tint); color: var(--red); }
.tile-teal { background: var(--teal-tint); color: var(--teal); }
.tile-violet { background: var(--violet-tint); color: var(--violet); }
.tile-yellow { background: var(--yellow-tint); color: var(--label); }
.tile.is-solid { color: #fff; }
.tile.is-solid .sym [stroke-width="1.6"] { stroke-width: 2.1px; }
.tile-neutral.is-solid { background: var(--solid-neutral); }
.tile-green.is-solid { background: var(--solid-green); }
.tile-orange.is-solid { background: var(--solid-orange); }
.tile-red.is-solid { background: var(--solid-red); }
.tile-teal.is-solid { background: var(--solid-teal); }
.tile-violet.is-solid { background: var(--solid-violet); }
.tile-yellow.is-solid { background: var(--accent); color: var(--on-accent); }
.tile-lg { width: 44px; height: 44px; border-radius: 12.3px; }

/* A label and its value — iOS's info row. */
.kv { display: grid; grid-template-columns: minmax(0, max-content) minmax(0, 1fr); margin: 0; padding-left: 16px; }
.kv dt, .kv dd { min-height: 46px; padding: 12px 0; display: flex; align-items: center; }
.kv dt { color: var(--label); padding-right: 16px; }
.kv dd { margin: 0; justify-content: flex-end; text-align: right; color: var(--label-2); padding-right: 16px; overflow-wrap: anywhere; }
.kv dd a { color: var(--tint); }
.kv dt:not(:first-of-type), .kv dt:not(:first-of-type) + dd { border-top: var(--hair) solid var(--sep); }

/* Empty: what will appear here and the first step, beside a quiet symbol; never a tall centred card saying nothing. */
.empty { padding: 18px 18px 18px; color: var(--label-2); font-size: var(--subhead); line-height: var(--subhead-lh); }
.empty:has(> .sym) { display: grid; grid-template-columns: 40px minmax(0, 1fr); column-gap: 14px; align-items: start; }
.empty > .sym { grid-row: 1 / span 4; width: 40px; height: 40px; padding: 9px; border-radius: 11px; background: var(--fill); color: var(--label-2); }
.empty:has(> .sym) > :not(.sym) { grid-column: 2; }
.empty h3 { color: var(--label); font-size: var(--body); line-height: var(--body-lh); font-weight: 650; margin: 0 0 2px; }
.empty p { font-size: var(--subhead); line-height: var(--subhead-lh); max-width: 62ch; margin: 0; }
.empty p + p { margin-top: 10px; }
.empty .btn { margin-top: 12px; justify-self: start; }
.empty p .btn { margin-top: 0; }
.group.empty.mt-5 { margin-top: 0; }

/* ---------- the security hero ---------- */
.hero {
  position: relative; overflow: hidden; isolation: isolate; border-radius: var(--radius-hero); padding: 20px 20px 20px;
  background: var(--surface); color: var(--label); border: var(--hair) solid var(--sep);
}
.hero:not(.is-disarmed) { border-color: transparent; }
@media (min-width: 700px) { .hero { padding: 26px 28px 28px; } }
/* The heySec shield, kept clear of the mode buttons. */
.hero::after {
  content: ""; position: absolute; z-index: -1; right: -50px; top: -40px; width: 196px; height: 196px;
  background: url("/images/shield.svg") no-repeat center / contain; opacity: var(--hero-shield); pointer-events: none;
}
@media (min-width: 700px) { .hero::after { width: 300px; height: 300px; right: -40px; top: -70px; } }
.hero-eyebrow { display: flex; align-items: center; gap: 6px; font-size: var(--subhead); line-height: var(--subhead-lh); font-weight: 600; }
.hero-eyebrow .sym [stroke-width="1.6"] { stroke-width: 2px; }
.hero-title { font-family: var(--font-display); font-size: var(--figure); line-height: var(--figure-lh); font-weight: 700; margin: 6px 0 2px; padding-right: 52px; overflow-wrap: anywhere; }
@media (min-width: 700px) and (max-width: 1023px) { .hero-title { font-size: 40px; line-height: 46px; } }
@media (min-width: 700px) { .hero-title { padding-right: 180px; } }
@media (min-width: 1024px) { .hero-title { font-weight: 650; letter-spacing: -.035em; } }
.hero-sub { font-size: var(--subhead); line-height: var(--subhead-lh); margin: 0; color: var(--label-2); max-width: 560px; }
.hero-chip {
  display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px 0 10px; margin-top: 12px; border-radius: 15px;
  background: rgba(255, 255, 255, .26); font-size: var(--subhead); font-weight: 600; font-variant-numeric: tabular-nums;
}
.hero.is-disarmed .hero-chip { background: var(--fill); }
.hero.is-disarmed .hero-eyebrow { color: var(--green); }
.hero.is-armed { background: var(--accent); color: var(--on-accent); }
.hero.is-pending { background: var(--solid-orange); color: #fff; }
.hero.is-alarm { background: var(--solid-red); color: #fff; }
.hero.is-armed::after { background-image: url("/images/shield-white.svg"); opacity: .34; }
.hero.is-pending::after, .hero.is-alarm::after { background-image: url("/images/shield-white.svg"); opacity: .14; }
.hero.is-armed .hero-sub { color: rgba(3, 1, 7, .72); }
.hero.is-pending .hero-sub, .hero.is-alarm .hero-sub { color: rgba(255, 255, 255, .86); }
.hero.is-alarm .hero-eyebrow .sym { animation: siren 1.1s ease-in-out infinite; }
@keyframes siren { 50% { opacity: .35; } }

/* The modes the server allows now: equal tiles, a symbol over the label (Control Center). */
.modes { display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: 8px; margin-top: 18px; max-width: 600px; }
.modes-1 { --n: 1; max-width: 200px; } .modes-2 { --n: 2; max-width: 400px; } .modes-3, .modes-4 { --n: 3; }
.modes form { margin: 0; display: contents; }
.mode-tile {
  height: 68px; width: 100%; border: 0; border-radius: 18px; padding: 0 6px; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  background: var(--surface-2); color: var(--label); font: 600 var(--footnote)/var(--footnote-lh) var(--font);
  transition: transform 260ms var(--spring), opacity 160ms ease, background-color 160ms;
}
.mode-tile .sym [stroke-width="1.6"] { stroke-width: 1.8px; }
.mode-tile:hover { filter: var(--hover-filter); }
.mode-tile:active { transform: scale(.95); opacity: .8; transition-duration: 90ms; }
.hero:not(.is-disarmed) .mode-tile { background: rgba(255, 255, 255, .3); color: inherit; }
.mode-tile.is-disarm { background: var(--ink-button); color: var(--on-ink-button); }
.hero:not(.is-disarmed) .mode-tile.is-disarm { background: var(--ink); color: #fff; }

/* A count and what it counts (Health's summary tile). */
.stat { padding: 14px 16px 16px; }
.stat .label { display: flex; align-items: center; gap: 6px; font-size: var(--subhead); line-height: var(--subhead-lh); font-weight: 600; color: var(--label-2); }
.stat .value { font-family: var(--font-display); font-size: var(--figure); line-height: var(--figure-lh); font-weight: 700; margin-top: 8px; font-variant-numeric: tabular-nums; }
.stat .small { margin-top: 2px; color: var(--label-2); }
@media (min-width: 1024px) { .stat .value { font-weight: 650; letter-spacing: -.035em; } }
.stat.is-green .label { color: var(--green); } .stat.is-orange .label { color: var(--orange); } .stat.is-red .label { color: var(--red); }
a.stat { display: block; color: inherit; text-decoration: none; transition: background-color 160ms var(--ease), border-color 160ms var(--ease); }
a.stat:hover { text-decoration: none; background: var(--surface-hover); border-color: var(--border); }

/* ---------- the figures that lead an overview: a ruled strip, a cell per figure (x-figure) ---------- */
/* auto-fill keeps a strip of one or two figures from stretching over the width: what an account does not have is simply
   not there, and the rest keep their size. The cells' left and top rules fall outside the strip on its first column and
   row, where overflow hides them. */
.figures {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 178px), 1fr)); overflow: hidden;
  border-block: var(--hair) solid var(--sep); margin: 0 0 30px;
}
.figure {
  position: relative; display: flex; flex-direction: column; gap: 3px; min-width: 0; padding: 15px 18px 16px;
  margin: calc(-1 * var(--hair)) 0 0 calc(-1 * var(--hair)); border-left: var(--hair) solid var(--sep); border-top: var(--hair) solid var(--sep);
  color: var(--label); text-decoration: none;
}
a.figure { transition: background-color 160ms ease; }
a.figure:hover { background: var(--fill); text-decoration: none; }
.figure-label { display: flex; align-items: center; gap: 6px; font-size: var(--footnote); line-height: var(--footnote-lh); font-weight: 600; color: var(--label-2); }
.figure-value { font-size: 28px; line-height: 34px; font-weight: 720; letter-spacing: -.025em; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.figure-value small { font-size: 15px; font-weight: 600; letter-spacing: -.01em; color: var(--label-2); margin-left: 3px; }
.figure-note { font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); overflow-wrap: anywhere; }
.figure.is-red .figure-value { color: var(--red); }
.figure.is-orange .figure-value { color: var(--orange); }
.figure.is-green .figure-value { color: var(--green); }
.figure.is-unknown .figure-value { color: var(--label-3); }
@media (max-width: 640px) {
  .figures { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .figure { padding: 12px 14px 13px; }
  .figure-value { font-size: 24px; line-height: 30px; }
}

/* The status of a location, then its figures. */
.hero + .figures { margin-top: 22px; }

/* ---------- a page with a rail: what needs a decision beside the main column, from 1280px; under it before ---------- */
.with-rail { display: grid; grid-template-columns: minmax(0, 1fr); gap: 30px 32px; align-items: start; }
.with-rail > * { min-width: 0; }
.with-rail > .main-col > .section:first-child, .with-rail > .main-col > .columns:first-child, .rail > .section:first-child { margin-top: 0; }
.rail { display: flex; flex-direction: column; gap: 30px; }
.rail > .section { margin-top: 0; }
@media (min-width: 1280px) { .with-rail { grid-template-columns: minmax(0, 1fr) 320px; } }

/* Cards in a grid: as many columns as fit, a lone card keeps its width. */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 290px), 1fr)); gap: 14px; }

/* A service card's own line under its name: its account and plan. */
.svc-card .place-top b { display: flex; align-items: center; gap: 6px; }

/* Get started: the steps a new service still needs, each done when the service shows it; gone once every one is. */
.checklist { list-style: none; margin: 0; padding: 4px 16px; }
.checklist li { display: flex; gap: 12px; align-items: flex-start; padding: 11px 0; }
.checklist li + li { border-top: var(--hair) solid var(--sep); }
.check-mark { flex: none; width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; border: 1.5px solid var(--label-4); margin-top: -1px; }
.check-mark svg { width: 14px; height: 14px; fill: none; stroke: #fff; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 16; stroke-dashoffset: 0; }
.checklist li.is-done .check-mark { background: var(--solid-green); border-color: var(--solid-green); }
.checklist li.is-done .check-mark svg { animation: check-draw 520ms var(--ease) 120ms both; }
.checklist li.is-done .check-text b { color: var(--label-2); font-weight: 500; }
.check-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; font-size: var(--subhead); line-height: var(--subhead-lh); }
.check-text b { font-weight: 600; color: var(--label); }
.check-text span { color: var(--label-2); }
.check-text a { font-weight: 600; }
@keyframes check-draw { from { stroke-dashoffset: 16; } to { stroke-dashoffset: 0; } }
.checklist-head { display: flex; align-items: center; gap: 8px; }
.checklist-head .aside { margin-left: auto; color: var(--label-2); font-size: var(--subhead); font-variant-numeric: tabular-nums; }

/* A service someone may order, offered where there is nothing yet (the overview of an empty account). */
.offer { display: flex; flex-direction: column; gap: 10px; padding: 16px 18px; }
.offer .place-top { align-items: flex-start; }
.offer p { margin: 0; font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); }
.offer .btn { align-self: flex-start; }

/* Who to ask, where the person may not order or choose themselves. */
.ask-list { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 0; padding: 0; list-style: none; }
.ask-list li { display: inline-flex; align-items: center; gap: 8px; padding: 4px 12px 4px 4px; border-radius: 999px; background: var(--fill); font-size: var(--subhead); color: var(--label); }
.ask-list .avatar { width: 26px; height: 26px; font-size: 10.5px; }

@media (prefers-reduced-motion: reduce) {
  .checklist li.is-done .check-mark svg { animation: none; }
  .nav-sub.is-arriving { animation: none; }
}

/* ---------- buttons: capsules ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: var(--control); padding: 0 20px;
  border: 0; border-radius: 999px; background: var(--fill); color: var(--label); cursor: pointer; white-space: nowrap;
  font: 600 var(--button-text)/var(--button-text-lh) var(--font); text-decoration: none;
  transition: transform 180ms var(--ease), opacity 160ms ease, background-color 160ms ease, filter 160ms ease;
}
.btn:hover { text-decoration: none; filter: var(--hover-filter); }
.btn:active { transform: scale(.97); opacity: .72; transition-duration: 60ms; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .45; cursor: default; transform: none; }
.btn .sym [stroke-width="1.6"] { stroke-width: 2px; }
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover { background: var(--accent-hover); filter: none; }
.btn-secondary { background: var(--fill); color: var(--label); }
.btn-ghost { background: transparent; color: var(--tint); padding: 0 12px; }
.btn-ghost:hover { background: var(--fill); filter: none; }
.btn-destructive { background: var(--red-tint); color: var(--red); }
.btn-danger { background: var(--solid-red); color: #fff; }
.btn-ink { background: var(--ink-button); color: var(--on-ink-button); }
.btn-lg { min-height: var(--control-lg); padding: 0 24px; }
.btn-sm { min-height: var(--control-sm); padding: 0 14px; font-size: var(--subhead); line-height: var(--subhead-lh); }
.btn-ghost.btn-sm { padding: 0 10px; }
.btn-mini { min-height: 28px; padding: 0 11px; font-size: var(--footnote); line-height: var(--footnote-lh); }
.btn-block { width: 100%; }
.btn-icon { width: var(--control-sm); padding: 0; }
.inline-form { display: inline; margin: 0; }

/* ---------- forms ---------- */
input[type=text], input[type=email], input[type=url], input[type=password], input[type=number], input[type=time], input[type=search], select, textarea {
  width: 100%; min-height: var(--control); padding: 10px 14px; border: 0; border-radius: var(--radius-field);
  background: var(--fill); color: var(--label); font: 400 var(--body)/var(--body-lh) var(--font);
  caret-color: var(--tint); transition: box-shadow 160ms ease, background-color 160ms ease;
}
input::placeholder, textarea::placeholder { color: var(--label-3); opacity: 1; }
input:focus, select:focus, textarea:focus { outline: none; box-shadow: 0 0 0 3px var(--focus); }
input:focus:not(:focus-visible) { box-shadow: 0 0 0 2px var(--focus); }
select {
  -webkit-appearance: none; appearance: none; cursor: pointer; padding-right: 36px;
  background-image: var(--chevrons); background-repeat: no-repeat; background-position: right 12px center; background-size: 16px;
}
input[type=number] { font-variant-numeric: tabular-nums; }
input[type=time] { font-variant-numeric: tabular-nums; }
input[type=search] { -webkit-appearance: none; appearance: none; }

/* A field on its own: label above the input. */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.field > label, .label { font-size: var(--subhead); line-height: var(--subhead-lh); font-weight: 600; }
.hint { font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); }
.error { font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--red); font-weight: 500; }

/* iOS's grouped form: rows of label and value on one card. */
.form-group { background: var(--surface); border-radius: var(--radius-card); border: var(--hair) solid var(--sep); overflow: hidden; }
.field-row {
  position: relative; display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 2px 16px; margin: 0; cursor: text;
}
/* A hairline between rows, never above the first: a form's hidden inputs are not rows. */
.field-row + .field-row::before, .form-group > :not(input[type=hidden]) ~ .field-row::before, .form-group > .field-row + *::before {
  content: ""; position: absolute; top: 0; left: 16px; right: 0; height: var(--hair); background: var(--sep);
}
.field-row > .field-label { flex: 0 0 auto; width: 9.5em; color: var(--label); }
.field-row > input, .field-row > select, .field-row > .control {
  flex: 1; min-width: 0; min-height: var(--control); padding: 10px 0; background-color: transparent; border-radius: 0; box-shadow: none;
}
.field-row > select { padding-right: 26px; background-position: right 0 center; color: var(--label-2); }
.field-row > input[type=number] { flex: 0 1 120px; text-align: right; margin-left: auto; }
.field-row > .unit { color: var(--label-2); }
.field-row.stacked { flex-direction: column; align-items: stretch; gap: 0; padding-top: 9px; }
/* A stacked label sits above its field, as wide as the row: the phone cap for side-by-side labels (45%) is not for it. */
.field-row.stacked > .field-label { width: auto; max-width: none; font-size: var(--footnote); line-height: 16px; color: var(--label-2); }
.field-row.stacked > input { min-height: 0; padding: 3px 0 9px; }
/* A row is framed only when the keyboard brings focus to a control without a caret: after a click or
   a pick from a menu the frame would stay on until something else is clicked, and a text field
   already shows where typing goes. */
.field-row:has(select:focus-visible, input[type=checkbox]:focus-visible, input[type=radio]:focus-visible) { box-shadow: inset 0 0 0 2px var(--focus); border-radius: 12px; }
.field-row:has(select, input[type=checkbox], input[type=radio]) { cursor: pointer; }
.form-group + .group-foot { margin-bottom: 0; }
/* A box of text or a set of choices is too tall to sit beside its label: the label goes above it at every width. */
.field-row:has(> textarea), fieldset.field-row { flex-direction: column; align-items: stretch; gap: 0; padding-top: 10px; }
.field-row:has(> textarea) > .field-label, fieldset.field-row > .field-label { width: auto; max-width: none; font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); }
fieldset.field-row { border: 0; min-width: 0; padding-bottom: 12px; cursor: default; }
fieldset.field-row > legend { float: left; padding: 0; margin-bottom: 6px; }
@media (max-width: 520px) {
  .field-row > .field-label { width: auto; min-width: 5.5em; max-width: 45%; }
  .field-row.stacks { flex-direction: column; align-items: stretch; gap: 0; padding-top: 10px; }
  .field-row.stacks > .field-label { width: auto; max-width: none; font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); }
  .field-row.stacks > input, .field-row.stacks > select { padding-top: 4px; }
}
.form-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 20px; }
.form-actions.end { justify-content: flex-end; }
.gone-note { display: flex; gap: 8px; align-items: flex-start; font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); padding: 12px 16px; margin: 0; }
.gone-note .sym { color: var(--label-3); margin-top: 0; }

/* A choice: a round selection mark, filled gold with a check when chosen. */
input[type=checkbox], input[type=radio] {
  -webkit-appearance: none; appearance: none; flex: none; width: 22px; height: 22px; margin: 0; border-radius: 50%; cursor: pointer;
  border: 1.5px solid var(--label-4); background: transparent; transition: background-color 160ms ease, border-color 160ms ease, transform 200ms var(--spring);
}
input[type=checkbox]:checked, input[type=radio]:checked {
  border-color: var(--tint); background: var(--tint) var(--check) center / 18px no-repeat;
}
input[type=checkbox]:active, input[type=radio]:active { transform: scale(.9); }
.check { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; }
/* A group of choices, one row each. */
.choices { background: var(--surface); border-radius: var(--radius-card); border: var(--hair) solid var(--sep); overflow: hidden; display: grid; grid-template-columns: repeat(var(--cols, 1), minmax(0, 1fr)); }
.choices-2 { --cols: 2; } .choices-3 { --cols: 3; }
@media (max-width: 640px) { .choices-2, .choices-3 { --cols: 1; } }
@media (min-width: 641px) and (max-width: 900px) { .choices-3 { --cols: 2; } }
.choice {
  position: relative; display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 11px 16px; cursor: pointer;
  box-shadow: inset 0 var(--hair) 0 var(--sep);
}
.choice:hover { background: var(--pressed); }
.choice .grow > span { display: block; }
.choice .sub { font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); }
.choice-list { display: block; }
.choice:has(> input[hidden]) { cursor: default; } .choice:has(> input[hidden]):hover { background: none; }
.choices > .choice:first-child, .choices-2 > .choice:nth-child(-n+2), .choices-3 > .choice:nth-child(-n+3) { box-shadow: none; }
@media (max-width: 640px) { .choices > .choice:not(:first-child) { box-shadow: inset 0 var(--hair) 0 var(--sep); } }
@media (min-width: 641px) and (max-width: 900px) { .choices-3 > .choice:nth-child(3) { box-shadow: inset 0 var(--hair) 0 var(--sep); } }
.choice .tile { width: 30px; height: 30px; }

/* The iOS switch. */
input[type=checkbox].switch {
  position: relative; width: 51px; height: 31px; border: 0; border-radius: 16px; background: var(--fill-strong);
  transition: background-color 180ms ease;
}
input[type=checkbox].switch::before {
  content: ""; position: absolute; top: 2px; left: 2px; width: 27px; height: 27px; border-radius: 50%; background: #fff;
  box-shadow: 0 3px 8px rgba(0, 0, 0, .15), 0 3px 1px rgba(0, 0, 0, .06), 0 0 0 .5px rgba(0, 0, 0, .04);
  transition: transform 300ms var(--spring);
}
input[type=checkbox].switch:checked { background: var(--switch-on); }
input[type=checkbox].switch:checked::before { transform: translateX(20px); }
input[type=checkbox].switch:active { transform: none; }
input[type=checkbox].switch:active::before { width: 31px; }
input[type=checkbox].switch:checked:active::before { transform: translateX(16px); }
.switch-row { position: relative; display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 8px 14px 8px 16px; cursor: pointer; }
.switch-row .grow > span { display: block; }
.switch-row .sub { font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); }
.form-group > :not(input[type=hidden]) ~ .switch-row::before, .switch-row + *::before { content: ""; position: absolute; top: 0; left: 16px; right: 0; height: var(--hair); background: var(--sep); }

/* ---------- segmented control ---------- */
.segmented {
  display: inline-flex; gap: 0; padding: 2px; border-radius: 999px; background: var(--fill); margin-bottom: 16px; max-width: 100%;
}
.segmented a, .segmented button {
  position: relative; flex: 1 1 0; min-width: 88px; min-height: 32px; padding: 0 16px; border: 0; border-radius: 999px; background: transparent;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  color: var(--label); font: 500 var(--control-text)/var(--control-text-lh) var(--font); text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: background-color 220ms var(--ease), box-shadow 220ms var(--ease);
}
.segmented a:hover { text-decoration: none; }
.segmented > * + *::before { content: ""; position: absolute; left: 0; top: 8px; bottom: 8px; width: 1px; background: var(--sep); transition: opacity 160ms; }
.segmented .active, .segmented .is-active { background: var(--segment-active); font-weight: 600; box-shadow: 0 0 0 var(--hair) var(--border); }
.segmented .active::before, .segmented .active + *::before, .segmented .is-active::before, .segmented .is-active + *::before { opacity: 0; }
.segmented .count { height: 18px; min-width: 18px; font-size: 11px; padding: 0 5px; }
/* The staff console's switches: each segment as wide as its label; a row too wide for the screen scrolls. */
.staff-seg { overflow-x: auto; scrollbar-width: none; }
.staff-seg::-webkit-scrollbar { display: none; }
.staff-seg a { flex: 0 0 auto; min-width: 0; }
.staff-seg .count { background: var(--fill-strong); color: var(--label-2); }
/* The staff overview's search: one wide field that finds a customer or a person. */
.staff-find { position: relative; display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.staff-find > .sym { position: absolute; left: 14px; color: var(--label-2); pointer-events: none; }
.staff-find input[type=search] { flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 10px 14px 10px 44px; border-radius: 12px; font-size: var(--body); }
.staff-clear { display: flex; align-items: center; gap: 14px; padding: 16px; }
.staff-clear .title { font-weight: 600; }
.staff-clear .sub { color: var(--label-2); font-size: var(--subhead); line-height: var(--subhead-lh); }
.staff-audit-rest { overflow-wrap: anywhere; color: var(--label-3); margin-top: 2px; }

/* ---------- tables (admin and reports) ---------- */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { width: 100%; border-collapse: collapse; font-size: var(--subhead); line-height: var(--subhead-lh); }
th, td { text-align: left; padding: 12px 16px; vertical-align: middle; }
td { border-top: var(--hair) solid var(--sep); }
tbody tr:first-child td { border-top-color: var(--sep); }
th {
  font-size: var(--footnote); line-height: var(--footnote-lh); font-weight: 600; color: var(--label-2); white-space: nowrap;
  padding-top: 14px; padding-bottom: 8px;
}
td strong { font-weight: 600; }
td .small { margin-top: 1px; }
td.empty { padding: 28px 16px; }
td.details { min-width: 240px; max-width: 420px; overflow-wrap: anywhere; }
tbody tr { transition: background-color 200ms ease; }
@media (hover: hover) { tbody tr:hover { background: color-mix(in srgb, var(--pressed) 55%, transparent); } }

/* ---------- status: tinted capsules with a dot; in a row, a dot and a word ---------- */
.pill {
  display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px 0 8px; border-radius: 13px;
  font-size: var(--footnote); line-height: var(--footnote-lh); font-weight: 600; white-space: nowrap;
  background: var(--fill); color: var(--label-2);
}
.pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.pill.no-dot { padding: 0 10px; }
.pill.no-dot::before { display: none; }
.pill-green { background: var(--green-tint); color: var(--green); }
.pill-red { background: var(--red-tint); color: var(--red); }
.pill-orange { background: var(--orange-tint); color: var(--orange); }
.pill-teal { background: var(--teal-tint); color: var(--teal); }
.pill-violet { background: var(--violet-tint); color: var(--violet); }
.pill-yellow { background: var(--yellow-tint); color: var(--label); }
.pill-yellow::before { background: var(--accent-pressed); }
/* Not known, not counted: an outline, the quietest of the tones. */
.pill-grey { background: transparent; color: var(--label-2); box-shadow: inset 0 0 0 var(--hair) var(--label-4); }
.pill-grey::before { background: var(--label-4); }
.status { display: inline-flex; align-items: center; gap: 6px; font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); white-space: nowrap; }
.status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.status-green { color: var(--green); } .status-red { color: var(--red); } .status-orange { color: var(--orange); } .status-teal { color: var(--teal); }
.status-yellow::before { background: var(--accent-pressed); } .status-yellow { color: var(--label); }
.status-neutral::before { background: var(--label-3); }
.status-grey::before { background: var(--label-4); }

/* ---------- notices ---------- */
.flash {
  position: relative; border-radius: 16px; padding: 13px 16px 14px 44px; margin-bottom: 16px;
  font-size: var(--subhead); line-height: var(--subhead-lh); background: var(--surface); color: var(--label);
}
.flash::before {
  content: ""; position: absolute; left: 14px; top: 13px; width: 20px; height: 20px; background: currentColor;
  -webkit-mask: var(--flash-icon) center / contain no-repeat; mask: var(--flash-icon) center / contain no-repeat;
}
.flash a { color: var(--tint); font-weight: 500; }
.flash-ok { --flash-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cmask id='m' maskUnits='userSpaceOnUse' x='0' y='0' width='24' height='24'%3E%3Crect width='24' height='24' fill='white'/%3E%3Cpath d='M8.2 12.3 L10.8 14.9 L15.9 9.3' fill='none' stroke='black' stroke-width='1.84' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/mask%3E%3Ccircle cx='12' cy='12' r='9.6' mask='url(%23m)'/%3E%3C/svg%3E"); background: var(--green-tint); }
.flash-error { --flash-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cmask id='m' maskUnits='userSpaceOnUse' x='0' y='0' width='24' height='24'%3E%3Crect width='24' height='24' fill='white'/%3E%3Cpath d='M12 9.2 V13.6' stroke='black' stroke-width='1.76' stroke-linecap='round'/%3E%3Ccircle cx='12' cy='16.6' r='1.25' fill='black'/%3E%3C/mask%3E%3Cpath mask='url(%23m)' d='M10.2 4.3 C11 2.9 13 2.9 13.8 4.3 L21.1 17.1 C21.9 18.5 20.9 20.2 19.3 20.2 H4.7 C3.1 20.2 2.1 18.5 2.9 17.1 Z'/%3E%3C/svg%3E"); background: var(--red-tint); }
.flash-info { --flash-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9.2'/%3E%3Cpath d='M12 10.8 V16.6'/%3E%3C/g%3E%3Ccircle cx='12' cy='7.8' r='1.25'/%3E%3C/svg%3E"); background: var(--teal-tint); }
.flash-warn { --flash-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cmask id='m' maskUnits='userSpaceOnUse' x='0' y='0' width='24' height='24'%3E%3Crect width='24' height='24' fill='white'/%3E%3Cpath d='M12 9.2 V13.6' stroke='black' stroke-width='1.76' stroke-linecap='round'/%3E%3Ccircle cx='12' cy='16.6' r='1.25' fill='black'/%3E%3C/mask%3E%3Cpath mask='url(%23m)' d='M10.2 4.3 C11 2.9 13 2.9 13.8 4.3 L21.1 17.1 C21.9 18.5 20.9 20.2 19.3 20.2 H4.7 C3.1 20.2 2.1 18.5 2.9 17.1 Z'/%3E%3C/svg%3E"); background: var(--orange-tint); }
.flash-ok::before { color: var(--green); } .flash-error::before { color: var(--red); } .flash-info::before { color: var(--teal); } .flash-warn::before { color: var(--orange); }
.flash > p { margin: 0; }

/* A page that follows something (public/js/app.js): what an update brought arrives once, and a page that could not be
   updated says so at the bottom, above the phone's tab bar. */
.is-live-new { animation: live-in 420ms var(--ease) 1; }
li.is-live-new, tr.is-live-new { animation: live-in 420ms var(--ease) 1, live-tint 1800ms var(--ease) 1; }
@keyframes live-in { from { opacity: 0; transform: translateY(-4px); } }
@keyframes live-tint { from { background-color: var(--teal-tint); } }
.live-note {
  position: fixed; z-index: 30; left: 50%; bottom: max(16px, env(safe-area-inset-bottom)); transform: translateX(-50%);
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: 4px 10px;
  width: max-content; max-width: calc(100vw - 32px); margin: 0; padding: 10px 16px; border-radius: 16px;
  font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label); text-align: center;
  background: var(--elevated); box-shadow: 0 0 0 var(--hair) var(--sep), 0 10px 30px rgba(3, 1, 7, .12);
  animation: live-note-in 320ms var(--ease) 1;
}
.live-note a { color: var(--tint); font-weight: 500; white-space: nowrap; }
@keyframes live-note-in { from { opacity: 0; transform: translate(-50%, 8px); } }
@media (max-width: 1023px) { .has-tabbar .live-note { bottom: calc(max(12px, calc(env(safe-area-inset-bottom) - 8px)) + 74px); } }
@media (prefers-reduced-motion: reduce) {
  .is-live-new, .live-note { animation: none; }
  li.is-live-new, tr.is-live-new { animation: live-tint 1800ms var(--ease) 1; }
}
.flash form { display: inline; }
/* A form sent in place (public/js/app.js): the page's own message floats above it for a moment while the message's
   place is out of sight, and so does what went wrong. It hangs under the top bar, where the message would have been and
   away from the control just pressed further down the page. A tap closes it. */
.toasts {
  position: fixed; z-index: 39; left: 50%; top: calc(var(--topbar) + env(safe-area-inset-top) + 12px); transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  width: max-content; max-width: min(560px, calc(100vw - 32px)); pointer-events: none;
}
.toasts > .flash {
  margin: 0; pointer-events: auto; cursor: pointer; overflow-wrap: anywhere;
  box-shadow: 0 0 0 var(--hair) var(--sep), 0 10px 30px rgba(3, 1, 7, .12);
  animation: toast-in 320ms var(--ease) 1;
}
.toasts > .flash-ok { background: linear-gradient(var(--green-tint), var(--green-tint)) var(--elevated); }
.toasts > .flash-error { background: linear-gradient(var(--red-tint), var(--red-tint)) var(--elevated); }
.toasts > .flash-info { background: linear-gradient(var(--teal-tint), var(--teal-tint)) var(--elevated); }
.toasts > .flash-warn { background: linear-gradient(var(--orange-tint), var(--orange-tint)) var(--elevated); }
.toasts > .flash.is-leaving { animation: toast-out 220ms var(--ease) 1 forwards; }
@media (min-width: 1024px) { .toasts { left: calc(50% + var(--sidebar) / 2); max-width: min(560px, calc(100vw - var(--sidebar) - 32px)); } }
@keyframes toast-in { from { opacity: 0; transform: translateY(-10px) scale(.98); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-6px); } }
@media (prefers-reduced-motion: reduce) {
  .toasts > .flash { animation: none; }
  .toasts > .flash.is-leaving { animation: toast-out 1ms linear 1 forwards; }
}
[aria-busy="true"] { cursor: progress; }
.flash-list { margin: 6px 0 12px; padding-left: 18px; }
.flash-list li + li { margin-top: 4px; }

/* ---------- pieces ---------- */
.code-display {
  font-family: var(--mono); font-size: 44px; line-height: 52px; font-weight: 700; letter-spacing: .14em; text-indent: .14em;
  padding: 22px 16px; border-radius: 22px; background: var(--accent); color: var(--on-accent); text-align: center; font-variant-numeric: tabular-nums;
}
@media (max-width: 420px) { .code-display { font-size: 34px; } }
.snapshot { display: block; width: 100%; border-radius: 14px; background: var(--surface-2); aspect-ratio: 4 / 3; object-fit: cover; }
.thumb { width: 74px; height: 56px; border-radius: 10px; object-fit: cover; background: var(--surface-2); flex: none; display: block; }
.snap-link { display: block; flex: none; border-radius: 10px; cursor: zoom-in; transition: opacity 160ms ease, transform 200ms var(--ease); }
.snap-link:hover { opacity: .88; }
.snap-link:active { transform: scale(.97); }
.snap-link.is-large { border-radius: 14px; }
/* A protected home's media opens on the viewer site (x-media-link): a row's tile, or a block with the words and the link. */
.media-link-thumb { display: grid; place-items: center; width: 74px; height: 56px; flex: none; border-radius: 10px; background: var(--surface-2); color: var(--green); }
.media-link-thumb:hover { opacity: .88; }
.media-link { display: grid; justify-items: center; gap: 10px; padding: 28px 20px; text-align: center; color: var(--label-2); }
.media-link > svg { color: var(--green); }
.media-link > p { margin: 0; max-width: 34ch; }
.media-link .btn svg { margin-left: 4px; }
.figure { padding: 12px; }
.figure .caption { font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); padding: 10px 4px 2px; margin: 0; }
/* A camera's ignore zones (devices/show): the motion detector's 16×12 tiles over its latest photo, a ticked tile shaded. */
.zone-picker { position: relative; aspect-ratio: 4 / 3; border-radius: 14px; overflow: hidden; background: var(--surface-2); }
.zone-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: fill; }
.zone-grid { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(16, 1fr); grid-template-rows: repeat(12, 1fr); }
.zone-tile { position: relative; cursor: pointer; box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.35); }
.zone-tile input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.zone-tile:has(input:checked) { background: rgba(255, 59, 48, 0.45); }
.zone-tile:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: -2px; }
/* An alarm's video, a player per camera, side by side where there is room. */
.clips { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); gap: 12px; padding: 12px; }
.clip-figure { margin: 0; min-width: 0; position: relative; }
/* Opens the clip in the viewer, over the video's top corner where its own controls are not. */
.clip-open {
  position: absolute; top: 10px; right: 10px; width: 36px; height: 36px; border: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; color: #fff; background: rgba(20, 20, 18, .55); cursor: zoom-in;
  -webkit-backdrop-filter: blur(12px) saturate(160%); backdrop-filter: blur(12px) saturate(160%);
  transition: background-color 160ms ease, transform 160ms var(--ease);
}
.clip-open:hover { background: rgba(20, 20, 18, .75); }
.clip-open:active { transform: scale(.92); }
.clip-figure .caption { font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); padding: 10px 4px 2px; margin: 0; }
.clip { display: block; width: 100%; aspect-ratio: 4 / 3; border-radius: 14px; background: #000; object-fit: contain; }
.clip-audio { display: block; width: 100%; }
.clips + .list > li:first-child { border-top: var(--hair) solid var(--sep); }

/* The viewer (x-viewer, public/js/app.js): a photo or clip large over the dimmed page, as Quick Look
   shows one — dark in both themes, filling the space whatever its own size, its caption below, the
   page's others a step away. What is still loading shows its small picture under a spinner. */
html:has(dialog.lightbox[open]) { overflow: hidden; }
dialog.lightbox {
  position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; border: 0;
  padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
  background: transparent; color: #f5f5f0; overflow: hidden;
}
dialog.lightbox[open] { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 12px; animation: fade-in 200ms ease; }
dialog.lightbox::backdrop { background: rgba(8, 8, 6, .86); -webkit-backdrop-filter: blur(24px) saturate(140%); backdrop-filter: blur(24px) saturate(140%); }
.lightbox-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 44px; }
.lightbox-count { font-size: var(--subhead); line-height: var(--subhead-lh); font-weight: 600; color: rgba(245, 245, 240, .72); font-variant-numeric: tabular-nums; padding-left: 6px; }
.lightbox-stage { position: relative; min-height: 0; display: flex; align-items: center; justify-content: center; touch-action: pan-y pinch-zoom; container-type: size; }
/* As large as the stage allows at the picture's own shape (--ratio, width over height, set by the script). */
.lightbox-frame {
  --ratio: 1.7778;
  position: relative; flex: none; width: min(100cqw, 100cqh * var(--ratio)); aspect-ratio: var(--ratio); overflow: hidden;
  border-radius: 14px; background: #1c1b17; box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
}
.lightbox-frame > :is(img, canvas, video) { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: contain; }
.lightbox-frame.is-loading > :is(img, canvas) { filter: blur(8px) brightness(.75); transform: scale(1.04); }
.lightbox-loading {
  position: absolute; top: 50%; left: 50%; width: 36px; height: 36px; margin: -18px 0 0 -18px; border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .28); border-top-color: #fff; animation: spin 800ms linear infinite;
}
dialog.lightbox[open] .lightbox-frame { animation: photo-in 320ms var(--ease); }
.lightbox-error { margin: 0; font-size: var(--body); line-height: var(--body-lh); color: rgba(245, 245, 240, .8); text-align: center; }
.lightbox-caption { margin: 0 auto; max-width: 720px; text-align: center; font-size: var(--subhead); line-height: var(--subhead-lh); color: rgba(245, 245, 240, .82); }
.lightbox-button {
  width: 44px; height: 44px; border: 0; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center;
  color: #fff; background: rgba(255, 255, 255, .14); cursor: pointer;
  -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%);
  box-shadow: inset 0 .5px 0 rgba(255, 255, 255, .18); transition: background-color 160ms ease, transform 160ms var(--ease);
}
.lightbox-button:hover { background: rgba(255, 255, 255, .22); }
.lightbox-button:active { transform: scale(.92); }
.lightbox-close { margin-left: auto; }
.lightbox-step { position: absolute; top: 50%; margin-top: -22px; z-index: 1; }
.lightbox-prev { left: 4px; }
.lightbox-next { right: 4px; }
@media (min-width: 700px) {
  dialog.lightbox { padding-inline: max(24px, env(safe-area-inset-left)) max(24px, env(safe-area-inset-right)); }
  .lightbox-stage { padding-inline: 64px; }
  .lightbox-prev { left: 0; }
  .lightbox-next { right: 0; }
}
@keyframes photo-in { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }
@keyframes spin { to { transform: rotate(360deg); } }
/* Redactor: violet is its tone; its pages share the Prompt Firewall pieces above (.fw-*) where they fit. */
.rd-textarea { width: 100%; min-height: 160px; resize: vertical; font: 500 14px/1.5 var(--mono); }
.rd-out { white-space: pre-wrap; overflow-wrap: anywhere; }
.rd-chip-group { clear: both; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 6px 0; }
.rd-chip-head { flex: 0 0 100%; font-size: var(--footnote); line-height: var(--footnote-lh); font-weight: 600; color: var(--label); }
.rd-chip { position: relative; display: inline-flex; cursor: pointer; }
.rd-chip > input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: inherit; }
.rd-chip > span { padding: 5px 12px; border-radius: 999px; background: var(--fill); color: var(--label); font-size: var(--subhead); line-height: var(--subhead-lh); transition: background 160ms, color 160ms, transform 160ms cubic-bezier(.3,1.6,.5,1); }
.rd-chip:hover > input:not(:checked) + span { background: var(--violet-tint); }
.rd-chip > input:checked + span { background: var(--violet); color: var(--surface); }
.rd-chip > input:active + span { transform: scale(.94); }
.rd-chip > input:focus-visible + span { box-shadow: 0 0 0 2px var(--focus); }
.rd-chip.is-covered { cursor: default; }
.rd-chip.is-covered > span { background: var(--violet-tint); color: var(--label-2); }
@media (prefers-reduced-motion: reduce) { .rd-chip > span { transition: none; } }

/* Shield: orange is its tone; its pages share the Prompt Firewall pieces above (.fw-*) where they fit. */
/* A box of text inside a form row (a site's hostnames). */
.field-row > textarea {
  flex: 1; min-width: 0; min-height: 0; padding: 8px 0 10px; border: 0; border-radius: 0; background: transparent; box-shadow: none;
  resize: vertical; font: 500 14px/1.5 var(--mono); color: var(--label);
}
.field-row.stacks > textarea { padding-top: 4px; }
/* The rules page: a kind of visitor with what it is, and its choice at the end of the row. */
.sh-rules .field-row > .grow, .sh-rows .field-row > .grow { min-width: 0; padding: 8px 0; }
.sh-rules .field-row > .grow > span, .sh-rows .field-row > .grow > span { display: block; }
.sh-rules .field-row .sub, .sh-rows .field-row .sub { font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); }
.sh-rules .field-row > select, .sh-rows .field-row > select { flex: 0 1 210px; margin-left: auto; text-align: right; }
.sh-rules .section { margin-top: 0; }
/* A site's declared form fields: the action over its list, Remove beside the action; names break at their separators. */
.sh-binding-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-width: 0; }
.sh-binding-head .field-label { min-width: 0; font-size: var(--footnote); line-height: 16px; color: var(--label-2); overflow-wrap: anywhere; }
.sh-binding-head .btn { flex: none; margin-right: -10px; }
.sh-binding > input { min-height: 0; padding: 3px 0 9px; }
.sh-binding.is-leaving { opacity: 0; transform: translateX(8px); transition: opacity 180ms ease, transform 180ms var(--ease); }
.sh-action { color: var(--label-3); margin-left: 4px; }
.sh-bindings-block { margin-top: 24px; }
.stack > .sh-bindings-block { margin-top: 0; }
@media (max-width: 520px) {
  .kv.sh-bindings { grid-template-columns: minmax(0, 1fr); }
  .kv.sh-bindings dt { min-height: 0; padding-bottom: 2px; }
  .kv.sh-bindings dd { min-height: 0; padding-top: 0; justify-content: flex-start; text-align: left; }
  .kv.sh-bindings dt:not(:first-of-type) + dd { border-top: 0; }
}
/* A mobile app's row: its keys' form opens full width under it. */
.list > li.sh-app { flex-wrap: wrap; row-gap: 8px; }
.sh-app > details.edit-panel[open] { flex: 1 1 100%; order: 5; }
.sh-app > details.edit-panel[open] .edit-box { margin-top: 0; }
.sh-app .title { overflow-wrap: anywhere; }
/* A choice that cannot be made here says why in its own line and is not offered. */
.choice:has(input:disabled) { opacity: .6; cursor: not-allowed; }
.choice:has(input:disabled):hover { background: transparent; }
@media (max-width: 640px) {
  .list > li.sh-app > .grow { flex: 1 1 calc(100% - 56px); min-width: 0; }
  .list > li.sh-app > .grow + * { margin-left: 44px; }
}
@media (max-width: 520px) { .sh-rules .field-row > select, .sh-rows .field-row > select { flex-basis: 150px; } }
/* The install guide: which site it is written for, and the tabs. */
.sh-for { margin-bottom: 14px; }
.sh-for .fw-filters { margin-bottom: 6px; }
.sh-tabs .segmented { margin-bottom: 18px; overflow-x: auto; }
.sh-tabs .segmented a { flex: 0 0 auto; }
.sh-tabs .sh-tabs .segmented { margin: 14px 0 12px; }
.sh-panel { animation: fade-in 160ms ease; }
.sh-panel h3 { margin: 18px 0 8px; }
.sh-panel .fw-copy-row + .fw-copy-row { margin-top: 10px; }
.sh-panel h3.sh-code-head { font-size: var(--subhead); line-height: var(--subhead-lh); font-weight: 600; overflow-wrap: anywhere; }
.sh-lib-head a { font-size: .86em; font-weight: 500; margin-left: 4px; overflow-wrap: anywhere; }
.sh-panel details.fw-more > h3, .sh-panel details.fw-more > .fw-copy-row { margin-inline: 12px; }
.sh-panel details.fw-more > .fw-copy-row:last-child { margin-bottom: 12px; }
.sh-libs .sub a { overflow-wrap: anywhere; }
.sh-version { font-size: var(--footnote); font-weight: 400; white-space: nowrap; }
.sh-libs .sh-install { display: inline-block; margin-top: 6px; max-width: 100%; overflow-wrap: anywhere; user-select: all; }
.sh-panel > .section:first-child { margin-top: 0; }
/* A secret shown once: it arrives with a check that draws itself, and answers a copy. */
.sh-reveal {
  display: flex; align-items: center; gap: 14px; padding: 14px 16px; margin-top: 12px; border-radius: var(--radius-card);
  background: var(--surface); transition: box-shadow 220ms var(--ease); animation: sh-pop 420ms var(--ease) both;
}
.sh-reveal.is-copied { box-shadow: 0 0 0 3px var(--green-tint); }
.sh-reveal .fw-copy-row { flex: 1; min-width: 0; }
.sh-reveal .fw-secret { flex: 1; min-width: 0; }
.sh-check { flex: none; width: 34px; height: 34px; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.sh-check circle { fill: var(--green-tint); stroke: none; }
.sh-check path { fill: none; stroke: var(--solid-green); stroke-dasharray: 20; stroke-dashoffset: 20; animation: sh-draw 520ms ease-out 260ms forwards; }
.sh-reveal.is-copied .sh-check { animation: sh-nudge 360ms var(--ease); }
@keyframes sh-pop { from { opacity: 0; transform: translateY(6px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes sh-draw { to { stroke-dashoffset: 0; } }
@keyframes sh-nudge { 40% { transform: scale(1.14); } }
/* A form that was sent says it is working. */
.btn.is-busy { opacity: .75; pointer-events: none; }
.btn.is-busy::before { content: ""; flex: none; width: 14px; height: 14px; margin-right: 8px; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent; animation: spin 700ms linear infinite; display: inline-block; }
@media (prefers-reduced-motion: reduce) {
  .sh-panel, .sh-reveal { animation: none; }
  .sh-check path { animation: none; stroke-dashoffset: 0; }
  .sh-reveal.is-copied .sh-check { animation: none; }
  .btn.is-busy::before { animation-duration: 1600ms; }
}

@media (prefers-reduced-motion: reduce) {
  dialog.lightbox[open], dialog.lightbox[open] .lightbox-frame { animation: none; }
  .lightbox-loading { animation-duration: 1600ms; }
  .snap-link:active, .lightbox-button:active, .clip-open:active { transform: none; }
}

/* A destructive action asks first: the button, then what goes with it and the real one. */
details.confirm > summary { list-style: none; display: inline-flex; }
details.confirm > summary::-webkit-details-marker { display: none; }
details.confirm[open] > summary { display: none; }
.confirm-box {
  display: flex; align-items: center; gap: 10px 12px; flex-wrap: wrap; padding: 12px 12px 12px 16px; border-radius: 16px;
  background: var(--red-tint); animation: fade-in 180ms ease;
}
.confirm-box > .small, .confirm-box > span { flex: 1 1 220px; font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label); }
.confirm-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.danger-zone { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }

.dot { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--label-3); }
.dot.red { background: var(--red); } .dot.orange { background: var(--orange); } .dot.green { background: var(--green); } .dot.yellow { background: var(--accent); }

.pager { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 18px; }
.pager .small { color: var(--label-2); font-variant-numeric: tabular-nums; }

/* heySec Sensor for desktop downloads, in the pairing panel */
.downloads { list-style: none; margin: 4px 0 0; padding: 0; }
.downloads li { position: relative; display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 8px 0; }
.downloads li + li::before { content: ""; position: absolute; top: 0; left: 42px; right: 0; height: var(--hair); background: var(--sep); }
.downloads a { font-weight: 500; }
.download-sha { overflow-wrap: anywhere; }
.download-sha .mono { display: block; font-size: 11px; }
/* Only a step is numbered: a list inside one (a step's downloads) is part of that step. */
.steps { margin: 0; padding: 0; list-style: none; counter-reset: step; }
.steps > li { position: relative; padding: 0 0 12px 36px; counter-increment: step; }
.steps > li::before {
  content: counter(step); position: absolute; left: 0; top: -1px; width: 24px; height: 24px; border-radius: 50%;
  background: var(--fill); color: var(--label); font-size: var(--footnote); font-weight: 600;
  display: flex; align-items: center; justify-content: center;
}
.pairing { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 24px; align-items: start; }
/* The code stays in view beside the long instructions. */
.pairing .code-side { position: sticky; top: 24px; }
@media (max-width: 860px) { .pairing { grid-template-columns: minmax(0, 1fr); } .pairing .code-side { order: -1; position: static; } }
.prose { font-size: var(--subhead); line-height: 1.4; color: var(--label-2); }
.prose p { margin-bottom: 10px; }
.prose strong { color: var(--label); }

/* ---------- guest (sign in): heySec's night, as heysec.com opens ---------- */
.auth { min-height: 100vh; min-height: 100dvh; display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); }
/* The night panel: the white wordmark, a big tightly set line, and the two kinds of owner with
   the services each can switch on — over a faint gold shield. */
.auth-brand {
  position: relative; overflow: hidden; isolation: isolate; background: var(--night); color: var(--on-night);
  padding: clamp(28px, 4.5vw, 56px); display: flex; flex-direction: column; gap: 28px;
}
/* A household and its organisation under one roof, as on heysec.com's photo heroes: the night holds the
   wordmark at the top and the line at the bottom left, and opens up over the house on the right. */
.auth-brand {
  background:
    linear-gradient(180deg, rgba(14, 13, 10, .78) 0%, rgba(14, 13, 10, .2) 22%, rgba(14, 13, 10, .25) 45%, rgba(14, 13, 10, .7) 75%, rgba(14, 13, 10, .95) 100%),
    linear-gradient(90deg, rgba(14, 13, 10, .8) 0%, rgba(14, 13, 10, .55) 45%, rgba(14, 13, 10, 0) 82%),
    url("/images/auth-kalamaja-studio-home.webp") 65% 30% / cover no-repeat,
    var(--night);
}
.auth-brand::after {
  content: ""; position: absolute; z-index: -1; right: -18%; bottom: -24%; width: 78%; aspect-ratio: 1;
  background: url("/images/shield.svg") no-repeat center / contain; opacity: .09; pointer-events: none;
}
.auth-logo { height: 30px; align-self: flex-start; --logo-word: #fff; --logo-shield: #fff; }
/* The services' dots on night, as the CVI's eyebrows on night. */
.auth-brand { --teal: #3fb4c6; --violet: #a99bf0; }
.auth-brand .pitch { margin-top: auto; max-width: 560px; }
.auth-brand .pitch h1 { font-size: clamp(40px, 4.6vw, 64px); font-weight: 760; line-height: .98; letter-spacing: -.048em; margin: 0; }
.auth-brand .pt { color: var(--accent); }
.auth-doors { display: grid; grid-template-columns: 1fr 1fr; border-top: 1px solid rgba(255, 255, 255, .18); max-width: 560px; }
.auth-door { padding: 14px 16px 0 0; display: flex; flex-direction: column; gap: 5px; }
.auth-door + .auth-door { padding-left: 16px; box-shadow: inset 1px 0 0 rgba(255, 255, 255, .18); }
.auth-door b { font-size: 15px; font-weight: 650; }
.auth-door span { display: flex; align-items: center; gap: 8px; font-size: 13px; color: rgba(245, 245, 240, .66); }
.auth-trust { display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: 12px; font-weight: 600; color: rgba(245, 245, 240, .45); }
.auth-trust span + span::before { content: "\00b7"; margin-right: 18px; }
.auth-panel { display: flex; align-items: center; justify-content: center; padding: 48px 24px; background: var(--surface); }
.auth-card { width: 100%; max-width: 400px; }
.auth-card h2 { font-size: var(--large-title); line-height: var(--large-title-lh); font-weight: 700; letter-spacing: -.034em; margin-bottom: 6px; }
.auth-card > .muted { font-size: var(--body); }
.auth-card .form-group { margin-top: 28px; background: var(--fill); }
.auth-card .form-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin: 14px 4px 22px; font-size: var(--subhead); }
.auth-foot { text-align: center; margin-top: 28px; font-size: var(--subhead); color: var(--label-2); }
.auth-or { display: flex; align-items: center; gap: 10px; margin: 16px 0; color: var(--label-3); font-size: var(--footnote); }
.auth-or::before, .auth-or::after { content: ""; flex: 1; height: var(--hair); background: var(--sep); }
.code-input { font: 600 28px/1 var(--mono) !important; letter-spacing: .3em; text-align: center; font-variant-numeric: tabular-nums; }
/* An invitation code (XXXX-XXXX-XXXX-XXXX) fits a phone's width. */
.code-input-long { font-size: 19px !important; letter-spacing: .06em; text-transform: uppercase; }
.code-input-long::placeholder { text-transform: none; letter-spacing: .06em; }
/* Sign-up while some services are released: the code for the others folds away until it is wanted. */
.invite-code { border-radius: var(--radius-field); background: var(--surface-2); padding: 10px 14px; }
.invite-code > summary { display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--tint); font-weight: 600; font-size: var(--subhead); list-style: none; }
.invite-code > summary::-webkit-details-marker { display: none; }
.invite-code[open] > summary { margin-bottom: 4px; }
.invite-code[open] > form { animation: invite-open 220ms var(--ease); }
@keyframes invite-open { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .invite-code[open] > form { animation: none; } }
/* A service still open by invitation, on the sign-in page's panel. */
.auth-invite { margin-left: 6px; padding: 0 6px; border-radius: 999px; font-size: 11px; line-height: 17px; color: rgba(245, 245, 240, .78); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .26); white-space: nowrap; }
/* Under the order form: the services an invitation would open, and where to enter its code. */
.invite-note { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 14px 0 0; padding: 0 4px; font-size: var(--subhead); color: var(--label-2); }
.invite-note > svg { flex: none; }
/* Staff's link to services and its code, shown once: one copy row each. */
.access-link { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.access-link .access-code { white-space: nowrap; overflow-wrap: normal; }
@media (max-width: 860px) {
  .auth { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr; }
  .auth-brand { padding: calc(20px + env(safe-area-inset-top)) 22px 22px; gap: 20px; }
  .auth-logo { height: 26px; }
  .auth-brand::after { right: -22%; bottom: -60%; width: 70%; }
  .auth-brand .pitch h1 { font-size: 30px; }
  .auth-doors, .auth-trust { display: none; }
  .auth-panel { align-items: flex-start; padding: 28px 16px calc(40px + env(safe-area-inset-bottom)); }
}

/* Setting up and giving the second step. */
.setup-way { padding: 16px; border-radius: 18px; background: var(--fill); }
.setup-way h3 { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.setup-way .btn { margin-top: 10px; }
.qr { width: 184px; height: 184px; margin: 12px auto; padding: 8px; border-radius: 14px; background: #fff; }
.qr svg { display: block; width: 100%; height: 100%; }
.secret { font: 600 13px/1.4 var(--mono); letter-spacing: .06em; word-break: break-all; }
details.recovery > summary { cursor: pointer; color: var(--tint); font-size: var(--subhead); }
.recovery-codes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 16px; margin: 0; padding: 16px 16px 16px 36px; border-radius: 18px; background: var(--fill); }
.recovery-codes code { font: 600 15px/1.6 var(--mono); letter-spacing: .04em; }
.link-button { border: 0; padding: 0; background: none; color: var(--tint); font: inherit; cursor: pointer; }
.link-button:hover { text-decoration: underline; }

/* ---------- error pages ---------- */
.error-page { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: 24px; text-align: center; }
.error-page .code { font-family: var(--font-display); font-size: var(--large-title); line-height: var(--large-title-lh); font-weight: 700; margin-bottom: 6px; }
.error-page img { height: 72px; margin-bottom: 18px; }
.error-page p { color: var(--label-2); margin-bottom: 22px; }

/* ---------- where the home is, automations and who is home ---------- */
.map-box { position: relative; height: clamp(320px, 52vh, 520px); margin-top: 14px; border-radius: var(--radius-card); overflow: hidden; background: var(--fill); }
.map-box .map { position: absolute; inset: 0; }
.map-loading { position: absolute; inset: 0; display: grid; place-items: center; margin: 0; color: var(--label-2); font-size: var(--subhead); }
.results { margin-top: 10px; }
.result {
  display: flex; align-items: center; width: 100%; min-height: 48px; padding: 8px 16px; border: 0; background: none; text-align: left;
  color: var(--label); font: inherit; cursor: pointer;
}
.result:hover { background: var(--pressed); }
.result .grow > span { display: block; }
.result .sub { font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); }
.area-pick {
  display: block; max-width: 100%; padding: 0; border: 0; background: none; text-align: left; color: var(--label);
  font: inherit; font-size: var(--body); line-height: var(--body-lh); cursor: pointer;
}
.area-pick[aria-current] { font-weight: 600; }
.problem { color: var(--orange); }
.automation + .automation, .person + .person { margin-top: 18px; }
.automation .gone-note { padding: 10px 16px 0; }
.hero-note { margin-top: 6px; }

/* ---------- people: whether each is home, under who they are; the role trails as a value ---------- */
.presence-line {
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; margin: 6px 0 2px;
  font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2);
}
.role-value { font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); white-space: nowrap; }
/* The household's People: everyone, or the people of one location (a segmented filter that scrolls when long). */
.people-filter { display: flex; width: fit-content; overflow-x: auto; scrollbar-width: none; margin-bottom: 22px; }
.people-filter::-webkit-scrollbar { display: none; }
.people-filter a { flex: 0 0 auto; min-width: 0; }
/* Someone without access to the location: listed (so it can be given), quieter. */
.list > li.member.is-faded .title { color: var(--label-2); }
.list > li.member { padding-block: 12px; }
/* On a phone a role that is only a value sits beside the name, so the lines under it keep the width. */
@media (max-width: 640px) {
  .list > li.member:not(.wraps) > .actions { position: absolute; top: 12px; right: 16px; }
  .list > li.member:not(.wraps) .title { padding-right: 7.5em; }
}

/* ---------- utilities (no inline styles: the CSP forbids them) ---------- */
.m-0 { margin: 0 !important; }
.mt-1 { margin-top: 4px !important; } .mt-2 { margin-top: 8px !important; } .mt-3 { margin-top: 12px !important; } .mt-4 { margin-top: 18px !important; } .mt-5 { margin-top: 24px !important; }
.mb-2 { margin-bottom: 8px !important; } .mb-3 { margin-bottom: 14px !important; } .mb-4 { margin-bottom: 18px !important; }
.mw-form { max-width: 680px; }
.plain-link { text-decoration: none; display: block; color: inherit; }
.plain-link:hover { text-decoration: none; }
.w-auto { width: auto !important; }
.grow-input { flex: 1; min-width: 160px; width: auto; }
.nowrap { white-space: nowrap; }
@media (max-width: 640px) { .wide-only { display: none; } }

/* ---------- homes ---------- */
.home-card {
  position: relative; display: flex; flex-direction: column; gap: 14px; padding: 16px 16px 18px; color: var(--label);
  transition: background-color 160ms ease, border-color 160ms ease, transform 160ms var(--ease);
}
.home-card:hover { text-decoration: none; background: var(--surface-hover); border-color: var(--border); }
.home-card:active { transform: scale(.985); transition-duration: 90ms; }
.home-card .top { display: flex; align-items: center; gap: 12px; }
.home-card h2 { font-size: var(--title-3); line-height: var(--title-3-lh); font-weight: 600; flex: 1; min-width: 0; overflow-wrap: anywhere; }
.home-card .meta { font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); margin: 0; }

/* ---------- households, organisations and their services ---------- */
.place-card { display: flex; flex-direction: column; gap: 12px; padding: 16px 18px; color: var(--label); transition: background-color 160ms ease, border-color 160ms ease, transform 160ms var(--ease); }
.place-card:hover { text-decoration: none; background: var(--surface-hover); border-color: var(--border); }
.place-card:active { transform: scale(.99); transition-duration: 90ms; }
.place-top { display: flex; align-items: center; gap: 12px; }
.place-top .grow { display: flex; flex-direction: column; }
.place-top b { font-size: var(--body); line-height: var(--body-lh); font-weight: 650; overflow-wrap: anywhere; }
.place-top span { font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); }
.place-card .meta { font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); margin: 0; }
/* A quota: <progress class="meter"> (no inline widths under the CSP). */
progress.meter { -webkit-appearance: none; appearance: none; display: block; width: 100%; height: 8px; border: 0; border-radius: 999px; background: var(--fill-strong); overflow: hidden; color: var(--solid-green); }
progress.meter::-webkit-progress-bar { background: var(--fill-strong); border-radius: 999px; }
progress.meter::-webkit-progress-value { background: var(--solid-green); border-radius: 999px; }
progress.meter::-moz-progress-bar { background: var(--solid-green); border-radius: 999px; }
progress.meter.is-warn { color: var(--solid-orange); }
progress.meter.is-warn::-webkit-progress-value { background: var(--solid-orange); }
progress.meter.is-warn::-moz-progress-bar { background: var(--solid-orange); }
.meter-line { display: flex; justify-content: space-between; gap: 12px; margin-top: -4px; font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); font-variant-numeric: tabular-nums; }
/* A quota block (bar, its line, the figures under it) spaces itself, so it reads the same in a card and on a subscription's page. */
.usage { display: flex; flex-direction: column; gap: 12px; }
.usage .meta { font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); margin: 0; }
.access-note { display: flex; gap: 10px; align-items: flex-start; padding: 12px 16px; margin: 0; font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); }
.access-note .sym { color: var(--label-3); margin-top: 1px; }
details.edit-panel > summary { list-style: none; display: inline-flex; }
details.edit-panel > summary::-webkit-details-marker { display: none; }
details.edit-panel[open] > summary { display: none; }
.edit-box { flex-basis: 100%; margin-top: 10px; padding: 14px; border-radius: 16px; background: var(--bg); animation: fade-in 160ms ease; }
.edit-box .form-group { background: var(--surface); }

/* ---------- setup guides (devices) ---------- */
.setup-guide { padding: 0; }
.setup-guide details > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 14px; padding: 14px 16px; }
.setup-guide details > summary::-webkit-details-marker { display: none; }
.setup-guide summary h2 { flex: 1; font-size: var(--body); line-height: var(--body-lh); font-weight: 600; font-family: var(--font); }
.setup-guide summary .chev { transition: transform 240ms var(--ease); }
.setup-guide details[open] summary .chev { transform: rotate(90deg); }
.setup-body { padding: 0 16px 18px 60px; }
/* Guides one after another read as one list of offers. */
.section:has(> .setup-guide) + .section:has(> .setup-guide) { margin-top: 12px; }
.setup-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px 18px; }
.setup-step { display: inline-flex; align-items: center; gap: 8px; font-size: var(--subhead); color: var(--label-2); }
.setup-mark { width: 24px; height: 24px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: var(--footnote); font-weight: 600; background: var(--fill); color: var(--label-2); flex: none; }
.setup-step.is-current { color: var(--label); font-weight: 600; }
.setup-step.is-current .setup-mark { background: var(--accent); color: var(--on-accent); }
.setup-step.is-done .setup-mark { background: var(--solid-green); color: #fff; }
.setup-current { margin-top: 14px; padding: 14px 16px; border-radius: 14px; background: var(--fill); }
.setup-current h3 { font-size: var(--body); }
.setup-current .small { font-size: var(--subhead); line-height: var(--subhead-lh); }
.setup-how { margin: 0; padding-left: 20px; }
.setup-how li + li { margin-top: 4px; }
@media (max-width: 640px) { .setup-body { padding-left: 16px; } }

/* ---------- floor plan (public/js/plan.js) ---------- */
.plan { overflow: hidden; }
.plan-error { margin: 12px 16px 0; }
.plan-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px 14px; border-bottom: var(--hair) solid var(--sep); }
.plan-modes { display: inline-flex; flex-wrap: wrap; padding: 2px; border-radius: 999px; background: var(--fill); }
.plan-mode {
  position: relative; border: 0; background: transparent; color: var(--label); font: 500 var(--control-text)/var(--control-text-lh) var(--font);
  min-height: 32px; padding: 0 16px; border-radius: 999px; cursor: pointer; transition: background-color 220ms var(--ease), box-shadow 220ms var(--ease);
}
.plan-mode.is-active { background: var(--segment-active); font-weight: 600; box-shadow: 0 0 0 var(--hair) var(--border); }
.plan-zoom, .plan-history { margin-left: auto; gap: 6px; }
.plan-history + .plan-zoom { margin-left: 0; }
.plan-zoom .btn, .plan-history .btn { min-width: 34px; }
.plan-floors { display: flex; gap: 6px; flex-wrap: wrap; padding: 10px 14px; border-bottom: var(--hair) solid var(--sep); }
.plan-floor-tab {
  border: 0; background: transparent; color: var(--label-2); font: 600 var(--dense-body)/var(--dense-body-lh) var(--font);
  min-height: 32px; padding: 0 14px; border-radius: 999px; cursor: pointer; transition: background-color 200ms;
}
.plan-floor-tab:hover { background: var(--fill); color: var(--label); }
.plan-floor-tab.is-active { background: var(--lens); color: var(--label); }
.plan-body { display: grid; grid-template-columns: minmax(0, 1fr) 340px; }
.plan-stage { background: var(--bg); border-right: var(--hair) solid var(--sep); min-width: 0; scroll-margin-top: 80px; }
.plan-hint { padding: 9px 16px; border-bottom: var(--hair) solid var(--sep); background: var(--surface); font-size: var(--dense-sub); line-height: var(--dense-sub-lh); color: var(--label-2); }
.plan-hint.is-armed { background: var(--yellow-tint); color: var(--label); }
.plan-hint.is-warn { background: var(--orange-tint); color: var(--orange); font-weight: 600; }
.plan-svg { display: block; width: 100%; height: 600px; touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab; font-family: var(--font); }
.plan-svg:active { cursor: grabbing; }
.plan-svg.is-tool, .plan-svg.is-tool:active { cursor: crosshair; }
.plan-svg.is-busy { opacity: .75; }
/* Beside the drawing the panel is exactly as tall as it (it adds no height to the row) and scrolls inside. */
.plan-side { padding: 18px 16px; display: flex; flex-direction: column; gap: 18px; height: 0; min-height: 100%; overflow-y: auto; scroll-margin-top: 80px; font-size: var(--dense-body); line-height: var(--dense-body-lh); }
.plan-head { display: flex; flex-direction: column; gap: 4px; }
.plan-head h2 { margin: 0; }
.plan-section { display: flex; flex-direction: column; gap: 8px; }
.plan-section > h3 { margin: 0; font-size: var(--dense-sub); line-height: var(--dense-sub-lh); font-weight: 400; text-transform: uppercase; color: var(--label-2); }
@media (min-width: 1024px) { .plan-section > h3 { font-size: 10px; line-height: 14px; font-weight: 650; letter-spacing: .12em; } }
.plan-side .list { background: var(--bg); border-radius: 14px; overflow: hidden; }
.plan-side .list > li { padding: 9px 12px; min-height: 44px; gap: 10px; }
.plan-side .list > li + li::before { left: 12px; }
.plan-side .list .title { font-size: var(--dense-body); line-height: var(--dense-body-lh); }
.plan-side .list .small { font-size: var(--dense-sub); line-height: var(--dense-sub-lh); }
.plan-side .list > li:has(a.title):hover { background: var(--fill); }
.plan-side .list > li.is-active { background: var(--lens); }
.plan-side .field > label { font-size: var(--dense-sub); line-height: var(--dense-sub-lh); color: var(--label-2); font-weight: 500; }
.plan-side input[type=text], .plan-side input[type=number], .plan-side select { min-height: 38px; font-size: var(--dense-body); padding-top: 8px; padding-bottom: 8px; }
.plan-side .check { font-size: var(--dense-body); }
.plan-kinds { display: flex; flex-wrap: wrap; gap: 6px; }
.plan-kind {
  border: 0; background: var(--fill); color: var(--label); font: 500 var(--control-text)/var(--control-text-lh) var(--font);
  min-height: 32px; padding: 0 13px; border-radius: 999px; cursor: pointer; transition: background-color 160ms, transform 160ms var(--ease);
}
.plan-kind:hover { background: var(--fill-strong); }
.plan-kind:active { transform: scale(.96); }
.plan-kind[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); font-weight: 600; }
.plan-armed { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 10px 12px; border-radius: 14px; background: var(--yellow-tint); }
.plan-side .confirm-box { padding: 10px 12px; }
.plan-size { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.plan-side form.row input[type=number] { width: 84px; }
.plan-gaps { margin: 0; padding-left: 18px; color: var(--orange); font-size: var(--dense-sub); line-height: var(--dense-sub-lh); }
.plan-first-floor { max-width: 340px; margin: 16px auto 0; text-align: left; }
.plan-legend { display: flex; flex-direction: column; gap: 7px; border-top: var(--hair) solid var(--sep); padding-top: 14px; margin-top: auto; }
.plan-legend span { display: flex; align-items: center; gap: 8px; }
.swatch { width: 18px; height: 12px; border-radius: 3px; flex: none; }
.swatch-cone { background: rgba(249, 206, 25, .45); border: 1px solid var(--accent-pressed); }
.swatch-hatch { background: repeating-linear-gradient(45deg, var(--orange-tint) 0 3px, transparent 3px 6px); border: 1px solid var(--orange-tint); }
.swatch-inactive { border: 1.5px dashed var(--label-3); }
@media (max-width: 1100px) {
  .plan-body { grid-template-columns: minmax(0, 1fr); }
  .plan-stage { border-right: 0; border-bottom: var(--hair) solid var(--sep); }
  .plan-svg { height: 440px; }
  .plan-side { height: auto; min-height: 0; }
}
@media (max-width: 640px) {
  .plan-svg { height: 380px; }
  .plan-toolbar { padding: 10px; }
  /* One line of modes that scrolls sideways, as a segmented control does not wrap. */
  .plan-modes { flex-wrap: nowrap; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
  .plan-modes::-webkit-scrollbar { display: none; }
  .plan-mode { flex: none; padding: 0 13px; }
}

/* The drawing. SVG presentation lives here: the CSP allows no style attributes. The selection is
   gold, as everywhere in heySec; the grid stays quiet. */
.plan-floor { pointer-events: none; }
.plan-grid-line { stroke: var(--label); stroke-opacity: .06; stroke-width: 1; }
.plan-room { fill: var(--surface); stroke: none; }
.plan-room.is-editable { cursor: move; }
.plan-room.is-selected { stroke: var(--tint); stroke-width: 2.5; vector-effect: non-scaling-stroke; }
.plan-unwatched { pointer-events: none; }
.plan-hatch-line { stroke: var(--orange); stroke-opacity: .32; }
.plan-cone { fill: var(--accent); fill-opacity: .34; stroke: var(--accent-pressed); stroke-width: 1; vector-effect: non-scaling-stroke; pointer-events: none; }
.plan-cone.is-inactive { fill: none; stroke: var(--label-3); stroke-dasharray: 5 4; }
.plan-label { fill: var(--label); font-weight: 600; pointer-events: none; }
.plan-sublabel { fill: var(--label-2); pointer-events: none; }
.plan-badge circle { fill: var(--solid-orange); }
.plan-badge text { fill: #fff; font-weight: 700; }
.plan-device-g { cursor: pointer; }
.plan-device-g.is-editable { cursor: move; }
.plan-device { fill: var(--solid-neutral); stroke: var(--surface); }
.plan-device.status-online { fill: var(--solid-green); }
.plan-device.status-offline, .plan-device.status-unreachable, .plan-device.status-missing { fill: var(--solid-red); }
.plan-device.status-bridge_offline { fill: var(--solid-orange); }
.plan-device-g.is-selected .plan-device { stroke: var(--tint); }
.plan-device-dir { stroke: var(--label); stroke-linecap: round; }
.plan-device-label { fill: var(--label); font-weight: 600; paint-order: stroke; stroke: var(--surface); stroke-width: 3px; stroke-linejoin: round; pointer-events: none; }
.plan-handle { fill: var(--surface); stroke: var(--tint); }
.plan-handle.is-corner { cursor: move; }
.plan-handle.is-rotate { cursor: grab; }
.plan-handle.is-add circle { fill: var(--surface); stroke: var(--accent-pressed); cursor: copy; }
.plan-handle.is-add text { fill: var(--tint); font-weight: 700; text-anchor: middle; pointer-events: none; }
.plan-rotate-line { stroke: var(--tint); stroke-dasharray: 3 3; pointer-events: none; }
.plan-js .plan-report-empty { display: none; }
/* The report follows the editor: its first section is not the page's first, so it keeps its gap. */
.plan-report > .section:first-child { margin-top: 30px; }
.plan-wall-outside { stroke: var(--label); stroke-linecap: square; pointer-events: none; }
.plan-wall-inside { stroke: var(--label-3); stroke-width: 1.5; vector-effect: non-scaling-stroke; pointer-events: none; }
.plan-wall-open { stroke: var(--label-3); stroke-width: 1.5; stroke-dasharray: 2 5; stroke-linecap: round; vector-effect: non-scaling-stroke; pointer-events: none; }
.plan-opening { stroke: var(--label-3); fill: none; cursor: pointer; stroke-linecap: butt; }
.plan-opening.is-editable { cursor: move; }
.plan-opening.is-watched { stroke: var(--green); }
.plan-opening.is-partly { stroke: var(--orange); }
.plan-opening.is-unwatched { stroke: var(--red); }
rect.plan-opening { fill: var(--surface); }
rect.plan-opening.is-ceiling { stroke-dasharray: 6 4; }
.plan-opening.is-selected { filter: drop-shadow(0 0 3px var(--tint)); }
.plan-opening.is-target { cursor: pointer; }
.plan-opening.is-hover { filter: drop-shadow(0 0 4px var(--tint)); }
.plan-room.is-touchable { cursor: pointer; }
.plan-svg .is-faded { opacity: .35; pointer-events: none; }
.plan-wall-outside.is-target { stroke: var(--tint); }
.plan-ghost { stroke: var(--accent-pressed); fill: none; stroke-linecap: butt; pointer-events: none; }
rect.plan-ghost { fill: var(--yellow-tint); }
.plan-ghost.is-bad { stroke: var(--red); }
.plan-ghost-device { fill: var(--accent); stroke: var(--surface); opacity: .85; pointer-events: none; }
.plan-street { fill: var(--label-2); font-weight: 700; letter-spacing: .12em; text-transform: uppercase; pointer-events: none; }
.plan-reasons { margin: 0; padding-left: 18px; }
.swatch-wall { background: var(--label); height: 4px; }
.swatch-open-wall { height: 0; border-top: 2px dotted var(--label-3); }
.swatch-way-watched { background: var(--green); height: 5px; width: 10px; }
.swatch-way-partly { background: var(--orange); height: 5px; width: 10px; }
.swatch-way-unwatched { background: var(--red); height: 5px; width: 10px; }
.plan-object { fill: var(--surface); stroke: var(--label-3); stroke-width: 1.5; vector-effect: non-scaling-stroke; cursor: pointer; }
.plan-object.is-editable { cursor: move; }
.plan-object.is-blocks-view { fill: var(--fill); }
.plan-object.is-blocking { stroke: var(--red); stroke-width: 2.5; }
.plan-object.is-selected { stroke: var(--tint); stroke-width: 2.5; }
.plan-object-label { fill: var(--label-2); font-weight: 600; paint-order: stroke; stroke: var(--surface); stroke-width: 3px; stroke-linejoin: round; pointer-events: none; dominant-baseline: middle; }
.plan-ghost-object { stroke: var(--accent-pressed); fill: var(--yellow-tint); pointer-events: none; vector-effect: non-scaling-stroke; stroke-width: 2; }
/* Splitting a room: the new wall as it is drawn, and the part that becomes the new room. Merging: the neighbour and the wall that goes. */
.plan-cut { stroke: var(--tint); fill: none; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.plan-cut-point { fill: var(--surface); stroke: var(--tint); stroke-width: 2; vector-effect: non-scaling-stroke; pointer-events: none; }
.plan-cut-point.is-ghost { fill: var(--accent); }
.plan-split-new { fill: var(--accent); fill-opacity: .24; stroke: none; pointer-events: none; }
.plan-split-label { fill: var(--tint); font-weight: 700; pointer-events: none; }
.plan-room.is-merge { fill: var(--yellow-tint); }
.plan-merge-wall { stroke: var(--red); stroke-dasharray: 6 4; fill: none; stroke-linecap: round; pointer-events: none; }

/* ---------- Prompt Firewall (its pages, the staff console, public/js/firewall.js) ---------- */
/* Endpoint and verdict colours, one per series, the same in every chart and legend. */
.fw-ep-text { --fw-c: var(--solid-teal); } .fw-ep-file { --fw-c: #7a5bd6; } .fw-ep-finalize { --fw-c: var(--solid-green); }
.fw-ep-wrap { --fw-c: var(--accent-pressed); } .fw-ep-clause { --fw-c: var(--solid-neutral); }
.fw-s-total { --fw-c: var(--solid-teal); } .fw-s-blocked { --fw-c: var(--solid-red); } .fw-s-allow { --fw-c: var(--solid-green); } .fw-s-other { --fw-c: var(--label-4); }
/* The range a page covers: presets, and a custom pair of dates. */
.fw-range { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; margin-bottom: 18px; }
.fw-range .segmented { margin-bottom: 0; }
.fw-range .segmented a { min-width: 64px; }
details.fw-custom > summary { list-style: none; display: inline-flex; }
details.fw-custom > summary::-webkit-details-marker { display: none; }
details.fw-custom[open] > summary { display: none; }
.fw-custom form { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fw-custom input[type=date], .fw-filters input[type=date] {
  width: auto; min-height: var(--control-sm); padding: 4px 10px; border: 0; border-radius: 10px; background: var(--fill); color: var(--label);
  font: 400 var(--subhead)/var(--subhead-lh) var(--font);
}
.fw-range .aside { color: var(--label-2); font-size: var(--subhead); }
/* A page's own filter sits on the period's row, before the note on times. */
.fw-range > .fw-filters { margin-bottom: 0; }
/* A figure's small chart: the trend under a count. */
.fw-spark { display: block; width: 100%; height: 34px; margin-top: 10px; overflow: visible; }
.fw-spark-line { fill: none; stroke: var(--solid-teal); stroke-width: 1.6; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.fw-spark-area { fill: var(--teal-tint); stroke: none; }
/* Bar charts: server-drawn SVG, a rectangle per bucket and series; the axis in HTML beside it. */
.fw-chart { padding: 16px 16px 12px; }
.fw-chart-plot { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px; align-items: stretch; }
.fw-chart-y { display: flex; flex-direction: column; justify-content: space-between; font-size: 11px; line-height: 14px; color: var(--label-3); text-align: right; font-variant-numeric: tabular-nums; }
.fw-chart svg { display: block; width: 100%; height: 150px; }
.fw-bar { fill: var(--fw-c, var(--solid-teal)); }
.fw-bar-empty { fill: var(--fill-strong); }
.fw-chart-x { display: flex; justify-content: space-between; gap: 8px; margin-top: 6px; padding-left: 34px; font-size: 11px; line-height: 14px; color: var(--label-3); font-variant-numeric: tabular-nums; }
.fw-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 10px; font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); }
.fw-legend span { display: inline-flex; align-items: center; gap: 6px; }
.fw-legend span::before { content: ""; width: 9px; height: 9px; border-radius: 3px; background: var(--fw-c); }
/* One bar split between its parts (verdicts). */
.fw-split { display: block; width: 100%; height: 12px; border-radius: 6px; overflow: hidden; }
/* Meters: quotas and shares. A quota over 90 % is red, over 75 % orange (is-warn). */
progress.meter.is-over { color: var(--solid-red); }
progress.meter.is-over::-webkit-progress-value { background: var(--solid-red); }
progress.meter.is-over::-moz-progress-bar { background: var(--solid-red); }
progress.meter.is-teal { color: var(--solid-teal); }
progress.meter.is-teal::-webkit-progress-value { background: var(--solid-teal); }
progress.meter.is-teal::-moz-progress-bar { background: var(--solid-teal); }
.list .meter { margin: 8px 0 6px; }
.list .meter-line { margin-top: 0; }
/* The verdict at the top of a request: what the scan concluded, and how long it took. */
.fw-verdict { display: flex; align-items: center; gap: 14px; padding: 16px 18px; border-radius: var(--radius-card); background: var(--surface); }
.fw-verdict .grow b { display: block; font-size: var(--title-3); line-height: var(--title-3-lh); font-weight: 650; }
.fw-verdict .grow span { color: var(--label-2); font-size: var(--subhead); line-height: var(--subhead-lh); }
.fw-verdict .fw-latency { text-align: right; font-variant-numeric: tabular-nums; }
.fw-verdict .fw-latency b { display: block; font-size: var(--title-3); line-height: var(--title-3-lh); }
.fw-verdict .fw-latency span { font-size: var(--footnote); color: var(--label-2); }
.fw-verdict.is-red { background: var(--red-tint); } .fw-verdict.is-green { background: var(--green-tint); }
.fw-verdict.is-orange { background: var(--orange-tint); } .fw-verdict.is-teal { background: var(--teal-tint); }
/* Reporting the verdict: a button beside it; its form opens on a line of its own inside the banner. */
.fw-verdict:has(> details.fw-report) { flex-wrap: wrap; }
details.fw-report > summary { list-style: none; display: inline-flex; }
details.fw-report > summary::-webkit-details-marker { display: none; }
details.fw-report[open] { flex-basis: 100%; }
details.fw-report[open] > summary { display: none; }
.fw-report-form { display: flex; flex-direction: column; gap: 12px; padding: 16px; border-radius: 14px; background: var(--surface); }
.fw-report-form > b { font-size: var(--body); line-height: var(--body-lh); }
.fw-report-form > p { margin: -6px 0 0; color: var(--label-2); font-size: var(--subhead); line-height: var(--subhead-lh); }
.fw-report-form .field { margin: 0; }
/* Code, requests and answers: monospace on the second ground, scrolling sideways inside. */
.fw-code { margin: 0; padding: 14px 16px; border-radius: 14px; background: var(--surface-2); color: var(--label); overflow-x: auto;
  font: 400 12.5px/1.55 var(--mono); white-space: pre; tab-size: 2; }
.group > .fw-code { border-radius: 0; background: transparent; }
.fw-code .fw-muted, .fw-prompt .fw-muted { color: var(--label-3); }
.fw-copy-row { display: flex; align-items: center; gap: 10px; }
.fw-copy-row > .fw-code, .fw-copy-row > code { flex: 1; min-width: 0; }
/* A card explaining the code above it stands apart from it. */
.fw-copy-row + .group, .fw-code + .group { margin-top: 12px; }
/* On a phone the code takes the whole width and its Copy button goes under it, at the end. */
@media (max-width: 520px) {
  .fw-copy-row { flex-wrap: wrap; justify-content: flex-end; }
  .fw-copy-row > .fw-code, .fw-copy-row > code { flex-basis: 100%; }
}
.fw-secret { display: block; padding: 12px 14px; border-radius: 12px; background: var(--surface-2); font: 600 14px/1.4 var(--mono); overflow-wrap: anywhere; user-select: all; }
code.fw-inline { font: 500 .92em var(--mono); padding: 1px 5px; border-radius: 5px; background: var(--fill); }
/* The scanned prompt: tags coloured, what detections matched marked by severity, redactions as labels. */
.fw-prompt { margin: 0; padding: 14px 16px; font: 400 13px/1.6 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; color: var(--label); max-height: 70vh; overflow-y: auto; }
.fw-tag { color: var(--teal); font-weight: 600; }
.fw-tag.is-threat { color: var(--red); }
mark.fw-hit { color: inherit; border-radius: 3px; padding: 0 1px; box-shadow: inset 0 -2px 0 currentColor; }
mark.fw-hit.sev-critical, mark.fw-hit.sev-high { background: var(--red-tint); box-shadow: inset 0 -2px 0 var(--red); }
mark.fw-hit.sev-medium { background: var(--orange-tint); box-shadow: inset 0 -2px 0 var(--orange); }
mark.fw-hit.sev-low, mark.fw-hit.sev-info { background: var(--yellow-tint); box-shadow: inset 0 -2px 0 var(--accent-pressed); }
.fw-pii { display: inline-flex; align-items: baseline; gap: 2px; padding: 0 6px; border-radius: 6px; background: var(--fill-strong); color: var(--label-2);
  font: 600 11px/18px var(--font); letter-spacing: .02em; vertical-align: 1px; }
.fw-pii small { font-size: 10px; color: var(--label-3); }
.fw-pii small::before { content: ":"; }
.fw-pii.is-sensitive { background: var(--orange-tint); color: var(--orange); }
.fw-pii.is-secret { background: var(--red-tint); color: var(--red); }
.fw-prompt-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 10px 16px; font-size: var(--footnote); color: var(--label-2); border-top: var(--hair) solid var(--sep); }
.fw-prompt-legend mark { padding: 0 4px; }
/* A detection: what fired, where, and the (redacted) text it matched. */
.fw-matched { margin: 6px 0 0; padding: 6px 10px; border-radius: 8px; background: var(--fill); font: 400 12.5px/1.5 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; }
/* A disclosure row (the raw request and answer): closed until asked for. */
details.fw-more > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 10px 16px; }
details.fw-more > summary::-webkit-details-marker { display: none; }
details.fw-more > summary .chev { margin-left: auto; transition: transform 240ms var(--ease); }
details.fw-more[open] > summary .chev { transform: rotate(90deg); }
details.fw-more + details.fw-more { border-top: var(--hair) solid var(--sep); }
details.fw-more > .fw-code { margin: 0 12px 12px; }
details.fw-more > .fw-note { margin: 0 16px 10px; }
.fw-note { font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); }
/* A session's calls on one time line: where each starts and how long it takes. */
.fw-wf { display: block; width: 100%; height: 10px; margin-top: 6px; border-radius: 3px; background: var(--fill); }

/* A containment session: the session (its verdict, totals and calls) stays beside the open call, so
   moving between calls changes only the call. Side by side where there is room, else stacked. */
.fw-session { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; align-items: start; }
.fw-call { min-width: 0; }
.fw-rail { background: var(--surface); border-radius: var(--radius-card); overflow: hidden; }
.fw-rail-head { padding: 14px 16px; }
.fw-rail-head.is-red { background: var(--red-tint); } .fw-rail-head.is-green { background: var(--green-tint); }
.fw-rail-head.is-orange { background: var(--orange-tint); } .fw-rail-head.is-teal { background: var(--teal-tint); }
.fw-rail-label { margin-bottom: 6px; font-size: 10px; line-height: 14px; font-weight: 650; letter-spacing: .12em; text-transform: uppercase; color: var(--label-2); }
.fw-rail-verdict { display: block; font-size: var(--body); line-height: var(--body-lh); font-weight: 650; }
.fw-rail-facts { margin: 6px 0 0; font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); }
details.fw-rail-calls { border-top: var(--hair) solid var(--sep); }
details.fw-rail-calls > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 8px 16px;
  font-size: var(--footnote); line-height: var(--footnote-lh); font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--label-2); }
details.fw-rail-calls > summary .muted { font-weight: 400; letter-spacing: 0; text-transform: none; }
details.fw-rail-calls > summary::-webkit-details-marker { display: none; }
details.fw-rail-calls > summary .chev { transition: transform 240ms var(--ease); }
details.fw-rail-calls[open] > summary .chev { transform: rotate(90deg); }
.fw-calls { position: relative; overflow-y: auto; max-height: 60vh; border-top: var(--hair) solid var(--sep); }
.fw-calls > li { gap: 10px; min-height: 44px; padding: 9px 12px; }
.fw-calls > li + li::before { left: 44px; }
.fw-calls .title { font-size: 13px; line-height: 18px; }
.fw-calls .sub { font-size: var(--footnote); line-height: var(--footnote-lh); }
.fw-calls .fw-wf { height: 6px; margin-top: 5px; }
.fw-step-no { flex: none; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--fill-strong);
  font-size: 11px; font-weight: 650; color: var(--label-2); font-variant-numeric: tabular-nums; }
.fw-calls > li.is-active .fw-step-no { background: var(--label); color: var(--surface); }
.fw-rail-foot { margin: 0; padding: 10px 16px 12px; border-top: var(--hair) solid var(--sep); font-size: var(--footnote); line-height: var(--footnote-lh); color: var(--label-2); }
.fw-rail-foot kbd { display: inline-block; min-width: 18px; padding: 0 4px; border-radius: 5px; background: var(--fill-strong); font: 600 11px/18px var(--font); text-align: center; }
.fw-call-head { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; min-height: 36px; margin-bottom: 12px; }
.fw-call-head h2 { margin: 0; display: flex; align-items: baseline; gap: 4px 10px; flex-wrap: wrap; }
.fw-call-head h2 .mono { font-size: var(--subhead); line-height: var(--subhead-lh); font-weight: 500; color: var(--label-2); }
.fw-steps { display: flex; gap: 8px; }
.fw-id { display: inline-flex; align-items: center; gap: 4px 8px; flex-wrap: wrap; overflow-wrap: anywhere; }
@media (min-width: 1100px) {
  .fw-session { grid-template-columns: 300px minmax(0, 1fr); gap: 24px; }
  .fw-rail { position: sticky; top: 24px; }
  .fw-calls { max-height: calc(100vh - 290px); }
}
/* The filters above a list. */
.fw-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 16px; }
.fw-filters .search input[type=search] { width: min(260px, 100%); }
.fw-filters select { width: auto; }
.fw-filters .segmented { margin-bottom: 0; }
/* Tables of logs: a row opens its request. */
.fw-table td { white-space: nowrap; }
.fw-table td.fw-wide { white-space: normal; min-width: 180px; max-width: 360px; overflow-wrap: anywhere; }
.fw-table a.fw-row-link { color: var(--label); font-weight: 500; }
/* A whole row opens its request; the request id's own link stays on top. */
.fw-table tr:has(a.fw-row-link) { position: relative; cursor: pointer; }
.fw-table tr:has(a.fw-row-link):hover td { background: var(--pressed); }
.fw-table a.fw-row-link::after { content: ""; position: absolute; inset: 0; }
.fw-table td a:not(.fw-row-link) { position: relative; z-index: 1; }
.fw-table .mono { font-size: 12px; }
/* The documentation: the page's sections beside its contents on a desktop. */
.fw-docs { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; align-items: start; }
@media (min-width: 1180px) { .fw-docs { grid-template-columns: 200px minmax(0, 1fr); } .fw-toc { position: sticky; top: 24px; } }
.fw-toc ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.fw-toc a { display: block; padding: 5px 10px; border-radius: 8px; color: var(--label-2); font-size: var(--subhead); line-height: var(--subhead-lh); }
.fw-toc a:hover { background: var(--fill); color: var(--label); text-decoration: none; }
.fw-toc .is-sub a { padding-left: 22px; font: 500 12px/18px var(--mono); }
.fw-doc { min-width: 0; }
.fw-doc .section { scroll-margin-top: 24px; }
.fw-doc .prose { font-size: var(--body); line-height: 1.55; color: var(--label); }
.fw-doc .prose p { margin: 0 0 12px; }
.fw-doc .prose ul { margin: 0 0 12px; padding-left: 20px; }
.fw-doc .prose li + li { margin-top: 4px; }
.fw-doc h3 { margin: 18px 0 8px; font-size: var(--footnote); line-height: var(--footnote-lh); font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--label-2); }
.fw-doc .group + .group, .fw-doc .fw-code + .fw-code { margin-top: 12px; }
.fw-method { display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: 6px; background: var(--teal-tint); color: var(--teal); font: 700 11px/1 var(--mono); letter-spacing: .04em; }
.fw-method.is-get { background: var(--green-tint); color: var(--green); }
.fw-endpoint-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.fw-endpoint-head code { font: 600 var(--body)/var(--body-lh) var(--mono); }
.fw-params td:first-child { white-space: nowrap; }
.fw-params code { font: 500 12.5px var(--mono); }

/* ---------- AI agents (App\Agents) ---------- */
/* After an agent's name wherever a name is shown (x-person-name): a small sparkles mark in the accent's ink-safe tone. */
.agent-mark { display: inline-flex; align-items: center; margin-left: .25em; color: var(--tint); vertical-align: -.08em; }
.agent-mark .sym { width: .85em; height: .85em; }
/* On the yellow hero the gold would not read: the mark takes the hero's ink. */
.hero .agent-mark { color: inherit; }
/* Its round mark (x-avatar): the agent symbol on the accent-tinted circle, instead of initials. */
.avatar-agent { background: var(--yellow-tint); color: var(--tint); }
.avatar-agent .sym { width: 20px; height: 20px; }
/* The first sign-in: its state chip arrives once (app.js adds is-arriving, once per sign-in). */
.agent-state.is-arriving { animation: agent-arrive 900ms var(--ease) both; }
@keyframes agent-arrive {
  0% { transform: scale(.82); box-shadow: 0 0 0 0 var(--green-tint); }
  45% { transform: scale(1.08); box-shadow: 0 0 0 7px var(--green-tint); }
  100% { transform: none; box-shadow: 0 0 0 0 transparent; }
}
/* An agent's pages: its tabs, the steps to set it up, a secret shown once, its deliveries and calls. */
.agent-tabs { margin-bottom: 18px; }
.agent-steps { margin: 0; padding: 14px 16px 14px 36px; display: flex; flex-direction: column; gap: 14px; }
.agent-steps li { line-height: 1.5; }
.agent-steps .fw-copy-row { margin-top: 8px; }
/* Addresses on a phone: the label above its value, so a long address has the row's whole width. */
@media (max-width: 640px) {
  .agent-addresses.kv { grid-template-columns: minmax(0, 1fr); }
  .agent-addresses.kv dt { min-height: 0; padding-bottom: 2px; }
  .agent-addresses.kv dd { min-height: 0; padding-top: 0; justify-content: flex-start; text-align: left; }
  .agent-addresses.kv dt:not(:first-of-type) + dd { border-top: 0; }
}
.agent-code { margin: 0; padding: 12px 14px; border-radius: 12px; background: var(--surface-2); font: 500 12.5px/1.5 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; }
.agent-consent .kv dd { text-align: right; }
.agent-consent .form-actions { gap: 10px; }
.agent-consent-note { margin: 12px 0 0; color: var(--label-2); font-size: var(--subhead); line-height: var(--subhead-lh); }
@media (prefers-reduced-motion: reduce) {
  .agent-state.is-arriving { animation: none; box-shadow: 0 0 0 3px var(--green-tint); }
}

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

/* ---------- Shield's human panel: a public page, one card in the middle ---------- */
.panel-page { min-height: 100vh; min-height: 100dvh; display: flex; align-items: center; justify-content: center; padding-block: 40px; padding-inline: 20px; background: var(--surface); }
.panel-card { width: 100%; max-width: 440px; }
.panel-logo { height: 26px; margin-bottom: 28px; }
.panel-card h2 { font-size: var(--large-title); line-height: var(--large-title-lh); font-weight: 700; letter-spacing: -.034em; margin: 0 0 8px; }
.panel-card h3 { font-size: var(--title-3); line-height: var(--title-3-lh); font-weight: 650; margin: 28px 0 6px; }
.panel-facts { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); }
.panel-facts li { display: flex; gap: 10px; align-items: flex-start; }
.panel-facts .sym { flex: none; margin-top: 1px; color: var(--label-3); }
.panel-facts b { color: var(--label); font-weight: 650; }
.panel-card .form-group { margin: 24px 0 18px; background: var(--fill); }
.panel-closed { margin-top: 20px; }
.panel-result { align-items: flex-start; margin-top: 4px; }
.panel-result h2 { font-size: var(--title-3); line-height: var(--title-3-lh); letter-spacing: -.01em; margin-bottom: 6px; }
.panel-result p { margin: 0; font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-2); }
.panel-mark { flex: none; color: var(--solid-orange); }
/* A small trend line at the end of a list row. */
.sh-trend { flex: none; width: 110px; }
.sh-trend .fw-spark { margin-top: 0; height: 28px; }

/* ---------- Code Scanner (its pages and the staff console's; public/js/code-scanner.js) ---------- */
/* Sub-views: each segment as wide as its label with its count; a row too wide for the screen scrolls inside itself. */
.cs-seg { overflow-x: auto; scrollbar-width: none; }
.cs-seg::-webkit-scrollbar { display: none; }
.cs-seg a { flex: 0 0 auto; min-width: 0; }
.cs-seg .count { background: var(--fill-strong); color: var(--label-2); }
.cs-seg .active .count { background: var(--fill); }
/* Identifiers and paths break only after their separators (Look::wbr). */
.cs-path { overflow-wrap: normal; word-break: normal; }
.cs-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 16px; }
.cs-filters select { width: auto; max-width: 100%; }
.cs-filters .search input[type=search] { width: min(260px, 100%); }
.cs-filters .segmented { margin-bottom: 0; }
.cs-export-form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.cs-export-form select { width: auto; max-width: 100%; }
.group-pad > .cs-export-form:first-child { margin-top: 0; }
/* An issue's row: its priority leads, as wide as the widest capsule so the titles line up. */
.list > li.cs-issue { align-items: flex-start; }
.cs-issue > .cs-prio { flex: none; min-width: 44px; display: flex; padding-top: 1px; }
.list > li.cs-issue + li.cs-issue::before { left: 74px; }
.cs-issue .status { padding-top: 1px; }
.cs-issue .chev, .cs-scan .chev { align-self: center; }
.cs-scan-line { margin: -12px 0 18px; color: var(--label-2); font-size: var(--subhead); line-height: var(--subhead-lh); }
/* A finding: its facts with each rating's reason under it. */
.cs-finding > .section { margin-top: 26px; }
.cs-kv dd.cs-dd-text { flex-direction: column; align-items: flex-end; gap: 2px; }
.cs-kv dd.cs-dd-text b { color: var(--label); font-weight: 600; }
.cs-kv dd .cs-prose { font-size: var(--subhead); line-height: var(--subhead-lh); }
.cs-kv dd .cs-prose p { margin: 0; }
.cs-reason { color: var(--label-2); }
@media (max-width: 640px) {
  .cs-kv { grid-template-columns: minmax(0, 1fr); padding-right: 16px; }
  .cs-kv dt { min-height: 0; padding: 12px 0 0; color: var(--label-2); font-size: var(--footnote); line-height: var(--footnote-lh); }
  .cs-kv dd, .cs-kv dd.cs-dd-text { min-height: 0; padding: 2px 0 12px; justify-content: flex-start; align-items: flex-start; text-align: left; border-top: 0 !important; }
}
.cs-actions { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px; margin: 14px 0 0; }
.cs-actions > details.edit-panel[open] { flex: 1 1 100%; order: 5; }
.cs-actions .edit-box { margin-top: 0; }
.cs-actions textarea { min-height: 64px; resize: vertical; }
/* Copy as Markdown: a check draws itself when the clipboard has it. */
.cs-copy .cs-check { display: none; width: 16px; height: 16px; fill: none; stroke: var(--solid-green); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 20; stroke-dashoffset: 20; }
[data-reveal].is-copied .cs-copy .cs-check { display: inline-block; animation: sh-draw 420ms var(--ease) forwards; }
[data-reveal].is-copied .cs-copy .cs-check + .sym { display: none; }
/* Model text: escaped Markdown, links and images as plain words. */
.cs-prose { font-size: var(--body); line-height: 1.55; color: var(--label); overflow-wrap: anywhere; }
.cs-prose > :last-child { margin-bottom: 0; }
.cs-prose p, .cs-prose ul, .cs-prose ol { margin: 0 0 8px; }
.cs-prose ul, .cs-prose ol { padding-left: 20px; }
.cs-prose code { font: 500 .9em var(--mono); padding: 1px 4px; border-radius: 5px; background: var(--fill); overflow-wrap: anywhere; }
.cs-prose pre { margin: 0 0 8px; padding: 10px 12px; border-radius: 10px; background: var(--surface-2); overflow-x: auto; }
.cs-prose pre code { padding: 0; background: none; }
.cs-prose h1, .cs-prose h2, .cs-prose h3, .cs-prose h4 { font-size: var(--body); line-height: var(--body-lh); margin: 8px 0 4px; }
.cs-plain-link { color: var(--label); text-decoration: underline dotted var(--label-3); text-underline-offset: 2px; }
.list .sub.cs-prose, .list .title.cs-prose { font-size: var(--subhead); line-height: var(--subhead-lh); }
.list .title.cs-prose { font-size: var(--body); line-height: var(--body-lh); }
.cs-stack { display: flex; flex-direction: column; gap: 14px; }
.cs-stack h3 { margin: 0 0 4px; font-size: var(--footnote); line-height: var(--footnote-lh); font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--label-2); }
.cs-stack h3 .mono { text-transform: none; letter-spacing: 0; font-weight: 500; }
.cs-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 8px 16px; margin: 0; padding-top: 12px; border-top: var(--hair) solid var(--sep); }
.cs-facts dt { color: var(--label-2); font-size: var(--subhead); line-height: 1.55; }
.cs-facts dd { margin: 0; min-width: 0; }
@media (max-width: 520px) { .cs-facts { grid-template-columns: minmax(0, 1fr); gap: 2px; } .cs-facts dd + dt { margin-top: 8px; } }
/* The trace: entry point → passes through → sink, each with its lines at the scanned commit. */
.cs-trace { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; counter-reset: cs-step; }
.cs-step { position: relative; display: flex; flex-direction: column; gap: 8px; padding: 12px 16px 14px; overflow: hidden; }
.cs-step-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-width: 0; }
.cs-step-head .cs-path { font-size: var(--subhead); line-height: var(--subhead-lh); min-width: 0; display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.cs-scope { color: var(--label-2); font-size: var(--footnote); line-height: var(--footnote-lh); min-width: 0; }
.cs-step + .cs-step::before { content: ""; position: absolute; left: 30px; top: -10px; width: 2px; height: 10px; background: var(--sep); }
.cs-steps { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 4px; }
.cs-badges { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 8px; }
/* Code and diffs: escaped lines on the second ground, scrolling sideways inside their own box. */
.cs-code-wrap { overflow-x: auto; border-radius: 10px; background: var(--surface-2); max-width: 100%; }
.cs-code-wrap + .cs-code-wrap { margin-top: 8px; }
.cs-code { margin: 0; padding: 8px 0; font: 400 12.5px/1.6 var(--mono); color: var(--label); white-space: pre; tab-size: 4; min-width: max-content; }
.cs-line { display: block; padding: 0 12px; }
.cs-ln { display: inline-block; min-width: 3.2em; padding-right: 12px; color: var(--label-3); text-align: right; user-select: none; }
.cs-line.is-mark { background: var(--yellow-tint); }
.cs-diff .is-add { background: var(--green-tint); color: var(--green); }
.cs-diff .is-del { background: var(--red-tint); color: var(--red); }
.cs-diff .is-hunk { color: var(--teal); }
.cs-mono-input { font: 500 13px/1.5 var(--mono); resize: vertical; }
.cs-time { flex: 0 1 120px !important; text-align: right; margin-left: auto; }
.cs-notes { white-space: pre-wrap; overflow-wrap: anywhere; }
.cs-warn { color: var(--orange); }
.cs-warn-line { display: flex; gap: 6px; align-items: flex-start; color: var(--orange); }
.cs-warn-line .sym { margin-top: 1px; }
.cs-summary .kv { padding-left: 0; }
.cs-summary .kv dd { padding-right: 0; }
.cs-summary > p { margin-top: 8px; }
.cs-support { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
/* A scan's stages: a step per stage, its check drawn once when it is done, the current one breathing gently once. */
.cs-stepper { list-style: none; margin: 0 0 24px; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 8px; }
.cs-stepper li { display: flex; align-items: center; gap: 8px; min-width: 0; padding: 9px 10px; border-radius: 12px; background: var(--surface); border: var(--hair) solid var(--sep);
  font-size: var(--subhead); line-height: var(--subhead-lh); color: var(--label-3); }
.cs-step-label { min-width: 0; overflow-wrap: normal; }
.cs-step-mark { flex: none; width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; border: 1.5px solid var(--label-4); }
.cs-step-mark svg { width: 13px; height: 13px; fill: none; stroke: #fff; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 16; stroke-dashoffset: 16; }
.cs-stepper li.is-done { color: var(--label); }
.cs-stepper li.is-done .cs-step-mark { background: var(--solid-green); border-color: var(--solid-green); }
.cs-stepper li.is-done .cs-step-mark svg { stroke-dashoffset: 0; }
.cs-stepper li.is-done.is-arriving .cs-step-mark svg { animation: check-draw 520ms var(--ease) 120ms both; }
.cs-stepper li.is-current { color: var(--label); font-weight: 600; border-color: var(--solid-teal); }
.cs-stepper li.is-current .cs-step-mark { border-color: var(--solid-teal); background: var(--teal-tint); }
.cs-stepper li.is-current.is-arriving { animation: cs-breathe 1400ms var(--ease) 1; }
.cs-stepper li.is-stopped { color: var(--label); border-color: var(--red); }
.cs-stepper li.is-stopped .cs-step-mark { border-color: var(--red); }
@keyframes cs-breathe { 50% { box-shadow: 0 0 0 4px var(--teal-tint); } }
@media (max-width: 640px) { .cs-stepper { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* A new event since the person last looked: one gentle pulse. */
.cs-events > li.is-new { animation: cs-pulse 1600ms var(--ease) 1; }
@keyframes cs-pulse { 0% { background: var(--teal-tint); } 100% { background: transparent; } }
/* A codebase's form: each repository a choice, its branch under its name while it is chosen (it slides in, quietly under
   reduced motion). A codebase scan's repositories: folder, repository, branch and commit, wrapping on a phone. */
.cs-members > .cs-member { position: relative; }
.cs-members > .cs-member:first-child > .choice { box-shadow: none; }
.cs-member-ref { padding-left: 50px; padding-top: 0; min-height: 0; cursor: text; }
.cs-member-ref:not([hidden]) { animation: cs-reveal 220ms var(--ease) 1; }
@keyframes cs-reveal { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .cs-member-ref:not([hidden]) { animation: none; } }
.cs-repos .sub .mono { overflow-wrap: anywhere; }
/* The staff console's Code Scanner pages. */
.cs-whose { position: relative; z-index: 1; color: var(--label-2); }
.cs-code.cs-wrap { white-space: pre-wrap; overflow-wrap: anywhere; min-width: 0; padding: 10px 12px; }
.cs-doc { min-height: 60vh; width: 100%; }
.cs-transcript { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.cs-transcript > li { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 8px; }
.cs-route-row { gap: 6px; padding-bottom: 10px; }
.cs-route-row select { min-height: var(--control-sm); }
.list > li.cs-warn-row { background: var(--red-tint); }

/* A list's own action (Order a service, Invite someone) above it, on the right; it wraps under a narrow screen. */
.list-actions { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }

/* A help line with its action: side by side where there is room, the action under the text on a phone. */
.help-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.help-row > p { flex: 1 1 22rem; }

/* Pictures (App\Support\Avatars): a person's or an account's picture in place of initials, and the picker to choose one.
   The chosen one carries an ink ring and settles in with a small spring; the keyboard's focus is the usual teal ring. */
img.avatar, img.mark { object-fit: cover; background: var(--surface-2); outline: 1px solid var(--sep); outline-offset: -1px; }
.avatar-picker:has(input:focus-visible) { box-shadow: none; }
/* Ten pictures: always two rows of five, each as wide as the row allows up to 72px. */
.avatar-options { display: grid; grid-template-columns: repeat(5, minmax(0, 72px)); gap: 12px; padding: 6px 0 4px; }
.avatar-option { position: relative; display: grid; place-items: center; aspect-ratio: 1; cursor: pointer; border-radius: 50%; }
.avatar-option-square { border-radius: 26%; }
.avatar-option img {
  width: 100%; max-width: 72px; height: auto; aspect-ratio: 1; border-radius: inherit; display: block;
  box-shadow: 0 0 0 0 var(--label); transition: box-shadow 180ms ease, transform 320ms cubic-bezier(.34, 1.56, .64, 1);
}
.avatar-option:has(input:checked) img { box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px var(--label); transform: scale(1.06); }
.avatar-option:has(input:focus-visible) img { box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px var(--focus); }
.avatar-option:active img { transform: scale(.96); }
@media (prefers-reduced-motion: reduce) {
  .avatar-option img { transition: box-shadow 120ms ease; }
  .avatar-option:has(input:checked) img, .avatar-option:active img { transform: none; }
}
