/*
  BurgiTech Portal — design system
  Dark product UI derived from the RB Console dashboard study
  (Revolut Business measured styles), re-tokened for the Burgi brand:
  black canvas, teal accent/actions, Inter interface type with
  Satoshi reserved for brand/display moments.
  Shared by index.html (technician app) and admin.html.
*/

:root {
  color-scheme: dark;

  /* Colour roles */
  --bt-canvas: #000;
  --bt-surface: rgba(255, 255, 255, 0.1);
  --bt-surface-nested: rgba(255, 255, 255, 0.06);
  --bt-surface-field: rgba(255, 255, 255, 0.12);
  --bt-surface-interactive: rgba(255, 255, 255, 0.2);
  --bt-surface-popover: #1e3238;
  --bt-text-primary: #fff;
  --bt-text-secondary: rgba(255, 255, 255, 0.7);
  --bt-text-disabled: rgba(255, 255, 255, 0.38);
  --bt-ink: #001318;
  --bt-accent: #18bfcc;
  --bt-accent-deep: #139fab;
  --bt-accent-soft: rgba(24, 191, 204, 0.16);
  --bt-accent-text: #63d8e2;
  --bt-info: #4ca6ff;
  --bt-info-soft: rgba(76, 166, 255, 0.16);
  --bt-info-text: #8fc4ff;
  --bt-neutral: rgba(255, 255, 255, 0.34);
  --bt-positive: #1ac097;
  --bt-positive-soft: rgba(26, 192, 151, 0.14);
  --bt-positive-text: #62dabd;
  --bt-warning: #ff9f0a;
  --bt-warning-soft: rgba(255, 159, 10, 0.14);
  --bt-warning-text: #ffc15c;
  --bt-danger: #ff5363;
  --bt-danger-soft: rgba(255, 83, 99, 0.14);
  --bt-danger-text: #ff8a96;
  --bt-line: rgba(255, 255, 255, 0.08);
  --bt-reflective-line: rgba(255, 255, 255, 0.05);

  /* Typography */
  --bt-font-interface: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --bt-font-display: "Satoshi", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;

  /* Geometry */
  --bt-radius-sm: 8px;
  --bt-radius-cell: 10px;
  --bt-radius-panel: 14px;
  --bt-radius-sheet: 22px;
  --bt-radius-round: 9999px;
  --bt-control-xs: 28px;
  --bt-control-sm: 32px;
  --bt-control-md: 44px;
  --bt-topbar-height: 60px;
  --bt-sidebar-width: 96px;
  --bt-shell-gap: 16px;
  --bt-rail-width: 360px;
  --bt-content-pad: 24px;
  --bt-wide-width: 1080px;
  --bt-narrow-width: 760px;
  --bt-profile-width: 560px;
  --bt-background-overlay: 0.805;

  /* Motion and elevation */
  --bt-duration-sm: 200ms;
  --bt-duration-md: 300ms;
  --bt-ease: cubic-bezier(0.15, 0.5, 0.5, 1);
  --bt-shadow-inset: 0 0 0 1px var(--bt-reflective-line) inset;
  --bt-shadow-popover: 0 4px 4px 4px rgba(0, 0, 0, 0.12), 0 16px 48px rgba(0, 0, 0, 0.28);
}

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

html {
  min-width: 320px;
  background: var(--bt-canvas);
}

body {
  min-height: 100vh;
  margin: 0;
  overflow-x: hidden;
  background: var(--bt-canvas);
  color: var(--bt-text-primary);
  font-family: var(--bt-font-interface);
  font-size: 15px;
  font-weight: 400;
  line-height: 20px;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

body.bt-has-background {
  background-color: #000;
  background-image:
    linear-gradient(
      rgba(0, 0, 0, var(--bt-background-overlay)),
      rgba(0, 0, 0, var(--bt-background-overlay))
    ),
    var(--bt-background-image);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  background-attachment: fixed;
}

button, input, select, textarea { color: inherit; font: inherit; }
button:not(:disabled), [role="button"] { cursor: pointer; }
[hidden] { display: none !important; }
a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }
h1, h2, h3, h4, p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

::selection { background: var(--bt-accent); color: var(--bt-ink); }

:focus-visible { outline: 2px solid var(--bt-accent); outline-offset: 2px; }

* {
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { border-radius: 999px; background: rgba(255, 255, 255, 0.14); }
*::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.24); }
*::-webkit-scrollbar-track { background: transparent; }

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

/* ---------------------------------------------------------------- typography */
.bt-heading-1 { font-size: 24px; font-weight: 700; line-height: 30px; }
.bt-heading-2 { font-size: 21px; font-weight: 700; line-height: 26px; }
.bt-heading-3 { font-size: 18px; font-weight: 700; line-height: 24px; }
.bt-subheader { font-size: 16px; font-weight: 500; line-height: 22px; }
.bt-body-1 { font-size: 15px; font-weight: 400; line-height: 20px; }
.bt-body-2 { font-size: 14px; font-weight: 400; line-height: 20px; }
.bt-body-3 { font-size: 12px; font-weight: 400; line-height: 18px; }
.bt-emphasis-1 { font-size: 15px; font-weight: 500; line-height: 20px; }
.bt-emphasis-2 { font-size: 14px; font-weight: 500; line-height: 20px; }
.bt-emphasis-3 { font-size: 12px; font-weight: 600; line-height: 18px; }
.bt-caption { font-size: 11px; font-weight: 600; line-height: 14px; }

.bt-overline {
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  line-height: 14px;
  text-transform: uppercase;
}

.bt-display { font-family: var(--bt-font-display); }

.bt-text-secondary { color: var(--bt-text-secondary); }
.bt-text-disabled { color: var(--bt-text-disabled); }
.bt-text-accent { color: var(--bt-accent-text); }
.bt-text-positive { color: var(--bt-positive-text); }
.bt-text-warning { color: var(--bt-warning-text); }
.bt-text-danger { color: var(--bt-danger-text); }
.bt-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Read by a screen reader, seen by nobody. For the places where a heading has
   to exist to be announced but would be noise on screen — a table column of
   icon buttons, say. Clipped rather than hidden, because display:none and
   visibility:hidden take it out of the accessibility tree too. */
.bt-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------------------------------------------------------------- icons & avatars */
.bt-icon { width: 20px; height: 20px; flex: 0 0 auto; color: currentColor; }
.bt-icon--16 { width: 16px; height: 16px; }
.bt-icon--18 { width: 18px; height: 18px; }
.bt-icon--24 { width: 24px; height: 24px; }

.bt-avatar {
  display: inline-grid;
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
  place-items: center;
  overflow: hidden;
  border-radius: var(--bt-radius-round);
  background: linear-gradient(150deg, #17aab6, #0c6b74);
  box-shadow: var(--bt-shadow-inset);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
}

.bt-avatar--24 { width: 24px; height: 24px; font-size: 10px; }
.bt-avatar--28 { width: 28px; height: 28px; font-size: 11px; }
.bt-avatar--36 { width: 36px; height: 36px; }
.bt-avatar--72 { width: 72px; height: 72px; font-size: 26px; }
.bt-avatar--96 { width: 96px; height: 96px; font-size: 34px; }
.bt-avatar--neutral { background: linear-gradient(150deg, #46606a, #26363d); }

.bt-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------------------------------------------------------------- layout primitives */
.bt-stack { display: flex; flex-direction: column; }
.bt-stack--4 { gap: 4px; }
.bt-stack--8 { gap: 8px; }
.bt-stack--12 { gap: 12px; }
.bt-stack--16 { gap: 16px; }
.bt-stack--24 { gap: 24px; }

.bt-cluster { display: flex; align-items: center; gap: 8px; }
.bt-cluster--6 { gap: 6px; }
.bt-cluster--12 { gap: 12px; }
.bt-cluster--wrap { flex-wrap: wrap; }
.bt-cluster--between { justify-content: space-between; }
/* For a slot that gains and loses a small button — a Save that only exists while
   there is something to save. Holding the button's height means the panel body
   doesn't step down the moment it appears, which is otherwise felt as the field
   you are typing in moving under the cursor. */
.bt-cluster--control { min-height: var(--bt-control-xs); }

.bt-spacer { flex: 1 1 auto; }

/* ---------------------------------------------------------------- surfaces */
.bt-panel {
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface);
}

.bt-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 16px 4px;
}
/* A head carrying period controls as well as a title runs out of room on a
   phone; let those wrap under the title rather than clipping off the edge. */
.bt-panel__head--controls { flex-wrap: wrap; }
.bt-panel__head--controls > .bt-cluster { flex-wrap: wrap; }

.bt-panel__body { padding: 8px; }
.bt-panel__body--pad { padding: 16px; }

.bt-panel__lede {
  padding: 2px 16px 0;
  color: var(--bt-text-secondary);
  font-size: 14px;
  line-height: 20px;
}

.bt-panel__foot {
  display: flex;
  min-height: 44px;
  align-items: center;
  justify-content: center;
  padding: 4px 8px 8px;
}

.bt-divider { height: 1px; border: 0; margin: 0; background: var(--bt-line); }

/* ---------------------------------------------------------------- buttons */
.bt-button,
.bt-icon-button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  transition:
    background-color var(--bt-duration-sm) var(--bt-ease),
    color var(--bt-duration-sm) var(--bt-ease),
    opacity var(--bt-duration-sm) var(--bt-ease),
    transform var(--bt-duration-sm) var(--bt-ease),
    filter var(--bt-duration-sm) var(--bt-ease);
  user-select: none;
}

.bt-button {
  min-height: var(--bt-control-sm);
  gap: 6px;
  padding: 0 14px;
  border-radius: var(--bt-radius-round);
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
  white-space: nowrap;
}

.bt-button--primary {
  background: var(--bt-accent);
  color: var(--bt-ink);
  font-weight: 600;
}

.bt-button--secondary {
  background: var(--bt-surface-interactive);
  color: var(--bt-text-primary);
}

.bt-button--subtle {
  background: var(--bt-surface);
  color: var(--bt-text-primary);
}

.bt-button--warning { background: var(--bt-warning-soft); color: var(--bt-warning-text); }
.bt-button--danger { background: var(--bt-danger-soft); color: var(--bt-danger-text); }

.bt-button--text {
  min-height: auto;
  padding: 0;
  border-radius: var(--bt-radius-cell);
  background: transparent;
  color: var(--bt-text-secondary);
}
.bt-button--text:hover { color: var(--bt-text-primary); }
/* A text button can still be the destructive one in its row. Both modifiers set
   colour and --text is declared last, so without this pair the danger tint is
   silently dropped and the one button you should read twice looks like the rest. */
.bt-button--text.bt-button--danger,
.bt-button--text.bt-button--danger:hover { color: var(--bt-danger-text); }

.bt-button--xs { min-height: var(--bt-control-xs); padding-inline: 10px; font-size: 12px; line-height: 18px; }
.bt-button--md { min-height: var(--bt-control-md); padding-inline: 20px; font-size: 15px; }
.bt-button--full { width: 100%; }

.bt-icon-button {
  width: var(--bt-control-sm);
  height: var(--bt-control-sm);
  flex: 0 0 auto;
  padding: 6px;
  border-radius: var(--bt-radius-round);
  background: transparent;
  color: var(--bt-text-secondary);
}

.bt-icon-button:hover { color: var(--bt-text-primary); background: var(--bt-surface); }
.bt-icon-button--filled { background: var(--bt-surface-interactive); color: var(--bt-text-primary); }
.bt-icon-button--danger:hover { color: var(--bt-danger-text); background: var(--bt-danger-soft); }

.bt-button:hover { filter: brightness(1.1); }
.bt-button:active,
.bt-icon-button:active { transform: scale(0.97); }

.bt-button:disabled,
.bt-icon-button:disabled {
  cursor: not-allowed;
  opacity: 0.38;
  transform: none;
}

/* ---------------------------------------------------------------- fields */
.bt-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }

.bt-label {
  color: var(--bt-text-secondary);
  font-size: 12px;
  font-weight: 600;
  line-height: 18px;
}
.bt-label em { font-style: normal; color: var(--bt-danger-text); }
/* The counterpart to that asterisk, for a field where leaving it empty is a real
   choice rather than an omission. Quieter than the label it follows — it is
   permission, not instruction. */
.bt-label__note { font-weight: 500; color: var(--bt-text-disabled); }

.bt-input-shell {
  display: flex;
  min-height: var(--bt-control-md);
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: 12px;
  background: var(--bt-surface-field);
  color: var(--bt-text-secondary);
  transition: border-color var(--bt-duration-sm) var(--bt-ease), background var(--bt-duration-sm) var(--bt-ease);
}

.bt-input-shell:focus-within {
  border-color: var(--bt-accent);
  background: var(--bt-surface);
}

.bt-input-shell--area { align-items: stretch; padding: 11px 14px; }
.bt-input-shell--round { border-radius: var(--bt-radius-round); }

/* A field the portal fills in rather than the person: it looks like a field so
   the value reads as part of the form, but flatter and without the focus ring,
   so it never invites a click that would do nothing. Used by the payroll form's
   Bank, which comes from the routing number. */
.bt-input-shell--locked {
  background: var(--bt-surface-nested);
  cursor: default;
}
.bt-input-shell--locked:focus-within { border-color: transparent; background: var(--bt-surface-nested); }
.bt-input-shell--locked .bt-input { color: var(--bt-text-primary); cursor: default; }
.bt-input-shell--locked .bt-input::placeholder { color: var(--bt-text-disabled); }

/* Address-suggestion dropdown (map.js BTMap.attachAutocomplete). Anchored to
   the field that holds the input, not the input itself — the shell needs
   room to sit above it. */
.btmap-suggest-host { position: relative; }
.btmap-suggest {
  position: absolute;
  z-index: 1000;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  max-height: min(300px, 45vh);
  overflow-y: auto;
  padding: 4px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  color: var(--bt-text-primary);
  isolation: isolate;
}
.btmap-suggest[hidden] { display: none; }
.btmap-suggest__opt {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  align-items: stretch;
  gap: 2px;
  width: 100%;
  min-height: 44px;
  padding: 7px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--bt-text-primary);
  font-family: inherit;
  font-size: 13px;
  line-height: 18px;
  text-align: left;
  white-space: normal;
  overflow-wrap: anywhere;
  cursor: pointer;
}
.btmap-suggest__primary { color: var(--bt-text-primary); font-weight: 600; }
.btmap-suggest__secondary { color: var(--bt-text-secondary); font-size: 12px; }
.btmap-suggest__opt:hover { background: var(--bt-surface-interactive); }

.bt-input {
  width: 100%;
  min-width: 0;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--bt-text-primary);
  font-size: 15px;
}
.bt-input::placeholder { color: var(--bt-text-disabled); }
.bt-input:disabled { color: var(--bt-text-disabled); }
/* For a value whose punctuation is the point — a job number pattern, where
   {SEQ} has to be told apart from SEQ at a glance. Slightly wider tracking
   because braces and hyphens crowd in a proportional face. */
.bt-input--mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 14px;
  letter-spacing: 0.02em;
}

textarea.bt-input {
  min-height: 76px;
  padding: 10px 0 12px;
  resize: vertical;
  line-height: 20px;
}

.bt-select {
  width: 100%;
  min-height: var(--bt-control-md);
  padding: 0 38px 0 14px;
  border: 1px solid transparent;
  border-radius: 12px;
  outline: 0;
  appearance: none;
  background-color: var(--bt-surface-field);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.7)' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-position: right 12px center;
  background-repeat: no-repeat;
  background-size: 16px;
  color: var(--bt-text-primary);
}
.bt-select:focus { border-color: var(--bt-accent); }
.bt-select option { background: var(--bt-surface-popover); color: var(--bt-text-primary); }
/* A select that sits beside other controls in a row (e.g. asset type editor's
   "available in" picker) rather than filling its own column. */
.bt-select--kind { width: 150px; flex: 0 0 150px; }

.bt-select-enhanced {
  position: relative;
  display: flex;
  align-items: center;
  font-family: var(--bt-font-interface);
  font-weight: 500;
  line-height: 20px;
  cursor: pointer;
  transition:
    border-color var(--bt-duration-sm) var(--bt-ease),
    background-color var(--bt-duration-sm) var(--bt-ease),
    box-shadow var(--bt-duration-sm) var(--bt-ease);
}
.bt-select-enhanced:hover { background-color: var(--bt-surface-interactive); }
.bt-select-enhanced:focus-within,
.bt-select-enhanced.is-open {
  border-color: var(--bt-accent);
  background-color: var(--bt-surface);
  box-shadow: 0 0 0 3px var(--bt-accent-soft);
}
.bt-select-enhanced.is-disabled { cursor: default; opacity: 0.5; }
.bt-select-enhanced.is-disabled:hover { background-color: var(--bt-surface-field); }
.bt-select-native {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  min-height: 0 !important;
  overflow: hidden !important;
  padding: 0 !important;
  border: 0 !important;
  opacity: 0 !important;
  pointer-events: none !important;
}
.bt-select__trigger {
  display: flex;
  min-width: 0;
  min-height: inherit;
  flex: 1 1 auto;
  align-items: center;
  padding: 0;
  border: 0;
  outline: 0;
  overflow: hidden;
  background: transparent;
  color: inherit;
  font: inherit;
  line-height: inherit;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}
.bt-select__trigger:disabled { cursor: default; }

.bt-select-menu {
  position: fixed;
  z-index: 180;
  display: flex;
  min-height: 44px;
  flex-direction: column;
  padding: 6px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--bt-radius-panel);
  overflow: hidden;
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  color: var(--bt-text-primary);
  font-family: var(--bt-font-interface);
  font-size: 13px;
  line-height: 18px;
  animation: bt-select-in var(--bt-duration-sm) var(--bt-ease);
}
@keyframes bt-select-in {
  from { opacity: 0; transform: translateY(-4px) scale(0.985); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
.bt-select-menu__search {
  display: flex;
  min-height: 38px;
  flex: 0 0 auto;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
  padding: 0 10px;
  border: 1px solid transparent;
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-field);
  color: var(--bt-text-secondary);
}
.bt-select-menu__search:focus-within {
  border-color: var(--bt-accent);
  color: var(--bt-text-primary);
}
.bt-select-menu__search input {
  width: 100%;
  min-width: 0;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--bt-text-primary);
  font: inherit;
}
.bt-select-menu__search input::placeholder { color: var(--bt-text-disabled); }
.bt-select-menu__list {
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.bt-select-menu__group {
  padding: 10px 10px 4px;
  color: var(--bt-text-disabled);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 14px;
  text-transform: uppercase;
}
.bt-select-menu__option {
  display: flex;
  width: 100%;
  min-height: 38px;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  outline: 0;
  background: transparent;
  color: var(--bt-text-secondary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.bt-select-menu__option:hover,
.bt-select-menu__option:focus-visible {
  background: var(--bt-surface-interactive);
  color: var(--bt-text-primary);
}
.bt-select-menu__option.is-selected {
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
  font-weight: 600;
}
.bt-select-menu__option:disabled {
  color: var(--bt-text-disabled);
  cursor: default;
  opacity: 0.5;
}
.bt-select-menu__option-text {
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bt-select-menu__empty {
  padding: 20px 12px;
  color: var(--bt-text-disabled);
  text-align: center;
}

/* Compact variant for selects that sit inside a list row alongside buttons. */
.bt-select--inline {
  width: auto;
  min-height: var(--bt-control-xs);
  padding: 0 28px 0 10px;
  border-radius: var(--bt-radius-sm);
  background-position: right 8px center;
  background-size: 14px;
  font-size: 12px;
  font-weight: 500;
}

/* Read-only job facts. Most of a job's detail is set when it's booked, so it
   reads as plain text; the fields a technician may correct carry a pencil that
   swaps in an input. */
.bt-label-row {
  display: flex;
  min-height: 18px;
  align-items: center;
  gap: 6px;
}

.bt-readonly {
  min-height: 22px;
  font-size: 14px;
  font-weight: 500;
  line-height: 22px;
  overflow-wrap: anywhere;
}
.bt-readonly:empty::before { content: "—"; color: var(--bt-text-disabled); }

.bt-inline-edit {
  display: grid;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  place-items: center;
  border: 0;
  /* A button carries 6px of side padding from the browser until told otherwise.
     With border-box sizing that left this 22px control a 10px content box, and
     the icon inside — capped by the reset's `max-width: 100%` — was squashed to
     10px wide in a 16px slot everywhere this button is used. */
  padding: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--bt-text-disabled);
  transition: background var(--bt-duration-sm) var(--bt-ease), color var(--bt-duration-sm) var(--bt-ease);
}
.bt-inline-edit:hover { background: var(--bt-surface-interactive); color: var(--bt-text-primary); }
.bt-inline-edit:focus-visible { outline: 2px solid var(--bt-accent); outline-offset: 1px; }
/* Held for a beat after a copy so the click has a visible answer. */
.bt-inline-edit.is-copied,
.bt-inline-edit.is-copied:hover { color: var(--bt-positive-text); }
/* Pressed state for the ones that toggle an editor open rather than fire once. */
.bt-inline-edit.is-active,
.bt-inline-edit.is-active:hover { background: var(--bt-accent-soft); color: var(--bt-accent-text); }

.bt-inline-editor { display: flex; align-items: center; gap: 6px; }
.bt-inline-editor .bt-input-shell { flex: 1 1 auto; min-width: 0; }
.bt-inline-editor .bt-select-enhanced { flex: 1 1 auto; min-width: 0; }

.bt-hint { font-size: 12px; line-height: 18px; color: var(--bt-text-disabled); }
.bt-field-err { display: none; font-size: 12px; line-height: 18px; font-weight: 600; color: var(--bt-danger-text); }

.bt-form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}
.bt-form-grid > .bt-field--full { grid-column: 1 / -1; }
.bt-schedule-inputs {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 132px;
  gap: 8px;
}
.bt-inline-editor .bt-schedule-inputs { flex: 1 1 auto; min-width: 0; }
/* The technician detail pane is deliberately narrow. In its inline schedule
   editor, stacking the controls protects the date from being squeezed down to
   a calendar icon by the time field and the two action buttons. */
.bt-inline-editor--schedule { align-items: flex-end; }
.bt-inline-editor--schedule .bt-schedule-inputs { grid-template-columns: minmax(0, 1fr); }

/* choice chips (e.g. the other assignees on a job) */
.bt-chip {
  display: inline-flex;
  min-height: var(--bt-control-sm);
  align-items: center;
  gap: 6px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface-field);
  color: var(--bt-text-secondary);
  font-size: 13px;
  font-weight: 500;
  transition: background var(--bt-duration-sm) var(--bt-ease), color var(--bt-duration-sm) var(--bt-ease);
}
.bt-chip:hover { color: var(--bt-text-primary); }
.bt-chip.is-active { background: var(--bt-accent); color: var(--bt-ink); font-weight: 600; }
.bt-chip:disabled { cursor: default; opacity: 0.45; }
.bt-chip:disabled.is-active { opacity: 0.75; }

.bt-static-pill {
  display: inline-flex;
  min-height: var(--bt-control-sm);
  align-items: center;
  gap: 8px;
  padding: 0 14px 0 4px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface);
  color: var(--bt-text-primary);
  font-size: 13px;
  font-weight: 500;
}

/* ---------------------------------------------------------------- badges */
.bt-badge {
  display: inline-flex;
  min-height: 22px;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface);
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  line-height: 16px;
  white-space: nowrap;
}

.bt-badge--accent { background: var(--bt-accent-soft); color: var(--bt-accent-text); }
/* "New" — a job you've been put on but haven't opened yet. Solid, not soft, so
   it reads as an alert rather than another status chip. */
.bt-badge--new {
  background: var(--bt-accent);
  color: var(--bt-ink);
  letter-spacing: 0.06em;
}
.bt-badge--positive { background: var(--bt-positive-soft); color: var(--bt-positive-text); }
.bt-badge--warning { background: var(--bt-warning-soft); color: var(--bt-warning-text); }
.bt-badge--danger { background: var(--bt-danger-soft); color: var(--bt-danger-text); }

/* A job's status, where it can be changed in place: a picker that carries the
   same colours as the badge it replaces, so a board scanned from across the
   room reads the same whether or not you happen to be able to edit it. */
.bt-status-select--in_progress { background-color: var(--bt-accent-soft); color: var(--bt-accent-text); }
.bt-status-select--on_hold { background-color: var(--bt-warning-soft); color: var(--bt-warning-text); }
.bt-status-select--completed { background-color: var(--bt-positive-soft); color: var(--bt-positive-text); }

/* ---------------------------------------------------------------- segmented filters */
/* Filters on the left (scrolling sideways when there are many), view controls
   pinned on the right. The two are separate boxes because the scroller would
   otherwise clip the columns popover. */
.bt-boardbar { display: flex; align-items: center; gap: 8px; }
.bt-boardbar__actions { display: flex; flex: 0 0 auto; align-items: center; gap: 8px; }

.bt-filterbar {
  display: flex;
  min-width: 0;
  flex: 1 1 auto;
  align-items: center;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 2px;
  scrollbar-width: none;
}
.bt-filterbar::-webkit-scrollbar { display: none; }

.bt-segmented {
  display: inline-flex;
  flex: 0 0 auto;
  flex-wrap: nowrap;
  gap: 2px;
  padding: 3px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface);
}

.bt-segmented__item {
  flex: 0 0 auto;
  min-height: 28px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--bt-radius-round);
  background: transparent;
  color: var(--bt-text-secondary);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  transition: background var(--bt-duration-sm) var(--bt-ease), color var(--bt-duration-sm) var(--bt-ease);
}
.bt-segmented__item:hover { color: var(--bt-text-primary); }
.bt-segmented__item.is-active {
  background: var(--bt-surface-interactive);
  color: var(--bt-text-primary);
}

/* ---------------------------------------------------------------- progress */
/* Segmented, multi-status bar: each checklist status paints its own slice, so
   the colour mix is the progress. Order left→right: done, not-necessary,
   in-progress, on-hold; the remainder is the empty (to-do) track. */
.bt-segbar {
  display: flex;
  width: 100%;
  height: 6px;
  overflow: hidden;
  border-radius: var(--bt-radius-round);
  background: rgba(255, 255, 255, 0.1);
}

.bt-segbar__seg {
  height: 100%;
  min-width: 0;
  transition: width var(--bt-duration-md) var(--bt-ease);
}
.bt-segbar__seg--done { background: var(--bt-accent); }
.bt-segbar__seg--not_necessary { background: var(--bt-neutral); }
.bt-segbar__seg--in_progress { background: var(--bt-info); }
.bt-segbar__seg--on_hold { background: var(--bt-warning); }

.bt-segbar--flush { height: 3px; border-radius: 0; background: rgba(255, 255, 255, 0.08); }

/* Compact key so the bar colours are legible at a glance. */
.bt-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
}
.bt-legend__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--bt-text-secondary);
  font-size: 12px;
  line-height: 16px;
}
.bt-legend__dot {
  width: 8px;
  height: 8px;
  flex: 0 0 auto;
  border-radius: 50%;
}
.bt-legend__dot--done { background: var(--bt-accent); }
.bt-legend__dot--not_necessary { background: var(--bt-neutral); }
.bt-legend__dot--in_progress { background: var(--bt-info); }
.bt-legend__dot--on_hold { background: var(--bt-warning); }
.bt-legend__item b { color: var(--bt-text-primary); font-weight: 600; }

/* ---------------------------------------------------------------- list rows */
.bt-list { display: flex; flex-direction: column; }

.bt-list-row {
  display: grid;
  min-height: 56px;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 8px;
  border: 0;
  border-radius: var(--bt-radius-cell);
  background: transparent;
  color: inherit;
  text-align: left;
  transition: background var(--bt-duration-sm) var(--bt-ease);
}

.bt-list-row:hover { background: var(--bt-surface-nested); }
.bt-list-row--static:hover { background: transparent; }
.bt-list-row--static + .bt-list-row--static { box-shadow: 0 -1px 0 var(--bt-line); }
.bt-list-row__content { min-width: 0; }
.bt-list-row__side { display: flex; align-items: center; gap: 6px; justify-self: end; }

/* Shared contract for list rows that open another view. Keep the rounded
   shape, hover/focus affordance and trailing chevron together whenever a new
   row is introduced. */
.bt-open-row {
  cursor: pointer;
  border-radius: var(--bt-radius-cell);
  transition: background var(--bt-duration-sm) var(--bt-ease);
}
.bt-open-row:hover { background: var(--bt-surface-nested); }
.bt-open-row:focus-visible { outline: 2px solid var(--bt-accent); outline-offset: -2px; }
.bt-row-chevron {
  flex: 0 0 auto;
  color: var(--bt-text-secondary);
  opacity: 0.8;
}

.bt-tile-icon {
  display: grid;
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  place-items: center;
  border-radius: 12px;
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
}

/* ---------------------------------------------------------------- metrics */
.bt-metric-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}

/* The jobs page has five summary metrics; keep them on one row on wide
   screens while leaving the other metric groups on their four-column grid. */
@media (min-width: 1181px) {
  #stats.bt-metric-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* Below that the five will not fit on a line, and the four-column default
   leaves the fifth stranded on a row of its own — which reads as a tile that
   failed to load rather than a deliberate 4 + 1. Three and two is the same
   five metrics with no orphan. */
@media (max-width: 1180px) {
  #stats.bt-metric-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Two columns on a phone — stated here rather than left to .bt-metric-grid's
   own phone rule, which this selector's id would out-specify. The same odd one
   out then takes the width instead of half of it. */
@media (max-width: 760px) {
  #stats.bt-metric-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #stats.bt-metric-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}

.bt-metric {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px;
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface);
}

.bt-metric__value {
  font-family: var(--bt-font-display);
  font-size: 26px;
  font-weight: 700;
  line-height: 32px;
}

.bt-metric__label { color: var(--bt-text-secondary); font-size: 12px; font-weight: 500; line-height: 18px; }

/* ---------------------------------------------------------------- alerts */
.bt-alert {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface);
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
}

.bt-alert .bt-icon { margin-top: 0; }
/* Inline literals — a URL fragment, a filename — inside explanatory copy. */
code {
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--bt-surface-nested);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
}

.bt-alert--positive { background: var(--bt-positive-soft); color: var(--bt-positive-text); }
.bt-alert--warning { background: var(--bt-warning-soft); color: var(--bt-warning-text); }
.bt-alert--danger { background: var(--bt-danger-soft); color: var(--bt-danger-text); }

/* ---------------------------------------------------------------- empty state */
.bt-empty {
  padding: 32px 16px;
  border: 1px dashed rgba(255, 255, 255, 0.16);
  border-radius: var(--bt-radius-panel);
  color: var(--bt-text-secondary);
  font-size: 14px;
  line-height: 20px;
  text-align: center;
}

/* ---------------------------------------------------------------- app shell */
.bt-shell {
  display: grid;
  min-height: 100vh;
  grid-template-columns: var(--bt-sidebar-width) minmax(0, 1fr) var(--bt-rail-width);
  grid-template-rows: var(--bt-topbar-height) minmax(0, 1fr);
}

/* Focused task views (jobs, forms, checklist, profile) drop the right rail. */
.bt-shell.is-focused {
  grid-template-columns: var(--bt-sidebar-width) minmax(0, 1fr);
}
.bt-shell.is-focused .bt-rail { display: none; }

.bt-sidebar {
  position: sticky;
  z-index: 30;
  top: 0;
  display: flex;
  height: 100vh;
  grid-column: 1;
  grid-row: 1 / -1;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 8px 12px;
}

.bt-sidebar__brand {
  display: grid;
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  place-items: center;
  overflow: hidden;
  margin-bottom: 8px;
  border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.09);
}
.bt-sidebar__brand img,
.bt-sidebar__brand svg { width: 100%; height: 100%; object-fit: cover; }

.bt-nav {
  display: flex;
  width: 72px;
  flex-direction: column;
}

/* Icon over label, with the hover/active highlight wrapped around the icon
   only — so the rail reads as a column of buttons rather than a column of
   blocks. The four numbers here are coupled; see the pill below before changing
   any of them. */
.bt-nav-item {
  position: relative;
  display: flex;
  width: 72px;
  height: 68px;
  flex: 0 0 auto;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Has to clear the pill's lower edge (6px past the icon) with room to spare,
     or the label sits tucked inside the highlight. */
  gap: 10px;
  border: 0;
  background: transparent;
  border-radius: 12px;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  line-height: 14px;
  transition: color var(--bt-duration-sm) var(--bt-ease);
}

/* The highlight. Sized to hug the 20px icon with 6px all round, which centred
   content in a 68px item places at y=12–32 — so the pill runs 6–38 and its
   bottom inset is 68 − 38 = 30. That leaves 4px of clear space above the
   label, which starts at y=42. */
.bt-nav-item::before {
  position: absolute;
  inset: 6px 14px 30px;
  border-radius: 12px;
  background: transparent;
  content: "";
  transition: background var(--bt-duration-sm) var(--bt-ease);
}

.bt-nav-item > * { position: relative; z-index: 1; }
.bt-nav-item:hover { color: var(--bt-text-primary); }
.bt-nav-item:hover::before { background: var(--bt-surface-nested); }
.bt-nav-item.is-active { color: var(--bt-text-primary); }
.bt-nav-item.is-active::before { background: var(--bt-surface); }

.bt-topbar {
  position: sticky;
  z-index: 20;
  top: 0;
  display: flex;
  min-width: 0;
  height: var(--bt-topbar-height);
  grid-column: 2 / -1;
  grid-row: 1;
  align-items: center;
  gap: 8px;
  padding: 0 var(--bt-content-pad) 0 var(--bt-shell-gap);
  isolation: isolate;
  background: transparent;
}

.bt-topbar::before {
  position: absolute;
  z-index: -1;
  top: 0;
  right: 0;
  bottom: 0;
  left: calc(-1 * var(--bt-sidebar-width));
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.3) 0%,
    rgba(0, 0, 0, 0.20) 28%,
    rgba(0, 0, 0, 0.05) 74%,
    rgba(0, 0, 0, 0) 100%
  );
  content: "";
  pointer-events: none;
}
.bt-shell.is-focused .bt-topbar { grid-column: 2; }

.bt-topbar__heading {
  display: flex;
  min-width: 0;
  flex-direction: column;
  justify-content: center;
}
.bt-topbar__jobline { display:flex; align-items:center; gap:10px; min-width:0; }
.bt-topbar__jobline .bt-topbar__title { flex:0 1 auto; }
#job-work-actions { display:flex; align-items:center; gap:6px; flex:0 0 auto; }
#job-work-actions .bt-button { white-space:nowrap; }
.bt-work-clock { color:var(--bt-text-secondary); font-size:13px; font-variant-numeric:tabular-nums; white-space:nowrap; }
.bt-jobgrid__main.is-work-locked { opacity:.62; }

.bt-topbar__title {
  min-width: 0;
  overflow: hidden;
  font-family: var(--bt-font-display);
  font-size: 22px;
  font-weight: 700;
  line-height: 30px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bt-topbar__sub {
  overflow: hidden;
  color: var(--bt-text-secondary);
  font-size: 13px;
  line-height: 18px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bt-topbar__actions {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}

.bt-topbar__progress {
  position: absolute;
  right: 0;
  bottom: -3px;
  left: 0;
  height: 3px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.08);
}
.bt-topbar__progress .bt-progress__bar { border-radius: 0; }

.bt-user-pill {
  display: inline-flex;
  height: 36px;
  flex: 0 0 auto;
  align-items: center;
  gap: 8px;
  padding: 0 14px 0 4px;
  border: 0;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface);
  color: var(--bt-text-primary);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  transition: filter var(--bt-duration-sm) var(--bt-ease), background var(--bt-duration-sm) var(--bt-ease);
}
.bt-user-pill:hover { background: var(--bt-surface-interactive); }
.bt-user-pill:active { transform: scale(0.98); }
.bt-user-pill__chevron {
  width: 14px;
  height: 14px;
  margin-left: -2px;
  color: var(--bt-text-secondary);
}

/* The mobile profile control joins the floating navigation dock. */
.bt-mobile-profile { display: none; }

.bt-main {
  min-width: 0;
  grid-column: 2;
  grid-row: 2;
  padding: 20px var(--bt-content-pad) 56px var(--bt-shell-gap);
}

.bt-rail {
  min-width: 0;
  grid-column: 3;
  grid-row: 2;
  padding: 20px var(--bt-content-pad) 56px 0;
}

.bt-rail__inner {
  position: sticky;
  top: calc(var(--bt-topbar-height) + 20px);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.bt-rail__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2px 2px;
}

/* Content column: left-aligned under the topbar title, capped for readability. */
.bt-page {
  display: flex;
  width: 100%;
  max-width: var(--bt-wide-width);
  flex-direction: column;
  gap: 20px;
}

.bt-page--narrow { max-width: var(--bt-narrow-width); }
.bt-page--create { max-width: 1180px; }
.bt-create-job-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}
.bt-create-job-grid > * { min-width: 0; }
@media (min-width: 900px) {
  .bt-create-job-grid {
    grid-template-areas:
      "alert alert"
      "number assignee"
      "template assignee"
      "description assignee"
      "dispatch dispatch"
      "tickets tickets"
      "details details"
      "benchmark submit";
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
  }
  .bt-create-job-grid__alert { grid-area: alert; }
  .bt-create-job-grid__template { grid-area: template; }
  .bt-create-job-grid__description { grid-area: description; }
  .bt-create-job-grid__assignee { grid-area: assignee; }
  .bt-create-job-grid__dispatch { grid-area: dispatch; }
  .bt-create-job-grid__tickets { grid-area: tickets; }
  .bt-create-job-grid__number { grid-area: number; }
  .bt-create-job-grid__details { grid-area: details; }
  .bt-create-job-grid__benchmark { grid-area: benchmark; }
  .bt-create-job-grid__submit { grid-area: submit; align-self: end; }
}
.bt-create-job-grid__dispatch.is-disabled .bt-toggle-row {
  opacity: .45;
  cursor: not-allowed;
}
.bt-create-job-grid__dispatch.is-disabled .bt-toggle-row:hover { background: transparent; }
.bt-checklist-picker {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.bt-checklist-picker__row {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
}
.bt-checklist-picker__order {
  display: grid;
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  place-items: center;
  border-radius: 50%;
  background: var(--bt-surface-interactive);
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 700;
}
.bt-checklist-picker__copy {
  display: flex;
  min-width: 0;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 2px;
}
.bt-checklist-picker__copy > .bt-badge { align-self: flex-start; }
.bt-checklist-picker__actions { display: flex; flex: 0 0 auto; gap: 2px; }
.bt-checklist-picker__actions .bt-icon-button { width: 30px; height: 30px; }
.bt-checklist-picker__add { padding-top: 2px; }
.bt-create-dispatch {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  margin-top: 14px;
  padding: 14px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
}
.bt-create-dispatch__column {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 14px;
}
/* Read-only (see the job's Edit button for changing it) — a plain stack,
   one fact per line rather than the two-column grid a since-removed edit
   button used to need column 2 for. */
.bt-dispatch-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
}
@media (max-width: 760px) {
  .bt-create-dispatch { grid-template-columns: minmax(0, 1fr); }
}
.bt-page--profile { max-width: var(--bt-profile-width); }
/* A readable column of panels, plus the section rail and its gap, so a panel is
   the same width on a page that has a rail as on one that doesn't.
   --bt-profile-width is that column; the 212px is the 188px rail and the 24px
   gap beside it. */
.bt-page--settings { max-width: calc(var(--bt-profile-width) + 212px); }

/* ---------------------------------------------------------------- integrations
   Each service owns one compact disclosure card. The grid can take more cards
   later without turning every integration's settings into a full page. */
.bt-integrations-page { max-width: 1120px; }
.bt-integrations-intro {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 18px;
}
.bt-integrations-intro p { margin: 4px 0 0; }
/* auto-fill counts the columns it can fit using the track's *max*, so a
   360–520px track stayed one-up until the grid itself passed 1056px — a laptop
   showed a single 520px card with a third of the row empty beside it. Counting
   against the 360px floor instead fills the row when there is room for two, and
   the 1056px cap (two 520s and the gap) stops a wide monitor squeezing them into
   three narrow ones. */
.bt-integration-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
  max-width: 1056px;
  gap: 16px;
  align-items: start;
}
.bt-integration-card {
  min-width: 0;
  border: 1px solid var(--bt-line);
  border-radius: 20px;
  background:
    radial-gradient(circle at 8% 0%, rgba(24, 191, 204, 0.11), transparent 36%),
    var(--bt-surface);
  box-shadow: var(--bt-shadow-inset), 0 16px 42px rgba(0, 0, 0, 0.12);
}
.bt-integration-card[open] { border-color: rgba(255, 255, 255, 0.16); }
.bt-integration-card__summary {
  display: grid;
  grid-template-columns: 116px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  min-height: 112px;
  padding: 16px;
  border-radius: inherit;
  cursor: pointer;
  list-style: none;
}
.bt-integration-card__summary::-webkit-details-marker { display: none; }
.bt-integration-card__summary:hover { background: rgba(255, 255, 255, 0.025); }
.bt-integration-card__summary:focus-visible {
  outline: 2px solid var(--bt-accent);
  outline-offset: 2px;
}
.bt-integration-card__logo {
  display: grid;
  width: 116px;
  height: 72px;
  place-items: center;
  padding: 14px;
  border: 1px solid rgba(139, 237, 231, 0.18);
  border-radius: 16px;
  background: linear-gradient(145deg, #102d43, #252044);
}
.bt-integration-card__logo img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 44px;
  object-fit: contain;
}
.bt-integration-card__identity {
  display: flex;
  min-width: 0;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}
.bt-integration-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
}
.bt-integration-status__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--bt-text-disabled);
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.04);
}
.bt-integration-status.is-positive { color: var(--bt-positive); }
.bt-integration-status.is-positive .bt-integration-status__dot {
  background: var(--bt-positive);
  box-shadow: 0 0 0 3px rgba(26, 192, 151, 0.16);
}
.bt-integration-status.is-danger { color: var(--bt-danger-text); }
.bt-integration-status.is-danger .bt-integration-status__dot {
  background: var(--bt-danger);
  box-shadow: 0 0 0 3px rgba(255, 83, 99, 0.16);
}
.bt-integration-card__manage {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--bt-text-secondary);
  font-size: 12px;
  font-weight: 600;
}
.bt-integration-card__manage .bt-icon { transition: transform var(--bt-duration-sm) var(--bt-ease); }
.bt-integration-card[open] .bt-integration-card__manage .bt-icon { transform: rotate(180deg); }
.bt-integration-card__body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 18px;
  border-top: 1px solid var(--bt-line);
  background: rgba(0, 0, 0, 0.08);
  border-radius: 0 0 20px 20px;
}
.bt-integration-card__section-head {
  display: flex;
  min-height: 24px;
  align-items: center;
  gap: 6px;
}
.bt-integration-card__section-head #syncro-saved { margin-left: auto; }
.bt-integration-label {
  display: flex;
  min-height: 24px;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
}
.bt-integration-label .bt-label { margin: 0; }
.bt-integration-help { position: relative; flex: 0 0 auto; }
.bt-integration-help::after {
  position: absolute;
  z-index: 50;
  top: calc(100% + 7px);
  left: 0;
  width: max-content;
  max-width: 260px;
  padding: 8px 10px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-sm);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  color: var(--bt-text-primary);
  content: attr(data-tooltip);
  font-size: 12px;
  font-weight: 400;
  line-height: 17px;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-4px);
  transition: opacity var(--bt-duration-sm) var(--bt-ease), transform var(--bt-duration-sm) var(--bt-ease);
}
.bt-integration-help:hover::after,
.bt-integration-help:focus::after { opacity: 1; transform: translateY(0); }

@media (max-width: 560px) {
  .bt-integration-grid { grid-template-columns: minmax(0, 1fr); }
  .bt-integration-card__summary { grid-template-columns: 88px minmax(0, 1fr); }
  .bt-integration-card__logo { width: 88px; height: 62px; padding: 10px; }
  .bt-integration-card__manage { grid-column: 2; justify-self: start; }
  .bt-integration-help::after { max-width: min(260px, calc(100vw - 52px)); }
  .bt-integration-card__section-head .bt-integration-help::after { right: 0; left: auto; }
}
.bt-page--fill { max-width: none; }
/* The jobs board is a table — it gets whatever width the window offers, so a
   job's columns fit on one line instead of wrapping. */
.bt-page--board { max-width: none; }

.bt-view { display: none; }
.bt-view.is-active { display: block; }

/* ---------------------------------------------------------------- progressive account creation */
.bt-add-account {
  display: flex;
  width: 100%;
  min-height: 68px;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border: 0;
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface);
  color: var(--bt-text-primary);
  text-align: left;
  transition: background var(--bt-duration-sm) var(--bt-ease), transform var(--bt-duration-sm) var(--bt-ease);
}
.bt-add-account:hover { background: var(--bt-surface-field); }
.bt-add-account:active { transform: scale(0.99); }
.bt-add-account__icon {
  display: grid;
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  place-items: center;
  border-radius: 50%;
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
}
.bt-add-account__copy {
  display: flex;
  min-width: 0;
  flex: 1 1 auto;
  flex-direction: column;
}
.bt-add-account__chevron {
  width: 18px;
  height: 18px;
  color: var(--bt-text-secondary);
}

/* The Team roster keeps account management behind one compact overflow button.
   Fixed positioning lets the menu sit above panel overflow and mobile rows. */
.bt-account-menu {
  position: fixed;
  z-index: 75;
  width: 220px;
  max-width: calc(100vw - 24px);
  padding: 6px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  opacity: 0;
  pointer-events: none;
  transform: translateY(-5px) scale(0.98);
  transform-origin: top right;
  transition: opacity var(--bt-duration-sm) var(--bt-ease), transform var(--bt-duration-sm) var(--bt-ease);
}
.bt-account-menu.is-open { opacity: 1; pointer-events: auto; transform: none; }
.bt-account-menu.is-above { transform-origin: bottom right; }
.bt-account-more,
.bt-client-more { background: transparent; color: var(--bt-text-secondary); }
.bt-account-more:focus-visible,
.bt-client-more:focus-visible,
.bt-account-more[aria-expanded="true"],
.bt-client-more[aria-expanded="true"] {
  background: var(--bt-surface-interactive);
  color: var(--bt-text-primary);
}
.bt-account-menu__note {
  padding: 7px 10px 5px;
  color: var(--bt-text-disabled);
  font-size: 11px;
  line-height: 16px;
}
.bt-client-row { border-radius: var(--bt-radius-cell); }
.bt-client-detail {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}
.bt-client-detail__facts {
  overflow: hidden;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
}
.bt-client-detail__facts .bt-info-row__value { max-width: min(520px, 70%); }
.bt-client-detail__location { position: relative; min-width: 0; }
.bt-client-detail__location .btmap { height: 240px; }
.bt-client-detail__location .bt-button { margin-top: 10px; }
@media (min-width: 760px) {
  .bt-client-detail { grid-template-columns: minmax(0, 1fr) minmax(280px, 0.75fr); align-items: start; }
}
.bt-menu-item--warning { color: var(--bt-warning-text); }
.bt-menu-item--warning .bt-icon { color: currentColor; }
/* The shape every "are you sure" wears: a badge, a heading, the consequence in
   plain words, and the two ways out. It was named for accounts because they were
   the first thing worth asking about; the layout never had anything to do with
   accounts, so the old name is kept only so existing markup goes on working. */
.bt-confirm-account,
.bt-confirm { padding: 4px 10px 10px; text-align: center; }
.bt-confirm-account__icon,
.bt-confirm__icon {
  display: grid;
  width: 44px;
  height: 44px;
  margin: 2px auto 14px;
  place-items: center;
  border-radius: 50%;
  background: var(--bt-warning-soft);
  color: var(--bt-warning-text);
}
.bt-confirm-account__icon .bt-icon,
.bt-confirm__icon .bt-icon { width: 22px; height: 22px; }
.bt-confirm-account__icon.is-danger,
.bt-confirm__icon.is-danger { background: var(--bt-danger-soft); color: var(--bt-danger-text); }
.bt-confirm-account .bt-heading-3,
.bt-confirm .bt-heading-3 { margin-bottom: 8px; }
.bt-confirm-account .bt-alert,
.bt-confirm .bt-alert { margin-top: 14px; text-align: left; }
.bt-confirm-account .bt-sheet__actions,
.bt-confirm .bt-sheet__actions { margin-top: 20px; }

/* The typed check. Left-aligned inside a centred dialog on purpose: it is a form
   field, and a centred label above a centred box reads as more decoration rather
   than as the one thing still being asked for. */
.bt-confirm__gate { margin-top: 16px; text-align: left; }
.bt-confirm__gate .bt-label { display: block; margin-bottom: 6px; }
.bt-confirm__gate .bt-label strong { color: var(--bt-text-primary); font-weight: 700; }

/* Field help stays available on touch screens: tapping the icon focuses it and
   opens the same compact tooltip that pointer users get on hover. */
.bt-field-help { position: relative; }
.bt-field-help::after {
  position: absolute;
  z-index: 90;
  top: calc(100% + 7px);
  left: 0;
  width: max-content;
  max-width: min(260px, calc(100vw - 64px));
  padding: 8px 10px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-sm);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  color: var(--bt-text-primary);
  content: attr(data-tooltip);
  font-size: 12px;
  font-weight: 400;
  line-height: 17px;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-4px);
  transition: opacity var(--bt-duration-sm) var(--bt-ease), transform var(--bt-duration-sm) var(--bt-ease);
}
.bt-field-help:hover::after,
.bt-field-help:focus::after { opacity: 1; transform: none; }

/* Both account-dialog actions live in the same track so their edges, height,
   and the space between them stay identical at every sheet width. */
.bt-sheet.bt-sheet--account,
.bt-sheet.bt-sheet--client { max-width: 780px; }
.bt-account-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}
.bt-account-form .btmap { height: 210px; }
.bt-sheet--client .btmap { height: 210px; }
.bt-account-form > .bt-alert,
.bt-account-form__wide { grid-column: 1 / -1; }
.bt-edit-account__actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.bt-edit-account__actions .bt-sheet__cancel { width: 100%; margin-top: 0; }

@media (min-width: 680px) {
  .bt-account-form { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 16px; }
  .bt-account-form .btmap,
  .bt-sheet--client .btmap { height: 230px; }
}

/* tooltips (pointer devices only) */
@media (hover: hover) {
  .bt-tooltip { position: relative; }
  .bt-tooltip::after {
    position: absolute;
    z-index: 40;
    top: calc(100% + 8px);
    left: 50%;
    max-width: 220px;
    padding: 6px 8px;
    border-radius: var(--bt-radius-sm);
    background: var(--bt-surface-popover);
    box-shadow: var(--bt-shadow-popover);
    color: var(--bt-text-primary);
    content: attr(data-tooltip);
    font-size: 12px;
    font-weight: 400;
    line-height: 18px;
    opacity: 0;
    pointer-events: none;
    transform: translate(-50%, -4px);
    transition: opacity var(--bt-duration-sm) var(--bt-ease), transform var(--bt-duration-sm) var(--bt-ease);
    white-space: nowrap;
  }
  .bt-tooltip:hover::after,
  .bt-tooltip:focus-visible::after { opacity: 1; transform: translate(-50%, 0); }

  /* A modal sheet scrolls vertically, which forces its horizontal overflow to
     clip too (an implicit CSS rule neither axis can opt out of once the other
     isn't "visible"). A tooltip centered under an icon near the sheet's left
     edge loses its left half to that clip, so anchor it to the icon instead
     of centering — it only ever needs room to grow rightward. */
  .bt-sheet .bt-tooltip::after { left: 0; transform: translate(0, -4px); }
  .bt-sheet .bt-tooltip:hover::after,
  .bt-sheet .bt-tooltip:focus-visible::after { transform: translate(0, 0); }

  /* Everything above is the fallback for a page with no script. Where the
     tooltip script *has* run it draws the message at the document root instead,
     and the pseudo-element becomes a box that is never seen and still takes up
     room — a couple of hundred pixels of nowrap text hanging off the last column
     of a grid, which is where the settings tables were getting a horizontal
     scrollbar from. `content: none` removes it rather than hiding it; hidden is
     not the same as gone, and only gone stops it counting. */
  .bt-tooltip-js .bt-tooltip::after { content: none; }
}

/* The same removal for the two help dots, which carry their own ::after rather
   than .bt-tooltip's and were therefore missed by the rule above. Both are
   tabindex="0" and tooltip.js shows the portal message on focus as well as
   hover, so it covers them on touch too — which makes the pseudo-element pure
   dead layout, and `width: max-content` worth of it. Left at 260px hanging off
   a help dot near the right edge, it was pushing the Integrations page 43px
   wider than the phone it was on. */
.bt-tooltip-js .bt-field-help::after,
.bt-tooltip-js .bt-integration-help::after { content: none; }

/* The shared tooltip script moves active messages to document.body so they
   cannot be cut off by a table, card, modal scroller, or the viewport edge. */
.bt-tooltip-portal {
  position: fixed;
  z-index: 2000;
  max-width: min(260px, calc(100vw - 16px));
  padding: 6px 8px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-sm);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  color: var(--bt-text-primary);
  font-size: 12px;
  font-weight: 400;
  line-height: 18px;
  overflow-wrap: anywhere;
  pointer-events: none;
}
.bt-tooltip--portaled::after { display: none !important; }

/* ---------------------------------------------------------------- login */
.bt-login {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
}

.bt-login__card {
  width: 100%;
  max-width: 400px;
  padding: 28px 24px;
  border-radius: 20px;
  background: var(--bt-surface);
  box-shadow: var(--bt-shadow-inset);
}

.bt-login__brand { width: 168px; margin-bottom: 26px; }
.bt-login__brand svg { width: 100%; height: auto; }

.bt-login__foot {
  margin-top: 20px;
  color: var(--bt-text-disabled);
  font-size: 12px;
  line-height: 18px;
  text-align: center;
}

.bt-wordmark path[fill="#0A0A0A"] { fill: #fff; }

/* ---------------------------------------------------------------- job board */
/* The board is a table of chosen columns. --job-cols is written by the client
   from the visible column set and shared by the header and every row, which is
   what keeps a job on one line and the columns aligned.

   A column set can also want more width than the window has — twelve columns
   are offered and the window is whatever the window is. The board scrolls
   inside its own panel rather than pushing the page sideways, which is the
   answer the timesheet and the permission matrix already give: the columns you
   chose are the ones you get, and the topbar, metrics and filter bar stay put
   instead of sliding off with them. --job-min is the width the current set
   needs, written beside --job-cols by renderJobHead; the head and the list
   carry it together or they scroll out of step. */
.bt-table {
  --job-cols: minmax(0, 1fr) auto;
  overflow-x: auto;
}
.bt-table__head,
.bt-joblist { min-width: var(--job-min, 0); }

.bt-table__head {
  display: grid;
  grid-template-columns: var(--job-cols);
  align-items: center;
  gap: 12px;
  /* Matches .bt-job-row's inline padding exactly, or the columns would not line
     up with their headings. */
  padding: 0 10px 8px;
  border-bottom: 1px solid var(--bt-line);
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.bt-job-sort {
  display: inline-flex;
  min-width: 0;
  align-items: center;
  gap: 4px;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
}
.bt-job-sort:hover,
.bt-job-sort:focus-visible { color: var(--bt-text-primary); }
.bt-job-sort:focus-visible { outline: 2px solid var(--bt-accent); outline-offset: 3px; border-radius: 2px; }
.bt-job-sort__mark { color: var(--bt-accent-text); font-size: 13px; line-height: 1; }

/* Inside Admin's board --job-cols is set per view; the technician app
   uses the same row as a two-part card, which is what the fallback describes. */
.bt-job-row {
  display: grid;
  grid-template-columns: var(--job-cols, minmax(0, 1fr) auto);
  align-items: center;
  gap: 12px;
  width: 100%;
  /* Fixed so the row never changes height with its contents: without it a row
     is as tall as its tallest cell, so entering select mode (which swaps the
     32px action buttons for a checkbox) would visibly shrink every row, and
     rows with avatars would sit taller than rows without. 32px of content
     plus the 10px padding either side. */
  min-height: 52px;
  padding: 10px;
  border: 0;
  border-radius: var(--bt-radius-cell);
  background: transparent;
  color: inherit;
  text-align: left;
  transition: background var(--bt-duration-sm) var(--bt-ease);
}

/* One cell: single line, clipped rather than wrapped. */
.bt-cell {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  line-height: 18px;
}
.bt-cell--job { font-weight: 600; }
.bt-cell__num { font-size: 14px; font-weight: 600; }
.bt-cell__muted { color: var(--bt-text-disabled); }
.bt-cell__pct {
  flex: 0 0 auto;
  min-width: 34px;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  text-align: right;
}
/* The phone-only summary under the job number. */
.bt-cell__sub { display: none; }
.bt-segbar--cell { min-width: 0; flex: 1 1 auto; }

/* Overlapping avatars for everyone on the job; the name is on hover.
   The job owner is first AND on top — the stack reads left to right, so
   the one that matters most must not be the one partly covered. Each avatar is
   given a descending z-index by the client (see assigneeStackHtml). */
.bt-avstack { display: flex; align-items: center; }
.bt-avstack > * { position: relative; margin-left: -6px; box-shadow: 0 0 0 2px var(--bt-surface); }
.bt-avstack > *:first-child { margin-left: 0; }
.bt-avstack__more {
  background: var(--bt-surface-interactive);
  color: var(--bt-text-secondary);
  font-size: 10px;
  font-weight: 600;
}
.bt-job-row:hover .bt-avstack > * { box-shadow: 0 0 0 2px var(--bt-surface-nested); }
.bt-job-row:hover { background: var(--bt-surface-nested); }
.bt-job-row + .bt-job-row { box-shadow: 0 -1px 0 var(--bt-line); }

/* The technician app stacks a job's detail into a card rather than columns:
   headline badges, a meta line, then the progress bar. Admin's board
   doesn't use these — its cells are .bt-cell — but both share .bt-job-row. */
.bt-job-row__content { min-width: 0; padding: 2px 0; }
.bt-job-row__head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.bt-job-row__num { font-size: 15px; font-weight: 600; line-height: 20px; }
.bt-job-row__meta {
  margin-top: 2px;
  color: var(--bt-text-secondary);
  font-size: 12px;
  line-height: 18px;
}
.bt-job-row__progress {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  max-width: 420px;
}
.bt-job-row__pct {
  flex: 0 0 auto;
  min-width: 66px;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  line-height: 14px;
  text-align: right;
}

.bt-job-row__side {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 2px;
  color: var(--bt-text-disabled);
}
.bt-job-row .bt-icon-button { opacity: 0; }
.bt-job-row:hover .bt-icon-button,
.bt-job-row .bt-icon-button:focus-visible { opacity: 1; }
@media (hover: none) {
  .bt-job-row .bt-icon-button { opacity: 1; }
}

/* Pagination lives with the board controls, immediately before Columns. It is
   intentionally quiet and compact so it does not compete with the filters. */
.bt-pagination {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 8px;
  min-height: 0;
  padding: 0;
  color: var(--bt-text-secondary);
  font-size: 12px;
  line-height: 18px;
}
.bt-pagination[hidden] { display: none; }
.bt-pagination__size {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.bt-pagination__size .bt-select { min-width: 60px; }
.bt-pagination__summary { white-space: nowrap; }
.bt-pagination__nav,
.bt-pagination__pages {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.bt-pagination__arrow,
.bt-pagination__page {
  display: inline-flex;
  width: 30px;
  height: 30px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: var(--bt-radius-sm);
  background: transparent;
  color: var(--bt-text-secondary);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.bt-pagination__arrow:hover:not(:disabled),
.bt-pagination__page:hover { background: var(--bt-surface-interactive); color: var(--bt-text-primary); }
.bt-pagination__page.is-active {
  background: var(--bt-surface-field);
  color: var(--bt-text-primary);
}
.bt-pagination__arrow:focus-visible,
.bt-pagination__page:focus-visible { outline: 2px solid var(--bt-accent); outline-offset: 1px; }
.bt-pagination__arrow:disabled { opacity: 0.35; cursor: default; }
.bt-pagination__ellipsis {
  display: inline-flex;
  width: 18px;
  justify-content: center;
  color: var(--bt-text-disabled);
}

/* Below tablet width there is no room for columns, so the board folds back into
   a stacked card: the job cell keeps its summary line, everything else drops
   away, and the row actions stay on the right. The header goes with them —
   column labels are meaningless once the columns are gone. */
@media (max-width: 900px) {
  .bt-table__head { display: none; }
  /* The columns are gone here, so the width they needed goes with them — a
     stacked card must not inherit the table's scroll. */
  .bt-table { overflow-x: visible; }
  .bt-table__head,
  .bt-joblist { min-width: 0; }
  .bt-job-row {
    grid-template-columns: minmax(0, 1fr) auto !important;
    align-items: flex-start;
    padding: 12px 10px;
  }
  .bt-job-row > .bt-cell { display: none; }
  .bt-job-row > .bt-cell--job,
  .bt-job-row > .bt-job-row__side,
  .bt-job-row > .bt-job-select { display: flex; }
  .bt-job-row > .bt-cell--job {
    flex-wrap: wrap;
    align-items: center;
    grid-column: 1;
  }
  .bt-job-row > .bt-job-row__side { grid-column: 2; align-items: center; }
  /* In selection mode the checkbox takes the first column and the job cell
     moves along one, so the row still reads left to right. */
  .bt-job-srow { grid-template-columns: auto minmax(0, 1fr) auto !important; }
  .bt-cell__sub {
    display: block;
    width: 100%;
    margin-top: 2px;
    color: var(--bt-text-secondary);
    font-size: 12px;
    font-weight: 400;
    line-height: 18px;
  }
}

/* Cells you can edit in place. They stay flat until hovered so the board still
   reads as a table rather than a wall of buttons. */
.bt-assign-cell,
.bt-tpl-cell {
  display: flex;
  min-width: 0;
  max-width: 100%;
  align-items: center;
  gap: 4px;
  padding: 3px 4px;
  /* Cancels the inline padding again. The padding is only there to give the
     hover chip room around the content, and without this it also pushes the
     content 4px right of the column edge — so an editable cell sat 4px off
     from its own column heading, and off from any cell in the same column that
     isn't editable (an unassigned job's dash).
     Bleeding the chip outwards instead keeps every cell in a column starting at
     the same x. The row's 12px grid gap absorbs the overhang. */
  margin: 0 -4px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  background: transparent;
  color: inherit;
  text-align: left;
  transition: background var(--bt-duration-sm) var(--bt-ease);
}
.bt-assign-cell:hover,
.bt-tpl-cell:hover { background: var(--bt-surface-interactive); }
.bt-checklist-cell {
  display: flex;
  min-width: 0;
  max-width: 100%;
  align-items: center;
}
.bt-assign-cell__add {
  display: grid;
  width: 24px;
  height: 24px;
  place-items: center;
  border: 1.5px dashed var(--bt-neutral);
  border-radius: 50%;
  color: var(--bt-text-secondary);
}
.bt-assign-cell:hover .bt-assign-cell__add { border-color: var(--bt-accent); color: var(--bt-accent-text); }
.bt-tpl-cell__caret { flex: 0 0 auto; color: var(--bt-text-disabled); opacity: 0; transition: opacity var(--bt-duration-sm) var(--bt-ease); }
.bt-tpl-cell:hover .bt-tpl-cell__caret { opacity: 1; }
@media (hover: none) {
  .bt-tpl-cell__caret { opacity: 1; }
}

/* The floating editor a board cell opens. */
.bt-rowpop {
  position: fixed;
  z-index: 70;
  width: 248px;
  max-height: 60vh;
  overflow-y: auto;
  padding: 6px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  color: var(--bt-text-primary);
  font-family: var(--bt-font-interface);
  font-size: 13px;
  line-height: 18px;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-4px);
  transition: opacity var(--bt-duration-sm) var(--bt-ease), transform var(--bt-duration-sm) var(--bt-ease);
}
.bt-rowpop.is-open { opacity: 1; pointer-events: auto; transform: none; }
.bt-rowpop--assignees { width: min(520px, calc(100vw - 16px)); overflow-x: hidden; }
.bt-rowpop__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 6px 8px;
}
.bt-rowpop__opt {
  display: flex;
  width: 100%;
  min-height: 38px;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  outline: 0;
  background: transparent;
  color: var(--bt-text-secondary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.bt-rowpop__opt:hover,
.bt-rowpop__opt:focus-visible {
  background: var(--bt-surface-interactive);
  color: var(--bt-text-primary);
}
.bt-rowpop__opt.is-on {
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
  font-weight: 600;
}
/* Same row, nothing to press: the read-only assignee list for a role that may
   see who is on a job but not change it. */
.bt-rowpop__opt--static { cursor: default; }
.bt-rowpop__opt--static:hover { background: transparent; }
.bt-rowpop__opt > .bt-icon:last-child { margin-left: auto; flex: 0 0 auto; }
.bt-rowpop__name { display: flex; min-width: 0; flex: 1 1 auto; align-items: center; gap: 6px; }
.bt-rowpop__tag {
  flex: 0 0 auto;
  padding: 0 6px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
  font-size: 10px;
  font-weight: 600;
}
.bt-rowpop__foot {
  padding: 8px 6px 2px;
  color: var(--bt-text-secondary);
  font-size: 11px;
  line-height: 16px;
}

/* Which columns the board shows. */
.bt-colmenu-wrap { position: relative; }
.bt-colmenu {
  position: absolute;
  z-index: 45;
  top: calc(100% + 6px);
  right: 0;
  width: 216px;
  max-height: min(70vh, 480px);
  padding: 6px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--bt-radius-panel);
  overflow: hidden;
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  color: var(--bt-text-primary);
  font-family: var(--bt-font-interface);
  font-size: 13px;
  line-height: 18px;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-4px);
  transition: opacity var(--bt-duration-sm) var(--bt-ease), transform var(--bt-duration-sm) var(--bt-ease);
}
.bt-colmenu.is-open { opacity: 1; pointer-events: auto; transform: none; }
.bt-colmenu__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 4px 10px 8px;
}
.bt-colmenu__list {
  max-height: min(60vh, 410px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.bt-colmenu__row {
  display: flex;
  min-height: 38px;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--bt-radius-sm);
  color: var(--bt-text-primary);
  cursor: pointer;
  font: inherit;
  user-select: none;
  transition:
    background-color var(--bt-duration-sm) var(--bt-ease),
    color var(--bt-duration-sm) var(--bt-ease);
}
.bt-colmenu__row:hover,
.bt-colmenu__row:focus-within { background: var(--bt-surface-interactive); }
.bt-colmenu__row.is-locked { cursor: default; color: var(--bt-text-secondary); }
.bt-colmenu__row.is-locked:hover { background: transparent; }
.bt-colmenu__label {
  display: inline-flex;
  min-width: 0;
  align-items: center;
  gap: 6px;
}
.bt-colmenu__lock {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  color: var(--bt-text-disabled);
}

.bt-row-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; }

/* ---------------------------------------------------------------- checklist */
.bt-cl-section { overflow: hidden; }

.bt-cl-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 16px 16px 6px;
}
.bt-cl-head__num { color: var(--bt-accent-text); font-size: 11px; font-weight: 600; line-height: 14px; letter-spacing: 0.06em; }
.bt-cl-head h3 { flex: 1; font-size: 16px; font-weight: 700; line-height: 22px; }
.bt-cl-head__count { color: var(--bt-text-secondary); font-size: 12px; font-weight: 600; line-height: 18px; }

.bt-cl-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  padding: 11px 10px;
  border: 0;
  border-radius: var(--bt-radius-cell);
  background: transparent;
  color: inherit;
  text-align: left;
  transition: background var(--bt-duration-sm) var(--bt-ease);
}
.bt-cl-item[role="button"]:hover { background: var(--bt-surface-nested); }

.bt-cl-item__body { flex: 1; min-width: 0; }
.bt-cl-item__label { font-size: 14px; font-weight: 500; line-height: 20px; }
.bt-cl-item__hint { margin-top: 1px; color: var(--bt-text-secondary); font-size: 12px; line-height: 18px; }

.bt-st-icon {
  display: flex;
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  margin-top: -1px;
  border: 2px solid rgba(255, 255, 255, 0.22);
  border-radius: 50%;
  color: transparent;
  transition: background var(--bt-duration-sm) var(--bt-ease), border-color var(--bt-duration-sm) var(--bt-ease);
}
.bt-st-icon .bt-icon { width: 13px; height: 13px; }

.st-done .bt-st-icon { background: var(--bt-accent); border-color: var(--bt-accent); color: var(--bt-ink); }
.st-prog .bt-st-icon { border-color: var(--bt-info); color: var(--bt-info); }
.st-hold .bt-st-icon { border-color: var(--bt-warning); color: var(--bt-warning-text); }
.st-nn .bt-st-icon { border-style: dashed; border-color: rgba(255, 255, 255, 0.3); color: var(--bt-text-secondary); }

.st-done .bt-cl-item__label {
  color: var(--bt-text-secondary);
  text-decoration: line-through;
  text-decoration-color: var(--bt-accent-deep);
}
.st-nn .bt-cl-item__label { color: var(--bt-text-disabled); }

.bt-st-chip {
  flex: 0 0 auto;
  align-self: flex-start;
  margin-top: 1px;
  padding: 3px 10px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--bt-radius-round);
  background: transparent;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  line-height: 16px;
  white-space: nowrap;
  transition: background var(--bt-duration-sm) var(--bt-ease), color var(--bt-duration-sm) var(--bt-ease), border-color var(--bt-duration-sm) var(--bt-ease);
}
button.bt-st-chip:hover { border-color: rgba(255, 255, 255, 0.34); color: var(--bt-text-primary); }

.st-done .bt-st-chip { background: var(--bt-accent-soft); border-color: transparent; color: var(--bt-accent-text); }
.st-prog .bt-st-chip { background: var(--bt-info-soft); border-color: transparent; color: var(--bt-info-text); }
.st-hold .bt-st-chip { background: var(--bt-warning-soft); border-color: transparent; color: var(--bt-warning-text); }
.st-nn .bt-st-chip { background: var(--bt-surface-nested); border-color: transparent; color: var(--bt-text-secondary); }

/* Checklist items that ask a question rather than being ticked off. The row
   carries its own control, so it is never a button and never strikes itself
   through: an answered question is still worth reading back. */
.bt-cl-item--entry { align-items: flex-start; }
.bt-cl-item--entry .bt-cl-item__body { display: flex; flex-direction: column; gap: 6px; }
.bt-cl-item--entry .bt-label-row { margin: 0; }
.bt-cl-item--entry.st-done .bt-cl-item__label { color: inherit; text-decoration: none; }
.bt-cl-item--entry .bt-cl-item__hint { margin-top: 0; }
.bt-cl-item--entry .bt-input-shell,
.bt-cl-item--entry .bt-select-enhanced { width: 100%; }

/* Standing instruction text between the steps: something to read, with nothing
   to record against it, so it is set apart rather than dressed as an item. */
.bt-cl-item--info {
  gap: 10px;
  border-left: 2px solid var(--bt-accent-deep);
  border-radius: 0 var(--bt-radius-cell) var(--bt-radius-cell) 0;
  background: var(--bt-surface-nested);
}
.bt-cl-item--info .bt-cl-item__icon {
  display: flex;
  flex: 0 0 auto;
  color: var(--bt-accent-text);
}
.bt-cl-item--info .bt-cl-item__label { font-weight: 500; color: var(--bt-text-secondary); }
.bt-cl-item--info .bt-st-chip { align-self: center; }

/* A single tick box, for the items that just want confirming. */
.bt-tick {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px 6px 10px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-round);
  cursor: pointer;
}
.bt-tick:hover { border-color: var(--bt-neutral); }
/* The row stacks its parts, so the pill has to say it doesn't want the width. */
.bt-cl-item--entry .bt-tick { align-self: flex-start; }
.bt-tick input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.bt-tick__label { font-size: 13px; font-weight: 600; line-height: 18px; color: var(--bt-text-secondary); }
.bt-tick input:checked ~ .bt-tick__label { color: var(--bt-accent-text); }
.bt-tick input:focus-visible + .bt-check__box { outline: 2px solid var(--bt-accent); outline-offset: 2px; }
.bt-tick input:disabled { cursor: default; }
.bt-tick:has(input:disabled) { cursor: default; opacity: 0.6; }

/* Pick one, or pick any: the same pill either way, so a checklist reads as one
   thing however its items were set up. The mark tells them apart — a dot for a
   choice you can only make once, a tick for one you can make alongside others. */
.bt-choices { display: flex; flex-wrap: wrap; gap: 8px; }
.bt-choice {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px 7px 10px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-round);
  background: transparent;
  cursor: pointer;
  transition: background var(--bt-duration-sm) var(--bt-ease), border-color var(--bt-duration-sm) var(--bt-ease);
}
.bt-choice:hover { border-color: var(--bt-neutral); background: var(--bt-surface-nested); }
.bt-choice input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.bt-choice__body {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  line-height: 18px;
  color: var(--bt-text-secondary);
}
.bt-choice__body::before {
  content: "";
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  border: 1.8px solid var(--bt-neutral);
  border-radius: 50%;
  transition: background var(--bt-duration-sm) var(--bt-ease), border-color var(--bt-duration-sm) var(--bt-ease);
}
.bt-choices--multi .bt-choice__body::before { border-radius: 5px; }
.bt-choice input:checked ~ .bt-choice__body { color: var(--bt-accent-text); }
.bt-choice input:checked ~ .bt-choice__body::before {
  border-color: var(--bt-accent);
  background: var(--bt-accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23001318' stroke-width='3.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / 12px no-repeat;
}
.bt-choice:has(input:checked) { border-color: transparent; background: var(--bt-accent-soft); }
.bt-choice:has(input:focus-visible) { outline: 2px solid var(--bt-accent); outline-offset: 2px; }
.bt-choice:has(input:disabled) { cursor: default; opacity: 0.6; }
.bt-choice:has(input:disabled):hover { border-color: var(--bt-line); background: transparent; }

/* collapsible details card */
.bt-collapse__head {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 16px;
  border: 0;
  background: transparent;
  color: inherit;
  text-align: left;
}
.bt-collapse__head .bt-icon { color: var(--bt-text-secondary); transition: transform var(--bt-duration-sm) var(--bt-ease); }
.bt-collapse.is-open .bt-collapse__head .bt-icon { transform: rotate(180deg); }
.bt-collapse__body { display: none; padding: 2px 16px 16px; }
.bt-collapse.is-open .bt-collapse__body { display: block; }

/* meta grid (admin job detail) */
.bt-meta-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 16px;
  padding: 16px;
}
.bt-meta-item b {
  display: block;
  margin-bottom: 2px;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  line-height: 14px;
  text-transform: uppercase;
}
.bt-meta-item div { font-size: 14px; font-weight: 500; line-height: 20px; overflow-wrap: anywhere; }

/* ---------------------------------------------------------------- job workspace (3-pane) */
/* A header strip above the workspace holds status badges + the job-level actions. */
.bt-jobhead {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
}
.bt-jobhead__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

/* The technician summary uses the same compact tag/action header as the
   admin job detail, then a key/value list rather than a tall field stack. */
.bt-job-detail__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.bt-job-detail__head > #d-tags { min-width: 0; }
.bt-job-detail .bt-kv__v > .bt-input-shell,
.bt-job-detail .bt-kv__v > .bt-select,
.bt-job-detail .bt-kv__v > .bt-schedule-inputs { width: 100%; }
/* The admin job editor lives in the narrow job-detail pane. Stack its
   schedule controls so the date field never collapses beside the fixed-width
   time control. Keep the assignee role tabs evenly distributed as well. */
.bt-job-detail .bt-schedule-inputs {
  grid-template-columns: minmax(0, 1fr);
}
.bt-job-detail .bt-picker__roles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px;
  padding: 4px;
  border-radius: 14px;
}
.bt-job-detail .bt-picker__roles--dispatch {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.bt-job-detail .bt-picker__roles .bt-segmented__item {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-width: 0;
  min-height: 28px;
  padding: 0 8px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bt-job-detail .bt-kv__v .bt-cluster { margin-top: 6px; }
.bt-job-detail .bt-kv__v--copy {
  display: flex;
  min-width: 0;
  align-items: flex-start;
  gap: 6px;
  white-space: nowrap;
}
.bt-job-detail .bt-kv__v--copy .bt-kv__value {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bt-job-detail .bt-kv__v--copy .bt-inline-edit {
  flex: 0 0 auto;
  margin-left: auto;
}

/* info · checklist · activity · conversation. The grid fills the window so the
   conversation sits hard against the right edge; below 1440 the activity log
   folds under the pair, and below 1240 the conversation joins it.
   Every child pins its own row: the conversation comes before the log in the
   DOM (so it stacks first on narrow screens), and without an explicit row the
   sparse auto-placement algorithm would push the log down a row rather than
   step back to column 3. */
.bt-jobgrid {
  --bt-job-pane-bottom: 24px;
  display: grid;
  width: 100%;
  margin-top: var(--bt-jobhead-space, 0);
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr) minmax(0, 320px) minmax(0, 360px);
  gap: 16px;
  align-items: start;
}
.bt-jobgrid__info  { grid-column: 1; grid-row: 1; }
.bt-jobgrid__main  { grid-column: 2; grid-row: 1; display: flex; min-width: 0; flex-direction: column; gap: 16px; }
.bt-jobgrid__log   { grid-column: 3; grid-row: 1; }
.bt-jobgrid__conv  { grid-column: 4; grid-row: 1; }
.bt-jobgrid__info,
.bt-jobgrid__log,
.bt-jobgrid__conv { position: sticky; top: calc(var(--bt-topbar-height) + 20px); min-width: 0; }

/* Keep a tall information rail inside the same usable viewport as the
   conversation. Otherwise the grid's lower edge pushes both sticky panes up
   behind the top bar when the checklist reaches its end. */
@media (min-width: 1241px) {
  .bt-jobgrid__info {
    display: flex;
    height: calc(100vh - var(--bt-job-pane-top, calc(var(--bt-topbar-height) + 20px)) - var(--bt-job-pane-bottom));
    height: calc(100dvh - var(--bt-job-pane-top, calc(var(--bt-topbar-height) + 20px)) - var(--bt-job-pane-bottom));
    flex-direction: column;
    overflow: hidden;
  }
  .bt-jobgrid__info > .bt-panel:first-child {
    min-height: 0;
    flex: 1 1 auto;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
  }
}

/* Compact assignee: avatar next to the name, so one person fits on one line.
   Everywhere it is used now it is static text — changing who is on a job is the
   picker's job (below). */
.bt-assignee {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: var(--bt-control-md);
  padding: 0 8px;
  border: 1px solid transparent;
  border-radius: 12px;
  background: var(--bt-surface-field);
}
.bt-assignee--static { background: transparent; padding: 0; }
/* Marks the job owner, and only worth showing when there are others. */
.bt-assignee__tag {
  flex: 0 0 auto;
  padding: 0 6px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
  font-size: 10px;
  font-weight: 600;
}
.bt-assignee__name {
  min-width: 0;
  overflow: hidden;
  font-size: 14px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bt-assignee__name.is-empty { color: var(--bt-text-secondary); font-weight: 500; }

/* ---------------------------------------------------------------- settings */
/* Settings is three unrelated concerns — where you are in the world, what the
   portal tells you about, and what it looks like — so it gets a rail of its own
   rather than stacking all three into one long scroll. The rail is the same
   idea as the app sidebar, one level in: a list on the left, one section's
   panels on the right. */
.bt-settings {
  display: grid;
  align-items: start;
  gap: 24px;
  grid-template-columns: 188px minmax(0, 1fr);
}
/* Sticks while the panels scroll, so switching section never means scrolling
   back up to find the rail. */
.bt-settings__nav {
  position: sticky;
  top: calc(var(--bt-topbar-height) + 16px);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.bt-settings__link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--bt-text-secondary);
  font-size: 14px;
  font-weight: 500;
  text-align: left;
  transition: background var(--bt-duration-sm) var(--bt-ease), color var(--bt-duration-sm) var(--bt-ease);
}
.bt-settings__link > .bt-icon { flex: 0 0 auto; }
.bt-settings__link:hover { background: var(--bt-surface-nested); color: var(--bt-text-primary); }
.bt-settings__link.is-active { background: var(--bt-surface); color: var(--bt-text-primary); font-weight: 600; }
.bt-settings__link:focus-visible { outline: 2px solid var(--bt-accent); outline-offset: 2px; }

.bt-settings__body { display: flex; flex-direction: column; gap: 20px; }
.bt-settings__section { display: flex; flex-direction: column; gap: 20px; }
/* `hidden` has to beat the display above, or the sections all render at once. */
.bt-settings__section[hidden] { display: none; }

.bt-policy-form {
  display: grid;
  grid-template-columns: minmax(0, 280px) auto;
  align-items: start;
  gap: 12px;
}
.bt-policy-form > .bt-button { justify-self: start; margin-top: 24px; }
.bt-policy-form > .bt-alert { grid-column: 1 / -1; }

/* No room for a rail on a phone, so it lies down above the panels and scrolls
   sideways — the same three keys, still one row. */
@media (max-width: 760px) {
  .bt-settings { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .bt-settings__nav {
    position: static;
    flex-direction: row;
    gap: 4px;
    overflow-x: auto;
    padding-bottom: 2px;
    scrollbar-width: none;
  }
  .bt-settings__nav::-webkit-scrollbar { display: none; }
  .bt-settings__link { flex: 0 0 auto; }
  .bt-policy-form { grid-template-columns: minmax(0, 1fr); }
  .bt-policy-form > .bt-button { margin-top: 0; }
}

/* ---------------------------------------------------------------- syncro tickets */
/* A linked ticket reads as one line: its number, what it's about, and where it
   stands. The number leads because that is what gets said out loud and typed
   into every other system. */
.bt-tickets { display: flex; flex-direction: column; gap: 10px; }
.bt-tickets__chosen { display: flex; flex-direction: column; gap: 6px; }

.bt-ticket {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 7px 8px;
  border-radius: 10px;
  background: var(--bt-surface-field);
  color: inherit;
  text-decoration: none;
}
.bt-ticket--link:hover { background: var(--bt-surface-interactive); }
.bt-ticket--empty { background: transparent; padding: 0; color: var(--bt-text-secondary); font-size: 13px; }
.bt-ticket__num {
  flex: 0 0 auto;
  align-self: flex-start;
  padding: 1px 7px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
}
.bt-ticket__body { display: flex; min-width: 0; flex: 1 1 auto; flex-direction: column; }
.bt-ticket__subject { font-size: 13px; font-weight: 500; line-height: 18px; }
.bt-ticket__meta { color: var(--bt-text-secondary); font-size: 11px; line-height: 16px; }
.bt-ticket > .bt-icon { flex: 0 0 auto; color: var(--bt-text-disabled); }
.bt-ticket--link:hover > .bt-icon { color: var(--bt-accent-text); }

/* The board's Tickets column. Numbers only — the column is ~96px, and the
   number is what gets read off a board and typed into something else. The
   subjects are in the tooltip. */
.bt-tickcell { display: flex; min-width: 0; align-items: center; gap: 4px; }
.bt-tickcell__num {
  flex: 0 0 auto;
  padding: 1px 6px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
  font-size: 11px;
  font-weight: 700;
  line-height: 16px;
}
.bt-tickcell__more {
  flex: 0 0 auto;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
}

/* Search results, in the same shape as the linked rows above them so picking
   one is visibly the same object arriving. */
.bt-tickets__results {
  display: grid;
  max-height: 260px;
  gap: 2px;
  overflow-y: auto;
  padding: 4px;
  border-radius: 12px;
  background: var(--bt-surface-field);
}
.bt-tickets__opt {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 10px;
  padding: 6px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  background: transparent;
  color: inherit;
  text-align: left;
}
.bt-tickets__opt:hover { background: var(--bt-surface-nested); }
.bt-tickets__opt:disabled { cursor: default; opacity: 0.55; }
.bt-tickets__opt:disabled:hover { background: transparent; }
.bt-ticket__on {
  flex: 0 0 auto;
  color: var(--bt-accent-text);
  font-size: 11px;
  font-weight: 600;
}

/* ---------------------------------------------------------------- assignee picker */
/* One control for the whole of "who is on this job": whoever is already on it
   at the top — job owner first — then a role filter over everyone who can
   be assigned. The booking form and the job pane share it, so assignment reads
   the same way wherever you happen to be doing it. The chosen list is the only
   part a read-only view renders, which is also all the job pane shows until
   the pencil is pressed. */
.bt-picker { display: flex; min-width: 0; flex-direction: column; gap: 10px; }
.bt-picker__chosen { display: flex; flex-direction: column; gap: 8px; }
.bt-picked { display: flex; align-items: center; gap: 10px; }
.bt-picked__body { display: flex; min-width: 0; flex: 1 1 auto; flex-direction: column; }
.bt-picked__name {
  min-width: 0;
  overflow: hidden;
  font-size: 14px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bt-picked__name.is-empty { color: var(--bt-text-secondary); font-weight: 500; }
.bt-picked__role { color: var(--bt-text-secondary); font-size: 11px; line-height: 16px; }

/* The assignee editor is wide enough to keep all role tabs visible together. */
.bt-picker__roles {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
  overflow: visible;
}
.bt-picker__roles .bt-segmented__item { flex: 0 0 auto; }

.bt-picker__list {
  display: grid;
  min-width: 0;
  max-height: 216px;
  gap: 2px;
  overflow-x: hidden;
  overflow-y: auto;
  padding: 4px;
  border-radius: 12px;
  background: var(--bt-surface-field);
}
.bt-picker__row { display: flex; align-items: center; gap: 2px; border-radius: var(--bt-radius-sm); }
.bt-picker__row:hover { background: var(--bt-surface-nested); }
.bt-picker__opt {
  display: flex;
  min-width: 0;
  flex: 1 1 auto;
  align-items: center;
  gap: 8px;
  padding: 6px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  background: transparent;
  color: inherit;
  font-size: 13px;
  text-align: left;
}
.bt-picker__row.is-on .bt-picker__opt { color: var(--bt-accent-text); }
.bt-picker__opt > .bt-icon:last-child { flex: 0 0 auto; margin-left: auto; }
.bt-picker__name { min-width: 0; flex: 1 1 auto; font-weight: 500; }
.bt-picker__route { flex: 0 1 auto; color: var(--bt-text-secondary); font-size: 11px; line-height: 16px; white-space: nowrap; }
/* Only offered for someone already on the job — promoting a person who isn't on
   it yet is just picking them, which the row itself does. */
.bt-picker__main {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  margin-right: 4px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  background: transparent;
  color: var(--bt-text-disabled);
}
.bt-picker__main:hover { background: var(--bt-surface-interactive); color: var(--bt-text-primary); }
.bt-picker__main.is-main { color: var(--bt-accent-text); }
.bt-picker__main.is-main:hover { background: transparent; color: var(--bt-accent-text); }
.bt-picker__main.is-route-active { background: var(--bt-accent-soft); color: var(--bt-accent-text); }
.bt-picker__main.is-route-active:hover { background: var(--bt-accent-soft); color: var(--bt-accent-text); }
.bt-picker__empty { padding: 10px 6px; color: var(--bt-text-secondary); font-size: 12px; }

/* Compact key/value details list (replaces the roomier meta grid in the pane). */
.bt-kv-list { display: grid; gap: 10px; }
.bt-kv { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 12px; align-items: baseline; }
.bt-kv__k { color: var(--bt-text-secondary); font-size: 12px; font-weight: 500; line-height: 18px; }
.bt-kv__v { font-size: 14px; font-weight: 500; line-height: 18px; overflow-wrap: anywhere; }

/* Activity log — a reverse-chronological timeline, shared by techs and admins. */
.bt-log__body {
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - var(--bt-topbar-height) - 132px);
  padding: 6px 16px 14px;
  overflow-y: auto;
}
.bt-event {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 10px;
  padding: 7px 0;
}
.bt-event:not(:last-child)::before {
  content: "";
  position: absolute;
  top: 19px;
  bottom: -7px;
  left: 5px;
  width: 2px;
  background: var(--bt-line);
}
.bt-event__dot {
  width: 12px;
  height: 12px;
  margin-top: 4px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--bt-neutral);
}
.bt-event__dot--done,
.bt-event__dot--completed { background: var(--bt-accent); }
.bt-event__dot--in_progress,
.bt-event__dot--started,
.bt-event__dot--resumed,
.bt-event__dot--assigned,
.bt-event__dot--helper,
.bt-event__dot--reopened,
.bt-event__dot--edit,
.bt-event__dot--dispatch,
/* archived/unarchived are retired event types, kept so log entries written
   before archiving was removed still get their colour. */
.bt-event__dot--unarchived { background: var(--bt-info); }
.bt-event__dot--on_hold,
.bt-event__dot--archived { background: var(--bt-warning); }
.bt-event__dot--created { background: var(--bt-positive); }
.bt-event__text { color: var(--bt-text-primary); font-size: 13px; line-height: 18px; overflow-wrap: anywhere; }
.bt-event__text b { font-weight: 600; }
.bt-event__time { margin-top: 2px; color: var(--bt-text-disabled); font-size: 11px; line-height: 16px; }

/* Under 1600 there isn't room for four panes without squeezing the checklist,
   so the activity log drops to a full-width strip below. The conversation stays
   the right-hand column either way. */
@media (max-width: 1599px) {
  .bt-jobgrid { grid-template-columns: minmax(0, 300px) minmax(0, 1fr) minmax(0, 360px); }
  .bt-jobgrid__conv { grid-column: 3; grid-row: 1; }
  .bt-jobgrid__log { position: static; grid-column: 1 / -1; grid-row: 2; }
  .bt-jobgrid__log .bt-log__body { max-height: 380px; }
}
/* Below 1240 both feeds become full-width strips under the info+checklist pair,
   conversation first. */
@media (max-width: 1240px) {
  .bt-jobgrid { grid-template-columns: minmax(0, 300px) minmax(0, 1fr); }
  .bt-jobgrid__conv { position: static; grid-column: 1 / -1; grid-row: 2; }
  .bt-jobgrid__log { grid-row: 3; }
}
@media (max-width: 760px) {
  .bt-jobgrid { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .bt-jobgrid__info { position: static; }
  /* One column: hand every pane back to auto-placement so they stack in DOM
     order (info · checklist · conversation · activity) instead of the pinned
     columns/rows creating phantom tracks. */
  .bt-jobgrid > * { grid-column: auto; grid-row: auto; }
}

/* Above the stacked layout, only the checklist scrolls with the document.
   JavaScript resolves the live grid tracks into viewport coordinates so the
   information, activity and conversation panes remain genuinely fixed rather
   than being pulled upward by a sticky containing block at the page end. */
@media (min-width: 1241px) {
  .bt-jobhead--fixed {
    position: fixed;
    z-index: 12;
    top: var(--bt-fixed-top);
    left: var(--bt-fixed-left);
    width: var(--bt-fixed-width);
  }
  .bt-jobgrid__pane--fixed {
    position: fixed;
    z-index: 10;
    top: var(--bt-fixed-top);
    left: var(--bt-fixed-left);
    width: var(--bt-fixed-width);
    margin: 0;
  }
  .bt-jobgrid__info.bt-jobgrid__pane--fixed,
  .bt-jobgrid__log.bt-jobgrid__pane--fixed,
  .bt-jobgrid__conv.bt-jobgrid__pane--fixed {
    height: var(--bt-fixed-height);
  }
  .bt-jobgrid__conv.bt-jobgrid__pane--fixed .bt-conv { height: 100%; }
  .bt-jobgrid__log.bt-jobgrid__pane--fixed .bt-log {
    display: flex;
    max-height: 100%;
    flex-direction: column;
    overflow: hidden;
  }
  .bt-jobgrid__log.bt-jobgrid__pane--fixed .bt-log__body {
    min-height: 0;
    flex: 1 1 auto;
    max-height: none;
    overflow-y: auto;
  }
}

/* ---------------------------------------------------------------- sheet / dialog */
.bt-scrim {
  position: fixed;
  z-index: 60;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
  background: rgba(0, 8, 10, 0.62);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--bt-duration-sm) var(--bt-ease);
}
.bt-scrim.is-open { opacity: 1; pointer-events: auto; }

.bt-sheet {
  width: 100%;
  max-width: 460px;
  /* Status options plus a note can outgrow a short screen (or one with the
     keyboard up), so the sheet scrolls rather than pushing Save off-screen. */
  max-height: 100%;
  overflow-y: auto;
  padding: 16px 14px calc(18px + env(safe-area-inset-bottom));
  border-radius: var(--bt-radius-sheet) var(--bt-radius-sheet) 0 0;
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  transform: translateY(24px);
  transition: transform var(--bt-duration-sm) var(--bt-ease);
}
.bt-scrim.is-open .bt-sheet { transform: none; }

.bt-sheet__title {
  padding: 0 10px 10px;
  color: var(--bt-text-secondary);
  font-size: 13px;
  font-weight: 600;
  line-height: 18px;
}

/* The work-clock prompt is operational copy, so it reads as one left-aligned
   instruction instead of the centred confirmation/reveal dialogs elsewhere. */
#work-overlay .bt-sheet { text-align: left; }
#work-dialog-title,
#work-dialog-copy { text-align: left; }
#work-dialog-copy { margin: 0; padding: 0 10px; }

.bt-sheet__opt {
  display: flex;
  width: 100%;
  min-height: 48px;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--bt-radius-cell);
  background: transparent;
  color: var(--bt-text-primary);
  font-size: 15px;
  font-weight: 500;
  text-align: left;
  transition: background var(--bt-duration-sm) var(--bt-ease);
}
.bt-sheet__opt:hover { background: var(--bt-surface-nested); }
.bt-sheet__opt.is-selected { background: var(--bt-accent-soft); }
.bt-sheet__opt .bt-st-icon { margin-top: 0; }
.bt-sheet__opt__check { margin-left: auto; color: var(--bt-accent-text); }

/* The note lives with the status options, so an item is set in one place. */
.bt-sheet__note { padding: 12px 10px 4px; }
.bt-sheet__note .bt-label { display: block; margin-bottom: 6px; }
.bt-sheet__note textarea.bt-input { min-height: 74px; resize: vertical; }

.bt-sheet__actions {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}
.bt-sheet__actions .bt-button { flex: 1 1 0; }

/* Record-save actions are a matched pair rather than two unrelated full-width
   controls. This keeps their size and the space between them consistent. */
.bt-sheet__actions.bt-record-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: 4px;
}
.bt-record-actions .bt-button,
.bt-record-actions .bt-sheet__cancel { width: 100%; margin-top: 0; justify-content: center; }

.bt-sheet__cancel {
  width: 100%;
  min-height: var(--bt-control-md);
  margin-top: 10px;
  border: 0;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface-interactive);
  color: var(--bt-text-primary);
  font-size: 14px;
  font-weight: 500;
}

@media (min-width: 761px) {
  .bt-scrim { align-items: center; padding: 24px; }
  .bt-sheet { max-width: 400px; border-radius: 18px; padding: 16px 14px 14px; }
}

/* ---------------------------------------------------------------- save pill */
.bt-save-pill {
  flex: 0 0 auto;
  color: var(--bt-text-secondary);
  font-size: 12px;
  font-weight: 600;
  line-height: 18px;
  white-space: nowrap;
}
.bt-save-pill.ok { color: var(--bt-positive-text); }
.bt-save-pill.bad { color: var(--bt-danger-text); }

/* ---------------------------------------------------------------- rail widgets */
.bt-widget {
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface);
}

.bt-widget__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 14px 16px 8px;
}

.bt-widget__body { padding: 0 12px 12px; }

.bt-stat-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: 6px 8px;
  border-radius: var(--bt-radius-cell);
}
.bt-stat-row + .bt-stat-row { box-shadow: 0 -1px 0 var(--bt-line); }
.bt-stat-row__value { font-family: var(--bt-font-display); font-size: 20px; font-weight: 700; line-height: 1; }

.bt-dot {
  width: 9px;
  height: 9px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: currentColor;
}

/* quick-action rows inside a rail widget */
.bt-quick {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 12px;
  padding: 10px 8px;
  border: 0;
  border-radius: var(--bt-radius-cell);
  background: transparent;
  color: inherit;
  text-align: left;
  transition: background var(--bt-duration-sm) var(--bt-ease);
}
.bt-quick:hover { background: var(--bt-surface-nested); }

/* ---------------------------------------------------------------- profile */
.bt-profile-head {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px 16px;
}

.bt-profile-photo {
  position: relative;
  flex: 0 0 auto;
}
.bt-profile-photo__edit {
  position: absolute;
  right: -2px;
  bottom: -2px;
  display: grid;
  width: 30px;
  height: 30px;
  place-items: center;
  border: 3px solid var(--bt-surface-popover);
  border-radius: 50%;
  background: var(--bt-accent);
  color: var(--bt-ink);
}
.bt-profile-photo__edit .bt-icon { width: 14px; height: 14px; }
.bt-profile-photo__edit:hover { filter: brightness(1.08); }
.bt-profile-photo__edit:active { transform: scale(0.94); }

.bt-info-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 48px;
  padding: 10px 16px;
}
.bt-info-row + .bt-info-row { box-shadow: 0 -1px 0 var(--bt-line); }
.bt-info-row__label { color: var(--bt-text-secondary); font-size: 13px; }
.bt-info-row__value { font-size: 14px; font-weight: 500; text-align: right; overflow-wrap: anywhere; }

/* ---------------------------------------------------------------- star rating */
/* Two identical rows of stars stacked on top of each other; the upper one is
   clipped to --fill, so any fraction of a star reads correctly. */
.bt-stars {
  position: relative;
  display: inline-block;
  flex: 0 0 auto;
  line-height: 0;
}

.bt-stars__row {
  display: flex;
  gap: 3px;
  white-space: nowrap;
}

.bt-stars__row .bt-icon {
  width: var(--bt-star-size, 18px);
  height: var(--bt-star-size, 18px);
}

.bt-stars__base { color: rgba(255, 255, 255, 0.16); }

.bt-stars__fill {
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
  width: var(--bt-star-fill, 0%);
  color: var(--bt-accent);
  transition: width 900ms var(--bt-ease);
}
.bt-stars__fill .bt-stars__row { width: max-content; }

.bt-stars--sm { --bt-star-size: 13px; }
.bt-stars--lg { --bt-star-size: 24px; }
.bt-stars--xl { --bt-star-size: 34px; }
.bt-stars--xl .bt-stars__row { gap: 6px; }

/* Scores below the benchmark shade warm rather than teal, so a weak result
   never reads as a good one at a glance. */
.bt-stars.is-low .bt-stars__fill { color: var(--bt-warning); }
.bt-stars.is-poor .bt-stars__fill { color: var(--bt-danger); }

.bt-score {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  font-family: var(--bt-font-display);
  font-weight: 700;
}
.bt-score__value { font-size: 1em; line-height: 1; }
.bt-score__max { color: var(--bt-text-disabled); font-size: 0.5em; font-weight: 500; }

/* ---------------------------------------------------------------- performance */
.bt-perf-head {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 16px 4px;
}

.bt-perf-head__score {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.bt-perf-head__score .bt-score { font-size: 40px; }

/* The grid closes out its panel, so its opaque cells would otherwise square off
   the panel's bottom corners. It carries the radius and clips them itself. */
.bt-perf-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  margin-top: 14px;
  background: var(--bt-line);
  border-top: 1px solid var(--bt-line);
  border-radius: 0 0 var(--bt-radius-panel) var(--bt-radius-panel);
}

.bt-perf-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  background: var(--bt-surface-nested);
}
.bt-perf-cell__value { font-family: var(--bt-font-display); font-size: 19px; font-weight: 700; line-height: 26px; }
.bt-perf-cell__label { color: var(--bt-text-secondary); font-size: 11px; font-weight: 500; line-height: 16px; }

/* Measured time against the benchmark. The marker sits at 100% of target.
   The track is block-level in its own right: it is used as a <span> inside the
   technician record's job rows, and an inline box would collapse to nothing and
   leave the absolutely-positioned marker floating on its own. */
.bt-pace {
  display: block;
  position: relative;
  height: 6px;
  overflow: hidden;
  border-radius: var(--bt-radius-round);
  background: rgba(255, 255, 255, 0.1);
}

.bt-pace__fill {
  height: 100%;
  border-radius: inherit;
  background: var(--bt-accent);
  transition: width var(--bt-duration-md) var(--bt-ease);
}
.bt-pace__fill--over { background: var(--bt-warning); }
.bt-pace__fill--late { background: var(--bt-danger); }

.bt-pace__mark {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 2px;
  background: var(--bt-text-primary);
  opacity: 0.6;
}

.bt-perf-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 8px;
  border: 0;
  border-radius: var(--bt-radius-cell);
  background: transparent;
  color: inherit;
  text-align: left;
  transition: background var(--bt-duration-sm) var(--bt-ease);
}
.bt-perf-row + .bt-perf-row { box-shadow: 0 -1px 0 var(--bt-line); }
.bt-perf-row:hover { background: var(--bt-surface-nested); }

.bt-perf-row__side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}

/* ---------------------------------------------------------------- rating reveal */
.bt-reveal {
  width: 100%;
  max-width: 420px;
  padding: 28px 24px 20px;
  border-radius: var(--bt-radius-sheet);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  text-align: center;
  transform: translateY(24px) scale(0.97);
  transition: transform var(--bt-duration-md) var(--bt-ease);
}
.bt-scrim.is-open .bt-reveal { transform: none; }

.bt-reveal__glow {
  position: relative;
  display: flex;
  justify-content: center;
  padding: 6px 0 14px;
}
.bt-reveal__glow::before {
  position: absolute;
  z-index: 0;
  top: 50%;
  left: 50%;
  width: 240px;
  height: 240px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--bt-accent-soft), transparent 62%);
  content: "";
  transform: translate(-50%, -50%);
}
.bt-reveal__glow > * { position: relative; z-index: 1; }

.bt-reveal__score {
  font-family: var(--bt-font-display);
  font-size: 56px;
  font-weight: 900;
  line-height: 1;
}

.bt-reveal__verdict {
  margin-top: 10px;
  font-family: var(--bt-font-display);
  font-size: 20px;
  font-weight: 700;
  line-height: 26px;
}

.bt-reveal__lede {
  margin-top: 6px;
  color: var(--bt-text-secondary);
  font-size: 14px;
  line-height: 20px;
}

.bt-reveal__times {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: 18px;
  text-align: left;
}

.bt-reveal__time {
  padding: 10px 12px;
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
}
.bt-reveal__time b { display: block; font-family: var(--bt-font-display); font-size: 18px; line-height: 24px; }
.bt-reveal__time span { color: var(--bt-text-secondary); font-size: 11px; font-weight: 500; }

/* ---------------------------------------------------------------- permission matrix */
.bt-matrix-scroll {
  overflow-x: auto;
  border-radius: var(--bt-radius-panel);
  -webkit-overflow-scrolling: touch;
}

.bt-matrix {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 13px;
}

.bt-matrix th,
.bt-matrix td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--bt-line);
  text-align: center;
  vertical-align: middle;
}

.bt-matrix thead th {
  position: sticky;
  z-index: 2;
  top: 0;
  background: transparent;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}

/* The permission name column stays put while the roles scroll past it. */
.bt-matrix th.bt-matrix__row-head,
.bt-matrix td.bt-matrix__row-head {
  position: sticky;
  z-index: 1;
  left: 0;
  min-width: 240px;
  background: transparent;
  font-weight: 500;
  text-align: left;
}
.bt-matrix thead th.bt-matrix__row-head { z-index: 3; }

.bt-matrix__group td {
  padding-top: 16px;
  background: transparent;
  color: var(--bt-accent-text);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-align: left;
  text-transform: uppercase;
}

.bt-matrix__locked { color: var(--bt-text-disabled); }

.bt-matrix tbody tr:hover td { background: var(--bt-surface-nested); }
.bt-matrix tbody tr:hover td.bt-matrix__row-head { background: var(--bt-surface-nested); }

/* A checkbox-backed toggle: the input stays focusable for keyboard users. */
.bt-toggle {
  position: relative;
  display: inline-flex;
  width: 38px;
  height: 22px;
  flex: 0 0 auto;
  align-items: center;
  cursor: pointer;
}
.bt-toggle input {
  position: absolute;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
  opacity: 0;
}
.bt-toggle__track {
  width: 100%;
  height: 100%;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface-interactive);
  transition: background var(--bt-duration-sm) var(--bt-ease);
}
.bt-toggle__track::after {
  display: block;
  width: 16px;
  height: 16px;
  margin: 3px;
  border-radius: 50%;
  background: var(--bt-text-primary);
  content: "";
  transition: transform var(--bt-duration-sm) var(--bt-ease);
}
.bt-toggle input:checked + .bt-toggle__track { background: var(--bt-accent); }
.bt-toggle input:checked + .bt-toggle__track::after { background: var(--bt-ink); transform: translateX(16px); }
.bt-toggle input:focus-visible + .bt-toggle__track { outline: 2px solid var(--bt-accent); outline-offset: 2px; }
.bt-toggle input:disabled { cursor: default; }
.bt-toggle input:disabled + .bt-toggle__track { opacity: 0.45; }

/* ---------------------------------------------------------------- benchmark editor */
.bt-bench-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 82px 132px;
  align-items: center;
  gap: 12px;
  padding: 12px 8px;
}
.bt-bench-row + .bt-bench-row { box-shadow: 0 -1px 0 var(--bt-line); }
.bt-bench-row__hours {
  justify-self: end;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.bt-bench-row__minutes {
  width: 132px;
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- rating scale editor */
/* A row reads as one sentence — "finished in 60% of the target, earns 5.0" — so
   the two numbers sit under headings instead of carrying labels of their own.
   The last column is held open whether or not a remove button is offered in it,
   or the fields shuffle sideways as rows come and go. */
.bt-scale__head,
.bt-scale__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) var(--bt-control-sm);
  align-items: center;
  gap: 12px;
}
.bt-scale__head {
  padding: 0 2px 8px;
  border-bottom: 1px solid var(--bt-line);
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.bt-scale__row { padding: 8px 2px; }
.bt-scale__row + .bt-scale__row { box-shadow: 0 -1px 0 var(--bt-line); }
.bt-scale__row .bt-input { font-variant-numeric: tabular-nums; }
/* The unit belongs to the number it follows, not to a hint under the field. */
.bt-scale__unit { flex: 0 0 auto; color: var(--bt-text-disabled); font-size: 13px; }

/* A checkbox that belongs to the button beside it rather than to the panel: it
   qualifies one save and appears only while that save is on offer, so it is
   sized to sit in a panel head next to an xs button instead of taking a row. */
.bt-check-inline {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: var(--bt-control-xs);
  padding-inline: 4px;
  color: var(--bt-text-secondary);
  font-size: 12px;
  font-weight: 500;
  line-height: 18px;
  white-space: nowrap;
  cursor: pointer;
}
.bt-check-inline:hover { color: var(--bt-text-primary); }
.bt-check-inline input[type="checkbox"] {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  margin: 0;
  accent-color: var(--bt-accent);
}
.bt-check-inline:has(input:checked) { color: var(--bt-accent-text); }

/* What the scale actually pays out, read off the curve the server returned
   rather than worked out a second time here. On-target is the number people
   come to this panel to argue about, so it is the one that is marked. */
.bt-scale__samples { display: flex; flex-wrap: wrap; gap: 6px; }
.bt-scale__sample {
  display: flex;
  gap: 6px;
  padding: 4px 9px;
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
  color: var(--bt-text-secondary);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.bt-scale__sample b { color: var(--bt-text-primary); font-weight: 600; }
.bt-scale__sample--target { background: var(--bt-accent-soft); color: var(--bt-accent-text); }
.bt-scale__sample--target b { color: var(--bt-accent-text); }

/* ---------------------------------------------------------------- conversation */
.bt-conv {
  display: flex;
  height: calc(100vh - var(--bt-job-pane-top, calc(var(--bt-topbar-height) + 20px)) - var(--bt-job-pane-bottom, 24px));
  height: calc(100dvh - var(--bt-job-pane-top, calc(var(--bt-topbar-height) + 20px)) - var(--bt-job-pane-bottom, 24px));
  flex-direction: column;
  overflow: hidden;
}
.bt-conv__body {
  display: flex;
  flex: 1 1 auto;
  min-height: 120px;
  flex-direction: column;
  gap: 14px;
  padding: 12px 14px;
  overflow-y: auto;
}

.bt-comment { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px; }
.bt-comment__avatar { width: 30px; height: 30px; flex: 0 0 auto; }
.bt-comment__main { min-width: 0; }
.bt-comment__head { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.bt-comment__author { font-size: 13px; font-weight: 600; }
.bt-comment__time { color: var(--bt-text-disabled); font-size: 11px; }
/* Edit and delete sit at the end of the byline and stay out of the way until
   the message is hovered — a conversation shouldn't read as a row of buttons. */
.bt-comment__act {
  padding: 2px;
  border: 0;
  background: transparent;
  color: var(--bt-text-disabled);
  opacity: 0;
  cursor: pointer;
  transition: opacity var(--bt-duration-sm) var(--bt-ease), color var(--bt-duration-sm) var(--bt-ease);
}
.bt-comment__act:first-of-type { margin-left: auto; }
.bt-comment:hover .bt-comment__act,
.bt-comment__act:focus-visible { opacity: 1; }
.bt-comment__act:hover { color: var(--bt-text-primary); }
.bt-comment__act--danger:hover { color: var(--bt-danger-text); }
@media (hover: none) {
  .bt-comment__act { opacity: 1; }
}
.bt-comment__editor { margin-top: 6px; }
.bt-comment__editor textarea.bt-input { min-height: 54px; resize: vertical; }
.bt-comment__body {
  margin-top: 2px;
  font-size: 13.5px;
  line-height: 19px;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}
.bt-comment__to {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 4px;
  padding: 1px 8px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
  font-size: 11px;
  font-weight: 600;
}
/* A name inside a message. Tinted rather than boxed: it sits mid-sentence, and a
   chip with its own padding and border would break the line it is part of. */
.bt-mention {
  padding: 0 2px;
  border-radius: 4px;
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
  font-weight: 600;
}

/* ---- the mention picker ----
   Anchored in the composer's own flow rather than positioned over the page: it
   only ever opens directly above the box, and a panel that shares the composer's
   width cannot be knocked out of place by the conversation scrolling underneath
   it. */
.bt-mentionpop {
  max-height: 216px;
  overflow-y: auto;
  margin-bottom: 6px;
  padding: 4px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.bt-mentionpop__row {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 8px;
  padding: 6px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  background: transparent;
  color: var(--bt-text-secondary);
  cursor: pointer;
  font-family: inherit;
  text-align: left;
}
/* Hover and the keyboard's highlight are one state: two different-looking
   "selected" rows in one list is two answers to which one Enter takes. */
.bt-mentionpop__row:hover,
.bt-mentionpop__row.is-active {
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
}
.bt-mentionpop__name { min-width: 0; flex: 1 1 auto; font-size: 13px; font-weight: 600; }
.bt-mentionpop__meta {
  display: block;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 400;
}
.bt-mentionpop__row:hover .bt-mentionpop__meta,
.bt-mentionpop__row.is-active .bt-mentionpop__meta { color: inherit; opacity: 0.75; }

/* Attachments: image thumbnails render inline, other files as a chip. */
.bt-attachments { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.bt-attach-imgbtn {
  display: block;
  padding: 0;
  border: 0;
  border-radius: var(--bt-radius-cell);
  background: transparent;
  line-height: 0;
  transition: opacity var(--bt-duration-sm) var(--bt-ease);
}
.bt-attach-imgbtn:hover { opacity: 0.85; }
.bt-attach-img {
  display: block;
  max-width: 160px;
  max-height: 160px;
  border-radius: var(--bt-radius-cell);
  border: 1px solid var(--bt-line);
  object-fit: cover;
}

/* An attachment you may remove carries its own × in the corner. It only shows
   on hover so a thread you're only reading stays clean, and stays put on touch
   where there is no hover to reveal it. */
.bt-attach { position: relative; display: inline-flex; }
.bt-attach__x {
  position: absolute;
  top: 4px;
  right: 4px;
  display: grid;
  width: 22px;
  height: 22px;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--bt-duration-sm) var(--bt-ease), background var(--bt-duration-sm) var(--bt-ease);
}
.bt-attach:hover .bt-attach__x,
.bt-attach__x:focus-visible { opacity: 1; }
.bt-attach__x:hover { background: var(--bt-danger); }
@media (hover: none) {
  .bt-attach__x { opacity: 1; }
}
/* A file chip is one short row, so the × sits at the end of it rather than on
   top of the name and size. */
.bt-attach--file .bt-attach-file { padding-right: 32px; }
.bt-attach--file .bt-attach__x {
  top: 50%;
  background: transparent;
  color: var(--bt-text-secondary);
  transform: translateY(-50%);
}
.bt-attach--file .bt-attach__x:hover { background: var(--bt-danger-soft); color: var(--bt-danger-text); }

/* Full-size viewer for an attached image, over the page rather than a new tab
   so the conversation is still there when it closes. */
.bt-lightbox {
  position: fixed;
  z-index: 90;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 16px;
  background: rgba(0, 6, 8, 0.88);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--bt-duration-sm) var(--bt-ease);
}
.bt-lightbox.is-open { opacity: 1; pointer-events: auto; }
.bt-lightbox__bar {
  display: flex;
  width: 100%;
  max-width: 900px;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}
.bt-lightbox__name {
  min-width: 0;
  flex: 1 1 auto;
  color: var(--bt-text-secondary);
  font-size: 13px;
}
.bt-lightbox__count {
  flex: 0 0 auto;
  color: var(--bt-text-disabled);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
/* The stage carries the arrows either side of whatever is being shown, so a
   message's attachments can be walked through without closing the viewer. */
.bt-lightbox__stage {
  position: relative;
  display: flex;
  width: 100%;
  min-height: 0;
  max-width: 900px;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
}
.bt-lightbox__img {
  max-width: 100%;
  /* Leaves room for the bar above it whatever the window height. */
  max-height: calc(100vh - 96px);
  border-radius: var(--bt-radius-cell);
  object-fit: contain;
}
/* Not every attachment is a picture. A file gets a card in the same slot so
   the sequence doesn't break where a PDF happens to sit. */
.bt-lightbox__file {
  display: flex;
  max-width: min(360px, 100%);
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 28px 32px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface);
  text-align: center;
}
.bt-lightbox__file-name {
  max-width: 100%;
  font-size: 14px;
  font-weight: 600;
  overflow-wrap: anywhere;
}
.bt-lightbox__file-size { color: var(--bt-text-disabled); font-size: 12px; }
.bt-lightbox__nav {
  position: absolute;
  top: 50%;
  display: grid;
  width: 40px;
  height: 40px;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.45);
  color: var(--bt-text-primary);
  cursor: pointer;
  transform: translateY(-50%);
  transition: background var(--bt-duration-sm) var(--bt-ease);
}
.bt-lightbox__nav:hover { background: rgba(0, 0, 0, 0.7); }
.bt-lightbox__nav[hidden] { display: none; }
.bt-lightbox__nav--prev { left: -4px; }
.bt-lightbox__nav--next { right: -4px; }
@media (min-width: 1000px) {
  .bt-lightbox__nav--prev { left: -52px; }
  .bt-lightbox__nav--next { right: -52px; }
}
.bt-attach-file {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 220px;
  padding: 8px 12px;
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
  color: var(--bt-text-primary);
  font-size: 12px;
  font-weight: 500;
  text-decoration: none;
}
.bt-attach-file:hover { background: var(--bt-surface-interactive); }
.bt-attach-file__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bt-attach-file__size { flex: 0 0 auto; color: var(--bt-text-disabled); }

/* Composer pinned under the thread. */
.bt-composer {
  flex: 0 0 auto;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--bt-line);
  background: var(--bt-surface);
}
.bt-composer__staging { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.bt-stage {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 180px;
  padding: 6px 26px 6px 10px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface-nested);
  font-size: 12px;
}
.bt-stage img { width: 22px; height: 22px; border-radius: 5px; object-fit: cover; }
.bt-stage__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bt-stage__x {
  position: absolute;
  right: 4px;
  display: grid;
  width: 18px;
  height: 18px;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--bt-text-secondary);
  cursor: pointer;
}
.bt-stage__x:hover { background: var(--bt-surface-interactive); color: var(--bt-text-primary); }

.bt-composer__to {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
  font-size: 12px;
  color: var(--bt-text-secondary);
}
/* Text first, tools underneath. Sharing one row with four buttons cost the
   textarea ~150px of its width and wrapped ordinary sentences after a handful
   of words; stacking gives every line the full pane. */
.bt-composer__field {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 2px;
  padding: 8px 8px 6px;
  border: 1px solid transparent;
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface-field);
}
.bt-composer__field:focus-within { border-color: var(--bt-accent); }
.bt-composer__input {
  width: 100%;
  min-width: 0;
  min-height: 20px;
  max-height: 160px;
  overflow-x: hidden;
  overflow-y: hidden;
  padding: 2px 4px;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--bt-text-primary);
  font: inherit;
  font-size: 14px;
  line-height: 20px;
  resize: none;
}
.bt-composer__tools { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }
.bt-composer__tool {
  display: grid;
  width: 34px;
  height: 34px;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--bt-text-secondary);
  cursor: pointer;
  transition: background var(--bt-duration-sm) var(--bt-ease), color var(--bt-duration-sm) var(--bt-ease);
}
.bt-composer__tool:hover { background: var(--bt-surface-interactive); color: var(--bt-text-primary); }
.bt-composer__tool.is-active { color: var(--bt-accent-text); }
/* Send sits at the end of the tool row and reads as one of them until there is
   something to send — an empty composer shouldn't advertise a filled button
   that does nothing. The moment there's text or an attachment it takes the
   accent and becomes the obvious next move. */
.bt-composer__send {
  display: grid;
  width: 34px;
  height: 34px;
  margin-left: auto;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--bt-text-disabled);
  cursor: default;
  transition: background var(--bt-duration-sm) var(--bt-ease), color var(--bt-duration-sm) var(--bt-ease);
}
.bt-composer__send:not(:disabled) {
  background: var(--bt-accent);
  color: var(--bt-ink);
  cursor: pointer;
}
.bt-composer__send:not(:disabled):hover { filter: brightness(1.08); }

/* Emoji picker popover, anchored above the composer. */
/* Anchored to the composer field it sits inside, so it always opens directly
   above the box however tall the textarea has grown. */
.bt-emoji-pop {
  position: absolute;
  z-index: 20;
  right: 0;
  bottom: calc(100% + 8px);
  display: none;
  grid-template-columns: repeat(8, 1fr);
  gap: 2px;
  width: 296px;
  max-height: 200px;
  overflow-y: auto;
  padding: 8px;
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
}
.bt-emoji-pop.is-open { display: grid; }
.bt-emoji-pop button {
  height: 32px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  background: transparent;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.bt-emoji-pop button:hover { background: var(--bt-surface-interactive); }

/* An assign-comment mini menu reuses the sheet options at the bottom. */
.bt-conv__empty {
  display: flex;
  max-width: 240px;
  margin: auto;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 24px 12px;
  text-align: center;
}
.bt-conv__empty-icon {
  display: grid;
  width: 48px;
  height: 48px;
  margin-bottom: 8px;
  place-items: center;
  border: 1px solid rgba(31, 194, 207, 0.22);
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 24%, rgba(31, 194, 207, 0.2), transparent 58%),
    var(--bt-accent-soft);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.2), var(--bt-shadow-inset);
  color: var(--bt-accent-text);
}
.bt-conv__empty-icon .bt-icon { width: 22px; height: 22px; }
.bt-conv__empty-title {
  color: var(--bt-text-primary);
  font-size: 13px;
  font-weight: 600;
  line-height: 18px;
}
.bt-conv__empty-copy {
  color: var(--bt-text-secondary);
  font-size: 12px;
  line-height: 17px;
}

/* ---------------------------------------------------------------- notifications */
.bt-bell {
  position: relative;
  display: grid;
  width: var(--bt-control-md);
  height: var(--bt-control-md);
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--bt-text-secondary);
  cursor: pointer;
  transition: background var(--bt-duration-sm) var(--bt-ease), color var(--bt-duration-sm) var(--bt-ease);
}
.bt-bell:hover { background: var(--bt-surface); color: var(--bt-text-primary); }
.bt-bell__badge {
  position: absolute;
  top: 6px;
  right: 6px;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-danger);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 17px;
  text-align: center;
}

.bt-notif-pop {
  position: absolute;
  z-index: 70;
  top: calc(var(--bt-topbar-height) - 6px);
  right: 12px;
  width: 380px;
  max-width: calc(100vw - 24px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  color: var(--bt-text-primary);
  font-family: var(--bt-font-interface);
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity var(--bt-duration-sm) var(--bt-ease), transform var(--bt-duration-sm) var(--bt-ease);
}
.bt-notif-pop.is-open { opacity: 1; transform: none; pointer-events: auto; }
.bt-notif-pop__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--bt-line);
}
.bt-notif-pop__body { max-height: min(70vh, 460px); overflow-y: auto; padding: 6px; }
.bt-notif {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 10px;
  width: 100%;
  min-height: 38px;
  padding: 10px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  outline: 0;
  background: transparent;
  color: inherit;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.bt-notif:hover,
.bt-notif:focus-visible { background: var(--bt-surface-interactive); }
.bt-notif__dot {
  width: 8px;
  height: 8px;
  margin-top: 6px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--bt-accent);
}
.bt-notif.is-read .bt-notif__dot { background: transparent; box-shadow: inset 0 0 0 1.5px var(--bt-neutral); }
.bt-notif__title { font-size: 13px; font-weight: 600; line-height: 18px; overflow-wrap: anywhere; }
.bt-notif.is-read .bt-notif__title { font-weight: 500; color: var(--bt-text-secondary); }
.bt-notif__body { color: var(--bt-text-secondary); font-size: 12px; line-height: 17px; overflow-wrap: anywhere; }
.bt-notif__time { margin-top: 2px; color: var(--bt-text-disabled); font-size: 11px; }
.bt-notif-pop__empty { padding: 30px 16px; color: var(--bt-text-secondary); font-size: 13px; text-align: center; }

/* ---------------------------------------------------------------- profile menu */
.bt-menu-pop {
  position: absolute;
  z-index: 70;
  top: calc(var(--bt-topbar-height) - 6px);
  right: 12px;
  width: 260px;
  max-width: calc(100vw - 24px);
  padding: 6px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  color: var(--bt-text-primary);
  font-family: var(--bt-font-interface);
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity var(--bt-duration-sm) var(--bt-ease), transform var(--bt-duration-sm) var(--bt-ease);
}
.bt-menu-pop.is-open { opacity: 1; transform: none; pointer-events: auto; }

.bt-menu-pop__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 10px 12px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--bt-line);
}
.bt-menu-pop__name { font-size: 14px; font-weight: 600; line-height: 18px; }
.bt-menu-pop__role { color: var(--bt-text-secondary); font-size: 12px; line-height: 16px; }

.bt-menu-item {
  display: flex;
  width: 100%;
  min-height: 38px;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  outline: 0;
  background: transparent;
  color: var(--bt-text-primary);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  transition: background var(--bt-duration-sm) var(--bt-ease);
}
.bt-menu-item:hover,
.bt-menu-item:focus-visible { background: var(--bt-surface-interactive); }
.bt-menu-item .bt-icon { color: var(--bt-text-secondary); }
.bt-menu-item--danger { color: var(--bt-danger-text); }
.bt-menu-item--danger .bt-icon { color: currentColor; }
.bt-menu-item__count {
  margin-left: auto;
  color: var(--bt-text-disabled);
  font-size: 12px;
  font-weight: 600;
}
.bt-menu-sep { height: 1px; margin: 4px 0; background: var(--bt-line); }

/* ---------------------------------------------------------------- trash */
.bt-trash-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 12px 8px;
}
.bt-trash-row + .bt-trash-row { box-shadow: 0 -1px 0 var(--bt-line); }
.bt-trash-row__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.bt-trash-row__meta { color: var(--bt-text-secondary); font-size: 12px; line-height: 18px; }
.bt-trash-row--selectable {
  grid-template-columns: auto minmax(0, 1fr);
  border-radius: var(--bt-radius-cell);
  cursor: pointer;
  transition: background-color var(--bt-duration-sm) var(--bt-ease);
}
.bt-trash-row--selectable:hover,
.bt-trash-row--selectable:focus-visible { background: var(--bt-surface-nested); }
.bt-trash-row--selectable:focus-visible { outline: 2px solid var(--bt-accent); outline-offset: -2px; }
.bt-trash-row--selectable.is-selected { background: var(--bt-accent-soft); }

/* ---------------------------------------------------------------- checklist item notes */
/* The saved note, shown under the item it belongs to. */
.bt-item-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 8px;
  padding: 8px 10px;
  border-left: 2px solid var(--bt-accent);
  border-radius: 0 var(--bt-radius-sm) var(--bt-radius-sm) 0;
  background: var(--bt-surface-nested);
  color: var(--bt-text-secondary);
  font-size: 12.5px;
  line-height: 18px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.bt-item-note .bt-icon { margin-top: 1px; flex: 0 0 auto; color: var(--bt-accent-text); }

/* ---------------------------------------------------------------- form jobs */
/* Fields stack down the middle pane, each with room to type. */
.bt-form-field + .bt-form-field { margin-top: 4px; }
.bt-form-field textarea.bt-input { min-height: 76px; resize: vertical; }

/* A recorded answer, shown read-only in Admin. */
.bt-answer {
  margin-top: 4px;
  color: var(--bt-text-primary);
  font-size: 13.5px;
  line-height: 20px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.bt-answer--empty { color: var(--bt-text-disabled); font-style: italic; }

/* An explanation that only matters once, parked next to the heading it
   explains. Focusable so the tooltip is reachable without a pointer. */
.bt-info-dot {
  display: grid;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  place-items: center;
  border-radius: 50%;
  color: var(--bt-text-disabled);
  transition: background var(--bt-duration-sm) var(--bt-ease), color var(--bt-duration-sm) var(--bt-ease);
}
.bt-info-dot:hover,
.bt-info-dot:focus-visible { background: var(--bt-surface-interactive); color: var(--bt-text-primary); }

/* Tooltips on this one wrap: it's a sentence, not a label. */
.bt-tooltip--wrap::after { white-space: normal; width: max-content; max-width: 260px; }

/* Templates are grouped by shape in the library. */
.bt-typegroup + .bt-typegroup { margin-top: 18px; }
.bt-typegroup__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px 8px;
  color: var(--bt-text-secondary);
}
.bt-typegroup__count {
  padding: 1px 7px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface-interactive);
  font-size: 11px;
  font-weight: 600;
}

/* ---------------------------------------------------------------- job type editor */
/* Sections and items are edited in place, so each row is a little form: the
   number, the inputs, and the move/remove controls. */
.bt-te-section {
  margin-bottom: 14px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
}
.bt-te-section:last-child { margin-bottom: 0; }
.bt-te-section__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--bt-line);
}
.bt-te-section__head .bt-input-shell { flex: 1 1 auto; min-width: 0; }
.bt-te-section__body { padding: 10px 12px 12px; }

.bt-te-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 0;
}
.bt-te-item + .bt-te-item { box-shadow: 0 -1px 0 var(--bt-line); }
.bt-te-item__n {
  min-width: 22px;
  padding-top: 10px;
  color: var(--bt-text-secondary);
  font-size: 12px;
  font-weight: 600;
  text-align: right;
}
.bt-te-item__fields {
  display: flex;
  min-width: 0;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 6px;
}
.bt-te-item__row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.bt-te-item__row .bt-select { flex: 0 1 180px; }
.bt-te-item__controls { display: flex; align-items: center; gap: 2px; padding-top: 4px; }
.bt-te-required { display: flex; align-items: center; gap: 8px; }

/* Picking the shape of a new job type: two big, obviously-exclusive choices. */
.bt-kindpick { display: flex; flex-direction: column; gap: 8px; }
.bt-kindpick__opt {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px;
  border: 1.5px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
  background: transparent;
  color: inherit;
  text-align: left;
  transition: border-color var(--bt-duration-sm) var(--bt-ease), background var(--bt-duration-sm) var(--bt-ease);
}
.bt-kindpick__opt:hover { background: var(--bt-surface-nested); }
.bt-kindpick__opt.is-selected { border-color: var(--bt-accent); background: var(--bt-accent-soft); }
.bt-kindpick__opt .bt-icon { margin-top: 2px; flex: 0 0 auto; color: var(--bt-text-secondary); }
.bt-kindpick__opt.is-selected .bt-icon { color: var(--bt-accent-text); }
.bt-kindpick__copy { display: flex; min-width: 0; flex-direction: column; }

@media (max-width: 760px) {
  .bt-te-item { flex-wrap: wrap; }
  .bt-te-item__controls { padding-top: 0; margin-left: auto; }
}

/* ---------------------------------------------------------------- settings: personalization + notification prefs */
.bt-background-picker {
  min-width: 0;
  padding: 0;
  border: 0;
  margin: 0;
}

.bt-background-picker > .bt-label { margin-bottom: 8px; }

.bt-background-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.bt-background-option {
  position: relative;
  display: block;
  min-width: 0;
}

.bt-background-option > input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.bt-background-option__card {
  display: flex;
  overflow: hidden;
  min-width: 0;
  flex-direction: column;
  gap: 8px;
  padding: 7px 7px 9px;
  border: 1.5px solid var(--bt-line);
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface-nested);
  transition:
    border-color var(--bt-duration-sm) var(--bt-ease),
    background var(--bt-duration-sm) var(--bt-ease),
    transform var(--bt-duration-sm) var(--bt-ease);
}

.bt-background-option:hover .bt-background-option__card {
  border-color: rgba(255, 255, 255, 0.2);
  background: var(--bt-surface);
  transform: translateY(-1px);
}

.bt-background-option > input:checked + .bt-background-option__card {
  border-color: var(--bt-accent);
  background: var(--bt-accent-soft);
  box-shadow: 0 0 0 1px rgba(24, 191, 204, 0.12);
}

.bt-background-option > input:focus-visible + .bt-background-option__card {
  outline: 2px solid var(--bt-accent);
  outline-offset: 2px;
}

.bt-background-option__preview {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  border-radius: var(--bt-radius-cell);
  background-color: #000;
  background-position: center;
  background-size: cover;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08) inset;
}

.bt-background-option__preview:not(.bt-background-option__preview--black)::after {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.58);
  content: "";
}

.bt-background-option__preview--black {
  background: #000;
}

.bt-background-option__preview--aurora {
  background-image: url("portal-bg-aurora.jpg");
}

.bt-background-option__preview--prism {
  background-image: url("portal-bg-prism.jpg");
}

.bt-background-option__preview--amber {
  background-image: url("portal-bg-amber.jpg");
}

.bt-background-option__name {
  overflow: hidden;
  padding: 0 3px;
  font-size: 13px;
  font-weight: 600;
  line-height: 18px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bt-background-brightness {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 18px;
  transition: opacity var(--bt-duration-sm) var(--bt-ease);
}

.bt-background-brightness__value {
  color: var(--bt-accent-text);
  font-size: 12px;
  font-weight: 600;
}

.bt-range {
  width: 100%;
  height: 6px;
  padding: 0;
  border: 0;
  border-radius: var(--bt-radius-round);
  appearance: none;
  -webkit-appearance: none;
  background:
    linear-gradient(
      to right,
      var(--bt-accent) 0,
      var(--bt-accent) var(--bt-range-fill, 50%),
      rgba(255, 255, 255, 0.14) var(--bt-range-fill, 50%),
      rgba(255, 255, 255, 0.14) 100%
    );
  cursor: pointer;
}

.bt-range::-webkit-slider-thumb {
  width: 18px;
  height: 18px;
  border: 3px solid var(--bt-accent);
  border-radius: 50%;
  appearance: none;
  -webkit-appearance: none;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}

.bt-range::-moz-range-thumb {
  width: 12px;
  height: 12px;
  border: 3px solid var(--bt-accent);
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}

.bt-range:disabled {
  cursor: not-allowed;
  opacity: 0.38;
}

.bt-range-labels {
  display: flex;
  justify-content: space-between;
  color: var(--bt-text-disabled);
  font-size: 11px;
  line-height: 14px;
}

.bt-panel.is-solid .bt-background-brightness {
  opacity: 0.58;
}


/* ---------------------------------------------------------------- bulk select */
/* A selectable row is the ordinary row with a checkbox track in front: the
   columns read identically, they just shift right by the width of the box.
   The track itself is part of --job-cols (see renderJobHead), so this must not
   redeclare grid-template-columns or the row would fall out of the table. */
.bt-job-select {
  display: grid;
  place-items: center;
  align-self: center;
}
.bt-check {
  position: relative;
  display: inline-grid;
  width: 20px;
  height: 20px;
  place-items: center;
  cursor: pointer;
}
.bt-check input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.bt-check__box {
  width: 20px;
  height: 20px;
  border: 1.8px solid var(--bt-neutral);
  border-radius: 6px;
  transition: background var(--bt-duration-sm) var(--bt-ease), border-color var(--bt-duration-sm) var(--bt-ease);
}
.bt-check input:checked + .bt-check__box,
.bt-tick input:checked + .bt-check__box {
  border-color: var(--bt-accent);
  background: var(--bt-accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23001318' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / 14px no-repeat;
}
/* Half-ticked: some of what this box governs is selected, not all of it. Left
   unstyled it is pixel-for-pixel the empty state, and a master box that reports
   "nothing selected" while three rows are is worse than having no master box.
   Declared after :checked so a box that is somehow both shows the dash. */
.bt-check input:indeterminate + .bt-check__box {
  border-color: var(--bt-accent);
  background: var(--bt-accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23001318' stroke-width='3.4' stroke-linecap='round'%3E%3Cpath d='M6 12h12'/%3E%3C/svg%3E") center / 14px no-repeat;
}
.bt-check input:focus-visible + .bt-check__box { outline: 2px solid var(--bt-accent); outline-offset: 2px; }

/* Rows in selection mode reveal their checkbox; the whole board dims the swipe. */
.bt-joblist.is-selecting .bt-job-row { cursor: default; }

/* Floating action bar for the current selection. */
.bt-bulkbar {
  position: fixed;
  z-index: 55;
  left: 50%;
  bottom: 24px;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: calc(100vw - 32px);
  padding: 8px 8px 8px 16px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-inset), var(--bt-shadow-popover);
  /* Parked well clear of the bottom edge — a percentage of its own height left
     the top few pixels (and their inset highlight) peeking above the fold, and
     visibility keeps it out of the way for good once the slide has finished. */
  transform: translate(-50%, calc(100% + 40px));
  visibility: hidden;
  transition: transform var(--bt-duration-md) var(--bt-ease),
              visibility 0s linear var(--bt-duration-md);
}
.bt-bulkbar.is-open {
  transform: translate(-50%, 0);
  visibility: visible;
  transition: transform var(--bt-duration-md) var(--bt-ease);
}
.bt-bulkbar__count { font-size: 14px; font-weight: 600; white-space: nowrap; }
.bt-bulkbar__actions { display: flex; align-items: center; gap: 6px; }
.bt-bulkbar__sep { width: 1px; height: 24px; background: var(--bt-line); }

/* ---------------------------------------------------------------- job notes */
/* Notes are usually a sentence and occasionally an essay, and the info pane is
   ~300px wide. So the pane shows the opening two lines and a button; the whole
   thing is read and written in the dialog, where there's room for it. */
.bt-notes-block { display: flex; flex-direction: column; gap: 8px; }
/* The clamp sits on an inner element, not on this one: `overflow: hidden`
   clips at the padding edge, so a padded box lets the third line bleed into
   the bottom padding instead of being cut off. The padding lives out here and
   the clipping happens in there, flush against the text. */
.bt-notes-preview {
  padding: 8px 10px;
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
  color: var(--bt-text-secondary);
  font-size: 14px;
  line-height: 20px;
}
.bt-notes-preview__text {
  display: -webkit-box;
  overflow: hidden;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}
.bt-notes-actions { display: flex; align-items: center; gap: 8px; }
.bt-notes-actions .bt-notes-open { flex: 1 1 auto; }
/* The dialog's own copy of the note, when it's being read rather than edited. */
.bt-notes-full {
  max-height: 46vh;
  overflow-y: auto;
  font-size: 14px;
  line-height: 21px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.bt-sheet__note textarea.bt-input.bt-notes-input { min-height: 180px; }

/* ---------------------------------------------------------------- map */
/* Tiles are positioned absolutely inside a clipped box (see map.js). Nothing
   here assumes a library — the classes are all ours. */
.btmap {
  position: relative;
  overflow: hidden;
  height: 300px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
  background: #0d1416;
}
/* Google's Map draws into this div itself, so it just needs to fill the
   shell — no tile/pin drawing of our own any more. */
.btmap__canvas { position: absolute; inset: 0; }
.btmap__status {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(280px, 84%);
  padding: 10px 12px;
  border-radius: var(--bt-radius-cell);
  background: rgba(0, 0, 0, 0.8);
  color: var(--bt-text-secondary);
  font-size: 12px;
  line-height: 17px;
  text-align: center;
  transform: translate(-50%, -50%);
  z-index: 1;
}
.btmap__traffic-legend {
  position: absolute;
  top: 10px;
  left: 10px;
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 5px 8px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--bt-radius-round);
  background: rgba(9, 30, 35, 0.86);
  color: #fff;
  font-size: 10px;
  line-height: 14px;
  pointer-events: none;
  z-index: 1;
}
.btmap__traffic-legend span { display: inline-flex; gap: 4px; align-items: center; }
.btmap__traffic-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; }
.btmap__traffic-dot--normal { background: #18bfcc; }
.btmap__traffic-dot--slow { background: #f5a623; }
.btmap__traffic-dot--jam { background: #e25555; }
.btmap--tall { height: 460px; }
.btmap--flat { border-radius: 0; border-width: 0; }

/* A client's logo. Letterboxed, never cropped — a logo cropped to a circle
   stops being the logo. */
.bt-logo {
  display: grid;
  overflow: hidden;
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  place-items: center;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
  color: var(--bt-text-secondary);
  font-size: 13px;
  font-weight: 700;
}
.bt-logo img { max-width: 100%; max-height: 100%; object-fit: contain; }
.bt-logo--64 { width: 64px; height: 64px; font-size: 18px; }
.bt-logo--24 { width: 24px; height: 24px; border-radius: 6px; font-size: 10px; }
/* Logo beside the name, labels on one line, boxes starting together. */
.bt-idrow { display: flex; align-items: flex-start; gap: 14px; }
/* The camera badge sits on the tile, the way the profile photo editor does —
   so the control is on the thing it changes rather than in a button row. */
.bt-logo-edit { position: relative; flex: 0 0 auto; }
.bt-logo-edit__btn,
.bt-logo-edit__x {
  position: absolute;
  display: grid;
  width: 26px;
  height: 26px;
  place-items: center;
  border: 3px solid var(--bt-surface-popover);
  border-radius: 50%;
  cursor: pointer;
}
.bt-logo-edit__btn {
  right: -8px;
  bottom: -8px;
  background: var(--bt-accent);
  color: var(--bt-ink);
}
.bt-logo-edit__x {
  right: -8px;
  top: -8px;
  background: var(--bt-danger-soft);
  color: var(--bt-danger-text);
}
.bt-logo-edit__btn .bt-icon { width: 13px; height: 13px; }
.bt-logo-edit__btn:hover { filter: brightness(1.08); }
.bt-logo-edit__x:hover { background: var(--bt-danger); color: #fff; }

/* ---------------------------------------------------------------- dispatch schedule */
.bt-onsite-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.bt-onsite-layout {
  display: grid;
  grid-template-columns: minmax(300px, 0.85fr) minmax(360px, 1.15fr);
  align-items: start;
  gap: 16px;
}
.bt-onsite-list {
  display: flex;
  min-width: 0;
  max-height: 650px;
  flex-direction: column;
  gap: 4px;
  overflow-y: auto;
}
.bt-onsite-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 72px;
  padding: 8px;
  border: 1px solid transparent;
  border-radius: var(--bt-radius-cell);
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.bt-onsite-row:hover { background: var(--bt-surface-nested); }
.bt-onsite-row.is-active {
  border-color: var(--bt-line-strong);
  background: var(--bt-surface-nested);
}
.bt-onsite-row:focus-visible { outline: 2px solid var(--bt-accent); outline-offset: 1px; }
.bt-onsite-row__body { display: flex; min-width: 0; flex-direction: column; gap: 2px; }
.bt-onsite-date {
  display: grid;
  width: 46px;
  height: 50px;
  flex: 0 0 auto;
  place-content: center;
  border-radius: 12px;
  background: var(--bt-surface-field);
  text-align: center;
}
.bt-onsite-date small {
  color: var(--bt-text-secondary);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 13px;
  text-transform: uppercase;
}
.bt-onsite-date b { font-size: 19px; line-height: 22px; }
.bt-onsite-avatars { display: flex; align-items: center; padding-left: 6px; }
.bt-onsite-avatars > * { position: relative; margin-left: -7px; }
.bt-onsite-avatars > :first-child { z-index: 2; margin-left: 0; }
.bt-onsite-avatars .bt-avatar { box-shadow: 0 0 0 2px var(--bt-surface); }
.bt-onsite-row:hover .bt-onsite-avatars .bt-avatar,
.bt-onsite-row.is-active .bt-onsite-avatars .bt-avatar { box-shadow: 0 0 0 2px var(--bt-surface-nested); }
.bt-onsite-avatar-more { background: var(--bt-surface-interactive); color: var(--bt-text-secondary); font-size: 10px; }

.bt-onsite-preview {
  position: sticky;
  top: calc(var(--bt-topbar-height) + 16px);
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface-nested);
}
.bt-onsite-preview[hidden] { display: none; }
.bt-onsite-preview__head { display: flex; min-width: 0; align-items: center; gap: 12px; }
.bt-onsite-preview__meta { display: flex; flex-direction: column; gap: 7px; color: var(--bt-text-secondary); font-size: 13px; }
.bt-onsite-preview__meta > span { display: flex; min-width: 0; align-items: flex-start; gap: 8px; }
.bt-onsite-preview__meta .bt-icon { flex: 0 0 auto; margin-top: 1px; }
.bt-onsite-preview__people { display: flex; flex-wrap: wrap; gap: 8px; }
.bt-onsite-preview__people > .bt-overline { width: 100%; }
.bt-onsite-person-chip {
  display: inline-flex;
  min-width: 0;
  align-items: center;
  gap: 7px;
  padding: 5px 8px 5px 5px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface-field);
}
.bt-onsite-person-chip strong,
.bt-onsite-person-chip small { display: block; line-height: 15px; }
.bt-onsite-person-chip strong { font-size: 12px; }
.bt-onsite-person-chip small { color: var(--bt-text-secondary); font-size: 10px; }
.bt-onsite-preview__actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
.btmap--onsite { height: 250px; }
.btmap--editor { height: 260px; }

.bt-sheet.bt-onsite-editor {
  max-width: min(960px, calc(100vw - 32px));
  max-height: min(90vh, 880px);
  overflow-y: auto;
}
.bt-onsite-editor-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
  padding: 4px 10px 10px;
}
.bt-onsite-editor-form > * { min-width: 0; }
.bt-onsite-editor__column {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 12px;
}
.bt-onsite-editor__actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.bt-onsite-editor__actions .bt-sheet__cancel { width: 100%; margin-top: 0; }
@media (min-width: 760px) {
  .bt-onsite-editor-form {
    grid-template-areas:
      "error error"
      "left right"
      "actions actions";
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
    gap: 14px 18px;
  }
  .bt-onsite-editor__error { grid-area: error; }
  .bt-onsite-editor__column--left { grid-area: left; }
  .bt-onsite-editor__column--right { grid-area: right; }
  .bt-onsite-editor__actions { grid-area: actions; }
  .bt-onsite-editor__column { gap: 14px; }
}
.bt-onsite-people-control { gap: 6px; }
.bt-onsite-people-control .bt-picker__list {
  max-height: 216px;
  overscroll-behavior: contain;
}
.bt-onsite-client-card {
  display: flex;
  min-height: 56px;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  padding: 8px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
}
@media (max-width: 900px) {
  .bt-onsite-layout { grid-template-columns: minmax(0, 1fr); }
  .bt-onsite-list { max-height: none; }
  .bt-onsite-preview { position: static; }
}
@media (max-width: 560px) {
  .bt-onsite-row { grid-template-columns: auto minmax(0, 1fr) auto; }
  .bt-onsite-row > .bt-onsite-avatars { grid-column: 2; justify-self: start; padding-left: 0; }
  .bt-onsite-row > .bt-row-chevron { grid-column: 3; grid-row: 1 / span 2; }
  .bt-onsite-preview__actions > * { flex: 1 1 auto; justify-content: center; }
}


/* ---------------------------------------------------------------- inventory */
/* Type rail beside the grid, the way the app this replaces works: the list of
   what's in here doubles as the filter. */
.bt-invgrid { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 18px; }
.bt-invgrid__rail { display: flex; flex-direction: column; gap: 2px; }
.bt-invgrid__rail[hidden] { display: none; }
.bt-invgrid__main { min-width: 0; }
.bt-invtype {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  background: transparent;
  color: var(--bt-text-secondary);
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}
.bt-invtype:hover { background: var(--bt-surface-nested); color: var(--bt-text-primary); }
.bt-invtype.is-active { background: var(--bt-accent-soft); color: var(--bt-accent-text); font-weight: 600; }
.bt-invtype__n { margin-left: auto; flex: 0 0 auto; font-variant-numeric: tabular-nums; }
@media (max-width: 860px) {
  /* No room for a rail — it becomes a scrolling row of chips above the grid. */
  .bt-invgrid { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .bt-invgrid__rail { flex-direction: row; overflow-x: auto; padding-bottom: 4px; }
  .bt-invgrid__rail .bt-overline { display: none; }
  .bt-invtype { width: auto; flex: 0 0 auto; border-radius: var(--bt-radius-round); }
}

/* A record's photos and paperwork. Thumbnails open the same viewer the job
   conversations use, so there is one way to look at a picture in this app. */
.bt-gallery { display: flex; flex-wrap: wrap; gap: 8px; }
.bt-gallery:empty { display: none; }
.bt-gallery__item { position: relative; display: inline-flex; }
.bt-gallery__open {
  display: block;
  overflow: hidden;
  width: 84px;
  height: 84px;
  padding: 0;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
  cursor: pointer;
  line-height: 0;
}
.bt-gallery__open:hover { border-color: var(--bt-accent); }
.bt-gallery__open img { width: 100%; height: 100%; object-fit: cover; }
/* Anything that isn't a picture still needs to be a tile, so the row of files
   reads as one set rather than pictures plus a list. */
.bt-gallery__doc {
  display: flex;
  width: 100%;
  height: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 6px;
  color: var(--bt-text-secondary);
  font-size: 10px;
  line-height: 13px;
}
.bt-gallery__doc .bt-truncate { max-width: 100%; }
.bt-gallery__x {
  position: absolute;
  top: -6px;
  right: -6px;
  display: grid;
  width: 22px;
  height: 22px;
  place-items: center;
  border: 2px solid var(--bt-surface-popover);
  border-radius: 50%;
  background: var(--bt-danger-soft);
  color: var(--bt-danger-text);
  cursor: pointer;
}
.bt-gallery__x:hover { background: var(--bt-danger); color: #fff; }

/* ---------------------------------------------------------------- timesheet */
/* The week as a table. Narrow screens scroll it sideways rather than reflowing
   into cards: a timesheet is read by scanning a column, and columns are the
   one thing cards throw away. */
.bt-timesheet-export__user {
  width: 160px;
  min-height: var(--bt-control-xs);
  padding-inline: 10px 30px;
  border-radius: var(--bt-radius-round);
  background-position: right 9px center;
  font-size: 12px;
}
@media (max-width: 620px) {
  .bt-timesheet-export__user { width: 100%; flex: 1 1 160px; }
}
/* Named apart from .bt-sheet — that's the bottom-sheet dialog, and a table
   sharing its class inherits a 400px cap, a popover background and a scroll
   box. */
.bt-tsheet-scroll { overflow-x: auto; }
.bt-tsheet {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  white-space: nowrap;
}
.bt-tsheet thead th {
  padding: 0 10px 8px;
  border-bottom: 1px solid var(--bt-line);
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-align: left;
  text-transform: uppercase;
}
.bt-tsheet__num { text-align: right; font-variant-numeric: tabular-nums; }
/* `.bt-tsheet thead th` outranks a bare class, so a numeric header would keep
   the left alignment while its column of numbers sat right — the heading has
   to travel with its column. */
.bt-tsheet thead th.bt-tsheet__num { text-align: right; }

/* Two report tables with identical columns should line up with each other.
   Auto table layout sizes every table independently from its own content, so
   "By person" and "By client" ended up with different column widths — fixed
   layout gives them one set of widths to agree on. The min-width keeps the
   number columns readable on a narrow screen; the scroller handles the rest. */
.bt-tsheet--report { table-layout: fixed; min-width: 620px; }
.bt-tsheet--report th:not(:first-child),
.bt-tsheet--report td:not(:first-child) { width: 104px; }
/* Fixed layout means a long name has to be told what to do instead of pushing
   its column wider. */
.bt-tsheet--report td:first-child > span {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The day band. Every day of the week gets one, worked or not. */
.bt-tsheet__day th {
  padding: 14px 10px 6px;
  color: var(--bt-text-primary);
  font-size: 12px;
  font-weight: 600;
  text-align: left;
}
.bt-tsheet__day.is-today th { color: var(--bt-accent-text); }
.bt-tsheet__dayname { font-weight: 700; }
.bt-tsheet__daydate { color: var(--bt-text-secondary); font-weight: 500; }
.bt-tsheet__none { margin-left: 10px; color: var(--bt-text-disabled); font-weight: 500; }
.bt-tsheet__row td {
  padding: 8px 10px;
  border-top: 1px solid var(--bt-line);
  vertical-align: top;
}
/* A row that opens something says so: the pointer, a lift in the background,
   and an accent edge down the left so it reads as "this one" rather than just
   a colour change you might not notice. Covers both grids — the timesheet's
   entries and the inventory's assets and stock. */
.bt-tsheet__row[data-entry],
.bt-tsheet__row[data-rec] { cursor: pointer; }
.bt-tsheet__row[data-entry] td:first-child,
.bt-tsheet__row[data-rec] td:first-child {
  border-radius: var(--bt-radius-cell) 0 0 var(--bt-radius-cell);
}
.bt-tsheet__row[data-entry] td:last-child,
.bt-tsheet__row[data-rec] td:last-child {
  border-radius: 0 var(--bt-radius-cell) var(--bt-radius-cell) 0;
}
.bt-tsheet__row[data-entry]:hover td,
.bt-tsheet__row[data-rec]:hover td { background: var(--bt-surface-nested); }
.bt-tsheet__row[data-entry]:hover td:first-child,
.bt-tsheet__row[data-rec]:hover td:first-child { box-shadow: inset 2px 0 0 var(--bt-accent); }
.bt-tsheet__clients { display: block; font-weight: 600; }
.bt-tsheet__summary {
  display: block;
  max-width: 320px;
  margin-top: 2px;
  color: var(--bt-text-secondary);
  font-size: 12px;
}
.bt-tsheet__files {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  color: var(--bt-text-secondary);
  font-size: 12px;
}
/* The file chip and the Used/Available badge are two separate inline-flex
   boxes of different heights — left to the table cell's own baseline
   alignment, the shorter one drifts off-line from the other. One flex row
   keeps them level regardless. */
.bt-invrow-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.bt-tsheet tfoot td {
  padding: 12px 10px 4px;
  border-top: 2px solid var(--bt-line);
  font-weight: 700;
}

/* The entry dialog: label left, field right, like the form it replaces. */
.bt-sheet--wide { max-width: 620px; }
.bt-entryform {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  gap: 12px 16px;
  align-items: start;
  padding: 4px 10px 8px;
}
.bt-entryform__label {
  padding-top: 8px;
  color: var(--bt-text-secondary);
  font-size: 13px;
  font-weight: 600;
  text-align: right;
}
.bt-entryform__label--req::after { content: " *"; color: var(--bt-danger-text); }
.bt-entryform__short { max-width: 140px; }
.bt-entryform__total {
  padding-top: 8px;
  font-size: 14px;
  font-weight: 600;
}
.bt-entryform__total.is-bad { color: var(--bt-danger-text); font-weight: 500; }
@media (max-width: 620px) {
  /* No room for a label column — stack them, and the labels go left-aligned. */
  .bt-entryform { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .bt-entryform__label { padding-top: 10px; text-align: left; }
  .bt-entryform__short { max-width: none; }
}

/* A chip you can take back off — the customers on an entry. */
.bt-chip__x {
  display: inline-grid;
  width: 16px;
  height: 16px;
  margin-left: 4px;
  margin-right: -4px;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  cursor: pointer;
  vertical-align: -3px;
}
.bt-chip__x:hover { background: rgba(0, 0, 0, 0.25); }

.bt-sheet__cancel--danger { background: var(--bt-danger-soft); color: var(--bt-danger-text); }

/* A switch with its explanation beside it — the account editor's Timesheet. */
.bt-toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 12px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
  cursor: pointer;
}
.bt-toggle-row:hover { background: var(--bt-surface-nested); }
/* A switch for something this account can never have — Payroll on an applicant.
   Dimmed and out of reach rather than removed: a row that vanishes leaves somebody
   hunting for a setting they remember, and the tooltip on the row says why. */
.bt-toggle-row.is-disabled { opacity: .45; cursor: not-allowed; }
.bt-toggle-row.is-disabled:hover { background: transparent; }
.bt-toggle-row__label { display: block; font-size: 14px; font-weight: 600; }
.bt-toggle-row input[type="checkbox"] {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  accent-color: var(--bt-accent);
}

/* ---------------------------------------------------------------- notes save status */
.bt-notes-status {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  min-height: 16px;
  color: var(--bt-text-disabled);
  font-size: 12px;
  font-weight: 500;
}
.bt-notes-status::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
}
.bt-notes-status.is-saving { color: var(--bt-text-secondary); }
.bt-notes-status.is-saved { color: var(--bt-positive-text); }
.bt-notes-status.is-dirty { color: var(--bt-warning-text); }
.bt-notes-status.is-error { color: var(--bt-danger-text); }

/* ---------------------------------------------------------------- responsive */
@media (max-width: 1180px) {
  /* Rail drops below the main content and spreads its widgets into a row. */
  .bt-shell {
    grid-template-columns: var(--bt-sidebar-width) minmax(0, 1fr);
    grid-template-rows: var(--bt-topbar-height) auto auto;
  }
  .bt-topbar { grid-column: 2; }
  .bt-main { grid-column: 2; grid-row: 2; }
  .bt-rail { grid-column: 2; grid-row: 3; padding: 0 var(--bt-content-pad) 48px var(--bt-shell-gap); }
  /* Below the rail breakpoint it drops under the main column, full-width. */
  .bt-rail__inner { position: static; }
}

@media (max-width: 760px) {
  :root { --bt-topbar-height: 56px; }

  body { padding-bottom: 92px; }

  .bt-shell,
  .bt-shell.is-focused {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: var(--bt-topbar-height) auto auto;
  }

  .bt-sidebar {
    position: fixed;
    z-index: 50;
    top: auto;
    right: auto;
    bottom: calc(10px + env(safe-area-inset-bottom));
    left: 50%;
    max-width: calc(100vw - 20px);
    flex-direction: row;
    align-items: center;
    height: auto;
    padding: 5px;
    border-radius: var(--bt-radius-round);
    background: rgba(9, 30, 35, 0.92);
    box-shadow: var(--bt-shadow-inset), var(--bt-shadow-popover);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    transform: translateX(-50%);
  }

  .bt-sidebar__brand { display: none; }
  /* An administrator's dock carries ten destinations and a phone is 375px
     wide, so the row cannot be made to fit — it has to be reachable instead.
     The nav scrolls sideways inside the dock; the profile button is its
     sibling rather than part of the scroller, so Account, Settings, Trash and
     Log out never scroll away from under the thumb. Without this the trailing
     destinations were simply clipped off the end, with nothing to say they
     were there. */
  .bt-nav {
    width: auto;
    min-width: 0;
    flex: 0 1 auto;
    flex-direction: row;
    gap: 2px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .bt-nav::-webkit-scrollbar { display: none; }
  .bt-nav-item { scroll-snap-align: center; }
  /* As a bottom bar the highlight wraps the whole item, so there is no pill for
     the label to collide with — the gap here is only about not crowding the
     icon, and the height is what a thumb bar can afford. */
  .bt-nav-item { width: 70px; height: 56px; gap: 5px; border-radius: var(--bt-radius-round); }
  .bt-nav-item::before { inset: 0; border-radius: var(--bt-radius-round); }
  .bt-nav-item .bt-icon { width: 19px; height: 19px; }

  .bt-mobile-profile {
    position: relative;
    display: grid;
    width: 54px;
    height: 54px;
    flex: 0 0 auto;
    place-items: center;
    margin-left: 2px;
    padding: 0;
    border: 0;
    border-radius: var(--bt-radius-round);
    background: transparent;
    color: var(--bt-text-secondary);
  }
  .bt-mobile-profile::before {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: transparent;
    content: "";
  }
  .bt-mobile-profile:hover::before,
  .bt-mobile-profile.is-active::before { background: var(--bt-surface); }
  .bt-mobile-profile .bt-avatar { position: relative; width: 32px; height: 32px; }

  .bt-topbar,
  .bt-shell.is-focused .bt-topbar { grid-column: 1; grid-row: 1; padding: 0 14px; }
  .bt-topbar::before { left: 0; }
  .bt-topbar__heading { flex: 1 1 auto; }
  .bt-topbar__title { font-size: 19px; }
  .bt-work-clock { display:none; }
  .bt-topbar .bt-user-pill { display: none; }

  .bt-main { grid-column: 1; grid-row: 2; padding: 14px 14px 20px; }
  .bt-rail { grid-column: 1; grid-row: 3; padding: 0 14px 24px; }
  .bt-page { gap: 14px; }

  /* Avoid iOS form-focus zoom, which otherwise makes the narrow layout jump. */
  .bt-input,
  .bt-select { font-size: 16px; }

  /* Give descriptive text room to breathe instead of forcing single-line
     ellipses into the narrow content column. */
  .bt-list-row__content > .bt-body-2.bt-truncate,
  .bt-job-row__meta.bt-truncate {
    display: -webkit-box !important;
    overflow: hidden;
    white-space: normal;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
  }
  .bt-job-row { gap: 8px; }
  .bt-job-row__progress { gap: 8px; max-width: none; }
  .bt-job-row__pct { min-width: 60px; }
  /* Chips bleed to the screen edges so the last one isn't clipped mid-scroll;
     the view controls sit under them rather than competing for the same row. */
  .bt-boardbar { flex-wrap: wrap; }
  .bt-filterbar {
    order: 2;
    margin-inline: -14px;
    padding-inline: 14px;
    scroll-padding-inline: 14px;
  }
  .bt-boardbar__actions { order: 1; flex-wrap: wrap; justify-content: flex-end; margin-left: auto; }
  .bt-pagination { gap: 6px; }
  .bt-pagination__size > span,
  .bt-pagination__summary,
  .bt-pagination__pages { display: none; }

  .bt-form-grid { grid-template-columns: minmax(0, 1fr); }
  .bt-schedule-inputs { grid-template-columns: minmax(0, 1fr) 120px; }
  .bt-picker__roles {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2px;
  }
  .bt-picker__roles .bt-segmented__item {
    width: 100%;
    min-width: 0;
    padding-inline: 6px;
  }
  .bt-metric-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .bt-perf-head { gap: 12px; padding: 16px 14px 4px; }
  .bt-perf-head__score .bt-score { font-size: 34px; }
  .bt-bench-row {
    grid-template-columns: minmax(0, 1fr) 66px 110px;
    gap: 8px;
  }
  .bt-bench-row__minutes { width: 110px; }
  .bt-matrix th.bt-matrix__row-head,
  .bt-matrix td.bt-matrix__row-head { min-width: 190px; }
  .bt-reveal { max-width: none; border-radius: var(--bt-radius-sheet) var(--bt-radius-sheet) 0 0; }
  .bt-reveal__score { font-size: 46px; }
  .bt-meta-grid { grid-template-columns: minmax(0, 1fr); }

  .bt-notif-pop { position: fixed; top: auto; bottom: calc(78px + env(safe-area-inset-bottom)); left: 12px; right: 12px; width: auto; }
  .bt-conv { max-height: none; }
  .bt-conv__body { max-height: 460px; }
  .bt-bulkbar { bottom: calc(78px + env(safe-area-inset-bottom)); }
}

@media (max-width: 480px) {
  .bt-panel__head { padding: 14px 14px 4px; }
  .bt-panel__lede { padding-inline: 14px; }
  .bt-panel__body { padding: 6px; }
  .bt-panel__body--pad { padding: 14px; }

  /* Inline admin actions are all available in the detail view; keeping only
     the disclosure chevron prevents them from crushing job information. */
  .bt-job-row__side .bt-icon-button { display: none; }

  .bt-list-row--static {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: start;
  }
  .bt-list-row--static > .bt-list-row__side {
    grid-column: 1 / -1;
    justify-self: stretch;
    padding-left: 44px;
  }
  .bt-list-row--static > .bt-list-row__side .bt-button { flex: 1 1 auto; }

  .bt-cl-item {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 8px 10px;
  }
  .bt-cl-item .bt-st-chip {
    grid-column: 2;
    justify-self: start;
    margin-top: 0;
  }

  .bt-info-row { align-items: flex-start; }
}

@media (max-width: 360px) {
  .bt-nav-item { width: 62px; }
  .bt-mobile-profile { width: 50px; }
}

/* ---------------------------------------------------------------- followers
   Following a job sits beside its status as a small bell with a count: it is
   set once and then left alone, so it does not earn standing space in a pane
   that is read all day. Everything else lives in the popover it opens. */
/* Status and bell stay together on the left; the header's space-between then
   pushes only the actions to the right. */
.bt-jobhead__status { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: 8px; }

.bt-watchbell { display: inline-flex; }
.bt-watchbell__btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 26px;
  padding: 0 8px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-round);
  background: transparent;
  color: var(--bt-text-secondary);
  cursor: pointer;
  transition: background var(--bt-duration-sm) var(--bt-ease), color var(--bt-duration-sm) var(--bt-ease),
              border-color var(--bt-duration-sm) var(--bt-ease);
}
.bt-watchbell__btn:hover { background: var(--bt-surface); color: var(--bt-text-primary); }
/* Following is the state worth showing at a glance, so it is the accented one. */
.bt-watchbell__btn.is-following {
  border-color: var(--bt-accent);
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
}
.bt-watchbell__count { font-size: 11px; font-weight: 700; line-height: 1; }

/* Fixed, not absolute, and positioned from JavaScript against the bell's own
   rectangle. The info pane is a scrolling column inside an overflow:hidden
   rail, so an absolutely-positioned panel is clipped twice over — the same
   reason the Team roster's account menu is fixed. */
.bt-watchpop {
  position: fixed;
  z-index: 75;
  width: 320px;
  max-width: calc(100vw - 24px);
  padding: 8px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface-popover);
  box-shadow: var(--bt-shadow-popover);
  color: var(--bt-text-primary);
  font-family: var(--bt-font-interface);
  text-align: left;
  /* A column so the follower list takes whatever height is left after the
     choices and the search box, and scrolls inside the panel rather than
     running off the bottom of the window. max-height is set from JavaScript,
     against the room actually available below (or above) the bell. */
  display: flex;
  min-height: 0;
  flex-direction: column;
}
.bt-watchpop__choices { display: grid; flex: none; gap: 2px; }
.bt-watchpop__choice {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  width: 100%;
  padding: 8px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  background: transparent;
  color: var(--bt-text-secondary);
  cursor: pointer;
  text-align: left;
}
.bt-watchpop__choice:hover { background: var(--bt-surface); color: var(--bt-text-primary); }
.bt-watchpop__choice.is-on { background: var(--bt-accent-soft); color: var(--bt-accent-text); }
.bt-watchpop__choicebody { flex: 1; min-width: 0; }
.bt-watchpop__choicetitle { display: block; font-size: 13px; font-weight: 600; }
.bt-watchpop__choicehint {
  display: block;
  margin-top: 1px;
  color: var(--bt-text-secondary);
  font-size: 11px;
  line-height: 1.35;
}
.bt-watchpop__choice.is-on .bt-watchpop__choicehint { color: inherit; opacity: 0.8; }
.bt-watchpop__tick { flex: none; margin-top: 2px; }

/* A note that belongs to both choices above it rather than to either one, so it
   sits outside them and is quieter than either. */
.bt-watchpop__note {
  margin: 2px 0 0;
  padding: 0 8px;
  color: var(--bt-text-secondary);
  font-size: 10.5px;
  line-height: 1.4;
}

/* .bt-input-shell supplies the rounded field, background and focus ring; this
   only has to size it for a compact popover and space it from the choices. */
.bt-watchpop__search {
  min-height: var(--bt-control-sm);
  flex: none;
  gap: 8px;
  margin: 10px 0 4px;
  padding: 0 12px;
}
.bt-watchpop__search .bt-icon { flex: none; }
.bt-watchpop__search .bt-input { font-size: 12.5px; }

.bt-watchpop__list { min-height: 0; flex: 1 1 auto; overflow-y: auto; }
.bt-watchpop__label {
  padding: 8px 6px 4px;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.bt-watchpop__row {
  display: flex;
  gap: 8px;
  align-items: center;
  width: 100%;
  padding: 5px 6px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  background: transparent;
  color: inherit;
  font-family: inherit;
  text-align: left;
}
.bt-watchpop__row--add { cursor: pointer; }
.bt-watchpop__row--add:hover, .bt-watchpop__row:hover { background: var(--bt-surface); }
.bt-watchpop__name { flex: 1; min-width: 0; font-size: 13px; font-weight: 500; }
.bt-watchpop__meta {
  display: block;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 400;
}

/* ------------------------------------------------------- notification centre
   The bell's popover is a peek; this is the page you come to when there is
   more than a peek's worth. Rail of questions on the left, list on the right. */
.bt-notifcentre { display: grid; gap: 16px; grid-template-columns: minmax(0, 180px) minmax(0, 1fr); align-items: start; }
.bt-notifcentre__rail { position: sticky; top: calc(var(--bt-topbar-height) + 20px); display: grid; gap: 2px; }
.bt-notifcentre__railhead {
  margin-top: 10px;
  padding: 6px 10px 2px;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.bt-notifcentre__filter {
  padding: 8px 10px;
  border: 0;
  border-radius: var(--bt-radius-sm);
  background: transparent;
  color: var(--bt-text-secondary);
  cursor: pointer;
  font-family: inherit;
  font-size: 13px;
  text-align: left;
}
.bt-notifcentre__filter:hover { background: var(--bt-surface); color: var(--bt-text-primary); }
.bt-notifcentre__filter.is-active { background: var(--bt-accent-soft); color: var(--bt-accent-text); font-weight: 600; }

.bt-notifcentre__main { min-width: 0; border-radius: var(--bt-radius-panel); background: var(--bt-surface); }
.bt-notifcentre__bar {
  display: flex;
  min-height: 44px;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: 6px 12px;
  border-bottom: 1px solid var(--bt-line);
}
/* The select-all box and the count it explains travel together on the left; the
   actions stay pinned right. The 2px nudge puts the box on the same vertical
   line as the row checkboxes below it, which is the only thing that makes it
   read as their master rather than as one more control in the bar. */
.bt-notifcentre__barleft {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-right: auto;
  padding-left: 2px;
}
.bt-notifcentre__count { color: var(--bt-text-secondary); font-size: 12px; }
.bt-notifcentre__day {
  padding: 12px 14px 6px;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.bt-notifcentre__more { padding: 12px; text-align: center; }

.bt-notifrow {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 10px 14px;
  border-bottom: 1px solid var(--bt-line);
}
.bt-notifrow:last-child { border-bottom: 0; }
.bt-notifrow:hover { background: var(--bt-surface-raised, rgba(255, 255, 255, 0.03)); }
.bt-notifrow.is-selected { background: var(--bt-accent-soft); }
.bt-notifrow__check { flex: none; margin-top: 6px; }
/* Unread is carried by a dot and a weight, not a background: a list where most
   rows are unread should not read as one solid block of colour. */
.bt-notifrow__dot {
  width: 7px;
  height: 7px;
  flex: none;
  margin-top: 13px;
  border-radius: 50%;
  background: var(--bt-accent);
}
.bt-notifrow.is-read .bt-notifrow__dot { background: transparent; }
.bt-notifrow.is-read .bt-notifrow__title { font-weight: 500; color: var(--bt-text-secondary); }
.bt-notifrow__body { display: grid; min-width: 0; gap: 2px; flex: 1; }
.bt-notifrow__title { font-size: 13px; font-weight: 600; }
.bt-notifrow__preview {
  overflow: hidden;
  color: var(--bt-text-secondary);
  font-size: 12px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bt-notifrow__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.bt-notifrow__job { color: var(--bt-text-secondary); font-size: 11px; font-weight: 600; }
.bt-notifrow__chip {
  padding: 1px 7px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface-raised, rgba(255, 255, 255, 0.06));
  color: var(--bt-text-secondary);
  font-size: 10px;
  font-weight: 600;
}
.bt-notifrow__time { color: var(--bt-text-secondary); font-size: 11px; }
.bt-notifrow__actions { display: flex; flex: none; align-items: center; gap: 4px; }
/* Actions appear on hover on a pointer device; on touch they are always there,
   because there is no hover to reveal them with. */
@media (hover: hover) {
  .bt-notifrow__actions { opacity: 0; transition: opacity var(--bt-duration-sm) var(--bt-ease); }
  .bt-notifrow:hover .bt-notifrow__actions,
  .bt-notifrow:focus-within .bt-notifrow__actions { opacity: 1; }
}

@media (max-width: 900px) {
  .bt-notifcentre { grid-template-columns: minmax(0, 1fr); }
  /* The rail lies down into a scrolling row above the list, the same way the
     settings rail does. */
  .bt-notifcentre__rail {
    position: static;
    display: flex;
    overflow-x: auto;
    gap: 6px;
    scrollbar-width: none;
  }
  .bt-notifcentre__rail::-webkit-scrollbar { display: none; }
  .bt-notifcentre__filter { flex: none; white-space: nowrap; }
  .bt-notifcentre__railhead { display: none; }
  .bt-notifrow__preview { white-space: normal; }
}

/* The bell popover's way through to the full page. */
.bt-notif-pop__foot {
  padding: 6px;
  border-top: 1px solid var(--bt-line);
  text-align: center;
}


/* ===================================================== notification settings
   Settings → Notifications carries four related screens: the person's own
   grid, and — for whoever may edit them — the company's role policy, the
   auto-follow rules and the delivery log. They sit behind sub-tabs rather than
   in a separate corner of Admin, because "what do I get" and "what does my
   company give people" are one subject asked from two sides.

   All four are wide tables, so this section is allowed off the narrow settings
   measure that suits a timezone picker — and off the 1080px reading measure the
   rest of the portal keeps to, since none of it is prose. A table's label column
   is the first thing to lose when the window is the constraint, and a notification
   is named in a sentence: the width bought here is spent on reading "A job you
   follow is completed" on one line rather than three. Still capped, and not far
   above the old number, because past about this point the channel columns have
   all the room they can use and every further pixel goes into the gap between a
   notification's name and its switches — which is the one distance a row is read
   across. */
.bt-page--settings.is-wide { max-width: 1240px; }
.bt-panel--flush > .bt-panel__body--wide { padding-top: 4px; }
/* The heading and its explanation are one block; the badge sits opposite. */
.bt-panel__head--stack { align-items: flex-start; gap: 16px; }
.bt-panel__head--stack .bt-panel__lede { margin: 4px 0 0; }

.bt-subtabs {
  display: flex;
  overflow-x: auto;
  gap: 2px;
  padding: 0 16px;
  border-bottom: 1px solid var(--bt-line);
  scrollbar-width: none;
}
.bt-subtabs::-webkit-scrollbar { display: none; }
.bt-subtabs__item {
  position: relative;
  padding: 10px 12px;
  border: 0;
  background: transparent;
  color: var(--bt-text-secondary);
  cursor: pointer;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
}
.bt-subtabs__item:hover { color: var(--bt-text-primary); }
.bt-subtabs__item.is-active { color: var(--bt-text-primary); font-weight: 600; }
.bt-subtabs__item.is-active::after {
  position: absolute;
  right: 12px;
  bottom: -1px;
  left: 12px;
  height: 2px;
  border-radius: 2px 2px 0 0;
  background: var(--bt-accent);
  content: '';
}

/* ---- the person's sets of switches ---- */
.bt-prefsets { margin: 14px 0 6px; }
.bt-prefsets__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  justify-content: space-between;
}
.bt-prefsets__pick { display: flex; min-width: 0; align-items: center; gap: 8px; }
.bt-prefsets__picklabel {
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
/* Not the hidden native select the enhancer leaves behind: it is absolutely
   positioned, so a width given to it hangs off the side of the control it is
   standing in for and widens the bar for nothing. */
.bt-prefsets__pick .bt-select:not(.bt-select-native) { min-width: 160px; max-width: 260px; }
.bt-prefsets__actions { display: flex; align-items: center; gap: 6px; }
.bt-prefsets__actions .bt-button { display: inline-flex; align-items: center; gap: 5px; }
.bt-prefsets__actions .bt-inline-edit:disabled { cursor: default; opacity: 0.35; }
/* The naming form appears in place under the bar rather than in a dialog: it is
   one field, and a dialog for one field is a bigger interruption than the thing
   it asks for. */
.bt-prefsets__form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding: 10px;
  border: 1px solid var(--bt-line);
  /* Wider than the field it holds: an outer corner tighter than its inner one
     reads as a mistake. */
  border-radius: var(--bt-radius-panel);
  background: var(--bt-surface-nested, rgba(255, 255, 255, 0.04));
}
.bt-prefsets__formlabel { color: var(--bt-text-secondary); font-size: 12px; font-weight: 600; }
.bt-prefsets__name { min-width: 0; flex: 1 1 200px; }
.bt-prefsets__name.bt-input-shell { min-height: var(--bt-control-sm); padding: 0 12px; }
.bt-prefsets__name .bt-input { font-size: 12.5px; }
.bt-prefsets__hint {
  margin: 8px 0 0;
  color: var(--bt-text-secondary);
  font-size: 11.5px;
  line-height: 1.5;
}
.bt-prefsets__hint strong { color: var(--bt-text-primary); font-weight: 600; }

/* ---- the person's own grid ---- */
/* No sideways scroll, at any width: the channel columns give up their room to
   the label first, and below the breakpoint further down the grid stops being a
   table altogether rather than being dragged off the side of the screen. */
.bt-prefgrid { display: grid; min-width: 0; }
.bt-prefgrid__row,
.bt-prefgrid__group {
  display: grid;
  align-items: center;
  gap: 12px;
  /* The label column takes the slack; channel columns stay a comfortable,
     equal width so the toggles line up down the page — and are allowed to
     shrink rather than overflow when there is less room than they would like. */
  grid-template-columns: minmax(0, 1fr) repeat(var(--bt-pref-cols, 4), minmax(0, 108px));
}
.bt-prefgrid__row { padding: 14px 4px; border-top: 1px solid var(--bt-line); }
.bt-prefgrid__row--head {
  /* Bottom-aligned, so a heading that wraps to two lines still sits on the
     same line as the rest instead of floating above them. */
  align-items: end;
  padding: 0 4px 10px;
  border-top: 0;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
/* A group heading, with its "all" switches sitting in the channel columns they
   belong to rather than on a row of their own. */
.bt-prefgrid__group { display: block; padding: 22px 4px 6px; border-top: 1px solid var(--bt-line); }
.bt-prefgrid__group:first-of-type { border-top: 0; }
.bt-prefgrid__groupname { font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
/* A flex column, not a grid: an auto grid track sizes itself to the widest thing
   inside it and then hangs over the edge of the cell, which is what put a
   sideways scrollbar under this whole table. Every child is held to the width it
   is given instead. */
.bt-prefgrid__ch {
  display: flex;
  min-width: 0;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  text-align: center;
}
.bt-prefgrid__ch > * { max-width: 100%; min-width: 0; }
/* Transparent to the row's grid, so the cells sit in the channel columns exactly
   as they did before this wrapper existed. It becomes a real box only in the
   narrow layout further down. */
.bt-prefgrid__cells { display: contents; }
.bt-prefgrid__chname { overflow-wrap: anywhere; }
/* An unplugged lead, until the channel can actually deliver. It replaces the
   line of small print that used to sit under every switched-on toggle in the
   column saying the same sentence. */
.bt-prefgrid__chwarn { display: inline-grid; flex: none; color: var(--bt-text-disabled); place-items: center; }
.bt-prefgrid__chwarn:hover, .bt-prefgrid__chwarn:focus-visible { color: var(--bt-text-primary); }
/* The channel's name repeated inside its own cell. Only wanted once the grid has
   reflowed into stacked rows and the headings are no longer above it. */
.bt-prefgrid__chlabel { display: none; }
.bt-prefgrid__label { min-width: 0; font-size: 13px; font-weight: 600; }
.bt-prefgrid__blurb {
  display: block;
  margin-top: 2px;
  color: var(--bt-text-secondary);
  font-size: 11.5px;
  font-weight: 400;
  line-height: 1.45;
}
.bt-prefgrid__ch--locked { color: var(--bt-text-secondary); }
.bt-prefgrid__lockstate { font-size: 10px; font-weight: 600; }

/* ---- the company's role policy ---- */
.bt-policy__lede { margin: 14px 0 0; }
.bt-rolepick {
  display: flex;
  overflow-x: auto;
  gap: 4px;
  margin: 14px 0 6px;
  padding: 4px;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface-nested, rgba(255, 255, 255, 0.04));
  scrollbar-width: none;
}
.bt-rolepick::-webkit-scrollbar { display: none; }
.bt-rolepick__item {
  padding: 7px 14px;
  border: 0;
  border-radius: var(--bt-radius-round);
  background: transparent;
  color: var(--bt-text-secondary);
  cursor: pointer;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
}
.bt-rolepick__item:hover { color: var(--bt-text-primary); }
.bt-rolepick__item.is-active { background: var(--bt-accent); color: var(--bt-ink); font-weight: 600; }

/* Sideways at any width rather than at a breakpoint: what this table needs is a
   number — a label column wide enough for the longest notification's name, and
   four columns wide enough for a switch and a lock — and a window either has it
   or it does not. Guessing at it with a media query got it wrong in the middle,
   where the settings rail is still taking 212px and the grid has stopped
   scrolling. */
.bt-policy { display: grid; overflow-x: auto; }
/* The switch and its lock are 78px however wide the window is, so the channel
   columns are held near that and every pixel of the slack goes to the label —
   the only column here whose content is a sentence. Four equal fractions used to
   split the slack five ways and wrap "A job you follow is completed" onto three
   lines while the dropdowns beside it sat half empty. */
.bt-policy__row {
  display: grid;
  align-items: center;
  gap: 12px;
  min-width: 640px;
  padding: 8px 4px;
  border-top: 1px solid var(--bt-line);
  grid-template-columns: minmax(260px, 1fr) repeat(var(--bt-policy-cols, 4), minmax(80px, 124px));
}
.bt-policy__row--head {
  /* Bottom-aligned, so a heading that wraps still sits on the same line as the
     rest — the same rule the person's own grid follows. */
  align-items: end;
  padding: 0 4px 10px;
  border-top: 0;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.bt-policy__row--head > span + span { text-align: center; }
.bt-policy__group {
  min-width: 640px;
  padding: 22px 4px 6px;
  border-top: 1px solid var(--bt-line);
  color: var(--bt-text-primary);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.bt-policy__group:first-of-type { border-top: 0; }
.bt-policy__type { min-width: 0; font-size: 13px; font-weight: 500; }
/* Switch and lock side by side — one decision with two parts, not two rows —
   centred under the channel they answer for, so a column reads down as cleanly
   as a row reads across. */
.bt-policy__cell {
  display: flex;
  min-width: 0;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.bt-policy__switch { flex: none; }
.bt-policy__lock {
  display: grid;
  width: var(--bt-control-sm);
  height: var(--bt-control-sm);
  flex: none;
  border: 1px solid var(--bt-line);
  border-radius: 9px;
  background: transparent;
  color: var(--bt-text-disabled);
  place-items: center;
  transition: color var(--bt-duration-sm) var(--bt-ease),
    border-color var(--bt-duration-sm) var(--bt-ease),
    background var(--bt-duration-sm) var(--bt-ease);
}
/* Locked is the state worth seeing from across the grid, so it is the accented
   one; an open lock keeps to the quietest ink there is, because on most rows it
   is saying nothing has been decided. */
.bt-policy__lock.is-on { border-color: var(--bt-accent); background: var(--bt-accent-soft); color: var(--bt-accent-text); }
/* Only the button is a button. The system's own lock is drawn with the same
   shape and takes none of the behaviour — a hover state that leads nowhere is a
   worse promise than the greyed-out control it replaced. */
button.bt-policy__lock { cursor: pointer; }
button.bt-policy__lock:hover { background: var(--bt-surface-nested); color: var(--bt-text-primary); }
button.bt-policy__lock:focus-visible { outline: 2px solid var(--bt-accent); outline-offset: 2px; }
.bt-policy__cell--system,
.bt-policy__cell--system .bt-toggle,
.bt-policy__cell--system .bt-toggle input { cursor: default; }
.bt-policy__cell--system .bt-toggle input:disabled + .bt-toggle__track { opacity: 0.55; }
.bt-policy__cell--system .bt-policy__lock { opacity: 0.75; }
.bt-policy__cell--note {
  color: var(--bt-text-disabled);
  font-size: 11.5px;
  gap: 5px;
  text-align: center;
}

/* ---- follower rules ---- */
.bt-rules { display: grid; margin-top: 14px; }
.bt-rules__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 4px;
  border-top: 1px solid var(--bt-line);
}
.bt-rules__row:first-child { border-top: 0; }
.bt-rules__label { font-size: 13px; font-weight: 500; }

/* ---- delivery log ---- */
.bt-outbox { display: grid; overflow-x: auto; }
.bt-outbox__row {
  display: grid;
  gap: 12px;
  align-items: center;
  padding: 10px 4px;
  border-top: 1px solid var(--bt-line);
  grid-template-columns: 84px minmax(200px, 1fr) minmax(180px, 260px) minmax(140px, 200px);
}
.bt-outbox__row--head {
  border-top: 0;
  color: var(--bt-text-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.bt-outbox__meta { color: var(--bt-text-secondary); font-size: 11.5px; }

@media (max-width: 860px) {
  /* The delivery log scrolls sideways inside its own container rather than
     crushing its columns — it is a dense table read by scanning a row, and
     there is no honest way to stack one. The policy grid does the same, but at
     the width it actually runs out of room rather than at this breakpoint. */
  .bt-outbox { display: block; }
  .bt-outbox__row { min-width: 640px; }
}

/* The person's own grid stops being a table instead of being dragged off the
   side of the screen: the four channels become a wrapping row of named switches
   underneath the thing they are about, which is the same information read down
   rather than across. */
@media (max-width: 720px) {
  .bt-prefgrid__row,
  .bt-prefgrid__group { display: block; }
  .bt-prefgrid__row { padding: 14px 4px 16px; }
  /* The headings have nothing left to head once the columns are gone, and each
     cell now carries its own name. */
  .bt-prefgrid__row--head { display: none; }
  .bt-prefgrid__cells {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 18px;
    margin-top: 12px;
  }
  .bt-prefgrid__ch {
    min-height: 0;
    flex: 0 0 auto;
    align-items: flex-start;
    gap: 5px;
    text-align: left;
  }
  .bt-prefgrid__chlabel {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--bt-text-secondary);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }
  .bt-prefgrid__ch--locked { flex-direction: column; align-items: flex-start; }
}

/* --------------------------------------------------------- small control set
   The dense tables above need controls a size below the form default. These
   follow the existing --xs / --md naming rather than inventing a scale. */
.bt-select--sm,
.bt-select--sm.bt-select-enhanced {
  min-height: var(--bt-control-sm);
  padding-right: 26px;
  padding-left: 9px;
  border-radius: 9px;
  font-size: 12px;
}
.bt-select--sm { background-position: right 7px center; background-size: 14px; }
.bt-button--sm { min-height: var(--bt-control-sm); padding-inline: 14px; font-size: 13px; }
/* The watcher popover's search field sits inside its own shell, so this only
   needs to set the height it lives at. */
.bt-input--sm { min-height: var(--bt-control-sm); font-size: 12.5px; }

/* The panel that holds the notification tabs: the head, the tab strip and the
   body each own their padding so the tabs can run the full width of the card. */
.bt-panel--flush { padding: 0; }
.bt-panel--flush > .bt-panel__head { padding: 16px 16px 0; }
.bt-panel--flush > .bt-panel__body { padding: 0 16px 16px; }

/* A size below the 16px icon, for the notes that sit inside a heading. */
.bt-icon--14 { width: 14px; height: 14px; }

/* The panel head spreads its children apart to push the badge right; the title
   and the dot that explains it have to travel together. */
.bt-panel__title { display: flex; min-width: 0; align-items: center; gap: 6px; }

/* ---------------------------------------------------------------- account sections */
/* In the technician app the Account page is two pages — Profile and Payroll —
   so it takes the rail Settings uses rather than inventing a second way of
   splitting a page. Same markup, same width arithmetic, and the same collapse
   to a scrolling row of links on a phone; only the entries differ. */
.bt-page--account { max-width: calc(var(--bt-profile-width) + 212px); }
/* An administrator in Admin has only Profile here — their payroll screen is a
   sidebar destination — and a rail with one link on it is not a rail. The page
   drops the empty first column and takes back the width one column wants. */
.bt-page--account.is-single { max-width: var(--bt-profile-width); }
.bt-page--account.is-single .bt-settings { grid-template-columns: minmax(0, 1fr); }

/* ---------------------------------------------------------------- payroll */
/* The section stacks its own panels, because it is mounted in two different
   places — a page of its own in Admin, a rail section in the technician app —
   and only one of those hands it a gap. */
.bt-payroll { display: flex; flex-direction: column; gap: 20px; }
/* The form is a single column of fields and reads badly stretched across a full
   page; the collection queue is a five-column table and wants the room. The
   module says which one it is drawing, so the same mount point suits both. */
.bt-payroll:not(.bt-payroll--managing) { max-width: var(--bt-narrow-width); }

/* Account and routing numbers are read a digit at a time, out loud, against a
   cheque — so they get tabular figures, where a 1 occupies the same width as an
   8 and two numbers of the same length line up under each other. */
.bt-mono {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: 0.02em;
}

/* What the server is doing with your bank details, as three statements rather
   than a paragraph. Each one is a promise the rest of this feature keeps. */
.bt-assurance {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px 0;
  border-top: 1px solid var(--bt-line);
}
.bt-assurance__item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px 0;
}
.bt-assurance__item + .bt-assurance__item { box-shadow: 0 -1px 0 var(--bt-line); }
.bt-assurance__icon {
  display: inline-grid;
  width: 28px;
  height: 28px;
  flex: 0 0 auto;
  place-items: center;
  border-radius: var(--bt-radius-sm);
  background: var(--bt-accent-soft);
  color: var(--bt-accent-text);
}
.bt-assurance__text { display: flex; min-width: 0; flex-direction: column; gap: 2px; }
.bt-assurance__title { font-size: 13px; font-weight: 600; line-height: 18px; }
.bt-assurance__blurb { color: var(--bt-text-secondary); font-size: 12px; line-height: 18px; }

/* The rows describing one submission, boxed so they read as one record rather
   than as a continuation of the panel around them. */
.bt-payroll-card {
  overflow: hidden;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
}
.bt-payroll-card .bt-info-row { padding: 10px 14px; }

/* The nothing-yet state carries the action, because on this page "add your bank
   details" is the only thing there is to do and hiding it in a panel head would
   put it further from the sentence that explains it. */
.bt-payroll-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 28px 20px;
}
.bt-payroll-empty__icon {
  display: inline-grid;
  width: 44px;
  height: 44px;
  place-items: center;
  border-radius: var(--bt-radius-round);
  background: var(--bt-surface);
  color: var(--bt-text-secondary);
}
.bt-payroll-empty__title { color: var(--bt-text-primary); font-size: 15px; font-weight: 600; }
.bt-payroll-empty .bt-button { margin-top: 8px; }

.bt-payroll-history { display: flex; flex-direction: column; }
.bt-payroll-history__row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 10px;
  padding: 10px 0;
}
.bt-payroll-history__row + .bt-payroll-history__row { box-shadow: 0 -1px 0 var(--bt-line); }
/* The date is the part that wraps; the account and its outcome stay together. */
.bt-payroll-history__row > .bt-body-3 { flex: 1 1 200px; }

.bt-payroll-person { display: flex; min-width: 0; align-items: center; gap: 10px; }
.bt-payroll-person__name { display: flex; min-width: 0; flex-direction: column; }

/* Person, account, action. The action column is sized to its button so the
   buttons line up down the list however long the names are. */
.bt-payroll-queue { display: flex; flex-direction: column; }
.bt-payroll-queue__row {
  display: grid;
  align-items: center;
  gap: 10px 16px;
  padding: 12px 0;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) auto;
}
.bt-payroll-queue__row + .bt-payroll-queue__row { box-shadow: 0 -1px 0 var(--bt-line); }
.bt-payroll-queue__meta { display: flex; min-width: 0; flex-direction: column; gap: 2px; }

/* Five columns of dates and names. It gets the width it needs and scrolls
   inside its own box rather than making the page scroll sideways. */
.bt-payroll-table-scroll { overflow-x: auto; }
.bt-payroll-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.bt-payroll-table th,
.bt-payroll-table td {
  padding: 10px 14px 10px 0;
  text-align: left;
  vertical-align: middle;
  white-space: nowrap;
}
.bt-payroll-table th {
  color: var(--bt-text-secondary);
  font-size: 12px;
  font-weight: 600;
}
.bt-payroll-table thead th { box-shadow: 0 -1px 0 var(--bt-line) inset; }
.bt-payroll-table tbody tr { box-shadow: 0 -1px 0 var(--bt-line); }
/* The clear button sits at the end of the row in a column just wide enough to
   hold it, so the columns that carry words keep theirs. */
.bt-payroll-table__actions { width: 44px; padding-right: 0; text-align: right; }

/* One revealed number: what it is, what it says, and a way to take it without
   retyping it. The value is the widest thing here and the one being read, so it
   takes the free space. */
.bt-payroll-reveal {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 14px;
  padding: 12px 14px;
  border: 1px solid var(--bt-line);
  border-radius: var(--bt-radius-cell);
  background: var(--bt-surface-nested);
}
.bt-payroll-reveal__label {
  flex: 0 0 auto;
  color: var(--bt-text-secondary);
  font-size: 12px;
  font-weight: 600;
}
.bt-payroll-reveal__value {
  flex: 1 1 160px;
  font-size: 18px;
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* The pill is sized to its words everywhere else it is used; here it is the
   gate on a destructive button directly below it, so it takes the full measure
   and reads as a step rather than as a chip floating beside one. */
.bt-payroll-confirm { display: flex; justify-content: flex-start; padding: 10px 14px; }
.bt-payroll-confirm .bt-tick__label { font-size: 14px; }

/* The segmented control, made out of real radio inputs so it is a radio group
   to a keyboard and a screen reader rather than only to the eye. */
.bt-segmented--choice .bt-segmented__item {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 30px;
}
.bt-segmented--choice input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.bt-segmented--choice input:focus-visible { outline: 2px solid var(--bt-accent); outline-offset: 2px; }

@media (max-width: 620px) {
  /* The button drops under the row rather than squeezing the name it belongs
     to down to an initial. */
  .bt-payroll-queue__row { grid-template-columns: minmax(0, 1fr); }
  .bt-payroll-queue__row > .bt-button { justify-self: start; }
}
