/* ==========================================================================
   WaveSync Office CRM — design system
   Served as a real stylesheet (not inline) so it survives the app's strict
   Content-Security-Policy. Nothing here depends on an external font or CDN:
   `default-src 'self'` blocks those, and self-hosting keeps the app fast.
   ========================================================================== */

/* --- Tokens ------------------------------------------------------------- */

:root {
  /* Neutrals — a slightly cool grey ramp. */
  --c-bg:           #f6f7f9;
  --c-surface:      #ffffff;
  --c-surface-2:    #fbfbfd;
  --c-sunken:       #f1f2f6;
  --c-border:       #e3e6ec;
  --c-border-strong:#d2d7e0;

  --c-text:         #14161c;
  --c-text-2:       #4c5566;
  --c-text-3:       #5c6578; /* 5.9:1 on white; #7b8496 was 3.8:1 and failed AA */

  /* Brand — indigo, kept restrained. */
  --c-accent:       #4f46e5;
  --c-accent-hover: #4338ca;
  --c-accent-soft:  #eef0ff;
  --c-accent-text:  #3730a3;
  --c-ring:         rgba(79, 70, 229, 0.28);
  /* Filled accent (buttons, chips, current page): white text on it is AA in
     both themes. --c-accent itself stays light in dark mode, where it is
     mostly used as link and icon colour on dark surfaces. */
  --c-accent-solid: #4f46e5;
  --c-accent-solid-hover: #4338ca;
  /* Form control boundaries need 3:1 against the surface (WCAG 1.4.11). */
  --c-input-border: #8a94a6;

  /* Semantics */
  --c-success:      #15803d;
  --c-success-soft: #e8f6ed;
  --c-warn:         #a16207;
  --c-warn-soft:    #fdf5e3;
  --c-danger:       #b91c1c;
  --c-danger-soft:  #fdeceb;
  --c-info:         #1d4ed8;
  --c-info-soft:    #e9effd;

  /* Sidebar is intentionally dark in both themes — it anchors the layout. */
  --c-nav-bg:       #14161f;
  --c-nav-text:     #a9b0c0;
  --c-nav-text-hi:  #ffffff;
  --c-nav-active:   rgba(255, 255, 255, 0.09);
  --c-nav-border:   rgba(255, 255, 255, 0.08);

  --radius:      10px;
  --radius-sm:   7px;
  --radius-lg:   14px;

  --shadow-sm:  0 1px 2px rgba(16, 20, 30, 0.05);
  --shadow:     0 1px 3px rgba(16, 20, 30, 0.07), 0 1px 2px rgba(16, 20, 30, 0.04);
  --shadow-lg:  0 10px 30px rgba(16, 20, 30, 0.10), 0 2px 8px rgba(16, 20, 30, 0.05);

  --sidebar-w: 236px;
  --sidebar-collapsed-w: 64px;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
          Arial, "Noto Sans", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;

  /* Thin, rounded, mostly-invisible-until-hovered scrollbar — replaces
     the browser's default (arrows, thick flat track) everywhere. */
  --scrollbar-thumb:       rgba(20, 22, 30, 0.16);
  --scrollbar-thumb-hover: rgba(20, 22, 30, 0.30);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --c-bg:           #0e1015;
    --c-surface:      #171a22;
    --c-surface-2:    #1c1f28;
    --c-sunken:       #12141b;
    --c-border:       #272b36;
    --c-border-strong:#343947;

    --c-text:         #eef0f5;
    --c-text-2:       #a8b0c0;
    --c-text-3:       #7a8395;

    --c-accent:       #7c74f2;
    --c-accent-hover: #8d86f6;
    --c-accent-soft:  #201f3d;
    --c-accent-text:  #b8b3ff;
    --c-ring:         rgba(124, 116, 242, 0.35);
    --c-accent-solid: #5b54e8;       /* white 5.4:1 (the old #7c74f2 was 3.7:1) */
    --c-accent-solid-hover: #4f46e5;
    --c-input-border: #626b7d;      /* 3.3:1 on the dark surface */
    --c-status-good: #4ade80; --c-status-warning: #fbbf24; --c-status-serious: #fb923c; --c-status-critical: #f87171;

    --c-success:      #4ade80;
    --c-success-soft: #13291d;
    --c-warn:         #fbbf24;
    --c-warn-soft:    #2a2312;
    --c-danger:       #f87171;
    --c-danger-soft:  #2d1617;
    --c-info:         #7ba5fb;
    --c-info-soft:    #15203a;

    --c-nav-bg:       #0a0c11;
    --c-nav-border:   rgba(255, 255, 255, 0.06);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow:    0 1px 3px rgba(0, 0, 0, 0.45), 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 14px 36px rgba(0, 0, 0, 0.55);
    color-scheme: dark;

    --scrollbar-thumb:       rgba(255, 255, 255, 0.14);
    --scrollbar-thumb-hover: rgba(255, 255, 255, 0.26);
  }
}

/* The person's own choice (the toggle in the top bar) wins over the system setting. */
:root[data-theme="dark"] {
    --c-bg:           #0e1015;
    --c-surface:      #171a22;
    --c-surface-2:    #1c1f28;
    --c-sunken:       #12141b;
    --c-border:       #272b36;
    --c-border-strong:#343947;

    --c-text:         #eef0f5;
    --c-text-2:       #a8b0c0;
    --c-text-3:       #7a8395;

    --c-accent:       #7c74f2;
    --c-accent-hover: #8d86f6;
    --c-accent-soft:  #201f3d;
    --c-accent-text:  #b8b3ff;
    --c-ring:         rgba(124, 116, 242, 0.35);
    --c-accent-solid: #5b54e8;       /* white 5.4:1 (the old #7c74f2 was 3.7:1) */
    --c-accent-solid-hover: #4f46e5;
    --c-input-border: #626b7d;      /* 3.3:1 on the dark surface */
    --c-status-good: #4ade80; --c-status-warning: #fbbf24; --c-status-serious: #fb923c; --c-status-critical: #f87171;

    --c-success:      #4ade80;
    --c-success-soft: #13291d;
    --c-warn:         #fbbf24;
    --c-warn-soft:    #2a2312;
    --c-danger:       #f87171;
    --c-danger-soft:  #2d1617;
    --c-info:         #7ba5fb;
    --c-info-soft:    #15203a;

    --c-nav-bg:       #0a0c11;
    --c-nav-border:   rgba(255, 255, 255, 0.06);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow:    0 1px 3px rgba(0, 0, 0, 0.45), 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 14px 36px rgba(0, 0, 0, 0.55);
    color-scheme: dark;

    --scrollbar-thumb:       rgba(255, 255, 255, 0.14);
    --scrollbar-thumb-hover: rgba(255, 255, 255, 0.26);
}
:root[data-theme="light"] { color-scheme: light; }

/* --- Scrollbars ----------------------------------------------------------
   A thin, rounded, mostly-invisible-until-hovered thumb on a transparent
   track, everywhere in the app — standing in for the browser default
   (a thick flat track with up/down arrow buttons) that otherwise looks
   the same as it did twenty-five years ago. Firefox reads the two
   `scrollbar-*` properties; everything WebKit/Blink reads the
   pseudo-elements below. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--scrollbar-thumb) transparent;
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background-color: var(--scrollbar-thumb);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background-color: var(--scrollbar-thumb-hover); }
*::-webkit-scrollbar-corner { background: transparent; }

/* The sidebar is always dark, in both themes (see the tokens above), so
   its own scroll region needs a light-on-dark thumb rather than the
   theme-following one everything else uses. */
.nav, .nav-drawer {
  scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
.nav::-webkit-scrollbar-thumb, .nav-drawer::-webkit-scrollbar-thumb { background-color: rgba(255, 255, 255, 0.18); }
.nav::-webkit-scrollbar-thumb:hover, .nav-drawer::-webkit-scrollbar-thumb:hover { background-color: rgba(255, 255, 255, 0.32); }

/* --- Reset -------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

/* `hidden` always wins. The browser's own [hidden] rule is weaker than any
   class that sets display (flex, grid, block), so an element JS "hid" with
   the hidden attribute stayed on screen. It bit three times: rail rows that
   would not filter, the settings panel, and the drag-and-drop overlay that
   sat over the whole conversation and covered the message box. One rule
   here ends that class of bug for every element, present and future. */
[hidden]:not([hidden="until-found"]) { display: none !important; }

body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 { margin: 0; font-weight: 640; letter-spacing: -0.015em; line-height: 1.25; }
p { margin: 0 0 0.8rem; }
p:last-child { margin-bottom: 0; }

a { color: var(--c-accent); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* --- App shell ---------------------------------------------------------- */

.shell { display: flex; min-height: 100vh; }

.sidebar {
  position: sticky;
  width: var(--sidebar-w);
  flex: 0 0 var(--sidebar-w);
  background: var(--c-nav-bg);
  color: var(--c-nav-text);
  display: flex;
  flex-direction: column;
  top: 0;
  height: 100vh;
  /* Flex items paint as if positioned, in DOM order, regardless of their
     own `position` — so without this, .content (the next flex item,
     later in the DOM) paints over anything here that pokes past the
     sidebar's own right edge, such as the resize handle and the collapse
     button below. .content is itself unpositioned, so its own sticky
     .topbar (z-index: 5) is what actually competes here, not .content —
     one better than that is enough. This lifts the whole sidebar so its
     own overflow stays on top instead of half-hidden behind the page. */
  z-index: 6;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 1.05rem 1.15rem;
  color: var(--c-nav-text-hi);
  font-weight: 640;
  font-size: 0.97rem;
  letter-spacing: -0.01em;
  border-bottom: 1px solid var(--c-nav-border);
  flex: 0 0 auto;
}
.brand:hover { text-decoration: none; }
.brand-mark {
  width: 26px; height: 26px;
  flex: 0 0 26px;
  display: grid;
  place-items: center;
}
.brand-mark svg { width: 26px; height: 26px; display: block; }

/* flex:1 1 auto + min-height:0 makes the nav itself the scroll region, so
   if the menu is ever taller than the viewport only the links scroll — the
   brand stays pinned at the top and the account menu at the foot, and the
   page background never moves. Grouping keeps it from needing to at all in
   the ordinary case. */
.nav { padding: 0.75rem 0.6rem; display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.nav-label:not(:first-child) { margin-top: 0.55rem; }
.nav-label {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--c-text-3);
  padding: 0.5rem 0.55rem 0.3rem;
  font-weight: 600;
}
.nav a {
  display: flex;
  align-items: center;
  gap: 0.62rem;
  padding: 0.5rem 0.55rem;
  border-radius: var(--radius-sm);
  color: var(--c-nav-text);
  font-size: 0.895rem;
  font-weight: 500;
  transition: background 0.12s ease, color 0.12s ease;
}
.nav a:hover { background: var(--c-nav-active); color: var(--c-nav-text-hi); text-decoration: none; }
.nav a[aria-current="page"] { background: var(--c-nav-active); color: var(--c-nav-text-hi); font-weight: 560; }
.nav svg { width: 16px; height: 16px; flex: 0 0 16px; opacity: 0.85; }

.nav-foot {
  border-top: 1px solid var(--c-nav-border);
  padding: 0.6rem 0.7rem;
  flex: 0 0 auto;
}

/* The account drop-up. A native <details>, so it toggles with no
   JavaScript at all (CSP stays default-src 'self') and is keyboard- and
   screen-reader-accessible out of the box. Occasional set-up screens live
   in here rather than the rail. */
.user-menu { position: relative; }
.user-menu > summary {
  list-style: none;
  cursor: pointer;
  width: 100%;
}
.user-menu > summary::-webkit-details-marker { display: none; }
.user-menu > summary:focus-visible {
  outline: 2px solid var(--c-nav-text-hi);
  outline-offset: 2px;
}
.user-menu-caret {
  margin-left: auto;
  flex: 0 0 16px;
  opacity: 0.65;
  transition: transform 0.15s ease;
}
.user-menu[open] .user-menu-caret { transform: rotate(180deg); }

.user-menu-panel {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% + 6px);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 0.35rem;
  display: flex;
  flex-direction: column;
  gap: 1px;
  z-index: 30;
  max-height: 70vh;
  overflow-y: auto;
}
.user-menu-label {
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--c-text-3);
  padding: 0.4rem 0.55rem 0.25rem;
  font-weight: 600;
}
.user-menu-panel a,
.user-menu-logout button {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 0.6rem;
  width: 100%;
  padding: 0.5rem 0.55rem;
  border-radius: var(--radius-sm);
  color: var(--c-text-2);
  font-size: 0.875rem;
  font-weight: 500;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
}
.user-menu-panel a:hover,
.user-menu-logout button:hover {
  background: var(--c-surface-2);
  color: var(--c-text);
  text-decoration: none;
}
.user-menu-panel a[aria-current="page"] {
  background: var(--c-surface-2);
  color: var(--c-text);
  font-weight: 560;
}
.user-menu-panel svg { width: 16px; height: 16px; flex: 0 0 16px; opacity: 0.8; }
.user-menu-sep { height: 1px; background: var(--c-border); margin: 0.3rem 0.2rem; }
.user-menu-logout { margin: 0; }
.avatar {
  width: 30px; height: 30px; flex: 0 0 30px;
  border-radius: 50%;
  background: linear-gradient(140deg, #6366f1, #8b5cf6);
  color: #fff;
  display: grid; place-items: center;
  font-size: 0.75rem; font-weight: 650;
  letter-spacing: 0.01em;
}
.nav-user-link {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex: 1;
  min-width: 0;
  border-radius: var(--radius-sm);
  padding: 0.2rem;
  margin: -0.2rem;
}
.nav-user-link:hover { background: var(--c-nav-active); text-decoration: none; }
.nav-user { min-width: 0; flex: 1; }
.nav-user-name {
  display: block;
  color: var(--c-nav-text-hi);
  font-size: 0.85rem;
  font-weight: 550;
  line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.nav-user-role { display: block; font-size: 0.72rem; line-height: 1.3; color: var(--c-text-3); }
.icon-btn {
  background: none;
  border: 1px solid transparent;
  color: var(--c-nav-text);
  border-radius: var(--radius-sm);
  padding: 0.3rem;
  cursor: pointer;
  display: grid;
  place-items: center;
  line-height: 0;
}
.icon-btn:hover { background: var(--c-nav-active); color: var(--c-nav-text-hi); }
.icon-btn svg { width: 16px; height: 16px; }

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

.topbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0 1.75rem;
  height: 58px;
  border-bottom: 1px solid var(--c-border);
  background: var(--c-surface);
  position: sticky; top: 0; z-index: 5;
}
.topbar h1 { font-size: 1.02rem; font-weight: 620; }
.topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 0.5rem; }

.page { padding: 1.75rem; max-width: 1180px; width: 100%; }
.page-wide { max-width: none; }

@media (max-width: 900px) {
  /* The sidebar becomes a horizontal strip. Its own overflow-x only
     scrolls if it is allowed to be narrower than its contents — a flex
     item defaults to min-width:auto, which refuses to shrink below the
     nav's natural width and drags the whole shell wider than the
     screen. That was one bug showing up on every page at phone width:
     the layout was 500px inside a 390px viewport, so every card was
     clipped on the right. */
  .shell { flex-direction: column; min-width: 0; max-width: 100%; }
  .sidebar {
    width: 100%; flex: none; height: auto; position: static;
    flex-direction: row; align-items: center; gap: 0.5rem;
    padding-right: 0.6rem;
    /* The horizontal scroll lives on .nav below, not here: a scroll
       container on the sidebar would also clip the account drop-up to the
       strip's height. Keeping the sidebar's overflow visible lets the
       menu fall open over the page, while .nav (min-width:0) still absorbs
       any horizontal overflow so the strip never drags the shell wider. */
    overflow: visible;
    min-width: 0; max-width: 100%;
  }
  .brand { border-bottom: none; border-right: 1px solid var(--c-nav-border); padding: 0.8rem 0.9rem; flex: none; }
  .brand-text { display: none; }
  .nav { flex-direction: row; padding: 0.4rem; gap: 2px; flex: 1 1 auto; min-width: 0; overflow-x: auto; }
  .nav-label { display: none; }
  .nav a { padding: 0.42rem 0.6rem; white-space: nowrap; }
  .nav-foot { border-top: none; border-left: 1px solid var(--c-nav-border); padding: 0.5rem 0.7rem; flex: none; }
  .nav-user { display: none; }
  /* On the horizontal strip the account menu sits at the top-right, so it
     opens downward rather than up off the top of the screen. */
  .user-menu-panel { top: calc(100% + 6px); bottom: auto; left: auto; right: 0; width: 232px; }
  .topbar { padding: 0 1.1rem; }
  .page { padding: 1.1rem; }
}

/* --- Cards -------------------------------------------------------------- */

.card {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  margin-bottom: 1.1rem;
  overflow: hidden;
}
.card-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.9rem 1.15rem;
  border-bottom: 1px solid var(--c-border);
  background: var(--c-surface-2);
}
.card-head h2 { font-size: 0.925rem; font-weight: 620; }
.card-head .spacer { margin-left: auto; }
.card-body { padding: 1.15rem; }
.card-body > :last-child { margin-bottom: 0; }

/* --- Stats -------------------------------------------------------------- */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
  margin-bottom: 1.1rem;
}
.stat {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 1.05rem 1.15rem;
}
.stat-label {
  font-size: 0.73rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-weight: 620;
  color: var(--c-text-3);
}
.stat-value {
  font-size: 1.95rem;
  font-weight: 680;
  letter-spacing: -0.02em;
  margin-top: 0.3rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.stat-hint { font-size: 0.8rem; color: var(--c-text-3); margin-top: 0.15rem; }
/* Inside a card (the attendance summaries) the tiles keep the card's
   inset rather than touching its edges. */
.collapse-body > .stats { padding: 0.25rem 1.15rem 0; }
/* On a phone, two tiles a row: one per row turned eight numbers into a
   screen and a half of scrolling before anything else. */
@media (max-width: 600px) {
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.6rem; }
  .stat { padding: 0.75rem 0.85rem; }
  .stat-value { font-size: 1.5rem; }
  .stat-label { font-size: 0.68rem; letter-spacing: 0.05em; }
}

/* --- Tables ------------------------------------------------------------- */

.table-wrap { overflow-x: auto; }
/* A long list (e.g. a machine's application-usage log) scrolls inside its
   own box instead of stretching the page - so the cards below it (recent
   commands, remove machine) stay reachable without scrolling past hundreds
   of rows. The header stays put as you scroll so the columns stay readable. */
.table-wrap-scroll { max-height: 420px; overflow-y: auto; border: 1px solid var(--c-border); border-radius: var(--radius); }
.table-wrap-scroll table { border-collapse: separate; border-spacing: 0; }
.table-wrap-scroll thead th { position: sticky; top: 0; background: var(--c-surface); z-index: 1; }
table { width: 100%; border-collapse: collapse; }
th, td {
  text-align: left;
  padding: 0.7rem 1.15rem;
  border-bottom: 1px solid var(--c-border);
  font-size: 0.9rem;
  vertical-align: middle;
}
thead th {
  font-size: 0.71rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--c-text-3);
  font-weight: 640;
  background: var(--c-surface-2);
  white-space: nowrap;
}
tbody tr:last-child td, tbody tr:last-child th { border-bottom: none; }
tfoot th {
  font-size: 0.8rem;
  font-weight: 650;
  color: var(--c-text-2);
  background: var(--c-surface-2);
  border-top: 1px solid var(--c-border);
  border-bottom: none;
  font-variant-numeric: tabular-nums;
}
tbody tr { transition: background 0.1s ease; }
tbody tr:hover { background: var(--c-surface-2); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
/* Row links read as content, not as a wall of blue; the accent appears on hover. */
td a { color: var(--c-text); }
td a:hover { color: var(--c-accent); }
td.shrink { width: 1%; white-space: nowrap; }
.cell-strong { font-weight: 560; }

/* --- Forms -------------------------------------------------------------- */

label {
  display: block;
  font-size: 0.815rem;
  font-weight: 560;
  color: var(--c-text-2);
  margin-bottom: 0.3rem;
}

/* Every text-like input type, not only the ones in use on the day this
   was written. An unlisted type falls back to the browser's default
   size and sits half the width of everything beside it — which is how
   `type="search"` on the chat search screen ended up looking broken. */
input[type="text"], input[type="email"], input[type="password"], input[type="number"],
input[type="date"], input[type="datetime-local"], input[type="search"],
input[type="tel"], input[type="url"], input[type="time"], input[type="month"],
input[type="week"], select, textarea {
  width: 100%;
  padding: 0.52rem 0.68rem;
  border: 1px solid var(--c-input-border);
  border-radius: var(--radius-sm);
  background: var(--c-surface);
  color: var(--c-text);
  font-size: 0.9rem;
  font-family: inherit;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
textarea { resize: vertical; min-height: 64px; }
/* Chrome draws its own clear button inside a search input; it sits over
   the border radius and matches nothing else on the page. */
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px var(--c-ring);
}
input::placeholder, textarea::placeholder { color: var(--c-text-3); }

/* The chevron is a real file, not a data: URI — `img-src` falls back to
   'self' under this app's CSP, which would block an inline data image. */
select {
  appearance: none;
  background-image: url("/assets/chevron.svg");
  background-repeat: no-repeat;
  background-position: right 0.5rem center;
  background-size: 15px;
  padding-right: 1.9rem;
}
/* A multi-select is a list, not a dropdown — the chevron would sit on
   top of the options and promise something that doesn't happen. */
select[multiple] {
  background-image: none;
  padding-right: 0.6rem;
  padding-top: 0.3rem;
  padding-bottom: 0.3rem;
}
select[multiple] option { padding: 0.18rem 0.25rem; border-radius: 4px; }

.field { margin-bottom: 0.85rem; }
.field:last-of-type { margin-bottom: 1rem; }
.field-hint { font-size: 0.78rem; color: var(--c-text-3); margin-top: 0.25rem; }
.field-error { font-size: 0.78rem; color: var(--c-danger); margin-top: 0.25rem; font-weight: 520; }
input.is-invalid, select.is-invalid, textarea.is-invalid {
  border-color: var(--c-danger);
  background: var(--c-danger-soft);
}
input.is-invalid:focus, select.is-invalid:focus, textarea.is-invalid:focus {
  box-shadow: 0 0 0 3px var(--c-danger-soft);
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 0 1rem;
}
.checkbox {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  margin: 0 0 1rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--c-text);
  cursor: pointer;
}
.checkbox input[type="checkbox"] {
  width: 16px; height: 16px;
  flex: 0 0 16px;
  margin-top: 0.15rem;
  accent-color: var(--c-accent);
  cursor: pointer;
}
.checkbox-hint {
  display: block;
  font-size: 0.79rem;
  font-weight: 400;
  color: var(--c-text-3);
  margin-top: 0.1rem;
}

.form-actions { display: flex; gap: 0.5rem; align-items: center; margin-top: 0.4rem; }
.form-inline { display: flex; gap: 0.5rem; align-items: flex-end; flex-wrap: wrap; }
/* A handful of one-click actions sitting side by side, each its own tiny
   form (so one button press can't submit its neighbour's command) — the
   machine detail page's "Do something", most visibly. */
.button-row { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.6rem; }
.button-row form { margin: 0; }
/* Several small forms sitting together in one table cell. */
.row-actions {
  display: flex;
  gap: 0.35rem;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
}
.row-actions form { margin: 0; }
.row-actions select { min-width: 120px; font-size: 0.82rem; padding: 0.3rem 1.7rem 0.3rem 0.5rem; }
/* Role + Save take their own line; the two secondary actions share the next. */
.row-actions > .form-inline { flex-basis: 100%; flex-wrap: nowrap; justify-content: flex-end; }
th.manage-col, td.manage-col { width: 300px; }
@media (max-width: 1100px) { th.manage-col, td.manage-col { width: auto; } }
.form-inline .field { margin-bottom: 0; }

/* --- People table: selection, bulk bar, compact per-row Manage ------------- */
th.col-check, td.col-check { width: 2.4rem; text-align: center; vertical-align: middle; }
.col-check input[type="checkbox"] { width: 1rem; height: 1rem; margin: 0; cursor: pointer; accent-color: var(--c-accent); }

.people-bulkbar {
  display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
  margin: 0 0 0.8rem; padding: 0.5rem 0.75rem;
  border: 1px solid var(--c-border); border-radius: var(--radius-sm);
  background: var(--c-surface-2);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.people-bulkbar.is-active { border-color: var(--c-accent); background: var(--c-accent-soft); }
.people-bulkbar .bulk-count { font-size: 0.85rem; min-width: 6rem; }
.people-bulkbar .bulk-actions { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-left: auto; }
.people-bulkbar button[disabled] { opacity: 0.45; cursor: not-allowed; }

/* The Manage cell is one tidy line: the role select, Save and the Manage
   button sit together and do not wrap, so the row is only as tall as the
   name + email beside it. */
.row-manage { display: flex; gap: 0.4rem; align-items: center; justify-content: flex-end; flex-wrap: nowrap; }
.row-manage form { margin: 0; }
.row-role { flex-wrap: nowrap; align-items: center; gap: 0.35rem; }
.row-role select { width: auto; min-width: 92px; font-size: 0.82rem; padding: 0.3rem 1.7rem 0.3rem 0.5rem; }
/* A touch more room for the three controls, and a tighter row. */
.people-table th.manage-col, .people-table td.manage-col { width: 330px; }
.people-table td { padding-top: 0.5rem; padding-bottom: 0.5rem; }

/* The Manage menu: a button that opens a floating menu in the browser's top
   layer (Popover API), so it is never clipped by the table's scroll-region
   and needs no row to grow. The button reuses the .secondary look (so its
   hover and colours match Save and read correctly in both themes); this adds
   only the chevron and the open-state tint. Click-outside and Escape are
   handled natively; app.js only positions it under its button. */
.row-menu-btn .chev { transition: transform 0.15s ease; }
.row-menu-btn[aria-expanded="true"] .chev { transform: rotate(180deg); }
.row-menu-btn[aria-expanded="true"] {
  background: var(--c-accent-soft); border-color: var(--c-accent); color: var(--c-accent);
}
.row-menu-btn[aria-expanded="true"]:hover { color: var(--c-accent); background: var(--c-accent-soft); }

.row-menu {
  position: fixed; margin: 0; inset: auto; /* JS sets top/left */
  min-width: 12rem; max-width: 16rem; padding: 0.35rem;
  border: 1px solid var(--c-border); border-radius: var(--radius);
  background: var(--c-surface); box-shadow: var(--shadow-lg);
  display: none; flex-direction: column; gap: 0.1rem;
}
.row-menu:popover-open { display: flex; }
.row-menu form { margin: 0; }
/* Each action reads as a flat, full-width menu item; its own colour (danger
   red, etc.) is kept as the text, not a filled button, so the menu stays calm. */
.row-menu button {
  width: 100%; justify-content: flex-start; text-align: left;
  background: transparent; border-color: transparent; box-shadow: none;
  padding: 0.5rem 0.6rem; border-radius: var(--radius-sm); font-weight: 500;
}
.row-menu button:hover { background: var(--c-surface-2); border-color: transparent; }
.row-menu button.danger { color: var(--c-danger); }
.row-menu button.danger:hover { background: var(--c-danger-soft); }
/* A link in a menu (Export, Close) reads exactly like a button in it. */
.row-menu > a.linklike {
  display: block; padding: 0.5rem 0.6rem; border-radius: var(--radius-sm);
  color: var(--c-text); font-weight: 500; text-decoration: none;
}
.row-menu > a.linklike:hover { background: var(--c-surface-2); }
.row-menu-sep { height: 1px; margin: 0.25rem 0.2rem; background: var(--c-border); }
.row-menu-label {
  padding: 0.35rem 0.6rem 0.1rem; font-size: 0.72rem; font-weight: 650;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--c-text-3);
}
.row-menu button.row-menu-sub { padding-left: 1.2rem; }
.chat-head-menu { min-width: 13.5rem; }
.chat-contact { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; text-align: center; padding: 0.4rem 0; }
.chat-contact-avatar { width: 64px; height: 64px; font-size: 1.3rem; }

@media (max-width: 760px) {
  .row-manage { justify-content: flex-start; }
  .people-bulkbar .bulk-actions { margin-left: 0; width: 100%; }
}

/* --- Buttons ------------------------------------------------------------ */

/* A link or a <summary> dressed as a button needs only its modifier
   (class="btn-sm secondary", "secondary sm"): the base look comes with
   it. Several screens were written that way and rendered as bare
   underlined links -- the Attendance policy and Planner access buttons
   among them. */
.btn, button,
:is(a, summary):is(.btn-sm, .btn-secondary, .btn-ghost, .btn-danger, .btn-success),
:is(a, summary).secondary.sm {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  background: var(--c-accent-solid);
  color: #fff;
  border: 1px solid transparent;
  padding: 0.5rem 0.9rem;
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
  font-family: inherit;
  font-weight: 550;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease, transform 0.06s ease;
}
.btn:hover, button:hover,
:is(a, summary):is(.btn-sm, .btn-secondary, .btn-ghost, .btn-danger, .btn-success):hover,
:is(a, summary).secondary.sm:hover { background: var(--c-accent-solid-hover); text-decoration: none; color: #fff; }
.btn:active, button:active, :is(a, summary):is(.btn-sm, .btn-secondary, .sm):active { transform: translateY(1px); }
.btn svg, button svg, :is(a, summary):is(.btn-sm, .btn-secondary, .sm) svg { width: 15px; height: 15px; }

.btn-secondary, button.secondary, :is(a, summary):is(.btn-sm, .sm).secondary, :is(a, summary).btn-secondary {
  background: var(--c-surface);
  color: var(--c-text);
  border-color: var(--c-border-strong);
  box-shadow: var(--shadow-sm);
}
.btn-secondary:hover, button.secondary:hover, :is(a, summary):is(.btn-sm, .sm).secondary:hover, :is(a, summary).btn-secondary:hover {
  background: var(--c-surface-2);
  color: var(--c-text);
  border-color: var(--c-text-3);
}

.btn-ghost, button.ghost, :is(a, summary).btn-sm.ghost, :is(a, summary).btn-ghost {
  background: transparent;
  color: var(--c-text-2);
  border-color: transparent;
  box-shadow: none;
}
.btn-ghost:hover, button.ghost:hover, :is(a, summary).btn-sm.ghost:hover, :is(a, summary).btn-ghost:hover { background: var(--c-sunken); color: var(--c-text); }

.btn-danger, button.danger, :is(a, summary).btn-sm.danger, :is(a, summary).btn-danger {
  background: transparent;
  color: var(--c-danger);
  border-color: var(--c-border-strong);
  box-shadow: none;
}
.btn-danger:hover, button.danger:hover, :is(a, summary).btn-sm.danger:hover, :is(a, summary).btn-danger:hover { background: var(--c-danger-soft); color: var(--c-danger); border-color: var(--c-danger); }
.btn-success, :is(a, summary).btn-success {
  background: transparent;
  color: var(--c-success);
  border-color: var(--c-border-strong);
  box-shadow: none;
}
.btn-success:hover, :is(a, summary).btn-success:hover { background: var(--c-success-soft); color: var(--c-success); border-color: var(--c-success); }

.btn-sm, button.sm, :is(a, summary).sm.secondary { padding: 0.33rem 0.62rem; font-size: 0.815rem; }
.btn-block { width: 100%; }

/* --- Badges ------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.14rem 0.5rem;
  border-radius: 999px;
  font-size: 0.735rem;
  font-weight: 580;
  letter-spacing: 0.005em;
  background: var(--c-sunken);
  color: var(--c-text-2);
  white-space: nowrap;
}
.badge-accent  { background: var(--c-accent-soft);  color: var(--c-accent-text); }
.badge-success { background: var(--c-success-soft); color: var(--c-success); }
.badge-warn    { background: var(--c-warn-soft);    color: var(--c-warn); }
.badge-danger  { background: var(--c-danger-soft);  color: var(--c-danger); }
.badge-info    { background: var(--c-info-soft);    color: var(--c-info); }
/* For a value the interface does not have a colour for — a notification kind
   added later, say. Deliberately plain rather than an unstyled badge. */
.badge-muted   { background: var(--c-sunken);       color: var(--c-text-2); }
.dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }

/* --- Flash / alerts ----------------------------------------------------- */

.alert {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius);
  font-size: 0.875rem;
  border: 1px solid transparent;
  margin-bottom: 1rem;
}
.alert svg { width: 16px; height: 16px; flex: none; margin-top: 0.12rem; }
.alert-error { background: var(--c-danger-soft); border-color: var(--c-danger); color: var(--c-danger); }
.alert-info  { background: var(--c-info-soft);   border-color: transparent; color: var(--c-info); }
.alert-warn  { background: var(--c-warn-soft);   border-color: var(--c-warn);  color: var(--c-warn); }
.alert-success { background: var(--c-success-soft); border-color: var(--c-success); color: var(--c-success); }
/* The muted second line of an alert keeps the alert's own colour, dimmed. */
.alert .muted { color: inherit; opacity: 0.8; }

/* --- Charging messages (agent <-> charger) ------------------------------ */

.pings { display: flex; flex-direction: column; gap: 0.85rem; }
.pings-empty { margin: 0; font-size: 0.88rem; }

.ping-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.ping {
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  padding: 0.5rem 0.7rem;
  background: var(--c-surface-2);
  max-width: 44rem;
}
/* My own side of the conversation, tinted and nudged across, so the two
   desks are telling apart at a glance without reading the labels. */
.ping-mine { background: var(--c-accent-soft); border-color: transparent; margin-left: auto; }
.ping-meta { display: flex; gap: 0.45rem; align-items: baseline; flex-wrap: wrap; font-size: 0.76rem; margin-bottom: 0.2rem; }
.ping-who { font-weight: 600; color: var(--c-text); }
.ping-when { font-size: 0.74rem; }
.ping-body { font-size: 0.9rem; color: var(--c-text); }

.ping-form { display: flex; flex-direction: column; gap: 0.5rem; margin: 0; }
.ping-presets { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.ping-preset { text-align: left; }
.ping-compose { display: flex; gap: 0.45rem; align-items: center; }
.ping-compose input[type="text"] { flex: 1 1 auto; min-width: 0; }
.ping-form .field-hint { margin: 0; }

/* The charger's one-tap reply from the queue itself. */
.ping-menu { position: relative; }
.ping-menu > summary { list-style: none; cursor: pointer; }
.ping-menu > summary::-webkit-details-marker { display: none; }
.ping-panel {
  position: absolute; top: calc(100% + 6px); right: 0; width: 272px; max-width: calc(100vw - 24px);
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 0.3rem; z-index: 20; text-align: left;
}
.ping-panel-head { font-size: 0.74rem; color: var(--c-text-3); padding: 0.4rem 0.55rem 0.5rem; }
.ping-panel form { margin: 0; }
.ping-option {
  display: block; width: 100%; text-align: left; padding: 0.45rem 0.6rem; border: 0; border-radius: 7px;
  background: transparent; color: var(--c-text); font-size: 0.86rem; cursor: pointer;
}
.ping-option:hover { background: var(--c-accent-soft); color: var(--c-accent-text); }
.ping-option-more { border-top: 1px solid var(--c-border); border-radius: 0 0 7px 7px; color: var(--c-text-2); }

/* A screenshot someone attached to a report: never wider than the card. */
.attached-shot { max-width: 100%; border: 1px solid var(--c-border); border-radius: 8px; display: block; }

/* A raw log or JSON dump: wrapped, and capped so it cannot run the page off
   the screen. (These were style attributes, which the CSP drops.) */
.dump {
  white-space: pre-wrap;
  word-break: break-word;
  overflow: auto;
  max-height: min(24rem, 55vh);
  margin: 0;
}

/* A long opaque string — a token — broken rather than overflowing. */
.break-all { word-break: break-all; }

/* "Test the key", under the save button: a quiet button and its one line. */
.addr-test { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; margin-top: 0.85rem; }
.addr-test .muted { font-size: 0.85rem; }

/* A list of facts, not a bulleted paragraph: no marker, no indent. */
.plain-list { list-style: none; padding: 0; margin: 0 0 0.9rem; }
.plain-list li { padding: 0.15rem 0; font-size: 0.89rem; }

/* --- Empty states ------------------------------------------------------- */

.empty { text-align: center; padding: 2.1rem 1rem; color: var(--c-text-3); }
.empty svg { width: 28px; height: 28px; opacity: 0.5; margin-bottom: 0.5rem; }
.empty-title { font-weight: 570; color: var(--c-text-2); font-size: 0.92rem; }
.empty-hint { font-size: 0.845rem; margin-top: 0.15rem; }

/* --- Pipeline (kanban) -------------------------------------------------- */

.board {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(250px, 1fr);
  gap: 0.9rem;
  overflow-x: auto;
  padding-bottom: 0.5rem;
  align-items: start;
  /* A grid sized by its columns will happily grow past its container
     and take the page with it. These keep the scrolling inside the
     board, which is what overflow-x was for. */
  min-width: 0;
  max-width: 100%;
}
.board-col {
  background: var(--c-sunken);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 220px);
}
.board-col-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 0.85rem;
  border-bottom: 1px solid var(--c-border);
  position: sticky; top: 0;
  background: var(--c-sunken);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.board-col-head h3 { font-size: 0.82rem; font-weight: 620; text-transform: uppercase; letter-spacing: 0.05em; color: var(--c-text-2); }
.board-col-count {
  margin-left: auto;
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--c-text-3);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: 999px;
  padding: 0.02rem 0.44rem;
  font-variant-numeric: tabular-nums;
}
.board-col-body { padding: 0.65rem; display: flex; flex-direction: column; gap: 0.55rem; overflow-y: auto; }
.board-col-foot {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.6rem 0.85rem;
  border-top: 1px solid var(--c-border);
}
.board-col-total {
  margin-left: auto;
  font-size: 0.86rem;
  font-weight: 640;
  font-variant-numeric: tabular-nums;
}
.deal {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  padding: 0.7rem 0.75rem;
  box-shadow: var(--shadow-sm);
}
.deal-title { font-weight: 570; font-size: 0.885rem; line-height: 1.35; }
.deal-meta {
  display: flex; align-items: baseline; gap: 0.5rem;
  margin-top: 0.15rem; margin-bottom: 0.5rem;
}
.deal-amount { font-size: 0.95rem; font-weight: 640; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.deal-customer { font-size: 0.79rem; color: var(--c-text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deal-move { display: flex; gap: 0.35rem; }
.deal-move select { font-size: 0.8rem; padding: 0.28rem 1.6rem 0.28rem 0.5rem; }
.deal-move button { padding: 0.28rem 0.55rem; font-size: 0.8rem; }

/* --- Attendance --------------------------------------------------------- */

.clock {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}
.clock-status { display: flex; align-items: center; gap: 0.6rem; }
.clock-state { font-size: 1.05rem; font-weight: 620; letter-spacing: -0.01em; }
.clock-actions { margin-left: auto; display: flex; gap: 0.5rem; flex-wrap: wrap; }
.pulse {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--c-text-3);
  flex: none;
}
.pulse-working { background: var(--c-success); box-shadow: 0 0 0 3px var(--c-success-soft); }
.pulse-break   { background: var(--c-warn);    box-shadow: 0 0 0 3px var(--c-warn-soft); }

.correction {
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  padding: 0.75rem 0.85rem;
  margin-bottom: 0.65rem;
  background: var(--c-surface-2);
}
.correction:last-child { margin-bottom: 0; }
.correction-head { display: flex; gap: 0.6rem; align-items: baseline; flex-wrap: wrap; }
.correction-date { font-weight: 580; font-size: 0.875rem; }
.correction-reason { color: var(--c-text-2); font-size: 0.855rem; }
.correction ul { margin: 0.45rem 0 0.6rem; padding-left: 1.1rem; font-size: 0.855rem; color: var(--c-text-2); }
.correction-actions { display: flex; gap: 0.45rem; }

/* --- Auth screens ------------------------------------------------------- */

.auth {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 1.5rem;
  background:
    radial-gradient(900px 500px at 50% -10%, var(--c-accent-soft), transparent 70%),
    var(--c-bg);
}
.auth-card {
  width: 100%;
  max-width: 400px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 1.75rem;
}
.auth-brand {
  display: flex; align-items: center; justify-content: center; gap: 0.55rem;
  margin-bottom: 1.35rem;
  font-weight: 650; font-size: 1.02rem; letter-spacing: -0.015em;
  color: var(--c-text);
}
.auth-card h1 { font-size: 1.22rem; margin-bottom: 0.3rem; }
.auth-sub { color: var(--c-text-2); font-size: 0.885rem; margin-bottom: 1.25rem; }
.auth-foot {
  margin-top: 1.15rem; padding-top: 1rem;
  border-top: 1px solid var(--c-border);
  font-size: 0.815rem; color: var(--c-text-3);
  text-align: center;
}

/* --- Download page ------------------------------------------------------
   Same centered/branded frame as the auth screens (.auth wraps it), but
   wider and free-flowing rather than a tight form card — there's a
   button, a metadata list and a short numbered guide to fit, not just
   two inputs. */
.download-card {
  width: 100%;
  max-width: 560px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 2rem 2.25rem;
}
.download-btn {
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  margin-top: 0.25rem;
}
.download-meta {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem;
  margin: 1rem 0 1.1rem; padding: 0.85rem 1rem;
  background: var(--c-sunken); border: 1px solid var(--c-border);
  border-radius: var(--radius);
  font-size: 0.83rem;
}
.download-meta > div { display: flex; gap: 0.4rem; align-items: baseline; }
.download-meta dt { color: var(--c-text-3); }
.download-meta dd { margin: 0; color: var(--c-text-2); font-weight: 550; }
.download-checksum { flex-basis: 100%; }
.download-checksum code {
  font-size: 0.76rem; word-break: break-all; color: var(--c-text-2);
}
.download-h2 { font-size: 0.95rem; margin: 1.5rem 0 0.6rem; }
.download-steps {
  margin: 0 0 1rem; padding-left: 1.2rem;
  font-size: 0.87rem; color: var(--c-text-2); line-height: 1.55;
}
.download-steps li { margin-bottom: 0.3rem; }

/* Authenticator enrolment: the QR is the primary path, the typed key
   the fallback. The SVG carries its own intrinsic size, so it stays
   square and legible even if this rule never arrives. */
.qr-enrol {
  margin: 0 0 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}
.qr-enrol svg {
  width: 100%;
  max-width: 208px;
  height: auto;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-sm);
  background: #fff;
  padding: 0.35rem;
}
.qr-enrol figcaption {
  font-size: 0.8rem;
  color: var(--c-text-3);
  text-align: center;
}
.secret-fallback {
  margin-bottom: 1rem;
}
.secret-fallback > summary {
  cursor: pointer;
  font-size: 0.815rem;
  color: var(--c-text-3);
  margin-bottom: 0.6rem;
}
.secret-fallback > summary:hover { color: var(--c-text-2); }
.secret-fallback .secret-box { margin-bottom: 0.6rem; }

.secret-box {
  background: var(--c-sunken);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-sm);
  padding: 0.65rem 0.75rem;
  margin-bottom: 1rem;
}
.secret-label {
  font-size: 0.71rem; text-transform: uppercase; letter-spacing: 0.07em;
  font-weight: 620; color: var(--c-text-3); margin-bottom: 0.25rem;
}
.secret-value {
  font-family: var(--font-mono);
  font-size: 0.86rem;
  word-break: break-all;
  letter-spacing: 0.02em;
  color: var(--c-text);
}
.temp-password {
  font-family: var(--font-mono);
  font-size: 1rem;
  letter-spacing: 0.04em;
  background: var(--c-sunken);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-sm);
  padding: 0.3rem 0.55rem;
  user-select: all;
}

.codes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 0.5rem;
}
.codes code {
  font-family: var(--font-mono);
  font-size: 0.92rem;
  letter-spacing: 0.04em;
  background: var(--c-sunken);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-sm);
  padding: 0.45rem 0.6rem;
  text-align: center;
  user-select: all;
}

.code-input {
  font-family: var(--font-mono);
  font-size: 1.28rem;
  letter-spacing: 0.34em;
  text-align: center;
  padding: 0.6rem 0.5rem;
}

/* --- Error page --------------------------------------------------------- */

.error-page {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 1.5rem;
  text-align: center;
  background:
    radial-gradient(900px 500px at 50% -10%, var(--c-accent-soft), transparent 70%),
    var(--c-bg);
}
.error-code {
  font-size: 3.4rem;
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1;
  color: var(--c-text-3);
  font-variant-numeric: tabular-nums;
}
.error-message { font-size: 1.05rem; font-weight: 560; margin: 0.6rem 0 0.35rem; }
.error-hint { color: var(--c-text-2); font-size: 0.89rem; margin-bottom: 1.25rem; }

/* --- Utilities ---------------------------------------------------------- */

.muted { color: var(--c-text-3); font-size: 0.855rem; }
.spacer { margin-left: auto; }
.stack > * + * { margin-top: 0.85rem; }
.row { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; }
.nowrap { white-space: nowrap; }
.mono { font-family: var(--font-mono); font-size: 0.875em; }
/* Visible to a screen reader, to nothing else.
 *
 * `left: 0` is not decoration. Without it an absolutely positioned
 * element sits at its static position, and inside anything wide —
 * the pipeline board, a table scrolling in its wrapper — that
 * position is hundreds of pixels to the right. It is one pixel and
 * clipped, so it cannot be seen, but it is positioned against the
 * page rather than against the scroller it is nominally inside, so
 * it escapes the clip and drags the whole document out with it. The
 * symptom was three screens that could be swiped sideways on a phone
 * into several hundred pixels of nothing.
 *
 * `clip-path` alongside the deprecated `clip` for the browsers that
 * have dropped the latter. */
.sr-only {
  /* Both offsets pinned. With `left` alone the element keeps its static
     VERTICAL position, so the author label on a message scrolled deep
     inside the chat log sat hundreds of pixels down and dragged the whole
     document's scroll height with it -- the page scrolled into a band of
     blank below the app. It is 1px and clipped either way; pinning top
     means it can never add height to anything. */
  position: absolute; top: 0; left: 0; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* Progressive enhancement: forms work without JavaScript (an explicit submit
   button); app.js sets .js on <html>, which hides the buttons it replaces
   with change-handlers. Nothing here is required for the app to function. */
.js .js-hidden { display: none; }

/* --- Chat --------------------------------------------------------------- */

/* A chat screen fills the window. Sized to its content it left a band of
   empty page under the conversation, and the message list got a smaller
   box than the screen actually had. The 92px is the chrome above it --
   the same budget the rail already used for its own cap. */
.chat {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  gap: 1rem;
  /* The fallback, for a browser without :has() below: the topbar (58px)
     plus the page's own padding (2 x 1.75rem). It used to say 92px, which
     was 22px too tall, and those 22px were enough to make the whole page
     scroll under a screen that is meant not to. */
  height: calc(100dvh - 114px);
  align-items: stretch;
}
/* Measured rather than guessed. The shell is normally min-height:100vh and
   grows with the page; a chat screen is the opposite -- it fills the window
   exactly and scrolls inside itself -- so for that one screen the shell is
   given a definite height and the chat takes whatever is left under the
   topbar. Without the definite height, `flex: 1` has nothing to divide and
   the chat grows the document instead of fitting in it.

   Desktop only: below 900px the chat is one column of ordinary page, and
   the media query further down sets its own heights. */
@media (min-width: 901px) {
  .shell:has(.chat) { height: 100dvh; overflow: hidden; }
  .shell:has(.chat) > .content { min-height: 0; }
  .page:has(> .chat) { flex: 1 1 auto; min-height: 0; }
  .page:has(> .chat) > .chat { height: 100%; }
}

.chat-rail {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 0.75rem;
  min-height: 0;
  overflow-y: auto;
}
.chat-rail-group + .chat-rail-group { margin-top: 1rem; }
.chat-rail-label {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 640;
  color: var(--c-text-3);
  padding: 0 0.4rem 0.35rem;
}
/* A conversation row: avatar, two lines of text, time and badge.
   Exactly one coloured thing per row at rest (the unread badge) -- that
   is what stops thirty rows reading as noise. */
.chat-row {
  display: flex;
  align-items: stretch;
  border-radius: var(--radius-sm);
  position: relative;
}
.chat-row-link {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.2rem 0.5rem 0.5rem;
  color: var(--c-text-2);
  border-radius: var(--radius-sm);
}
.chat-row-link:hover { text-decoration: none; color: var(--c-text); }
.chat-row:hover { background: var(--c-sunken); }
/* Selected beats hover, and carries a bar on the leading edge. */
.chat-row.is-active { background: var(--c-accent-soft); }
.chat-row.is-active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 3px;
  border-radius: 0 2px 2px 0;
  background: var(--c-accent-solid);
}
.chat-row.is-active .chat-row-name { color: var(--c-accent-text); }
.chat-row-link:focus-visible { outline: 2px solid var(--c-ring); outline-offset: -2px; }

.chat-avatar {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.82rem;
  font-weight: 650;
  background: var(--c-sunken);
  color: var(--c-text-2);
}
.chat-row.is-active .chat-avatar { background: var(--c-surface); }

.chat-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.chat-row-top, .chat-row-bottom { display: flex; align-items: center; gap: 0.3rem; min-width: 0; }
.chat-row-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.885rem;
  font-weight: 500;
  color: var(--c-text);
}
.chat-row.is-unread .chat-row-name { font-weight: 680; }
/* The time never truncates -- it wins over the name. */
.chat-row-when { flex: none; font-size: 0.72rem; color: var(--c-text-3); }
.chat-row-mute, .chat-row-pin { flex: none; color: var(--c-text-3); }
.chat-row-preview {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.78rem;
  color: var(--c-text-3);
}
.chat-row.is-unread .chat-row-preview { color: var(--c-text-2); }

/* Reserved at rest so crossing the row with the mouse never shifts it. */
.chat-row-menu-btn {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  min-height: 26px;
  padding: 0;
  margin-right: 0.15rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--c-text-3);
  visibility: hidden;
  cursor: pointer;
}
.chat-row:hover .chat-row-menu-btn,
.chat-row-menu-btn:focus-visible,
.chat-row-menu-btn[aria-expanded="true"] { visibility: visible; }
.chat-row-menu-btn:hover { background: none; color: var(--c-text); }
/* The search box in the rail, and what it turns up. */
.chat-search {
  position: relative;
  display: flex;
  align-items: center;
  margin: 0 0.3rem 0.5rem;
}
.chat-search-icon {
  position: absolute;
  left: 0.55rem;
  color: var(--c-text-3);
  pointer-events: none;
}
.chat-search input {
  width: 100%;
  padding: 0.42rem 1.9rem 0.42rem 2rem;
  font-size: 0.83rem;
  border-radius: 999px;
  background: var(--c-sunken);
}
.chat-search input::-webkit-search-cancel-button { display: none; }
.chat-search-clear {
  position: absolute;
  right: 0.3rem;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--c-text-3);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.chat-search-clear:hover { background: var(--c-surface); color: var(--c-text); }
.chat-find-empty { padding: 0.4rem 0.6rem; font-size: 0.82rem; }
.chat-chips { display: flex; flex-wrap: wrap; gap: 0.25rem; margin: 0 0.3rem 0.5rem; }

/* Your own avatar in the rail, which opens chat settings. */
.chat-me { flex: none; padding: 0; border: 0; background: none; border-radius: 50%; cursor: pointer; }
.chat-me .chat-avatar { width: 30px; height: 30px; font-size: 0.72rem; }
.chat-me:focus-visible { outline: 2px solid var(--c-ring); outline-offset: 2px; }

/* Settings take the list's place: everything else in the rail steps
   aside (menus and dialogs stay, they live in the top layer). */
.chat-rail.is-settings > :not(.chat-settings):not([popover]) { display: none; }
.chat-settings[hidden] { display: none; }
.chat-settings { display: flex; flex-direction: column; gap: 0.2rem; }
.chat-settings-head { display: flex; align-items: center; gap: 0.4rem; padding: 0.1rem 0.2rem 0.5rem; border-bottom: 1px solid var(--c-border); }
.chat-settings-head strong { font-size: 0.95rem; }
.chat-settings-profile {
  display: flex; flex-direction: column; align-items: center; gap: 0.3rem;
  padding: 1rem 0.5rem; text-align: center; border-bottom: 1px solid var(--c-border);
}
.chat-settings-profile .muted { font-size: 0.8rem; overflow-wrap: anywhere; }
.chat-settings-section { padding: 0.75rem 0.4rem; border-bottom: 1px solid var(--c-border); }
.chat-settings-section h3 {
  margin: 0 0 0.45rem; font-size: 0.72rem; font-weight: 650; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--c-text-3);
}
.chat-settings-section h3:not(:first-of-type) { margin-top: 0.8rem; }
.chat-keys { display: grid; grid-template-columns: auto 1fr; gap: 0.35rem 0.6rem; margin: 0; font-size: 0.8rem; }
.chat-keys dt { white-space: nowrap; color: var(--c-text-2); }
.chat-keys dd { margin: 0; color: var(--c-text-3); }
.chat-keys kbd {
  display: inline-block; padding: 0 0.3rem; border: 1px solid var(--c-border); border-bottom-width: 2px;
  border-radius: 4px; font: inherit; font-size: 0.75rem; background: var(--c-surface-2);
}
.chat-chips .chip {
  padding: 0.18rem 0.6rem;
  border: 1px solid var(--c-border);
  border-radius: 999px;
  background: none;
  color: var(--c-text-2);
  font-size: 0.76rem;
  cursor: pointer;
}
.chat-chips .chip:hover { background: var(--c-sunken); }
.chat-chips .chip.is-active {
  background: var(--c-accent-soft);
  border-color: var(--c-accent);
  color: var(--c-accent-text);
  font-weight: 600;
}
.chat-shelf {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.4rem 0.5rem;
  margin-bottom: 0.3rem;
  border-radius: var(--radius-sm);
  font-size: 0.83rem;
  color: var(--c-text-2);
}
.chat-shelf:hover { background: var(--c-sunken); color: var(--c-text); text-decoration: none; }
.chat-find-results { margin-top: 0.6rem; border-top: 1px solid var(--c-border); padding-top: 0.5rem; }
.chat-find-hit {
  display: flex;
  flex-direction: column;
  gap: 0.12rem;
  padding: 0.4rem 0.5rem;
  border-radius: var(--radius-sm);
  color: var(--c-text-2);
}
.chat-find-hit:hover { background: var(--c-sunken); text-decoration: none; }
.chat-find-hit-top { display: flex; align-items: baseline; gap: 0.4rem; min-width: 0; }
.chat-find-hit-who {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--c-text);
}
.chat-find-hit-when { flex: none; font-size: 0.7rem; color: var(--c-text-3); }
.chat-find-hit-body {
  font-size: 0.78rem;
  color: var(--c-text-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chat-find-all { display: block; padding: 0.4rem 0.5rem; font-size: 0.78rem; }
.chat-find-people { margin-top: 0.5rem; border-top: 1px solid var(--c-border); padding-top: 0.5rem; }
.chat-find-person {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  text-align: left;
  padding: 0.35rem 0.45rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--c-text-2);
  cursor: pointer;
}
.chat-find-person:hover { background: var(--c-sunken); color: var(--c-text); }
.chat-find-person .chat-avatar { width: 30px; height: 30px; font-size: 0.72rem; }
.chat-find-person-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.85rem;
  font-weight: 500;
}

.chat-rail-list { display: flex; flex-direction: column; gap: 1px; }
/* `display: flex` beats the `hidden` attribute's `display: none`, so a
   filtered-out row stayed on screen while the "nothing matches" line
   appeared above it. Anything given a display here has to say this. */
.chat-row[hidden], .chat-pick-row[hidden], .chat-find-hit[hidden] { display: none; }
/* Still used by the "All groups" join rows in the settings panel. */
.chat-rail-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.85rem; }
.chat-rail-empty { padding: 0.6rem 0.5rem; font-size: 0.83rem; }

.chat-unread {
  margin-left: auto;
  background: var(--c-accent-solid);
  color: #fff;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 650;
  padding: 0.02rem 0.4rem;
  font-variant-numeric: tabular-nums;
}
/* Moderator controls above a channel: rename it, archive it, bring it
   back. Wraps rather than scrolls, because the name field is the wide
   part and a phone has nowhere to put it beside two buttons. */
/* The rail's toolbar, and the conversation header. One line each: the
   forms they replaced used to sit permanently open and pushed the
   conversations -- and the messages -- down the screen. */
.chat-rail-head {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.15rem 0.3rem 0.5rem;
  border-bottom: 1px solid var(--c-border);
  margin-bottom: 0.5rem;
}
.chat-rail-title {
  flex: 1;
  min-width: 0;
  font-weight: 640;
  font-size: 0.9rem;
  color: var(--c-text);
  padding-left: 0.15rem;
}
.chat-tool {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex: none;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--c-text-2);
  cursor: pointer;
}
.chat-tool:hover { background: var(--c-sunken); color: var(--c-text); text-decoration: none; }

.chat-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 1.15rem;
  border-bottom: 1px solid var(--c-border);
}
.chat-head-who { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.chat-head-who strong { font-size: 0.95rem; }
.chat-head-who .muted { font-size: 0.78rem; }

/* A panel in the top layer, so it is never clipped by the rail's own
   scrolling. ::backdrop dims what is behind it. */
.chat-dialog, .pop-dialog {
  width: min(28rem, calc(100vw - 2rem));
  max-height: min(34rem, calc(100vh - 4rem));
  padding: 0;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  background: var(--c-surface);
  color: var(--c-text);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.26);
  overflow: hidden;
}
.chat-dialog::backdrop, .pop-dialog::backdrop { background: rgba(0, 0, 0, 0.3); }
.chat-dialog-head, .pop-dialog-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--c-border);
}
.chat-dialog-head strong, .pop-dialog-head strong { flex: 1; min-width: 0; }
.chat-dialog-close, .pop-dialog-close {
  width: 26px;
  height: 26px;
  flex: none;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--c-text-2);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}
.chat-dialog-close:hover, .pop-dialog-close:hover { background: var(--c-sunken); color: var(--c-text); }
/* A form in a dialog (People -> Edit details): the fields stack, the
   actions sit at the bottom right. */
.pop-dialog-body {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 0.9rem;
  margin: 0;
}
.pop-dialog-body .field input { width: 100%; }
.pop-dialog-body .form-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin: 0; }
.chat-dialog-body {
  padding: 0.6rem 0.9rem 0.9rem;
  overflow-y: auto;
  max-height: calc(min(34rem, 100vh - 4rem) - 3rem);
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}
.chat-dialog-body > form { gap: 0.45rem; }
.chat-dialog-link {
  display: block;
  padding: 0.4rem 0.1rem;
  font-size: 0.88rem;
}

.chat-manage { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center;
               padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--c-border); }
.chat-manage input[type="text"] { flex: 1 1 10rem; min-width: 0; font-size: 0.85rem; padding: 0.35rem 0.5rem; }

.chat-rail-form { display: flex; flex-direction: column; gap: 0.4rem; padding: 0.3rem 0.4rem 0; }
.chat-rail-form input, .chat-rail-form select { font-size: 0.83rem; padding: 0.35rem 0.5rem; }
.chat-rail-form select { padding-right: 1.7rem; }

.chat-main {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  /* min-height:0 so the log can actually shrink inside the grid row;
     without it a flex child refuses to go below its content height and
     the whole column overflows the window instead of scrolling. */
  min-height: 0;
}
.chat-log {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 1rem 1.15rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
/* The message list sits in its own wrapper so the live refresh can
   replace just the messages and leave the "load earlier" control alone.
   That wrapper has to carry the column layout, or .msg stops being a flex
   child of the scroller and own-messages stop sitting on the right. */
.chat-log > [data-chat-body] {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.chat-older {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.5rem;
  padding: 0.15rem 0 0.35rem;
}
.chat-older-busy { font-size: 0.82rem; color: var(--c-text-3); }

/* What is about to be sent, under the composer. */
.chat-attachments {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.5rem 0.85rem 0;
}
.chat-attachment {
  position: relative;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--c-border);
  border-radius: 0.5rem;
  overflow: hidden;
  background: var(--c-surface-2);
}
.chat-attachment img {
  display: block;
  width: 72px;
  height: 72px;
  object-fit: cover;
}
.chat-attachment-name {
  padding: 0.45rem 1.6rem 0.45rem 0.6rem;
  font-size: 0.82rem;
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chat-attachment-drop {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 20px;
  height: 20px;
  padding: 0;
  line-height: 1;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.62);
  color: #fff;
  font-size: 0.95rem;
  cursor: pointer;
}
.chat-attachment-drop:hover { background: rgba(0, 0, 0, 0.82); }

/* --- The message list ----------------------------------------------------
   The spacing ladder is most of what reads as "clean": 2px between
   messages inside a run, 12px between runs, 24px around a day separator.
   A run is one person speaking without a break; see _log.php. */
.chat-log > [data-chat-body] { gap: 0; }

.msg {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  max-width: min(65ch, 560px);
  margin-top: 2px;
}
.msg.starts-run { margin-top: 12px; }
.msg.is-self { align-self: flex-end; flex-direction: row-reverse; }
.msg-main { min-width: 0; display: flex; flex-direction: column; }
.msg-bubble { position: relative; min-width: 0; }

/* Who said it, once per run. In a direct message the side already says. */
.msg-head { display: flex; align-items: baseline; gap: 0.45rem; margin-bottom: 0.15rem; }
.msg.is-self .msg-head { justify-content: flex-end; }
.msg-author { font-size: 0.8rem; font-weight: 640; color: var(--c-text-2); }

.msg-avatar {
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 650;
  background: var(--c-sunken);
  color: var(--c-text-2);
  margin-top: 1.15rem;
}
/* Messages later in a run line up under the first one's text. */
.msg.in-run:not(.is-self) { padding-left: calc(28px + 0.5rem); }

.msg-time { font-size: 0.7rem; color: var(--c-text-3); font-variant-numeric: tabular-nums; }
.msg-head form { margin: 0; }

.msg-body {
  background: var(--c-sunken);
  border: 1px solid var(--c-border);
  border-radius: 4px 12px 12px 12px;
  padding: 0.5rem 0.7rem;
  font-size: 0.9rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
}
/* Only the first bubble of a run gets the cut corner — the cheap,
   robust version of a tail. On every bubble it reads as clutter. */
.msg.in-run:not(.is-self) .msg-body { border-radius: 12px; }
.msg.is-self .msg-body {
  background: var(--c-accent-solid);
  border-color: transparent;
  color: #fff;
  border-radius: 12px 4px 12px 12px;
}
.msg.is-self.in-run .msg-body { border-radius: 12px; }

/* A day, and the line you had read up to. Sticky, so scrolling back
   through February always says which February day you are in. */
.msg-day {
  position: sticky;
  top: 0;
  z-index: 1;
  align-self: center;
  margin: 24px 0 12px;
  pointer-events: none;
}
.msg-day span {
  display: inline-block;
  padding: 0.18rem 0.6rem;
  border-radius: 999px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--c-text-3);
}
.msg-divider {
  align-self: stretch;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 16px 0 8px;
  color: var(--c-accent-text);
  font-size: 0.72rem;
  font-weight: 650;
}
.msg-divider::before, .msg-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--c-accent-solid);
  opacity: 0.4;
}

/* Jump to the newest messages, with what you have not seen on it. */
.chat-jump {
  position: absolute;
  right: 1.2rem;
  bottom: 5.2rem;
  z-index: 2;
  width: 38px;
  height: 38px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--c-border);
  border-radius: 50%;
  background: var(--c-surface);
  color: var(--c-text-2);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16);
  cursor: pointer;
}
.chat-jump:hover { background: var(--c-sunken); color: var(--c-text); }
.chat-jump-count {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 18px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--c-accent-solid);
  color: #fff;
  font-size: 0.66rem;
  font-weight: 700;
  line-height: 18px;
}
.chat-main { position: relative; }

.msg-system {
  align-self: center;
  max-width: min(65ch, 560px);
  margin: 12px 0;
  text-align: center;
  font-size: 0.74rem;
  color: var(--c-text-3);
}

/* Reactions: a chip row under the bubble, and the quick row in the menu.
   A chip the viewer has used is outlined in the accent, which is what
   makes "have I already reacted?" answerable at a glance. */
/* Dropping files on the conversation, searching inside it, and the
   star that marks a bookmarked message. */
.chat-drop {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px dashed var(--c-accent);
  border-radius: var(--radius-lg);
  background: var(--c-accent-soft);
  color: var(--c-accent-text);
  font-weight: 600;
  pointer-events: none;
}
.chat-drop[hidden] { display: none; }
.chat-here {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1.15rem;
  border-bottom: 1px solid var(--c-border);
}
.chat-here input { flex: 1; min-width: 0; font-size: 0.85rem; padding: 0.35rem 0.6rem; border-radius: 999px; }
.chat-here-count { flex: none; font-size: 0.76rem; color: var(--c-text-3); }
.chat-here-results {
  max-height: 11rem;
  overflow-y: auto;
  border-bottom: 1px solid var(--c-border);
  padding: 0.3rem 0.8rem 0.5rem;
}
.chat-here-hit {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  width: 100%;
  text-align: left;
  padding: 0.35rem 0.45rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  cursor: pointer;
}
.chat-here-hit:hover { background: var(--c-sunken); }
.chat-here-who { font-size: 0.72rem; font-weight: 600; color: var(--c-text-2); }
.chat-here-text {
  font-size: 0.78rem;
  color: var(--c-text-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Where a jump landed, briefly. */
.msg.is-found .msg-body { outline: 2px solid var(--c-accent); outline-offset: 2px; }
.msg-star { color: var(--c-warn); display: inline-flex; align-items: center; }

/* A message shown before the server has confirmed it, and one that did
   not make it. The text is never greyed: people re-read what they just
   sent. Only the state line says it is still on its way. */
.msg-body-pending { white-space: pre-wrap; }
/* The foot sits under the bubble, on the page, so it is muted text --
   not the white that suits text inside an accent-coloured bubble. */
.msg.is-pending .msg-state { font-size: 0.7rem; color: var(--c-text-3); }
.msg.is-pending .msg-foot { justify-content: flex-end; }
.msg.is-failed .msg-body { background: var(--c-danger-soft); color: var(--c-text); border: 1px solid var(--c-danger); }
.msg.is-failed .msg-state { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; color: var(--c-danger); }
.msg.is-failed .msg-state .linklike { font-size: 0.75rem; font-weight: 600; }

/* Selecting several messages. The box is hidden until selecting, and
   the whole row is the target then — aiming at a small box is the fiddly
   part of selecting on any screen. */
.msg-select { display: none; flex: none; margin: 0.4rem 0 0; width: 18px; height: 18px; }
.chat-log.is-selecting .msg { cursor: pointer; }
.chat-log.is-selecting .msg-select { display: block; }
.chat-log.is-selecting .msg-menu { display: none; }
.msg.is-picked .msg-body { box-shadow: 0 0 0 2px var(--c-accent); }
.chat-bulkbar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.65rem 1.15rem;
  border-top: 1px solid var(--c-border);
  background: var(--c-surface);
}
.chat-bulkbar[hidden], .chat-compose[hidden] { display: none; }
.chat-bulk-count { font-size: 0.88rem; font-weight: 600; }
.chat-bulkbar .spacer { flex: 1; }

/* Who is around, and who is writing. */
.presence-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 0.3rem;
  vertical-align: 1px;
  background: var(--c-text-3);
}
.presence-dot.is-available { background: var(--c-success); }
.presence-dot.is-away { background: var(--c-warn); }
.chat-typing {
  margin: 0;
  padding: 0.25rem 1.15rem 0;
  font-size: 0.78rem;
  color: var(--c-text-3);
  font-style: italic;
}

.msg-reactions { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-top: 0.25rem; }
.msg-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  min-height: 24px;
  padding: 0.1rem 0.4rem;
  border: 1px solid var(--c-border);
  border-radius: 999px;
  background: var(--c-surface);
  color: var(--c-text-2);
  font-size: 0.78rem;
  line-height: 1.3;
  cursor: pointer;
}
.msg-chip:hover { background: var(--c-sunken); }
.msg-chip.is-mine { border-color: var(--c-accent); background: var(--c-accent-soft); color: var(--c-accent-text); }
.msg-chip-emoji { font-size: 0.9rem; }
.msg-chip-n { font-variant-numeric: tabular-nums; font-weight: 600; }

.msg-quick {
  display: flex;
  flex-wrap: wrap;
  gap: 0.1rem;
  padding-bottom: 0.3rem;
  margin-bottom: 0.2rem;
  border-bottom: 1px solid var(--c-border);
}
.msg-quick-btn {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.msg-quick-btn:hover { background: var(--c-sunken); }

/* The picker, shared by the composer and by any message. */
.emoji-pop {
  width: min(20rem, calc(100vw - 2rem));
  max-height: 22rem;
  padding: 0;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  background: var(--c-surface);
  color: var(--c-text);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.26);
  overflow: hidden;
}
.emoji-pop::backdrop { background: rgba(0, 0, 0, 0.18); }
.emoji-search { padding: 0.55rem 0.65rem; border-bottom: 1px solid var(--c-border); }
.emoji-search input { width: 100%; font-size: 0.83rem; padding: 0.35rem 0.55rem; border-radius: 999px; }
.emoji-grid { padding: 0.5rem 0.65rem 0.75rem; overflow-y: auto; max-height: 17rem; }
.emoji-group-name {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-weight: 650;
  color: var(--c-text-3);
  margin: 0.4rem 0 0.25rem;
}
.emoji-group-items { display: flex; flex-wrap: wrap; gap: 0.1rem; }
.emoji-btn {
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
}
.emoji-btn:hover { background: var(--c-sunken); }
.emoji-none { padding: 0 0.75rem 0.75rem; font-size: 0.82rem; }
.chat-emoji-btn {
  flex: none;
  display: flex;
  align-items: center;
  padding: 0.3rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--c-text-3);
  cursor: pointer;
}
.chat-emoji-btn:hover { background: none; color: var(--c-text); }

.msg-delete {
  background: none;
  border: none;
  color: var(--c-text-3);
  font-size: 1rem;
  line-height: 1;
  padding: 0 0.2rem;
  cursor: pointer;
  box-shadow: none;
}
.msg-delete:hover { background: none; color: var(--c-danger); }

/* The @ list, above the message box. Anchored to the composer, which is
   position:relative, and capped so a company channel's list scrolls
   rather than filling the screen. */
.chat-at {
  position: absolute;
  left: 1.15rem;
  right: 1.15rem;
  bottom: calc(100% - 0.35rem);
  z-index: 6;
  max-height: 15rem;
  overflow-y: auto;
  padding: 0.3rem;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  background: var(--c-surface);
  box-shadow: 0 -8px 28px rgba(0, 0, 0, 0.16);
}
.chat-at[hidden] { display: none; }
.chat-at-row {
  display: flex;
  width: 100%;
  align-items: center;
  /* Buttons centre their content by default; a list row reads left. */
  justify-content: flex-start;
  gap: 0.6rem;
  padding: 0.4rem 0.5rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--c-text);
  text-align: left;
  box-shadow: none;
  cursor: pointer;
}
.chat-at-row[hidden] { display: none; }
.chat-at-row:hover, .chat-at-row.is-active { background: var(--c-sunken); color: var(--c-text); }
.chat-at-row .chat-avatar { flex: none; }
.chat-at-main { display: flex; flex-direction: column; min-width: 0; align-items: flex-start; }
.chat-at-name { font-weight: 550; font-size: 0.88rem; }
.chat-at-sub { font-size: 0.76rem; color: var(--c-text-3); }
.chat-at-all { background: var(--c-accent-soft); color: var(--c-accent-text); font-weight: 700; }
.chat-at-none { padding: 0.5rem; margin: 0; font-size: 0.85rem; }
.chat-at-none[hidden] { display: none; }

/* A name inside a message. The viewer's own mention is the accent one --
   "this one is about you" is the only thing the colour has to say. */
.mention {
  font-weight: 560;
  color: var(--c-text-2);
  border-radius: 4px;
}
.mention.is-me {
  color: var(--c-accent-text);
  background: var(--c-accent-soft);
  padding: 0 0.15rem;
}
.msg.is-self .mention { color: inherit; font-weight: 640; }
.msg.is-self .mention.is-me { background: rgba(255, 255, 255, 0.22); color: inherit; }

.chat-compose {
  position: relative;
  display: flex;
  gap: 0.6rem;
  align-items: flex-end;
  padding: 0.85rem 1.15rem;
  border-top: 1px solid var(--c-border);
}
/* One line to start, growing to about six, then scrolling inside itself.
   field-sizing does it in CSS where supported; app.js sets the height for
   the rest. resize:none because a drag handle fights the auto height. */
.chat-compose textarea {
  flex: 1;
  min-height: 44px;
  max-height: 10.5em;
  resize: none;
  overflow-y: auto;
  field-sizing: content;
}
.chat-note { padding: 0 1.15rem 0.85rem; margin: 0; }

/* The paperclip. The real <input type="file"> is visually hidden and
   this label stands in for it, so the control matches everything else
   on the page — clicking the label opens the picker natively, with no
   script involved. */
.chat-attach {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-sm);
  color: var(--c-text-3);
  background: var(--c-surface);
  cursor: pointer;
}
.chat-attach:hover { color: var(--c-text); border-color: var(--c-border-strong); }
.chat-attach:focus-within { outline: 2px solid var(--c-accent); outline-offset: 1px; }

/* A shared file, under the message that shared it. */
.msg-file {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin-top: 0.4rem;
  padding: 0.42rem 0.6rem;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-sm);
  background: var(--c-sunken);
  color: var(--c-text);
  font-size: 0.845rem;
  text-decoration: none;
  max-width: 100%;
}
.msg-file:hover { border-color: var(--c-accent); }
.msg-file svg { flex: 0 0 16px; color: var(--c-text-3); }
.msg-file-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.msg-file-size { margin-left: auto; color: var(--c-text-3); font-size: 0.79rem; white-space: nowrap; }

.msg-image { display: block; margin-top: 0.4rem; }
/* Intrinsic width and height are on the <img> so the log does not jump
   while images load; this keeps a large one inside the bubble. */
.msg-image img {
  max-width: min(320px, 100%);
  height: auto;
  border-radius: var(--radius-sm);
  border: 1px solid var(--c-border);
  display: block;
}

.search-results { display: flex; flex-direction: column; gap: 0.85rem; }
.search-hit { border-left: 2px solid var(--c-border); padding-left: 0.75rem; }
.search-hit-head {
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
  flex-wrap: wrap;
  font-size: 0.815rem;
  margin-bottom: 0.2rem;
}
.search-hit-head a { font-weight: 570; }
.search-hit-body { font-size: 0.9rem; line-height: 1.5; overflow-wrap: anywhere; }

.nav-badge {
  margin-left: auto;
  background: var(--c-accent-solid);
  color: #fff;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 650;
  padding: 0.02rem 0.38rem;
  font-variant-numeric: tabular-nums;
}
.nav-badge[hidden] { display: none; }

@media (max-width: 900px) {
  /* One column, and the page scrolls again: a fixed-height two-pane
     layout on a phone leaves two tiny scrollers instead of one screen. */
  .chat { grid-template-columns: minmax(0, 1fr); height: auto; }
  .chat-rail { max-height: 50vh; }
  .chat-main { min-height: 60vh; }
  .chat-log { max-height: 56vh; }
  .msg { max-width: 88%; }
}

/* --- Notes timeline ----------------------------------------------------- */

.timeline { border-top: 1px solid var(--c-border); }
.note {
  padding: 0.85rem 1.15rem;
  border-bottom: 1px solid var(--c-border);
}
.note:last-child { border-bottom: none; }
.note-head {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
}
.note-head form { margin: 0; }
.note-author { font-size: 0.85rem; font-weight: 620; }
.note-time { font-size: 0.76rem; color: var(--c-text-3); font-variant-numeric: tabular-nums; }
.note-body { font-size: 0.9rem; line-height: 1.55; overflow-wrap: anywhere; }

/* --- Topbar search ------------------------------------------------------ */

.topbar-search {
  margin-left: auto;
  position: relative;
  display: flex;
  align-items: center;
  max-width: 320px;
  width: 100%;
}
.topbar-search svg {
  position: absolute;
  left: 0.6rem;
  width: 15px;
  height: 15px;
  color: var(--c-text-3);
  pointer-events: none;
}
.topbar-search input {
  padding-left: 2rem;
  font-size: 0.86rem;
  background: var(--c-sunken);
}
.topbar-search input:focus { background: var(--c-surface); }
.topbar-actions { margin-left: 0; }
.search-field { flex: 1; min-width: 220px; }

@media (max-width: 760px) {
  .topbar-search { display: none; }
}

/* --- Fieldsets ---------------------------------------------------------- */

.fieldset {
  border: none;
  border-top: 1px solid var(--c-border);
  margin: 0 0 1.1rem;
  padding: 0.9rem 0 0;
}
.fieldset:first-of-type { border-top: none; padding-top: 0; }
.fieldset legend {
  padding: 0;
  font-size: 0.73rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-weight: 640;
  color: var(--c-text-3);
  margin-bottom: 0.65rem;
}
.label-optional {
  font-weight: 400;
  color: var(--c-text-3);
  text-transform: none;
  letter-spacing: 0;
}

/* --- Autosave ----------------------------------------------------------- */

.autosave-status {
  font-size: 0.78rem;
  color: var(--c-text-3);
  font-weight: 520;
  white-space: nowrap;
}
.autosave-status[data-state="saving"] { color: var(--c-text-2); }
.autosave-status[data-state="saved"]  { color: var(--c-success); }
.autosave-status[data-state="dirty"]  { color: var(--c-warn); }
.autosave-status[data-state="error"]  { color: var(--c-danger); }

.draft-banner { align-items: center; flex-wrap: wrap; }
.draft-banner-text { flex: 1; min-width: 220px; }
.draft-banner-actions { display: flex; gap: 0.4rem; align-items: center; }
.draft-banner-actions form { margin: 0; }

/* --- Live gateway indicator --------------------------------------------- */

.gateway-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.28rem 0.6rem;
  border: 1px solid var(--c-border-strong);
  border-radius: 999px;
  background: var(--c-surface);
  color: var(--c-text-2);
  font-size: 0.8rem;
  font-weight: 560;
  white-space: nowrap;
}
.gateway-chip:hover { background: var(--c-surface-2); color: var(--c-text); text-decoration: none; }
.gateway-chip[hidden] { display: none; }
.gateway-chip-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--c-text-3);
  flex: none;
}
.gateway-chip[data-state="live"]    .gateway-chip-dot { background: var(--c-success); box-shadow: 0 0 0 3px var(--c-success-soft); }
.gateway-chip[data-state="sandbox"] .gateway-chip-dot { background: var(--c-warn);    box-shadow: 0 0 0 3px var(--c-warn-soft); }
.gateway-chip[data-state="none"]    .gateway-chip-dot { background: var(--c-danger);  box-shadow: 0 0 0 3px var(--c-danger-soft); }
.gateway-chip[data-state="none"] { color: var(--c-danger); border-color: var(--c-danger); }

.gateway-now { display: flex; align-items: center; gap: 0.85rem; }
.gateway-now-dot {
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--c-danger); box-shadow: 0 0 0 4px var(--c-danger-soft);
  flex: none;
}
.gateway-now-dot.is-live { background: var(--c-success); box-shadow: 0 0 0 4px var(--c-success-soft); }
.gateway-now-name { font-size: 1.15rem; font-weight: 660; letter-spacing: -0.015em; }

@media (max-width: 900px) { .gateway-chip-label { display: none; } }

th.status-col, td.status-col { width: 210px; }
td.status-col select { min-width: 120px; font-size: 0.82rem; }
.gateway-own-form { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--c-border); }
@media (max-width: 1000px) { th.status-col, td.status-col { width: auto; } }

/* --- Notification bell -------------------------------------------------- */

.bell {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 34px; height: 34px;
  border-radius: var(--radius-sm);
  color: var(--c-text-2);
  flex: none;
}
.bell:hover { background: var(--c-sunken); color: var(--c-text); text-decoration: none; }
.bell svg { width: 18px; height: 18px; }
.bell-count {
  position: absolute;
  top: 1px; right: 0;
  min-width: 16px;
  padding: 0 0.22rem;
  border-radius: 999px;
  background: var(--c-danger);
  color: #fff;
  font-size: 0.64rem;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.bell-count[hidden] { display: none; }

/* The bell's own dropdown: a native <details> for the same reason as the
   account menu (list-style/marker suppressed below so `summary.bell` keeps
   looking exactly like the plain icon button it used to be), closed by the
   generic popup-menu handler in app.js on an outside click or Escape. */
.bell-menu { position: relative; }
.bell-menu > summary.bell {
  list-style: none;
  cursor: pointer;
}
.bell-menu > summary.bell::-webkit-details-marker { display: none; }
.bell-menu > summary.bell:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
}
.bell-panel {
  position: absolute;
  top: calc(100% + 8px);
  /* Anchored to the bell's left edge, not its right: the bell sits well
     left of centre in the topbar (title, help icon, then the bell, with
     the search bar and everything else still to come), so right-anchoring
     ran the panel off the left edge of the viewport whenever the sidebar
     was collapsed and the bell had little room to its left. */
  left: 0;
  width: 350px;
  max-width: calc(100vw - 24px);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  z-index: 40;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.bell-panel-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.65rem 0.85rem;
  border-bottom: 1px solid var(--c-border);
}
.bell-panel-head strong { font-size: 0.88rem; }
.bell-mark-all {
  background: none;
  border: none;
  color: var(--c-accent);
  font-size: 0.78rem;
  font-weight: 620;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
  border-radius: var(--radius-sm);
  font-family: inherit;
}
.bell-mark-all:hover { background: var(--c-accent-soft); text-decoration: underline; }
.bell-mark-all[hidden] { display: none; }
.bell-panel-body {
  max-height: 360px;
  overflow-y: auto;
}
.bell-panel-loading,
.bell-panel-error {
  padding: 1.4rem 0.85rem;
  text-align: center;
  color: var(--c-text-3);
  font-size: 0.85rem;
}
.bell-panel-empty {
  padding: 1.6rem 0.85rem;
  text-align: center;
  color: var(--c-text-3);
}
.bell-panel-empty svg { width: 24px; height: 24px; opacity: 0.5; margin-bottom: 0.35rem; }
.bell-panel-empty-title { font-weight: 570; color: var(--c-text-2); font-size: 0.88rem; }
.bell-item {
  display: block;
  padding: 0.65rem 0.85rem;
  border-bottom: 1px solid var(--c-border);
  color: var(--c-text-2);
  text-decoration: none;
  cursor: pointer;
}
.bell-item:last-child { border-bottom: none; }
.bell-item:hover { background: var(--c-surface-2); text-decoration: none; color: var(--c-text); }
.bell-item.is-unread { background: var(--c-accent-soft); }
.bell-item-title { font-size: 0.85rem; font-weight: 610; }
.bell-item-body { font-size: 0.8rem; margin-top: 0.15rem; color: var(--c-text-2); overflow-wrap: anywhere; }
.bell-item-time { font-size: 0.73rem; color: var(--c-text-3); margin-top: 0.25rem; font-variant-numeric: tabular-nums; }
.bell-panel-foot {
  display: block;
  text-align: center;
  padding: 0.55rem;
  font-size: 0.82rem;
  font-weight: 610;
  color: var(--c-accent);
  border-top: 1px solid var(--c-border);
  background: var(--c-surface-2);
}
.bell-panel-foot:hover { background: var(--c-sunken); text-decoration: none; }
@media (max-width: 560px) {
  .bell-panel { position: fixed; top: 56px; right: 12px; left: 12px; width: auto; }
}

/* --- Bulk actions ------------------------------------------------------- */

.bulk-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding-top: 0.9rem;
  border-top: 1px solid var(--c-border);
}
td input[type="checkbox"], th input[type="checkbox"] {
  width: 16px; height: 16px;
  accent-color: var(--c-accent);
  cursor: pointer;
}

.badge-lg { font-size: 0.85rem; padding: 0.24rem 0.7rem; }
.sale-amount { text-align: right; }
.note.is-unread { background: var(--c-accent-soft); }

/* --- Permissions -------------------------------------------------------- */

/* A second line inside a table cell — the description under a permission
   name, the role under a person's name. */
.cell-sub {
  margin-top: 0.15rem;
  font-size: 0.8rem;
  color: var(--c-text-2);
}

/* The read-only list of permissions this person cannot pass on. */
.perm-list {
  margin: 0.6rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.45rem;
}
.perm-list li {
  font-size: 0.875rem;
  color: var(--c-text-2);
  padding-left: 0.9rem;
  position: relative;
}
.perm-list li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.52em;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--c-border-strong);
}
.perm-list strong { color: var(--c-text); font-weight: 600; }

/* The granted-permissions table: without explicit widths the permission
   description takes the whole row and everything else wraps to two lines. */
.perm-table { table-layout: fixed; }
.perm-table th:nth-child(1), .perm-table td:nth-child(1) { width: 17%; }
.perm-table th:nth-child(2), .perm-table td:nth-child(2) { width: 33%; }
.perm-table th:nth-child(3), .perm-table td:nth-child(3) { width: 16%; }
.perm-table th:nth-child(4), .perm-table td:nth-child(4) { width: 11%; }
.perm-table th:nth-child(5), .perm-table td:nth-child(5) { width: 13%; }
.perm-table th:nth-child(6), .perm-table td:nth-child(6) { width: 10%; }
.perm-table td { vertical-align: top; }

/* --- Data columns ------------------------------------------------------- */

/* Switching between customers / sales / deals on the columns screen. */
.tabs {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 1.1rem;
  border-bottom: 1px solid var(--c-border);
}
.tabs a {
  padding: 0.5rem 0.85rem;
  font-size: 0.875rem;
  font-weight: 540;
  color: var(--c-text-2);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tabs a:hover { color: var(--c-text); text-decoration: none; }
.tabs a[aria-current="page"] { color: var(--c-accent-text); border-bottom-color: var(--c-accent); }

/* One configured column, with its controls. Not a table: the controls
   wrap onto their own line on a narrow screen, which a table row can't. */
.field-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
  align-items: flex-start;
  padding: 0.9rem 1.15rem;
  border-top: 1px solid var(--c-border);
}
.field-row-main { flex: 1 1 260px; min-width: 0; }
.field-row-title { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; }
.field-row-options { display: flex; gap: 0.3rem; flex-wrap: wrap; margin-top: 0.45rem; }
.field-row-forms {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  flex: 1 1 420px;
}
.field-row-forms form { margin: 0; }
.field-row-forms input[type="text"] {
  width: auto;
  min-width: 130px;
  font-size: 0.82rem;
  padding: 0.33rem 0.55rem;
}

/* A defined dropdown option, shown read-only. */
.chip {
  display: inline-flex;
  align-items: center;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--c-border);
  background: var(--c-sunken);
  font-size: 0.755rem;
  color: var(--c-text-2);
}

/* A long-text custom column takes the full width of the form grid. */
.field-wide { grid-column: 1 / -1; }

/* --- Record report ------------------------------------------------------ */

.col-picker {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.1rem;
  padding-bottom: 0.9rem;
  margin-bottom: 0.9rem;
  border-bottom: 1px solid var(--c-border);
}
.col-picker-group { min-width: 0; }
.col-picker-label {
  display: block;
  font-size: 0.72rem;
  font-weight: 640;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-text-3);
  margin-bottom: 0.5rem;
}
.col-picker .checkbox { margin-bottom: 0.4rem; font-weight: 450; }

/* A report can have more columns than fit; scroll the table, not the page. */
.table-scroll { overflow-x: auto; }
.table-scroll table { min-width: 100%; }

/* --- Duplicate suggestions ---------------------------------------------- */

.match-zone:empty { display: none; }

.match-card {
  border: 1px solid var(--c-warn);
  background: var(--c-warn-soft);
  border-radius: var(--radius);
  padding: 0.9rem 1rem;
  margin: 0 0 1rem;
}
.match-head {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--c-warn);
  margin-bottom: 0.3rem;
}
.match-head svg { width: 17px; height: 17px; flex: none; }
.match-note {
  font-size: 0.8rem;
  color: var(--c-text-2);
  margin: 0 0 0.7rem;
}

.match-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1rem;
  align-items: center;
  padding: 0.6rem 0;
  border-top: 1px solid var(--c-border);
}
.match-who { flex: 1 1 220px; min-width: 0; }
.match-who a { font-weight: 600; }
.match-keys { display: flex; align-items: center; gap: 0.3rem; flex-wrap: wrap; flex: 0 1 auto; }
.match-pick { margin-left: auto; }

/* The matched keys, so the agent can judge rather than trust. */
.chip-match {
  border-color: var(--c-warn);
  background: var(--c-surface);
  color: var(--c-warn);
  font-weight: 600;
}

.match-continue {
  padding-top: 0.75rem;
  margin-top: 0.3rem;
  border-top: 1px solid var(--c-border);
}
.match-continue label {
  display: block;
  font-size: 0.82rem;
  font-weight: 560;
  margin-bottom: 0.3rem;
}

/* --- Roles --------------------------------------------------------------- */

.role-table th:last-child, .role-table td:last-child { text-align: right; }

/* The permission grid: a section per area, a row per capability. */
.perm-group { border-top: 1px solid var(--c-border); padding: 0.85rem 1.15rem 0.5rem; }
.perm-group-title {
  font-size: 0.72rem;
  font-weight: 640;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-text-3);
  margin: 0 0 0.6rem;
}
.perm-row {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.3rem 0;
}
.perm-row .checkbox { flex: 1 1 auto; margin: 0; font-weight: 450; min-width: 0; }
.perm-row select { flex: 0 0 auto; width: auto; min-width: 128px; font-size: 0.82rem; padding: 0.28rem 1.7rem 0.28rem 0.5rem; }
/* A capability the editor does not hold is shown, not hidden — somebody
   wondering why they cannot grant it deserves an answer. */
.perm-row-locked { opacity: 0.55; }
.perm-row-locked .checkbox { cursor: default; }

@media (max-width: 560px) {
  .perm-row { flex-wrap: wrap; }
  .perm-row select { width: 100%; }
}

/* --- Form layout editor -------------------------------------------------- */

.layout-table td { vertical-align: middle; }
.layout-table input[type="text"] { width: 100%; min-width: 140px; }
.pos-input { width: 60px; text-align: center; padding-left: 0.4rem; padding-right: 0.4rem; }

/* --- Pagination ---------------------------------------------------------- */

/* Sits under a listing, inside the card, so it reads as part of the
   table rather than as a separate thing floating below it. */
.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.9rem;
  flex-wrap: wrap;
  padding: 0.8rem 1.15rem;
  border-top: 1px solid var(--c-border);
}
.pager-range { font-size: 0.82rem; margin: 0; }
p.pager-range { padding: 0.8rem 1.15rem; border-top: 1px solid var(--c-border); }
.pager .pager-range { padding: 0; border-top: 0; }

.pager-controls { display: flex; align-items: center; gap: 0.5rem; }
.pager-position { font-size: 0.82rem; color: var(--c-text-2); white-space: nowrap; }

.pager-step {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.38rem 0.7rem;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-sm);
  font-size: 0.82rem;
  font-weight: 560;
  color: var(--c-text);
  text-decoration: none;
  white-space: nowrap;
  background: var(--c-surface);
}
.pager-step:hover { background: var(--c-sunken); }

/* Still drawn, so the controls do not jump about as you page, but
   plainly not a thing to press. */
.pager-step.is-disabled {
  color: var(--c-text-3);
  background: transparent;
  cursor: default;
  opacity: 0.55;
}

/* A stage showing fewer cards than it holds says so above them. */
.board-col-more {
  font-size: 0.78rem;
  margin: 0 0 0.35rem;
  padding: 0.3rem 0.4rem;
  border-bottom: 1px dashed var(--c-border);
}

@media (max-width: 560px) {
  /* The range above the controls rather than beside them; at this width
     they do not fit on one line without the numbers being cramped. */
  .pager { flex-direction: column; align-items: stretch; gap: 0.6rem; }
  .pager-controls { justify-content: space-between; }
}

/* --- Agent scores: charts and the penalty form ------------------------- */

/* Two panels side by side on a wide screen, stacked on a phone. */
.grid-2 {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  margin-bottom: 1rem;
}

/* A no-JavaScript, no-inline-style bar chart. The bar is an SVG whose
   rect width is a 0–100 attribute stretched across the track by
   preserveAspectRatio="none"; everything else is HTML text. */
.bar-chart { display: flex; flex-direction: column; gap: 0.55rem; }
.bar-row {
  display: grid;
  grid-template-columns: minmax(6rem, 8rem) minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.65rem;
}
.bar-name {
  font-size: 0.85rem;
  color: var(--c-text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bar-track {
  background: var(--c-sunken);
  border-radius: 999px;
  height: 12px;
  overflow: hidden;
}
.bar-svg { display: block; width: 100%; height: 12px; }
.bar-fill { fill: var(--c-accent); }
.bar-fill-neg { fill: var(--c-danger); }
.bar-val {
  font-size: 0.85rem;
  font-weight: 620;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.bar-val-neg { color: var(--c-danger); }

/* A numeric table column, right-aligned with tabular figures. */
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cell-danger { color: var(--c-danger); font-weight: 640; }

/* The penalty form: a labelled radio with an amount box on the same line. */
.radio-line {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.3rem 0;
  font-size: 0.9rem;
}
.inline-input {
  width: 6rem;
  padding: 0.3rem 0.5rem;
  font-size: 0.9rem;
  text-align: right;
}

/* --- Settings: timezone ------------------------------------------------- */
.tz-current {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.8rem 0.9rem;
  margin: 0.9rem 0 1.1rem;
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  background: var(--c-surface-2);
}
.tz-current-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--c-text-3);
  font-weight: 600;
  margin-right: 0.4rem;
}
.tz-current-zone { font-weight: 600; margin-right: 0.5rem; }
.tz-form { max-width: 26rem; }

/* A role's name opens its editor, so it reads as clickable. */
.role-name-link { color: inherit; }
.role-name-link:hover { color: var(--c-accent); text-decoration: none; }
.role-name-link:hover strong { text-decoration: underline; }

/* --- Permissions catalog ------------------------------------------------ */
.perm-cat-group { padding: 0 0 0.4rem; }
.perm-cat-group-label {
  display: block;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--c-text-3);
  font-weight: 600;
  padding: 0.7rem 1.15rem 0.35rem;
}
.perm-cat { border-top: 1px solid var(--c-border); }
.perm-cat-summary {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 1.15rem;
  cursor: pointer;
  list-style: none;
}
.perm-cat-summary::-webkit-details-marker { display: none; }
.perm-cat-summary:hover { background: var(--c-surface-2); }
.perm-cat-main { flex: 1; min-width: 0; }
.perm-cat-name { display: block; font-weight: 550; font-size: 0.9rem; }
.perm-cat-desc { display: block; font-size: 0.8rem; color: var(--c-text-3); }
.perm-cat-count { flex: 0 0 auto; }
.perm-cat-caret { flex: 0 0 16px; opacity: 0.6; transition: transform 0.15s ease; }
.perm-cat[open] .perm-cat-caret { transform: rotate(180deg); }
.perm-cat-body { padding: 0.2rem 1.15rem 0.9rem; }
.perm-cat-table { width: 100%; border-collapse: collapse; }
.perm-cat-table td { padding: 0.4rem 0.5rem; border-top: 1px solid var(--c-border); font-size: 0.875rem; }
.perm-cat-table tr:first-child td { border-top: none; }
.perm-cat-action { text-align: right; width: 1%; white-space: nowrap; }

/* --- Follow-ups (promise-to-pay / call-back reminders) ------------------ */
.follow-up-list { border-top: 1px solid var(--c-border); }
.follow-up { padding: 0.8rem 1.15rem; border-bottom: 1px solid var(--c-border); }
.follow-up:last-child { border-bottom: none; }
.follow-up.is-due { background: var(--c-surface-2); }
.follow-up-head { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.follow-up-sale { font-weight: 550; color: var(--c-text); }
.follow-up-sale:hover { color: var(--c-accent); }
.follow-up-when { font-size: 0.82rem; color: var(--c-text-3); white-space: nowrap; }
.follow-up-when.is-due { color: var(--c-danger); font-weight: 600; }
.follow-up-note { font-size: 0.85rem; margin-top: 0.3rem; }
.follow-up-actions { margin-top: 0.55rem; }
.follow-up-actions > summary { display: inline-flex; list-style: none; cursor: pointer; }
.follow-up-actions > summary::-webkit-details-marker { display: none; }
.follow-up-forms {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem;
  margin-top: 0.6rem;
}
.follow-up-forms form { margin: 0; }
.follow-up-reschedule { display: flex; align-items: center; gap: 0.35rem; }
.follow-up-reschedule input { width: auto; }
/* The sale-page setter. */
.follow-up-set { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.6rem; }
.follow-up-set .field { margin: 0; }
.follow-up-table { width: 100%; border-collapse: collapse; margin-top: 0.6rem; }
.follow-up-table th, .follow-up-table td { padding: 0.4rem 0.5rem; border-top: 1px solid var(--c-border); font-size: 0.875rem; text-align: left; }
.follow-up-table th { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--c-text-3); }
.follow-up-set .field-grow { flex: 1; min-width: 12rem; }
.follow-up-history { margin-top: 0.7rem; }
.follow-up-history > summary { cursor: pointer; font-size: 0.85rem; color: var(--c-text-2); }

/* --- Attendance policy + summary ---------------------------------------- */
.policy-grid { display: flex; flex-wrap: wrap; gap: 1rem; }
.policy-grid .field { flex: 1; min-width: 8rem; margin: 0; }
.policy-grid input, .field .unit { display: inline-block; }
.field .unit { color: var(--c-text-3); font-size: 0.85rem; margin-left: 0.35rem; }
.weekday-row { display: flex; flex-wrap: wrap; gap: 0.9rem; }
.weekday-row .check { margin: 0; }
.attendance-days { border-top: 1px solid var(--c-border); }
.attendance-days > summary {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 1.15rem;
  cursor: pointer;
  font-weight: 550;
  font-size: 0.9rem;
}
.attendance-download { margin-left: auto; }
.attendance-who { display: flex; align-items: baseline; gap: 0.75rem; padding-bottom: 0; }
.attendance-who p { margin: 0; }
.attendance-table tfoot th, .attendance-table tfoot td {
  border-top: 2px solid var(--c-border-strong);
  font-weight: 600;
  background: var(--c-surface-2);
}

/* Hours per day (partials/attendance_chart.php). The four status colours
   are the reserved status palette -- good, warning, serious, critical --
   the same in light and dark, and never the only thing saying what a
   day was: legend labels, a tooltip per day and the table do that. */
:root {
  /* AA as marks on white (3:1+); dark-mode values sit with the dark tokens. */
  --c-status-good: #15803d;
  --c-status-warning: #b45309;
  --c-status-serious: #c2410c;
  --c-status-critical: #b91c1c;
}
.att-chart { margin: 0; padding: 0.4rem 1.15rem 1rem; position: relative; border-top: 1px solid var(--c-border); }
.att-chart-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 1.25rem;
  padding: 0.6rem 0 0.5rem;
}
.att-chart-title { font-weight: 600; font-size: 0.9rem; color: var(--c-text); }
.att-legend { display: flex; flex-wrap: wrap; gap: 0.35rem 0.9rem; font-size: 0.78rem; color: var(--c-text-2); }
.att-key { display: inline-flex; align-items: center; gap: 0.35rem; }
.att-swatch { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.att-swatch-dot { border-radius: 50%; }
.att-swatch.att-bar-present { background: var(--c-status-good); }
.att-swatch.att-bar-tardy { background: var(--c-status-warning); }
.att-swatch.att-bar-half_day { background: var(--c-status-serious); }
.att-swatch.att-bar-absent { background: var(--c-status-critical); }
.att-swatch-off { background: var(--c-sunken); border: 1px solid var(--c-border); }
/* Wide ranges scroll inside the chart's own box, never the page. */
.att-chart-scroll { overflow-x: auto; }
.att-chart-svg { display: block; max-width: none; }
.att-grid { stroke: var(--c-border); stroke-width: 1; }
.att-axis { fill: var(--c-text-3); font-size: 10.5px; font-family: var(--font); }
.att-axis.is-upcoming { opacity: 0.5; }
.att-off { fill: var(--c-sunken); }
.att-bar-present { fill: var(--c-status-good); }
.att-bar-tardy { fill: var(--c-status-warning); }
.att-bar-half_day { fill: var(--c-status-serious); }
.att-bar-absent { fill: var(--c-status-critical); }
/* Worked on a day off: still a bar, in the neutral ink. */
.att-bar-off { fill: var(--c-text-3); }
.att-full { stroke: var(--c-text-2); stroke-width: 1.25; stroke-dasharray: 4 4; }
.att-full-label { fill: var(--c-text-2); font-size: 10.5px; font-family: var(--font); }
.att-hit { fill: transparent; }
.att-col:hover .att-bar, .att-col.is-hover .att-bar { opacity: 0.8; }
.att-col:hover .att-hit, .att-col.is-hover .att-hit { fill: var(--c-text); fill-opacity: 0.05; }
.att-tip {
  position: absolute;
  z-index: 5;
  max-width: 18rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-sm);
  background: var(--c-surface);
  color: var(--c-text);
  font-size: 0.78rem;
  line-height: 1.4;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  pointer-events: none;
}
@media (forced-colors: active) {
  .att-bar { fill: CanvasText; }
}

/* Flagged chat messages, one card each (chat/flagged.php). */
.flagged-list { display: flex; flex-direction: column; }
.flagged-item { padding: 0.9rem 1.15rem; border-top: 1px solid var(--c-border); }
.flagged-item.is-done { opacity: 0.68; }
.flagged-meta { font-size: 0.82rem; color: var(--c-text-3); margin-bottom: 0.4rem; }
.flagged-body {
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-sm);
  background: var(--c-sunken);
  /* The point of the screen is reading the digits exactly. */
  font-variant-numeric: tabular-nums;
  word-break: break-word;
}
.flagged-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.6rem; }
.flagged-actions form { margin: 0; }

/* Ticking rows in a table (the Bin). The bar sits above the table and
   only ever says how many are ticked; the button it holds is part of the
   same form as the ticks. */
.bulk-bar {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 1.15rem;
  border-top: 1px solid var(--c-border);
  border-bottom: 1px solid var(--c-border);
  background: var(--c-surface-2);
}
.bulk-count { font-size: 0.85rem; color: var(--c-text-2); font-weight: 550; }
tr.is-picked > td { background: var(--c-accent-soft); }

/* --- Manager attendance edits: approval queue --------------------------- */
.attendance-review { display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: flex-start; }
.attendance-review form { margin: 0; }
.review-clarify > summary { list-style: none; cursor: pointer; display: inline-flex; }
.review-clarify > summary::-webkit-details-marker { display: none; }
.review-clarify form { display: flex; gap: 0.35rem; margin-top: 0.4rem; }
.queried-edit { padding: 0.7rem 0; border-top: 1px solid var(--c-border); }
.queried-edit .alert { margin: 0.5rem 0; }

/* --- Delegation limits (what a role may hand out) ------------------------ */
.limit-choices { display: flex; flex-wrap: wrap; gap: 0.35rem 1.2rem; padding: 0.4rem 0 0.7rem 1.6rem; }
.limit-choices .check { margin: 0; font-size: 0.875rem; }
.limit-group-label {
  display: block; margin-top: 0.5rem;
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--c-text-3); font-weight: 600;
}

/* --- Organisation: reporting lines, team leads, role order ---------------- */
.org-row {
  display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
  padding: 0.55rem 1.15rem; border-top: 1px solid var(--c-border);
}
.org-row select { width: auto; min-width: 12rem; }
.org-person { flex: 1 1 14rem; min-width: 0; display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.org-name { font-weight: 550; }
.org-top { margin-left: auto; }
/* Depth, drawn as a left margin. Classes rather than style="" (CSP). */
.org-indent-0 { padding-left: 1.15rem; }
.org-indent-1 { padding-left: 2.4rem; }
.org-indent-2 { padding-left: 3.65rem; }
.org-indent-3 { padding-left: 4.9rem; }
.org-indent-4 { padding-left: 6.15rem; }
.org-indent-5 { padding-left: 7.4rem; }
.org-indent-6 { padding-left: 8.65rem; }
.org-move { display: inline-flex; gap: 0.25rem; margin-left: auto; }
.org-move form { margin: 0; }
.icon-btn-plain {
  background: var(--c-surface); color: var(--c-text-2);
  border: 1px solid var(--c-border); border-radius: var(--radius-sm);
  padding: 0.3rem; line-height: 0; cursor: pointer;
}
.icon-btn-plain:hover:not(:disabled) { background: var(--c-surface-2); color: var(--c-text); }
.icon-btn-plain:disabled { opacity: 0.35; cursor: not-allowed; }
@media (max-width: 600px) {
  .org-indent-1, .org-indent-2, .org-indent-3, .org-indent-4, .org-indent-5, .org-indent-6 { padding-left: 1.6rem; }
}

/* --- Help centre ---------------------------------------------------------- */
.help-link {
  display: inline-grid; place-items: center; color: var(--c-text-3);
  padding: 0.3rem; border-radius: var(--radius-sm); line-height: 0;
}
.help-link:hover { color: var(--c-text); background: var(--c-surface-2); text-decoration: none; }

.help-title { font-size: 1.45rem; font-weight: 650; letter-spacing: -0.01em; margin: 0 0 0.4rem; }
.help-lead { font-size: 1.02rem; color: var(--c-text-2); margin: 0 0 1.2rem; }
.help-search { display: flex; gap: 0.5rem; margin-top: 0.8rem; max-width: 40rem; }
.help-search input { flex: 1; }
.help-search-small input { width: 100%; }

.help-results { list-style: none; margin: 0; padding: 0; }
.help-results li { padding: 0.8rem 1.15rem; border-top: 1px solid var(--c-border); }
.help-results p { margin: 0.2rem 0 0; font-size: 0.875rem; }
.help-result-title { font-weight: 600; margin-right: 0.5rem; }

.help-layout { display: grid; grid-template-columns: minmax(0, 1fr) 15rem; gap: 1.25rem; align-items: start; }
.help-side { position: sticky; top: 4.5rem; font-size: 0.875rem; }
.help-side-h {
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--c-text-3); font-weight: 600; margin: 1.1rem 0 0.35rem;
}
.help-side-list { list-style: none; margin: 0; padding: 0; }
.help-side-list a { display: block; padding: 0.28rem 0.5rem; border-radius: var(--radius-sm); color: var(--c-text-2); }
.help-side-list a:hover { background: var(--c-surface-2); color: var(--c-text); text-decoration: none; }
.help-side-list a[aria-current="page"] { background: var(--c-surface-2); color: var(--c-text); font-weight: 600; }

.help-article .card-body { max-width: 46rem; }
.help-article p, .help-article li { line-height: 1.6; }
.help-h { font-size: 1.1rem; font-weight: 640; margin: 1.7rem 0 0.5rem; }
.help-steps, .help-list { padding-left: 1.3rem; margin: 0.5rem 0 1rem; }
.help-steps li, .help-list li { margin: 0.3rem 0; }
.help-article code {
  background: var(--c-surface-2); border: 1px solid var(--c-border);
  border-radius: 4px; padding: 0.05rem 0.3rem; font-size: 0.86em;
}
.help-callout {
  display: flex; gap: 0.6rem; margin: 1rem 0; padding: 0.7rem 0.9rem;
  border-radius: var(--radius); border: 1px solid var(--c-border); background: var(--c-surface-2);
  line-height: 1.5;
}
.help-callout-label { flex: 0 0 auto; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; padding-top: 0.15rem; }
.help-tip { border-color: var(--c-accent-soft); background: var(--c-accent-soft); }
.help-warn { border-color: var(--c-warn-soft); background: var(--c-warn-soft); }
.help-table th, .help-table td { text-align: left; vertical-align: top; }
.help-shot { margin: 1.1rem 0; }
.help-shot img {
  display: block; max-width: 100%; height: auto;
  border: 1px solid var(--c-border); border-radius: var(--radius); box-shadow: var(--shadow-sm);
}
.help-shot figcaption { margin-top: 0.4rem; font-size: 0.82rem; color: var(--c-text-3); }

@media (max-width: 900px) {
  .help-layout { grid-template-columns: minmax(0, 1fr); }
  .help-side { position: static; }
}

.perm-cat-add { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; padding: 0.75rem 0.5rem 0.25rem; border-top: 1px solid var(--c-border); }
.perm-cat-add select { flex: 1 1 10rem; min-width: 0; }

/* A Save button with nothing to save: greyed out and inert. */
button:disabled, .btn[aria-disabled="true"] {
  opacity: 0.45;
  filter: grayscale(0.7) blur(0.4px);
  cursor: not-allowed;
  pointer-events: auto;
}
button:disabled:hover { background: inherit; color: inherit; }
button:disabled:active { transform: none; }

/* Choice groups: multiple choice, checkboxes, rating and scale. */
.choice-group { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; padding: 0.25rem 0; }
.choice { display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer; }
.choice-group.scale .choice { gap: 0.25rem; padding: 0.2rem 0.6rem; border: 1px solid var(--c-border); border-radius: 999px; }
.choice-group.scale .choice:has(input:checked) { background: var(--c-accent-solid); color: #fff; border-color: var(--c-accent); }

/* --- Sidebar groups ------------------------------------------------------
   Collapsible headings, native <details> (no JavaScript, CSP-safe). Any number
   may be open at once; the one holding the current page starts open. If the
   open groups (or a zoomed page) make the list taller than the window, the
   list scrolls between the brand and the account block. */
.nav-drawer { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; }
.nav-drawer > .nav { flex: 0 0 auto; overflow: visible; }
.nav-drawer > summary { display: none; list-style: none; }
.nav-drawer > summary::-webkit-details-marker { display: none; }

.nav-group > summary {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.62rem;
  padding: 0.55rem 0.55rem;
  border-radius: var(--radius-sm);
  color: var(--c-nav-text);
  font-size: 0.895rem;
  font-weight: 560;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.nav-group > summary::-webkit-details-marker { display: none; }
.nav-group > summary:hover { background: var(--c-nav-active); color: var(--c-nav-text-hi); }
.nav-group > summary:focus-visible { outline: 2px solid var(--c-nav-text-hi); outline-offset: -2px; }
.nav-group[open] > summary { color: var(--c-nav-text-hi); }
.nav-group-label { flex: 1 1 auto; min-width: 0; }
.nav .nav-group-caret { width: 14px; height: 14px; flex: 0 0 14px; margin-left: auto; opacity: 0.6; transition: transform 0.15s ease; }
.nav-group[open] .nav-group-caret { transform: rotate(180deg); }
.nav-group[open] .nav-group-badge { display: none; }
.nav-group-badge { margin-left: auto; }
.nav-group-badge + .nav-group-caret { margin-left: 0.4rem; }

.nav-sub {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin: 0.1rem 0 0.4rem 1.05rem;
  padding-left: 0.6rem;
  border-left: 1px solid var(--c-nav-border);
}
.nav .nav-sub a { padding: 0.4rem 0.6rem; font-size: 0.865rem; justify-content: space-between; }

@media (max-width: 900px) {
  .sidebar { flex-wrap: wrap; }
  .nav-drawer { order: 3; flex: 1 0 100%; }
  .nav-drawer > summary {
    display: block;
    padding: 0.55rem 0.9rem;
    color: var(--c-nav-text-hi);
    font-weight: 600;
    cursor: pointer;
    border-top: 1px solid var(--c-nav-border);
  }
  .nav-drawer[open] > summary { border-bottom: 1px solid var(--c-nav-border); }
  .nav { flex-direction: column; overflow-x: visible; overflow-y: auto; max-height: 70vh; padding: 0.4rem; }
}

/* Theme toggle in the top bar */
.theme-toggle {
  display: inline-grid; place-items: center;
  width: 34px; height: 34px; padding: 0;
  background: transparent; color: var(--c-text-2);
  border: 1px solid var(--c-border); border-radius: 999px;
}
.theme-toggle:hover { background: var(--c-sunken); color: var(--c-text); }
.theme-toggle svg { width: 17px; height: 17px; }
.theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* --- My desk ------------------------------------------------------------- */
.desk-list { display: flex; flex-direction: column; gap: 0.6rem; }
.desk-stickies { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0.9rem; }
.desk-item { border: 1px solid var(--c-border); border-radius: var(--radius); padding: 0.8rem 0.95rem; background: var(--c-surface); }
.desk-item.is-done .desk-item-head strong, .desk-item.is-done .desk-body { text-decoration: line-through; opacity: 0.6; }
.desk-item.is-overdue { border-color: var(--c-danger); }
.desk-body { margin: 0.35rem 0; white-space: normal; overflow-wrap: anywhere; }
.desk-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; margin-top: 0.6rem; }
.desk-actions form { margin: 0; }
/* A desk item that points somewhere (a flagged chat message): the whole
   card opens it. The title's link is stretched over the card; the action
   buttons and their pop-outs sit above that layer so they still work. */
.desk-item.has-link { position: relative; cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s; }
.desk-item.has-link:hover { border-color: var(--c-accent); box-shadow: 0 2px 10px rgb(0 0 0 / 0.08); }
.desk-item.has-link:focus-within { border-color: var(--c-accent); }
.desk-link { color: inherit; text-decoration: none; }
.desk-link::after { content: ""; position: absolute; inset: 0; border-radius: var(--radius); }
.desk-link:hover strong, .desk-link:focus-visible strong { text-decoration: underline; }
.desk-item.has-link .desk-actions { position: relative; z-index: 1; }
.desk-more > summary { list-style: none; cursor: pointer; display: inline-block; padding: 0.33rem 0.62rem; font-size: 0.815rem; border-radius: var(--radius-sm); color: var(--c-text-2); }
.desk-more > summary::-webkit-details-marker { display: none; }
.desk-more[open] { flex-basis: 100%; }
.desk-yellow { background: #fff6bf; border-color: #ecd96c; color: #3a3410; }
.desk-green  { background: #dcf5df; border-color: #9fd6a6; color: #14361a; }
.desk-blue   { background: #dbeafe; border-color: #93bdf5; color: #12305e; }
.desk-pink   { background: #fde0ec; border-color: #f0a3c3; color: #4d1230; }
.desk-purple { background: #eadcfd; border-color: #c2a2f0; color: #2c1458; }
.desk-gray   { background: var(--c-surface); }
:root[data-theme="dark"] .desk-yellow { background: #3b3611; border-color: #6b6020; color: #f5efc0; }
:root[data-theme="dark"] .desk-green  { background: #143220; border-color: #2f6a44; color: #cdeed6; }
:root[data-theme="dark"] .desk-blue   { background: #16294a; border-color: #2f4f86; color: #d3e4ff; }
:root[data-theme="dark"] .desk-pink   { background: #3f1a2c; border-color: #7a3455; color: #fbd9e8; }
:root[data-theme="dark"] .desk-purple { background: #2a1c47; border-color: #55388d; color: #e4d5ff; }
.text-danger { color: var(--c-danger); }

/* --- Chat, the WhatsApp way: menus, ticks, replies, groups, voice ---------- */
.msg-menu { position: relative; margin-left: 0.15rem; }
.msg-menu > summary { list-style: none; cursor: pointer; color: var(--c-text-3); padding: 0 0.3rem; border-radius: 6px; line-height: 1.2; }
.msg-menu > summary::-webkit-details-marker { display: none; }
.msg-menu > summary:hover, .msg-menu[open] > summary { background: var(--c-sunken); color: var(--c-text); }
.msg-menu-list {
  position: absolute; z-index: 20; top: 1.5rem; right: 0; min-width: 11.5rem;
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 0.3rem; text-align: left;
}
.msg:not(.is-self) .msg-menu-list { right: auto; left: 0; }
.msg-menu-list form { margin: 0; }
.msg-menu-list .linklike, .msg-menu-list summary {
  display: block; width: 100%; text-align: left; padding: 0.4rem 0.6rem; border-radius: 6px; font-size: 0.85rem;
}
.msg-edit summary { cursor: pointer; color: var(--c-text-2); }
.msg-edit summary:hover, .msg-menu-list .linklike:hover { background: var(--c-sunken); }
.msg-edit form { padding: 0.3rem 0.4rem; display: flex; flex-direction: column; gap: 0.35rem; }
.linklike { background: none; border: none; box-shadow: none; color: var(--c-text); cursor: pointer; font: inherit; padding: 0; }
.linklike:hover { background: none; text-decoration: none; }
.linklike.danger, .linklike.danger:hover { color: var(--c-danger); }

.msg-foot { display: flex; justify-content: flex-end; gap: 0.35rem; align-items: center; margin-top: 0.15rem; min-height: 1rem; }
.msg-edited { font-size: 0.72rem; color: var(--c-text-3); font-style: italic; }
.tick { display: inline-flex; color: var(--c-text-3); }
.tick-seen { color: #2f80ed; }
.msg-tombstone { font-style: italic; color: var(--c-text-3); background: transparent; border-style: dashed; }
.msg.is-self .msg-tombstone { background: transparent; color: var(--c-text-3); border-color: var(--c-border); }
.msg-review { margin-top: 0.3rem; padding: 0.45rem 0.65rem; border-left: 3px solid var(--c-warn); background: var(--c-sunken); border-radius: 6px; font-size: 0.85rem; }
.msg-review-tag { display: block; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--c-text-3); margin-bottom: 0.15rem; }
.msg-quote {
  display: block; margin-bottom: 0.25rem; padding: 0.3rem 0.6rem; border-left: 3px solid var(--c-accent);
  background: var(--c-sunken); border-radius: 6px; font-size: 0.8rem; color: var(--c-text-2); text-decoration: none;
}
.msg-quote strong { display: block; font-size: 0.75rem; color: var(--c-accent-text); }
.msg-system { align-self: center; font-size: 0.78rem; color: var(--c-text-3); background: var(--c-sunken); padding: 0.2rem 0.75rem; border-radius: 999px; }
.msg-voice { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.3rem; }
.msg-voice audio { height: 36px; max-width: 100%; }
.msg-voice-len { font-size: 0.78rem; color: var(--c-text-3); font-variant-numeric: tabular-nums; }

.chat-reply { display: flex; justify-content: space-between; gap: 0.6rem; align-items: center; margin: 0 1.15rem; padding: 0.4rem 0.7rem; border-left: 3px solid var(--c-accent); background: var(--c-sunken); border-radius: 6px; font-size: 0.83rem; }
.chat-reply[hidden] { display: none; }
.chat-mic { background: none; border: 1px solid var(--c-border); border-radius: var(--radius); color: var(--c-text-2); padding: 0.5rem; cursor: pointer; box-shadow: none; }
.chat-mic:hover { color: var(--c-text); border-color: var(--c-border-strong); background: none; }
.chat-mic[hidden], .chat-recording[hidden] { display: none; }
.chat-recording { display: inline-flex; align-items: center; gap: 0.5rem; font-variant-numeric: tabular-nums; }
.rec-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--c-danger); animation: rec-pulse 1.1s ease-in-out infinite; }
@keyframes rec-pulse { 50% { opacity: 0.3; } }

.chat-members { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; max-height: 14rem; overflow-y: auto; }
.chat-members li { display: flex; justify-content: space-between; gap: 0.6rem; align-items: center; font-size: 0.87rem; }
.chat-member-actions { display: inline-flex; gap: 0.7rem; }
.chat-member-actions form { margin: 0; }
.chat-member-actions .linklike { font-size: 0.8rem; color: var(--c-accent-text); }
.chat-pick { max-height: 9rem; overflow-y: auto; border: 1px solid var(--c-border); border-radius: var(--radius); padding: 0.3rem 0.5rem; display: flex; flex-direction: column; gap: 0.15rem; }
.chat-pick-row { display: flex; gap: 0.45rem; align-items: center; font-size: 0.83rem; }
/* A person you can pick straight out of the list, rather than a name in
   a dropdown you have to find first. */
.chat-person-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  text-align: left;
  padding: 0.3rem 0.35rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--c-text-2);
  font-size: 0.85rem;
  cursor: pointer;
}
.chat-person-row:hover { background: var(--c-sunken); color: var(--c-text); }
.chat-person-row[hidden] { display: none; }
.chat-person-row .chat-avatar { width: 26px; height: 26px; font-size: 0.68rem; }
.chat-rail-join { display: flex; justify-content: space-between; gap: 0.4rem; align-items: center; padding: 0.15rem 0.4rem; }
.tag { display: inline-block; font-size: 0.7rem; padding: 0.05rem 0.45rem; border-radius: 999px; background: var(--c-accent-soft); color: var(--c-accent-text); }
.tag-danger { background: var(--c-danger-soft); color: var(--c-danger); }
.deleted-list { display: flex; flex-direction: column; gap: 0.7rem; }
.deleted-item { padding: 0.8rem 1rem; }
.deleted-meta { font-size: 0.84rem; margin-bottom: 0.35rem; }
.deleted-body { padding: 0.5rem 0.7rem; background: var(--c-sunken); border-radius: 6px; }
.deleted-edits { margin-top: 0.5rem; font-size: 0.85rem; }
.deleted-edit { margin-top: 0.25rem; }

/* Drag handle on the sidebar's right edge (double-arrow cursor). */
.sidebar-resizer {
  position: absolute; top: 0; right: -4px; width: 9px; height: 100%; z-index: 30;
  cursor: col-resize; touch-action: none;
}
.sidebar-resizer::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: 4px; width: 2px; background: transparent; transition: background 0.12s;
}
.sidebar-resizer:hover::after, .sidebar-resizer:focus-visible::after, body.is-resizing .sidebar-resizer::after { background: var(--c-accent-solid); }
.sidebar-resizer:focus-visible { outline: none; }
body.is-resizing { cursor: col-resize; user-select: none; }
@media (max-width: 900px) { .sidebar-resizer { display: none; } }

/* Collapse the sidebar to a narrow icon rail. Remembered in a cookie, the
   same way the theme is, so the very first paint already renders it
   collapsed rather than flashing full-width first (see layout.php). */
.sidebar { transition: width 0.15s ease, flex-basis 0.15s ease; }
body.is-resizing .sidebar { transition: none; }

.sidebar-collapse-toggle {
  position: absolute; top: 20px; right: -14px; z-index: 31;
  width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center; padding: 0;
  background: linear-gradient(155deg, var(--c-accent), var(--c-accent-hover));
  color: #fff;
  border: 2px solid var(--c-nav-bg);
  box-shadow: 0 2px 6px rgba(79, 70, 229, 0.4), var(--shadow);
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.sidebar-collapse-toggle:hover {
  transform: scale(1.08);
  box-shadow: 0 3px 10px rgba(79, 70, 229, 0.55), var(--shadow-lg);
}
.sidebar-collapse-toggle:active { transform: scale(0.96); }
.sidebar-collapse-toggle:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }
.sidebar-collapse-toggle svg { width: 14px; height: 14px; transition: transform 0.15s ease; }
.shell[data-sidebar="collapsed"] .sidebar-collapse-toggle svg { transform: rotate(180deg); }
@media (max-width: 900px) { .sidebar-collapse-toggle { display: none; } }

.shell[data-sidebar="collapsed"] .sidebar { width: var(--sidebar-collapsed-w); flex-basis: var(--sidebar-collapsed-w); }
.shell[data-sidebar="collapsed"] .sidebar-resizer { display: none; }
.shell[data-sidebar="collapsed"] .brand { justify-content: center; padding-inline: 0; gap: 0; }
.shell[data-sidebar="collapsed"] .brand-text { display: none; }
.shell[data-sidebar="collapsed"] .nav { align-items: center; padding-inline: 0.45rem; }
.shell[data-sidebar="collapsed"] .nav a,
.shell[data-sidebar="collapsed"] .nav-group > summary { justify-content: center; padding-inline: 0.55rem; width: 40px; }
.shell[data-sidebar="collapsed"] .nav > a > span:not(.nav-badge),
.shell[data-sidebar="collapsed"] .nav-group-label,
.shell[data-sidebar="collapsed"] .nav-group-caret { display: none; }
/* A group's items become a flyout to the right of the rail instead of an
   indented list beneath it — there is no room to indent into. `fixed`
   rather than `absolute`: .nav-drawer/.nav clip horizontal overflow (it's
   how the rail keeps its own vertical scrollbar instead of growing wider
   than the page), and a `fixed` box is the one kind of positioning that
   escapes an ancestor's clip without also escaping the rail visually —
   app.js sets its exact `top` to line it up with the group that opened
   it; `left` alone is safe as a static value since the rail's own width
   is fixed and pinned to the left edge either way. */
.shell[data-sidebar="collapsed"] .nav-group { position: relative; }
.shell[data-sidebar="collapsed"] .nav-sub {
  position: fixed; left: calc(var(--sidebar-collapsed-w) + 8px); top: 0; margin: 0;
  min-width: 190px; padding: 0.35rem; border: 1px solid var(--c-nav-border);
  border-radius: var(--radius); background: var(--c-nav-bg); box-shadow: var(--shadow-lg);
  z-index: 40; max-height: calc(100vh - 16px); overflow-y: auto;
}
.shell[data-sidebar="collapsed"] .nav-sub a { justify-content: flex-start; width: auto; }
.shell[data-sidebar="collapsed"] .nav-user { display: none; }
.shell[data-sidebar="collapsed"] .nav-user-link { justify-content: center; padding-inline: 0; }
.shell[data-sidebar="collapsed"] .user-menu-caret { display: none; }
.shell[data-sidebar="collapsed"] .user-menu-panel { left: calc(100% + 8px); right: auto; bottom: 0; width: 220px; }

/* ==========================================================================
   Collapsible sections, live sections, media gallery, lightbox, live viewer
   ========================================================================== */

/* --- Breadcrumb ----------------------------------------------------------- */
.crumbs { margin: 0 0 0.85rem; font-size: 0.85rem; }
.crumbs a { display: inline-flex; align-items: center; gap: 0.3rem; color: var(--c-text-2); }
.crumbs a:hover { color: var(--c-text); text-decoration: none; }

/* --- Collapsible cards ------------------------------------------------------
   Any .card.collapsible folds down to its header bar. The bar keeps a
   one-line summary (shown only while folded) and the section's actions,
   so the useful bits stay reachable. */
.collapsible > .card-head { flex-wrap: wrap; row-gap: 0.55rem; min-height: 3.1rem; cursor: default; }
.collapsible.is-collapsed > .card-head { border-bottom-color: transparent; }
.collapse-btn {
  width: 28px; height: 28px; padding: 0; flex: 0 0 28px;
  background: transparent; color: var(--c-text-2);
  border: 1px solid transparent; border-radius: var(--radius-sm);
}
.collapse-btn:hover { background: var(--c-sunken); color: var(--c-text); border-color: var(--c-border); }
.collapse-btn svg { transition: transform 0.18s ease; }
.collapsible.is-collapsed .collapse-btn svg { transform: rotate(-90deg); }
.card-summary {
  display: none;
  align-items: center; flex-wrap: wrap; gap: 0.2rem 1rem;
  font-size: 0.83rem; color: var(--c-text-2); min-width: 0;
}
.collapsible.is-collapsed .card-summary { display: flex; }
.card-summary code { font-size: 0.8rem; }
/* Fleet online/offline counts: always in the header, folded or not. */
.fleet-counts { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 0.4rem; }
/* Uptime section totals row. */
.uptime-totals { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; margin: 0.2rem 0 0.6rem; font-size: 0.83rem; }
/* Pipeline quick-range preset chips. */
.pipe-presets { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0 0 0.7rem; }
.pipe-presets .chip { padding: 0.25rem 0.7rem; font-size: 0.8rem; text-decoration: none; cursor: pointer; }
.pipe-presets .chip:hover { background: var(--c-accent-soft); color: var(--c-accent); border-color: transparent; }
.pipe-presets .chip.is-active { background: var(--c-accent-solid); color: #fff; border-color: transparent; }
.card-actions { margin-left: auto; display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
.card-actions form { margin: 0; }
.card-body-tight { padding: 0.9rem 1.15rem 0.6rem; }
.section-intro { margin: 0 0 0.75rem; }
[data-fragment][aria-busy="true"] { position: relative; }
[data-fragment][aria-busy="true"]::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--c-accent), transparent);
  background-size: 200% 100%; animation: wso-busy 0.9s linear infinite;
}
@keyframes wso-busy { from { background-position: 100% 0; } to { background-position: -100% 0; } }

/* --- Status pills --------------------------------------------------------- */
.machine-title { display: flex; align-items: center; flex-wrap: wrap; gap: 0.45rem 0.6rem; min-width: 0; }
.machine-title h2 { font-size: 1.02rem; font-weight: 660; overflow-wrap: anywhere; }
.icon-btn-sm {
  width: 28px; height: 28px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--c-text-3);
  border: 1px solid transparent; border-radius: var(--radius-sm);
}
.icon-btn-sm:hover { background: var(--c-sunken); color: var(--c-text); border-color: var(--c-border); }
.status-pill {
  display: inline-flex; align-items: center; gap: 0.38rem;
  padding: 0.16rem 0.6rem 0.16rem 0.5rem; border-radius: 999px;
  font-size: 0.775rem; font-weight: 600; white-space: nowrap;
  background: var(--c-sunken); color: var(--c-text-2); border: 1px solid var(--c-border);
}
.status-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.status-pill.is-online { background: var(--c-success-soft); color: var(--c-success); border-color: transparent; }
.status-pill.is-online .status-dot { box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-success) 22%, transparent); }
.status-pill.is-offline .status-dot { background: var(--c-text-3); }
.status-pill.is-recording { background: var(--c-danger-soft); color: var(--c-danger); border-color: transparent; }
.status-pill.is-recording .status-dot { animation: wso-pulse 1.4s ease-in-out infinite; }
.elapsed { font-variant-numeric: tabular-nums; }
@keyframes wso-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
.rec-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--c-danger); flex: none; }
.stop-square { width: 9px; height: 9px; border-radius: 2px; background: currentColor; flex: none; }

/* --- Machine details: a grid of label/value tiles ---------------------------
   Replaces the old stacked list, which ran a column of label-then-value
   pairs down most of the screen. Fills the width and reflows by itself. */
.detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 0.6rem; margin: 0 0 0.8rem;
}
.detail {
  background: var(--c-surface-2); border: 1px solid var(--c-border); border-radius: var(--radius);
  padding: 0.6rem 0.75rem; min-width: 0;
}
.detail dt { font-size: 0.7rem; font-weight: 640; letter-spacing: 0.06em; text-transform: uppercase; color: var(--c-text-3); }
.detail dd { margin: 0.2rem 0 0; font-size: 0.875rem; overflow-wrap: anywhere; }
.detail dd code { font-size: 0.82rem; }
.detail-sub { display: block; font-size: 0.76rem; color: var(--c-text-3); margin-top: 0.1rem; }
.overview-forms {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0.9rem 1.5rem; margin: 1rem 0 0.4rem; padding-top: 1rem; border-top: 1px solid var(--c-border);
}
.overview-form { margin: 0; }
.overview-form .checkbox { margin: 0.5rem 0 0; }
.overview-form-label { display: block; font-size: 0.82rem; font-weight: 600; margin-bottom: 0.35rem; }
.input-row { display: flex; gap: 0.5rem; align-items: stretch; }
.input-row input, .input-row select { flex: 1 1 auto; min-width: 0; }

/* --- Filter bar (date range, presets, search, export) --------------------- */
.filter-bar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.6rem 0.75rem; margin: 0; }
.filter-field { display: flex; flex-direction: column; gap: 0.2rem; margin: 0; min-width: 0; }
.filter-field input { padding: 0.38rem 0.55rem; font-size: 0.84rem; min-width: 0; }
.filter-label { font-size: 0.72rem; font-weight: 620; color: var(--c-text-3); text-transform: uppercase; letter-spacing: 0.05em; }
.filter-search { position: relative; flex: 1 1 220px; justify-content: flex-end; }
.filter-search svg { position: absolute; left: 0.6rem; bottom: 0.55rem; color: var(--c-text-3); pointer-events: none; }
.filter-search input { padding-left: 2rem; width: 100%; }
.filter-actions { display: flex; gap: 0.4rem; align-items: center; }
.filter-presets { display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; }
.filter-presets .chip {
  padding: 0.28rem 0.65rem; font-size: 0.78rem; font-weight: 540; color: var(--c-text-2);
  background: var(--c-surface); text-decoration: none;
}
.filter-presets .chip:hover { background: var(--c-accent-soft); color: var(--c-accent-text); border-color: transparent; }
.filter-export { margin-left: auto; }

/* --- Scroll regions: long lists scroll inside their own box ----------------
   The standing rule: a section that would grow past a sensible height
   caps it and scrolls internally (header row stays put), with page
   numbers below for older items. */
.scroll-region { max-height: min(460px, 62vh); overflow: auto; overscroll-behavior: contain; border-top: 1px solid var(--c-border); }
/* Inside a card body rather than flush against its edges: no rule on top,
   and a little breathing room so the scrollbar is not against the text. */
.scroll-region-plain { border-top: 0; padding-right: 0.35rem; }
.scroll-region table { border-collapse: separate; border-spacing: 0; }
.scroll-region thead th { position: sticky; top: 0; z-index: 1; background: var(--c-surface-2); box-shadow: inset 0 -1px 0 var(--c-border); }
.table-compact th, .table-compact td { padding-top: 0.55rem; padding-bottom: 0.55rem; }
.nowrap { white-space: nowrap; }
.cell-clip { max-width: 0; width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.result { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.84rem; font-weight: 540; }
.result-success { color: var(--c-success); }
.result-danger { color: var(--c-danger); }
.result-info { color: var(--c-info); }
.result-warn { color: var(--c-warn); }
.result-muted { color: var(--c-text-3); }
.spinner {
  width: 11px; height: 11px; border-radius: 50%; flex: none;
  border: 2px solid currentColor; border-right-color: transparent; animation: wso-spin 0.8s linear infinite;
}
@keyframes wso-spin { to { transform: rotate(360deg); } }

/* --- Pager: numbered pages ------------------------------------------------- */
.pager-numbers { display: flex; align-items: center; gap: 0.25rem; list-style: none; margin: 0; padding: 0; }
.pager-num {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2rem; height: 2rem; padding: 0 0.45rem;
  border-radius: var(--radius-sm); border: 1px solid transparent;
  font-size: 0.82rem; font-weight: 560; color: var(--c-text-2); text-decoration: none;
  font-variant-numeric: tabular-nums;
}
a.pager-num:hover { background: var(--c-sunken); color: var(--c-text); text-decoration: none; }
.pager-num.is-current { background: var(--c-accent-solid); color: #fff; }
.pager-gap { color: var(--c-text-3); padding: 0 0.15rem; }
@media (max-width: 560px) {
  .pager-step-label { display: none; }
  .pager-numbers { flex-wrap: wrap; justify-content: center; }
}

/* --- Tabs inside a section ------------------------------------------------- */
.section-tabs {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.25rem 0.5rem;
  padding: 0 1.15rem; border-bottom: 1px solid var(--c-border);
}
.section-tabs [role="tab"] {
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.75rem 0.4rem 0.65rem; margin-right: 0.6rem;
  font-size: 0.875rem; font-weight: 560; color: var(--c-text-2);
  border-bottom: 2px solid transparent; margin-bottom: -1px; text-decoration: none;
}
.section-tabs [role="tab"]:hover { color: var(--c-text); text-decoration: none; }
.section-tabs [role="tab"][aria-selected="true"] { color: var(--c-accent-text); border-bottom-color: var(--c-accent); }
.section-tabs .count {
  font-size: 0.72rem; font-weight: 640; padding: 0.05rem 0.45rem; border-radius: 999px;
  background: var(--c-sunken); color: var(--c-text-2); font-variant-numeric: tabular-nums;
}
.section-tabs [aria-selected="true"] .count { background: var(--c-accent-soft); color: var(--c-accent-text); }
.section-tabs .spacer { margin-left: auto; }
.view-controls { display: flex; gap: 0.4rem; align-items: center; padding: 0.4rem 0; }
.segmented {
  display: inline-flex; padding: 2px; gap: 2px;
  background: var(--c-sunken); border: 1px solid var(--c-border); border-radius: var(--radius-sm);
}
.segmented[hidden] { display: none; }
.seg {
  min-width: 30px; height: 28px; padding: 0 0.5rem;
  background: transparent; color: var(--c-text-2); border: 0; border-radius: 5px;
  font-size: 0.78rem; font-weight: 640;
}
.seg:hover { background: var(--c-surface); color: var(--c-text); }
.seg[aria-pressed="true"] { background: var(--c-surface); color: var(--c-accent-text); box-shadow: var(--shadow-sm); }

/* --- Selection bar ------------------------------------------------------------ */
.selection-bar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem;
  margin: 0.75rem 0 0.15rem; padding: 0.45rem 0.6rem 0.45rem 0.85rem;
  background: var(--c-accent-soft); border-radius: var(--radius);
}
.selection-bar[hidden] { display: none; }
.selection-bar .spacer { margin-left: auto; }
.selection-count { font-size: 0.85rem; font-weight: 620; color: var(--c-accent-text); }

/* --- Gallery: grid or list, three sizes -------------------------------------- */
.gallery-scroll { max-height: min(720px, 75vh); padding: 1rem 1.15rem; }
.gallery { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.9rem;
  grid-template-columns: repeat(auto-fill, minmax(var(--tile-min, 210px), 1fr)); }
.gallery.size-s { --tile-min: 150px; }
.gallery.size-m { --tile-min: 220px; }
.gallery.size-l { --tile-min: 340px; }
.tile {
  position: relative; display: flex; flex-direction: column; min-width: 0;
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius);
  overflow: hidden; transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.tile:hover { border-color: var(--c-border-strong); box-shadow: var(--shadow); }
.tile.is-selected { border-color: var(--c-accent); box-shadow: 0 0 0 2px var(--c-ring); }
.tile-media {
  position: relative; display: block; width: 100%; aspect-ratio: 16 / 10; padding: 0; border: 0; border-radius: 0;
  background: var(--c-sunken); overflow: hidden; cursor: zoom-in;
}
.tile-media:hover { background: var(--c-sunken); }
.tile-media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.25s ease; }
.tile:hover .tile-media img { transform: scale(1.025); }
.tile-placeholder {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--c-text-3); font-size: 0.8rem; text-align: center; padding: 0.5rem;
}
.tile.is-processing .tile-media { cursor: default; }
.tile-play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 42px; height: 42px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: rgba(10, 12, 18, 0.62); color: #fff; padding-left: 3px; pointer-events: none;
}
.tile-meta { padding: 0.5rem 0.65rem 0.6rem; min-width: 0; padding-right: 2.4rem; }
.tile-title { font-size: 0.82rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tile-sub { font-size: 0.75rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tile-download { position: absolute; right: 0.4rem; bottom: 0.45rem; }
.tile-check {
  position: absolute; top: 0.45rem; left: 0.45rem; z-index: 2;
  width: 26px; height: 26px; border-radius: 6px; display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, 0.92); box-shadow: var(--shadow-sm);
  opacity: 0; transition: opacity 0.12s ease; cursor: pointer;
}
.tile-check input { width: 16px; height: 16px; margin: 0; accent-color: var(--c-accent); cursor: pointer; }
.tile:hover .tile-check, .tile:focus-within .tile-check, .is-selecting .tile-check, .tile.is-selected .tile-check { opacity: 1; }
@media (hover: none) { .tile-check { opacity: 1; } }
.gallery.size-s .tile-sub { display: none; }

/* List view: one row per capture, small preview at the left. */
.gallery.is-list { grid-template-columns: 1fr; gap: 0; }
.gallery.is-list .tile {
  flex-direction: row; align-items: center; border-radius: 0; border-width: 0 0 1px 0; box-shadow: none;
  padding: 0.45rem 0.4rem 0.45rem 2.6rem;
}
.gallery.is-list .tile:hover { background: var(--c-surface-2); }
.gallery.is-list .tile.is-selected { box-shadow: none; background: var(--c-accent-soft); }
.gallery.is-list .tile-media { width: 112px; flex: none; border-radius: 6px; }
.gallery.is-list .tile-meta { flex: 1 1 auto; padding: 0 0.9rem; }
.gallery.is-list .tile-sub { display: block; }
.gallery.is-list .tile-check { top: 50%; transform: translateY(-50%); left: 0.4rem; opacity: 1; background: transparent; box-shadow: none; }
.gallery.is-list .tile-download { position: static; margin-right: 0.3rem; }
.gallery.is-list .tile-play { width: 28px; height: 28px; }
.gallery.is-list .tile-play svg { width: 13px; height: 13px; }

/* --- Responsive helpers ------------------------------------------------------- */
@media (max-width: 900px) { .hide-md { display: none !important; } }
.show-sm { display: none !important; }
@media (max-width: 640px) {
  .hide-sm { display: none !important; }
  .show-sm { display: block !important; }
  .card-actions { margin-left: 0; width: 100%; }
  .card-actions .btn, .card-actions button { flex: 1 1 auto; }
  .card-actions form { flex: 1 1 auto; display: flex; }
  .filter-bar > .filter-field:not(.filter-search) { flex: 1 1 calc(50% - 0.4rem); }
  .filter-field input[type="datetime-local"] { width: 100%; }
  .filter-export { margin-left: 0; }
  .detail-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .gallery.size-l { --tile-min: 220px; }
  .gallery.size-m { --tile-min: 150px; }
  .gallery.size-s { --tile-min: 110px; }
  .gallery-scroll { padding: 0.75rem; }
  .section-tabs { padding: 0 0.75rem; }
  .view-controls { width: 100%; justify-content: flex-end; }
}

/* --- Toasts --------------------------------------------------------------------- */
.toast-region {
  position: fixed; z-index: 1000; right: 1rem; bottom: 1rem; left: auto;
  display: flex; flex-direction: column; gap: 0.5rem; align-items: flex-end; pointer-events: none;
}
.toast {
  pointer-events: auto; max-width: min(420px, calc(100vw - 2rem));
  padding: 0.7rem 0.95rem; border-radius: var(--radius); font-size: 0.86rem; font-weight: 520;
  background: var(--c-text); color: var(--c-surface); box-shadow: var(--shadow-lg);
  animation: wso-toast-in 0.18s ease-out;
}
.toast-success { border-left: 3px solid var(--c-success); }
.toast-error { background: var(--c-danger); color: #fff; }
.toast.is-leaving { opacity: 0; transform: translateY(6px); transition: opacity 0.3s ease, transform 0.3s ease; }
@keyframes wso-toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (max-width: 640px) { .toast-region { left: 1rem; align-items: stretch; } }

/* --- Confirm dialog ------------------------------------------------------------- */
.confirm-dialog {
  border: 1px solid var(--c-border); border-radius: var(--radius-lg); padding: 0;
  width: min(440px, calc(100vw - 2rem)); background: var(--c-surface); color: var(--c-text);
  box-shadow: var(--shadow-lg);
}
.confirm-dialog::backdrop { background: rgba(10, 12, 18, 0.45); }
.confirm-dialog form { padding: 1.3rem 1.3rem 1.1rem; margin: 0; }
.confirm-text { font-size: 0.95rem; line-height: 1.5; margin: 0 0 1.2rem; }
.confirm-actions { display: flex; justify-content: flex-end; gap: 0.5rem; }
.confirm-ok.btn-danger { background: var(--c-danger); color: #fff; border-color: var(--c-danger); }
.confirm-ok.btn-danger:hover { background: var(--c-danger); filter: brightness(1.08); color: #fff; }

/* --- Lightbox ------------------------------------------------------------------- */
html.has-lightbox { overflow: hidden; }
.lightbox {
  position: fixed; inset: 0; z-index: 900; display: none;
  grid-template-columns: auto 1fr auto; grid-template-rows: auto 1fr;
  background: rgba(8, 10, 14, 0.94); color: #fff;
}
.lightbox.is-open { display: grid; animation: wso-fade 0.15s ease-out; }
@keyframes wso-fade { from { opacity: 0; } to { opacity: 1; } }
.lightbox-bar {
  grid-column: 1 / -1; display: flex; align-items: center; gap: 0.6rem;
  padding: 0.6rem 0.8rem 0.6rem 1.1rem; min-height: 3.2rem;
}
.lightbox-caption { font-size: 0.9rem; font-weight: 560; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lightbox-pos { font-size: 0.8rem; color: rgba(255, 255, 255, 0.6); white-space: nowrap; margin-right: auto; }
.lightbox-btn {
  display: inline-flex; align-items: center; gap: 0.4rem; height: 36px; padding: 0 0.7rem;
  border-radius: var(--radius-sm); background: rgba(255, 255, 255, 0.08); color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.12); font-size: 0.84rem; font-weight: 540; text-decoration: none;
}
.lightbox-btn:hover { background: rgba(255, 255, 255, 0.16); color: #fff; text-decoration: none; }
.lightbox-stage { grid-row: 2; grid-column: 2; display: flex; align-items: center; justify-content: center; min-width: 0; min-height: 0; padding: 0 0.5rem 1rem; }
.lightbox-media { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 6px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5); background: #000; }
.lightbox-nav {
  grid-row: 2; align-self: center; width: 46px; height: 46px; margin: 0 0.6rem; padding: 0;
  border-radius: 50%; background: rgba(255, 255, 255, 0.1); color: #fff; border: 1px solid rgba(255, 255, 255, 0.14);
}
.lightbox-nav:hover { background: rgba(255, 255, 255, 0.2); }
.lightbox-prev { grid-column: 1; }
.lightbox-next { grid-column: 3; }
@media (max-width: 640px) {
  .lightbox-nav { position: fixed; bottom: 1rem; margin: 0; }
  .lightbox-prev { left: 1rem; }
  .lightbox-next { right: 1rem; }
  .lightbox-stage { grid-column: 1 / -1; padding: 0 0 4.5rem; }
}

/* --- Live viewer (its own tab) --------------------------------------------------- */
.live-body { margin: 0; background: #07080b; color: #e9ecf3; overflow: hidden; }
.live-viewer { display: flex; flex-direction: column; height: 100vh; height: 100dvh; background: #07080b; }
.live-bar {
  display: flex; align-items: center; gap: 0.75rem 1rem; flex-wrap: wrap;
  padding: 0.55rem 0.9rem; background: #11131a; border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}
.live-back {
  width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; flex: none;
  border-radius: var(--radius-sm); color: #c5cad6; border: 1px solid rgba(255, 255, 255, 0.1);
}
.live-back:hover { background: rgba(255, 255, 255, 0.08); color: #fff; text-decoration: none; }
.live-title { min-width: 0; flex: 1 1 200px; }
.live-title h1 { font-size: 1rem; font-weight: 660; color: #fff; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.live-sub { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.15rem; }
.live-sub .status-pill { font-size: 0.7rem; padding: 0.05rem 0.5rem 0.05rem 0.42rem; border-color: transparent; background: rgba(255, 255, 255, 0.08); color: #c5cad6; }
.live-sub .status-pill.is-online { background: rgba(74, 222, 128, 0.14); color: #4ade80; }
.live-user { font-size: 0.78rem; color: #8d95a7; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.live-stats { display: flex; align-items: center; gap: 0.7rem; }
.live-pill {
  display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.2rem 0.65rem 0.2rem 0.55rem;
  border-radius: 999px; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  background: rgba(255, 255, 255, 0.08); color: #c5cad6;
}
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.live-pill[data-live-state="live"] { background: #dc2626; color: #fff; }
.live-pill[data-live-state="live"] .live-dot { background: #fff; animation: wso-pulse 1.6s ease-in-out infinite; }
.live-pill[data-live-state="connecting"] .live-dot, .live-pill[data-live-state="stalled"] .live-dot { animation: wso-pulse 0.9s ease-in-out infinite; }
.live-pill[data-live-state="stalled"], .live-pill[data-live-state="waiting"] { background: rgba(251, 191, 36, 0.16); color: #fbbf24; }
.live-metric { font-size: 0.8rem; color: #8d95a7; font-variant-numeric: tabular-nums; white-space: nowrap; }
.live-metric.is-slow { color: #fbbf24; }
.live-actions { display: flex; align-items: center; gap: 0.4rem; margin-left: auto; }
.live-btn {
  height: 34px; padding: 0 0.75rem; gap: 0.45rem;
  background: rgba(255, 255, 255, 0.07); color: #e9ecf3; border: 1px solid rgba(255, 255, 255, 0.1);
  font-size: 0.84rem; font-weight: 560;
}
.live-btn:hover { background: rgba(255, 255, 255, 0.14); color: #fff; }
.live-btn[aria-pressed="false"] { background: rgba(124, 116, 242, 0.25); }
.live-btn:disabled { opacity: 0.6; cursor: default; }
.live-btn.is-recording { background: rgba(220, 38, 38, 0.18); color: #fca5a5; border-color: rgba(220, 38, 38, 0.4); }
.live-btn.is-recording .rec-dot { animation: wso-pulse 1.4s ease-in-out infinite; }
.live-btn-primary { background: #4f46e5; border-color: #4f46e5; color: #fff; min-width: 5.2rem; }
.live-btn-primary:hover { background: #4338ca; }
.live-stage { position: relative; flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.live-stage.is-actual-size { overflow: auto; align-items: flex-start; justify-content: flex-start; }
.live-frame { max-width: 100%; max-height: 100%; object-fit: contain; display: block; user-select: none; }
.live-stage.is-actual-size .live-frame { max-width: none; max-height: none; }
.live-viewer:fullscreen .live-bar { position: absolute; inset: 0 0 auto; z-index: 2; opacity: 0; transition: opacity 0.2s ease; }
.live-viewer:fullscreen .live-bar:hover { opacity: 1; }
.live-message { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 2rem; gap: 0.5rem; }
.live-message[hidden] { display: none; }
.live-message-title { font-size: 1.05rem; font-weight: 600; color: #fff; margin: 0.4rem 0 0; }
.live-message-hint { font-size: 0.88rem; color: #8d95a7; max-width: 30rem; margin: 0; line-height: 1.5; }
.live-spinner { width: 34px; height: 34px; border-radius: 50%; border: 3px solid rgba(255, 255, 255, 0.15); border-top-color: #7c74f2; animation: wso-spin 0.9s linear infinite; }
.live-message.no-spinner .live-spinner { display: none; }
@media (max-width: 640px) {
  .live-actions { margin-left: 0; width: 100%; }
  .live-actions .live-btn { flex: 1 1 auto; }
  .live-stats { order: 3; }
}

/* Somebody who has asked their system for less motion gets it everywhere,
   not only on the handful of things we remembered to list. Chat alone adds
   bubble entry, smooth scrolling and a typing indicator; naming each one
   is a list that goes stale on the next feature. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
.check-flush { margin: 0; }
@media (max-width: 640px) {
  /* Chevron and name share a line; the icon-only actions keep their size
     so Live view and Record get the room. */
  .collapsible > .card-head > .machine-title { flex: 1 1 0; }
  .card-actions .act-icon { flex: 0 0 auto; }
  .card-actions .act-icon button { min-width: 40px; }
  .detail dd code { font-size: 0.76rem; }
}
.live-frame[hidden] { display: none; }
[data-live-fit] { min-width: 3.4rem; font-variant-numeric: tabular-nums; }

/* --- Machines list page ------------------------------------------------------ */
.count-pill {
  font-size: 0.74rem; font-weight: 650; padding: 0.08rem 0.5rem; border-radius: 999px;
  background: var(--c-sunken); color: var(--c-text-2); font-variant-numeric: tabular-nums;
}
.text-danger { color: var(--c-danger); }
.action-bar { display: flex; flex-direction: column; gap: 0.55rem; border-top: 1px solid var(--c-border); }
.action-bar-count { margin: 0; }
.action-bar-controls { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.action-bar-controls select { width: auto; min-width: 12rem; flex: 0 1 auto; }
.action-bar .check { margin: 0; font-size: 0.84rem; }
@media (max-width: 640px) {
  .action-bar-controls select { flex: 1 1 100%; min-width: 0; }
  .action-bar-controls button { flex: 1 1 auto; }
}

/* Storage */
.usage-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 0.75rem; margin-bottom: 0.4rem; }
.usage-tile { border: 1px solid var(--c-border); border-radius: var(--radius); padding: 0.8rem 0.95rem; background: var(--c-surface-2); min-width: 0; }
.usage-label { font-size: 0.7rem; font-weight: 640; letter-spacing: 0.06em; text-transform: uppercase; color: var(--c-text-3); }
.usage-value { font-size: 1.35rem; font-weight: 680; letter-spacing: -0.01em; margin-top: 0.2rem; font-variant-numeric: tabular-nums; }
.usage-of { font-size: 0.82rem; font-weight: 500; color: var(--c-text-3); letter-spacing: 0; }
.usage-sub { font-size: 0.78rem; color: var(--c-text-3); margin-top: 0.15rem; }
.usage-disk.is-warn { border-color: var(--c-warn); background: var(--c-warn-soft); }
.usage-disk.is-danger { border-color: var(--c-danger); background: var(--c-danger-soft); }
.meter { position: relative; display: block; height: 8px; border-radius: 999px; background: var(--c-sunken); overflow: hidden; margin: 0.5rem 0 0.25rem; border: 1px solid var(--c-border); }
.meter > span { position: absolute; left: 0; top: 0; bottom: 0; width: 0; transition: width 0.4s ease; }
.meter-other { background: var(--c-border-strong); }
.meter-captures { background: var(--c-accent-solid); }
.usage-disk.is-warn .meter-other { background: var(--c-warn); }
.usage-disk.is-danger .meter-other { background: var(--c-danger); }
.share-bar { display: inline-block; vertical-align: middle; width: 90px; height: 6px; border-radius: 999px; background: var(--c-sunken); overflow: hidden; margin-right: 0.35rem; }
.share-bar > span { display: block; height: 100%; width: 0; background: var(--c-accent-solid); border-radius: 999px; }

/* Recording form */
.record-form { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1.4fr) minmax(0, 1fr) auto; gap: 1rem 1.25rem; align-items: start; }
.record-step { border: 0; padding: 0; margin: 0; min-width: 0; }
.record-step legend { font-size: 0.82rem; font-weight: 640; margin-bottom: 0.45rem; padding: 0; }
.segmented-radio { display: flex; flex-direction: column; gap: 0.3rem; margin-bottom: 0.5rem; }
.segmented-radio label { display: flex; align-items: center; gap: 0.45rem; font-size: 0.86rem; cursor: pointer; }
.segmented-radio input { accent-color: var(--c-accent); }
.machine-picks {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 0.3rem;
  max-height: 180px; overflow: auto; padding: 0.35rem; border: 1px solid var(--c-border); border-radius: var(--radius-sm); background: var(--c-surface-2);
}
.machine-picks.is-disabled { opacity: 0.45; pointer-events: none; }
.machine-pick { display: flex; align-items: center; gap: 0.45rem; padding: 0.35rem 0.45rem; border-radius: 6px; font-size: 0.85rem; cursor: pointer; min-width: 0; }
.machine-pick:hover { background: var(--c-sunken); }
.machine-pick input { accent-color: var(--c-accent); margin: 0; }
.machine-pick-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 540; }
.machine-pick .muted { font-size: 0.75rem; }
.dot-online { background: var(--c-success); }
.dot-offline { background: var(--c-text-3); }
.record-at { margin-bottom: 0.35rem; }
.record-at input { width: 100%; }
.record-submit { align-self: end; padding-bottom: 1.6rem; }
.rec-dot-light { background: #fff; }
@media (max-width: 1100px) { .record-form { grid-template-columns: 1fr 1fr; } .record-submit { padding-bottom: 0; } }
@media (max-width: 640px) { .record-form { grid-template-columns: 1fr; } .record-submit button { width: 100%; } }

/* People: permanently deleting a deleted account's data (people/purge). */
.purge-columns { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem 2rem; margin: 1rem 0 1.25rem; }
.purge-columns h3 { font-size: 0.95rem; margin: 0 0 0.5rem; }
.purge-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--c-border); border-radius: var(--radius, 8px); }
.purge-list li { display: flex; justify-content: space-between; gap: 1rem; padding: 0.45rem 0.75rem; }
.purge-list li + li { border-top: 1px solid var(--c-border); }

/* A wide table whose rows become stacked blocks on a phone - each row's
   cells one under another, so action buttons are never scrolled off the
   right edge. Used where the last column is the actions (People). */
@media (max-width: 640px) {
  table.stack-sm thead { display: none; }
  table.stack-sm, table.stack-sm tbody, table.stack-sm tr, table.stack-sm td { display: block; width: auto; }
  table.stack-sm tr { padding: 0.75rem 1rem; border-bottom: 1px solid var(--c-border); }
  table.stack-sm td { border: 0; padding: 0.2rem 0; }
  table.stack-sm td.hide-sm, table.stack-sm td.hide-md { display: none; }
  table.stack-sm .row-actions { justify-content: flex-start; }
  table.stack-sm .row-actions > .form-inline { justify-content: flex-start; flex-wrap: wrap; }
  /* Stacked rows: the row-select sits in the card's top corner rather than
     as a stray checkbox on its own line, and Manage aligns left. */
  table.stack-sm tr { position: relative; }
  table.stack-sm td.col-check { position: absolute; top: 0.7rem; right: 0.9rem; width: auto; padding: 0; }
  table.stack-sm .row-manage { justify-content: flex-start; }
}

/* --- Live notifications: pop-ups in the corner (app.js "Live updates") ---- */
.note-popups {
  position: fixed; z-index: 1001; right: 1rem; top: 4.25rem; display: flex; flex-direction: column; gap: 0.5rem;
  width: min(360px, calc(100vw - 2rem)); pointer-events: none;
}
.note-popup {
  position: relative; display: block; pointer-events: auto; padding: 0.75rem 2.2rem 0.7rem 0.95rem;
  background: var(--c-surface); color: var(--c-text); border: 1px solid var(--c-border);
  border-left: 4px solid var(--c-accent); border-radius: var(--radius); box-shadow: var(--shadow-lg);
  text-decoration: none; animation: wso-note-in 0.22s ease-out;
}
.note-popup:hover { border-color: var(--c-accent); text-decoration: none; }
.note-popup.note-new_sale { border-left-color: var(--c-success); }
.note-popup.note-chargeback { border-left-color: var(--c-danger); }
.note-popup.note-approval { border-left-color: var(--c-warn); }
.note-popup-title { font-weight: 640; font-size: 0.9rem; line-height: 1.3; }
.note-popup-body { margin-top: 0.2rem; font-size: 0.83rem; color: var(--c-text-2); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.note-popup-when { margin-top: 0.3rem; font-size: 0.75rem; color: var(--c-text-3, var(--c-text-2)); }
.note-popup-close {
  position: absolute; top: 0.35rem; right: 0.35rem; width: 1.6rem; height: 1.6rem; padding: 0;
  border: 0; background: transparent; color: var(--c-text-2); font-size: 1.1rem; line-height: 1; cursor: pointer;
}
.note-popup-close:hover { color: var(--c-text); background: var(--c-surface-2); }
.note-popup.is-leaving { opacity: 0; transform: translateX(12px); transition: opacity 0.4s ease, transform 0.4s ease; }
@keyframes wso-note-in { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }
@media (max-width: 640px) { .note-popups { top: auto; bottom: 1rem; left: 1rem; width: auto; } }

/* A row that arrived while the person was looking (live regions). */
tr.is-new > td, .is-new { animation: wso-row-new 2.6s ease-out; }
@keyframes wso-row-new { 0%, 30% { background: var(--c-accent-soft, #eef2ff); } 100% { background: transparent; } }

/* Account: notification sounds. */
.sound-rows { display: grid; gap: 0.5rem; margin: 0.75rem 0 1rem; }
.sound-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(150px, 220px) auto; gap: 0.6rem; align-items: center; }
.sound-row label { font-weight: 560; }
.sound-row button { display: inline-flex; align-items: center; gap: 0.3rem; }
input[type="range"] { width: 100%; max-width: 320px; accent-color: var(--c-accent); padding: 0; border: 0; background: transparent; }
@media (max-width: 640px) { .sound-row { grid-template-columns: minmax(0, 1fr) auto; } .sound-row label { grid-column: 1 / -1; } }

/* Machine page: the Software line above "Update software". */
.software-line { margin: 0.15rem 0 0.5rem; font-size: 0.9rem; }
.software-line .muted { font-size: 0.82rem; }

/* --- Card details on a sale (sales/_cards.php) ---------------------------- */
.pay-cards { list-style: none; margin: 0; padding: 0; }
.pay-card { padding: 0.75rem 1.25rem; border-top: 1px solid var(--c-border); }
.pay-card-main { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.9rem; }
.pay-card-network {
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.02em; padding: 0.15rem 0.5rem; border-radius: 6px;
  background: var(--c-surface-2); border: 1px solid var(--c-border);
}
.pay-card-network.net-visa { color: #1a1f71; }
.pay-card-network.net-mastercard { color: #c2410c; }
.pay-card-network.net-amex { color: #0369a1; }
.pay-card-number { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-weight: 600; font-size: 1rem; }
.pay-card-exp { font-size: 0.9rem; }
.pay-card-by { font-size: 0.82rem; }
.pay-card-actions { margin-left: auto; display: inline-flex; gap: 0.4rem; align-items: center; }
.pay-card-actions form { margin: 0; }
.card-frame-slot { margin-top: 0.75rem; }
.card-capture { margin: 0; padding: 1rem 1.25rem; border-top: 1px solid var(--c-border); }
.card-frame { display: block; width: 100%; height: 260px; border: 1px solid var(--c-border); border-radius: var(--radius); background: var(--c-surface); }
.card-body-hint { padding: 0 1.25rem 0.9rem; margin: 0.5rem 0 0; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .pay-card-network.net-visa { color: #a5b4fc; } }
:root[data-theme="dark"] .pay-card-network.net-visa { color: #a5b4fc; }
@media (max-width: 640px) { .pay-card { padding: 0.75rem 1rem; } .pay-card-actions { margin-left: 0; width: 100%; } }

/* Deleting log entries (audit/delete): the count that would go. */
.purge-count { margin: 1rem 0; padding: 0.75rem 1rem; border: 1px solid var(--c-border); border-radius: var(--radius); background: var(--c-surface-2); }
.purge-count.has-some { border-color: var(--c-danger); }
.purge-count strong { font-size: 1.2rem; }

/* Agent scores: period filter row and the formula rule divider. */
.filter-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem 1rem; }
.filter-row .field { margin: 0; }
.filter-row .field-or { color: var(--c-text-2); font-size: 0.85rem; padding-bottom: 0.5rem; }
hr.rule { border: 0; border-top: 1px solid var(--c-border); margin: 1.1rem 0; }

/* --- Sales grid (sales/grid, grid_table) ---------------------------------
   The finder's filter form lays out as a wrapping grid of fields; the
   table is clickable rows, each opening the sale in a pop-up. */
.filter-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0.6rem 0.9rem; align-items: end; }
.filter-grid .field { margin: 0; min-width: 0; }
.filter-grid .filter-search { grid-column: 1 / -1; }
.filter-grid .filter-actions { grid-column: 1 / -1; justify-content: flex-start; }
.grid-rows tbody tr { cursor: pointer; }
.grid-rows tbody tr:hover > td { background: var(--c-surface-2); }
.grid-rows tbody tr:focus-visible { outline: 2px solid var(--c-accent); outline-offset: -2px; }
.grid-rows a[data-sale-link] { color: inherit; text-decoration: none; }
.grid-rows tbody tr:hover a[data-sale-link] { text-decoration: underline; }
.note-dot { color: var(--c-accent-text); margin-left: 0.3rem; font-size: 0.8rem; cursor: help; }

/* --- Sale pop-up (sales/_detail_modal in the dialog app.js builds) -------- */
.sale-dialog {
  width: min(680px, 94vw); max-height: 90vh; padding: 0; border: 1px solid var(--c-border);
  border-radius: var(--radius-lg, 14px); background: var(--c-surface); color: var(--c-text);
  box-shadow: 0 24px 60px rgba(0,0,0,0.3); overflow: hidden;
}
.sale-dialog::backdrop { background: rgba(15,18,28,0.5); backdrop-filter: blur(2px); }
.sale-dialog-close {
  position: absolute; top: 0.5rem; right: 0.6rem; z-index: 2; width: 2rem; height: 2rem; line-height: 1;
  font-size: 1.4rem; border: 0; border-radius: 8px; background: transparent; color: var(--c-text-2); cursor: pointer;
}
.sale-dialog-close:hover { background: var(--c-surface-2); color: var(--c-text); }
.sale-dialog-body { max-height: 90vh; overflow: auto; padding: 1.25rem 1.4rem 1.4rem; }
.sale-dialog-loading { padding: 2.5rem 1rem; text-align: center; color: var(--c-text-3); }
.sale-modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; margin-bottom: 1rem; padding-right: 1.5rem; }
.sale-modal-head h2 { margin: 0; font-size: 1.1rem; }
.sale-modal-head p { margin: 0.15rem 0 0; font-size: 0.82rem; }
.sale-modal-edit { margin: 0 0 1rem; }
.sale-modal-meta { margin-top: 0.4rem; }
.detail-wide { grid-column: 1 / -1; }
.sale-modal-saved { color: var(--c-success); font-size: 0.85rem; }
.sale-modal-cards { margin-top: 0.4rem; }
.sale-modal-cards h3 { font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--c-text-3); margin: 0 0 0.4rem; }
.pay-card-line { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; padding: 0.35rem 0; font-size: 0.9rem; }
.sale-modal-foot { margin-top: 1rem; padding-top: 0.9rem; border-top: 1px solid var(--c-border); }
@media (max-width: 640px) {
  .sale-dialog { width: 100vw; max-width: 100vw; max-height: 100vh; height: 100vh; border-radius: 0; }
  .sale-dialog-body { max-height: 100vh; }
}

/* --- Address auto-complete (sales/customer address fields) ----------------
   The list is positioned (fixed) and appended to <body> by app.js, so a
   card's own overflow can never clip it. */
.addr-suggest {
  position: fixed; z-index: 60; margin: 0; padding: 0.25rem;
  list-style: none; background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: var(--radius); box-shadow: 0 12px 28px rgba(0,0,0,0.18); max-height: 16rem; overflow: auto;
}
.addr-suggest-item {
  padding: 0.45rem 0.6rem; border-radius: 7px; font-size: 0.88rem; cursor: pointer; color: var(--c-text);
}
.addr-suggest-item:hover, .addr-suggest-item.is-active { background: var(--c-accent-soft); color: var(--c-accent-text); }

/* --- Guided sale form (the New sale wizard; app.js builds the controls) --- */
.wizard-nav { margin: 0 0 1.1rem; }
.wizard-dots {
  display: flex; flex-wrap: wrap; gap: 0.3rem 0.5rem; list-style: none; margin: 0; padding: 0; counter-reset: none;
}
.wizard-dot {
  display: inline-flex; align-items: center; gap: 0.45rem; padding: 0.3rem 0.7rem 0.3rem 0.4rem;
  border-radius: 999px; font-size: 0.82rem; color: var(--c-text-3); background: var(--c-surface-2);
  border: 1px solid var(--c-border); cursor: default; user-select: none;
}
.wizard-dot.is-reachable { cursor: pointer; }
.wizard-dot-num {
  display: inline-flex; align-items: center; justify-content: center; width: 1.4rem; height: 1.4rem;
  border-radius: 50%; background: var(--c-surface); border: 1px solid var(--c-border);
  font-size: 0.78rem; font-weight: 640; color: var(--c-text-2); flex: none;
}
.wizard-dot.is-current { color: var(--c-accent-text); background: var(--c-accent-soft); border-color: transparent; }
.wizard-dot.is-current .wizard-dot-num { background: var(--c-accent-solid); color: #fff; border-color: transparent; }
.wizard-dot.is-done { color: var(--c-text-2); }
.wizard-dot.is-done .wizard-dot-num { background: var(--c-success-soft); color: var(--c-success); border-color: transparent; }
.wizard-dot-label { white-space: nowrap; }
.wizard-controls { display: flex; gap: 0.5rem; align-items: center; margin-top: 0.5rem; }
.wizard-controls .btn[hidden] { display: none; }
/* Only hide steps once the wizard is live; no-JS keeps them all visible.
   These elements set their own display, which beats the [hidden] UA rule, so
   hiding them needs an explicit rule. */
.js form[data-wizard] [data-wizard-step][hidden],
.js form[data-wizard] .form-actions[hidden] { display: none; }
@media (max-width: 560px) {
  .wizard-dot-label { display: none; }
  .wizard-dot.is-current .wizard-dot-label { display: inline; }
}

/* --- Charge-timing choice (New sale card step) + charging queue ----------- */
.charge-choices { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.charge-choice {
  display: flex; align-items: flex-start; gap: 0.55rem; flex: 1 1 180px; min-width: 0;
  padding: 0.7rem 0.85rem; border: 1px solid var(--c-border); border-radius: var(--radius);
  background: var(--c-surface-2); cursor: pointer;
}
.charge-choice:has(input:checked) { border-color: var(--c-accent); background: var(--c-accent-soft); }
.charge-choice input { margin-top: 0.15rem; flex: none; }
.charge-choice-body { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.charge-choice-body small { color: var(--c-text-3); font-size: 0.78rem; }
.charge-choice:has(input:checked) .charge-choice-body small { color: var(--c-accent-text); }

/* --- Charging queue rows (charging/queue) --------------------------------- */
.stat.stat-warn { border-color: var(--c-warn); }
.stat.stat-warn .stat-value { color: var(--c-warn); }
.charge-what { font-size: 0.8rem; margin-top: 0.1rem; max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.charging-rows td { vertical-align: middle; }
/* Charged / Declined / Say… sit on one line. A flex row rather than
   nowrap: the "Say…" reply menu is a <details>, which is a block and
   would otherwise drop under the buttons and double the row's height. */
.charge-actions { display: flex; gap: 0.25rem; align-items: center; justify-content: flex-end; }
.charge-actions .btn { white-space: nowrap; }
@media (max-width: 640px) {
  .charge-actions { flex-wrap: wrap; justify-content: flex-start; }
  .charge-actions .btn { flex: 1 1 auto; }
  .charge-what { max-width: 20ch; }
}

/* --- "View as role" switch and banner (layout topbar) --------------------- */
.viewas-menu { position: relative; }
.viewas-menu > summary.viewas-toggle { list-style: none; cursor: pointer; }
.viewas-menu > summary.viewas-toggle::-webkit-details-marker { display: none; }
.viewas-toggle {
  display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.34rem 0.6rem;
  border: 1px solid var(--c-border); border-radius: 8px; background: var(--c-surface);
  color: var(--c-text-2); font-size: 0.82rem; font-weight: 540;
}
.viewas-toggle:hover { background: var(--c-surface-2); color: var(--c-text); }
.viewas-toggle:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }
.viewas-panel {
  position: absolute; top: calc(100% + 8px); right: 0; width: 230px; max-width: calc(100vw - 24px);
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 0.3rem; z-index: 20;
}
.viewas-panel-head { font-size: 0.74rem; color: var(--c-text-3); padding: 0.4rem 0.55rem 0.5rem; }
.viewas-panel form { margin: 0; }
.viewas-option {
  display: block; width: 100%; text-align: left; padding: 0.5rem 0.6rem; border: 0; border-radius: 7px;
  background: transparent; color: var(--c-text); font-size: 0.88rem; cursor: pointer;
}
.viewas-option:hover { background: var(--c-accent-soft); color: var(--c-accent-text); }
.viewas-exit { margin: 0; }
.viewas-exit-btn {
  display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.36rem 0.7rem;
  border: 1px solid var(--c-warn); border-radius: 999px; background: var(--c-warn-soft);
  color: var(--c-warn); font-size: 0.82rem; font-weight: 560; cursor: pointer;
}
.viewas-exit-btn:hover { filter: brightness(0.97); }
@media (max-width: 760px) {
  .viewas-toggle-label { display: none; }
  .viewas-exit-btn span { display: none; }
  .viewas-exit-btn { padding: 0.36rem 0.5rem; }
}

/* --- Machine name as a button (machines fleet list) ----------------------- */
.machine-open { max-width: 100%; }
.machine-open span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.machine-host { margin-top: 0.25rem; padding-left: 0.2rem; font-size: 0.78rem; }

/* --- Processing queue (processing/queue) ---------------------------------- */
.proc-rows td { vertical-align: middle; }
.proc-today { white-space: nowrap; }
.proc-check { display: inline-flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; margin: 0.3rem 0 0; }
.proc-check select, .proc-check input { padding: 0.32rem 0.5rem; font-size: 0.84rem; }
.proc-check .proc-bill { width: 6.5rem; }
.proc-check .proc-details { width: 11rem; }
.proc-today .badge { margin-right: 0.35rem; }
@media (max-width: 640px) {
  .proc-check { width: 100%; }
  .proc-check select, .proc-check .proc-bill, .proc-check .proc-details { flex: 1 1 auto; width: auto; }
}
.proc-assign { max-width: 420px; margin: 0.5rem 0; }
.proc-check-page { margin-top: 0.6rem; }
.section-subhead { font-size: 0.85rem; font-weight: 620; margin: 1rem 0 0.4rem; color: var(--c-text-2); }

/* --- New sale form on one page (sales/index single-page sections) ---------- */
.sale-steps { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.9rem; }
.sale-step {
  display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.3rem 0.7rem 0.3rem 0.4rem;
  border-radius: 999px; border: 1px solid var(--c-border); background: var(--c-surface-2);
  color: var(--c-text-2); font-size: 0.82rem; text-decoration: none;
}
.sale-step:hover { background: var(--c-accent-soft); color: var(--c-accent-text); border-color: transparent; }
.sale-step-num {
  display: inline-flex; align-items: center; justify-content: center; width: 1.35rem; height: 1.35rem;
  border-radius: 50%; background: var(--c-surface); border: 1px solid var(--c-border);
  font-size: 0.76rem; font-weight: 640; flex: none;
}
.sale-form-scroll { padding: 0.9rem; }
.sale-section { scroll-margin-top: 0.4rem; }
.sale-section + .sale-section { margin-top: 0.5rem; padding-top: 0.7rem; border-top: 1px solid var(--c-border); }
.sale-section .fieldset { margin: 0; border: 0; padding: 0; }

/* The charging queue's "there is a conversation on this one" flag, beside
   the customer rather than in a column of its own — eight columns did not
   fit, and it is about that customer's sale anyway. */
.ping-flag { margin-left: 0.3rem; text-decoration: none; vertical-align: middle; }

/* "Who works whose sales": the two selects need room for their wording —
   a shrink column squeezed "New sales only" down to "New". */
.route-apply-col { min-width: 13rem; }
.route-apply-col select { width: 100%; }

/* "Marcus Bell works for Priya, Daniel" — the routing picture read from the
   processor's side, which is how a manager asks the question half the time. */
.covers-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.35rem; }
.covers-list li { font-size: 0.88rem; display: flex; gap: 0.4rem; align-items: baseline; flex-wrap: wrap; }

/* Team members as removable chips. Two identical unlabelled dropdowns (one
   to add, one to remove, both listing the whole company) were impossible to
   tell apart — and the remove one let you take somebody off a team they
   were never on. Each member now carries their own remove. */
.member-chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.35rem; }
.member-chip {
  display: inline-flex; align-items: center; gap: 0.15rem;
  padding: 0.15rem 0.2rem 0.15rem 0.5rem;
  border: 1px solid var(--c-border); border-radius: 999px;
  background: var(--c-surface-2); font-size: 0.82rem; white-space: nowrap;
}
.member-chip form { margin: 0; display: inline-flex; }
.member-chip-x {
  border: 0; background: transparent; color: var(--c-text-3); cursor: pointer;
  font-size: 1rem; line-height: 1; padding: 0 0.3rem; border-radius: 999px;
}
.member-chip-x:hover { background: var(--c-danger-soft); color: var(--c-danger); }
/* Room for a real name rather than "Arslan a…". */
.member-pick { min-width: 11rem; max-width: 16rem; }

/* Inline team rename sits in the name cell: a snug input beside its button,
   wrapping on narrow screens rather than stretching the column. */
.team-rename { flex-wrap: nowrap; align-items: center; }
.team-rename input { min-width: 8rem; max-width: 14rem; }
@media (max-width: 40rem) { .team-rename { flex-wrap: wrap; } }

/* The emergency stop card: a red hairline so it reads as a last-resort
   control, not an everyday one. */
.danger-zone { border-color: var(--c-danger); }
.danger-zone > .card-head { border-bottom-color: var(--c-danger); }

/* Owner reading a conversation they are not in. */
.chat-observer{padding:8px 14px;font-size:13px;background:var(--c-sunken);border-bottom:1px solid var(--c-border);color:var(--c-text-3)}
.chat-observer a{margin-left:8px}
.all-convos{list-style:none;margin:0;padding:0;max-height:70vh;overflow:auto}
.all-convos li+li{border-top:1px solid var(--c-border)}
.all-convos a{display:flex;gap:12px;align-items:baseline;padding:10px 16px;text-decoration:none;color:inherit}
.all-convos a:hover{background:var(--c-sunken)}
.all-convos a strong{min-width:0;flex:0 1 40%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.all-convos a .muted:last-child{margin-left:auto;white-space:nowrap}

/* "Read by N" under your own message in a group, and who it means. */
.msg-readby { background: none; border: 0; padding: 0 2px; font: inherit; font-size: 11px; color: var(--c-text-3); cursor: pointer; }
.msg-readby:hover, .msg-readby:focus-visible { color: var(--c-accent); text-decoration: underline; }
.msg-readby-pop { min-width: 200px; max-height: 320px; overflow: auto; padding: 6px 0; }
.msg-readby-group + .msg-readby-group { border-top: 1px solid var(--c-border); margin-top: 4px; padding-top: 4px; }
.msg-readby-name { padding: 3px 14px; font-size: 13px; }

/* Jumping to a quoted message: it lights up so the eye lands on it. */
.msg.is-flash .msg-body { animation: msg-flash 1.6s ease-out; }
@keyframes msg-flash { 0%, 30% { background: var(--c-accent-soft); box-shadow: 0 0 0 3px var(--c-accent-soft); } 100% { box-shadow: 0 0 0 3px transparent; } }
@media (prefers-reduced-motion: reduce) { .msg.is-flash .msg-body { animation: none; outline: 2px solid var(--c-accent); outline-offset: 2px; } }

/* The keyboard shortcuts sheet (press ?). */
.kbd-sheet { width: min(460px, calc(100vw - 32px)); }
.kbd-list { display: grid; grid-template-columns: auto 1fr; gap: 8px 16px; margin: 0; align-items: baseline; }
.kbd-list dt { white-space: nowrap; }
.kbd-list dd { margin: 0; color: var(--c-text-2); }
.kbd-sheet kbd { display: inline-block; min-width: 1.6em; padding: 1px 6px; border: 1px solid var(--c-border-strong); border-bottom-width: 2px; border-radius: 5px; background: var(--c-surface); font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; text-align: center; }
.msg-quote-gone { display: block; font-size: 11px; color: var(--c-text-3); font-style: italic; }

/* --- Attachment menu (paperclip) ------------------------------------------ */
button.chat-attach { background: none; border: 0; padding: 6px; color: var(--c-text-2); cursor: pointer; border-radius: var(--radius-sm); display: inline-flex; }
button.chat-attach:hover, button.chat-attach[aria-expanded="true"] { background: var(--c-sunken); color: var(--c-text); }
.attach-menu { min-width: 210px; padding: 6px; }
.attach-menu .attach-item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 8px; border-radius: var(--radius-sm); text-align: left; color: var(--c-text); text-decoration: none; }
.attach-menu .attach-item:hover, .attach-menu .attach-item:focus-visible { background: var(--c-sunken); }
.attach-ico { width: 30px; height: 30px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #fff; flex: none; }
.attach-ico-doc { background: #7c3aed; }
.attach-ico-media { background: #2563eb; }
.attach-ico-camera { background: #db2777; }
.attach-ico-audio { background: #ea580c; }
.attach-ico-contact { background: #0891b2; }
.attach-ico-poll { background: #ca8a04; }
.attach-ico-event { background: #dc2626; }
.attach-ico-sticker { background: #16a34a; }

/* --- Card dialogs ---------------------------------------------------------- */
.card-dialog { width: min(440px, calc(100vw - 32px)); }
.card-dialog .pop-dialog-body input[type="text"], .card-dialog .pop-dialog-body input[type="search"],
.card-dialog .pop-dialog-body input[type="datetime-local"], .card-dialog .pop-dialog-body textarea { width: 100%; }
.card-people { max-height: 320px; overflow: auto; margin-top: 8px; }
.card-person { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px; background: none; border: 0; border-radius: var(--radius-sm); text-align: left; color: var(--c-text); cursor: pointer; font: inherit; }
.card-person:hover, .card-person:focus-visible { background: var(--c-sunken); }
.card-person > span:last-child { display: flex; flex-direction: column; min-width: 0; }
.card-person .muted { font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-poll-inputs { display: flex; flex-direction: column; gap: 6px; max-height: 260px; overflow: auto; }
.card-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 480px) { .card-row { grid-template-columns: 1fr; } }
.sticker-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; }
.sticker-pick { font-size: 34px; line-height: 1; padding: 8px 0; background: none; border: 0; border-radius: var(--radius); cursor: pointer; width: 100%; }
.sticker-pick:hover, .sticker-pick:focus-visible { background: var(--c-sunken); transform: scale(1.08); }
.camera-dialog { width: min(560px, calc(100vw - 32px)); }
.camera-view, .camera-still { width: 100%; border-radius: var(--radius); background: #000; display: block; max-height: 60vh; object-fit: contain; }

/* --- Cards in the conversation -------------------------------------------- */
.msg-card { min-width: min(280px, 70vw); max-width: 360px; padding: 10px 12px; border-radius: var(--radius-lg); background: var(--c-surface); border: 1px solid var(--c-border); color: var(--c-text); }
.msg-card-sticker { background: none; border: 0; padding: 0; min-width: 0; }
.msg-sticker { font-size: 84px; line-height: 1.05; display: block; }
.card-contact { display: flex; gap: 10px; align-items: center; }
.card-contact-main { display: flex; flex-direction: column; min-width: 0; font-size: 13px; }
.card-contact-main a { overflow: hidden; text-overflow: ellipsis; }
.msg-card .card-actions { margin-top: 8px; display: flex; gap: 6px; flex-wrap: wrap; }
.msg-card .card-actions button { width: 100%; }
.card-sub { font-size: 12px; margin: 2px 0 8px; }
.card-poll-options { display: flex; flex-direction: column; gap: 6px; }
.card-poll-option { display: grid; grid-template-columns: 20px 1fr auto; grid-template-rows: auto 6px; gap: 3px 8px; align-items: center; width: 100%; padding: 6px 8px; background: var(--c-sunken); border: 1px solid transparent; border-radius: var(--radius-sm); text-align: left; cursor: pointer; font: inherit; color: var(--c-text); }
.card-poll-option:hover:not(:disabled) { border-color: var(--c-border-strong); }
.card-poll-option:disabled { cursor: default; }
.card-poll-option.is-mine { border-color: var(--c-accent); background: var(--c-accent-soft); }
.card-poll-check { width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--c-border-strong); display: inline-flex; align-items: center; justify-content: center; font-size: 12px; color: #fff; }
.card-poll-option.is-mine .card-poll-check { background: var(--c-accent-solid); border-color: var(--c-accent); }
.card-poll-count { font-size: 12px; color: var(--c-text-2); }
.card-poll-bar { grid-column: 2 / 4; width: 100%; height: 6px; }
.card-poll-bar::-webkit-meter-bar { background: var(--c-border); border: 0; border-radius: 3px; }
.card-poll-bar::-webkit-meter-optimum-value { background: var(--c-accent-solid); border-radius: 3px; }
.card-poll-bar::-moz-meter-bar { background: var(--c-accent-solid); border-radius: 3px; }
.card-who { margin-top: 8px; font-size: 12px; color: var(--c-text-2); }
.card-who summary { cursor: pointer; color: var(--c-accent-text); }
.card-who div { margin-top: 4px; }
.card-event { display: flex; gap: 12px; align-items: center; }
.card-event-date { width: 46px; flex: none; border-radius: var(--radius-sm); overflow: hidden; border: 1px solid var(--c-border); text-align: center; background: var(--c-surface); }
.card-event-date span { display: block; background: var(--c-danger); color: #fff; font-size: 11px; text-transform: uppercase; padding: 1px 0; }
.card-event-date strong { display: block; font-size: 20px; padding: 2px 0; }
.card-event-main { display: flex; flex-direction: column; min-width: 0; font-size: 13px; }
.card-event-main strong { font-size: 14px; }
.card-event-details { margin: 8px 0 0; font-size: 13px; color: var(--c-text-2); }
.card-rsvp { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.card-row > * { min-width: 0; }

/* --- Arrange sidebar (Account → Arrange sidebar) -------------------------- */
.arrange-sections, .arrange-items { list-style: none; margin: 0; padding: 0; }
.arrange-sections { display: flex; flex-direction: column; gap: 10px; max-width: 560px; }
.arrange-section { border: 1px solid var(--c-border); border-radius: var(--radius); background: var(--c-surface); }
.arrange-section.is-fixed { background: var(--c-sunken); }
.arrange-items { padding: 4px 8px 8px 28px; }
.arrange-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: var(--radius-sm); }
.arrange-head { padding: 9px 10px; }
.arrange-item .arrange-row:hover { background: var(--c-sunken); }
.arrange-grip { color: var(--c-text-3); cursor: grab; letter-spacing: -3px; font-size: 14px; user-select: none; }
.arrange-btn { background: none; border: 1px solid var(--c-border); color: var(--c-text-2); padding: 3px; border-radius: var(--radius-sm); }
.arrange-btn:hover:not(:disabled) { background: var(--c-surface); border-color: var(--c-border-strong); color: var(--c-text); }
.arrange-btn:disabled { opacity: 0.35; cursor: default; background: none; }
li.is-dragging { opacity: 0.5; }
.arrange-status { margin-left: 6px; font-weight: 600; }

/* =========================================================================
   Video meetings (resources/views/meetings/*, public/assets/meeting.js)
   ========================================================================= */
.meet-list { list-style: none; margin: 0; padding: 0; }
.meet-list li + li { border-top: 1px solid var(--c-border); }
.meet-row { display: flex; align-items: center; gap: 12px; padding: 12px 16px; flex-wrap: wrap; }
.meet-row.is-live { background: var(--c-success-soft); }
.meet-row-icon { width: 36px; height: 36px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: var(--c-accent-soft); color: var(--c-accent); flex: none; }
.meet-row-main { display: flex; flex-direction: column; min-width: 0; flex: 1; text-decoration: none; color: inherit; }
.meet-row-main .muted { font-size: 12px; }
.meet-when { white-space: nowrap; font-size: 13px; }
.inline-form { display: inline; }
.pick-list { max-height: 220px; overflow: auto; margin-top: 6px; border: 1px solid var(--c-border); border-radius: var(--radius-sm); }
.pick-row { display: flex; align-items: center; gap: 10px; padding: 6px 10px; cursor: pointer; }
.pick-row:hover { background: var(--c-sunken); }
.copy-line { display: inline-flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.copy-line code { word-break: break-all; }

/* The room is a page of its own, dark like every meeting app. */
.meet-body { margin: 0; background: #0f1115; color: #e8eaf0; min-height: 100dvh; }
.meet { min-height: 100dvh; display: flex; flex-direction: column; }
.meet .muted { color: #9aa3b5; }
.meet-center { flex: 1; display: flex; align-items: center; justify-content: center; padding: 24px 16px; }
.meet-panel { text-align: center; max-width: 440px; }
.meet-panel h1, .meet-prejoin h1 { font-size: 22px; margin: 0 0 8px; color: #fff; }
.meet-prejoin { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(260px, 1fr); gap: 32px; align-items: center; width: min(1000px, 100%); }
@media (max-width: 760px) { .meet-prejoin { grid-template-columns: 1fr; gap: 16px; } }
.meet-preview { position: relative; aspect-ratio: 16 / 9; background: #1b1f27; border-radius: 14px; overflow: hidden; }
.meet-preview video { width: 100%; height: 100%; object-fit: cover; transform: scaleX(-1); }
.meet-preview-off { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #9aa3b5; background: #1b1f27; }
.meet-preview-controls { position: absolute; left: 0; right: 0; bottom: 14px; display: flex; gap: 12px; justify-content: center; }
.meet-prejoin-side { display: flex; flex-direction: column; gap: 12px; }
.meet-field { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: #c3c9d6; }
.meet-field input, .meet-field select { background: #1b1f27; color: #fff; border: 1px solid #333a47; border-radius: 8px; padding: 9px 10px; font: inherit; width: 100%; }
.meet-devices { display: flex; flex-direction: column; gap: 10px; }
.meet-note { font-size: 13px; color: #f5c26b; min-height: 1em; margin: 0; }
.meet-join { background: var(--c-accent-solid); color: #fff; border: 0; border-radius: 999px; padding: 12px 26px; font: inherit; font-weight: 600; font-size: 15px; cursor: pointer; align-self: flex-start; }
.meet-join:hover { background: var(--c-accent-solid-hover); }
.meet-join:disabled { opacity: 0.6; cursor: default; }
.meet-secondary { background: #262b35; color: #e8eaf0; border: 1px solid #3a4150; border-radius: 999px; padding: 9px 18px; font: inherit; cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; }
.meet-secondary:hover { background: #2f3542; color: #fff; }
.meet-row-buttons { display: flex; gap: 10px; justify-content: center; margin-top: 16px; flex-wrap: wrap; }
.meet-spinner { width: 42px; height: 42px; border-radius: 50%; border: 3px solid #333a47; border-top-color: var(--c-accent); margin: 0 auto 16px; animation: meet-spin 1s linear infinite; }
@keyframes meet-spin { to { transform: rotate(360deg); } }

.meet-btn { position: relative; width: 48px; height: 48px; border-radius: 50%; border: 0; background: #2a303b; color: #fff; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; }
.meet-btn:hover { background: #353c49; }
.meet-btn .when-off { display: none; }
.meet-btn[aria-pressed="false"] .when-on { display: none; }
.meet-btn[aria-pressed="false"] .when-off { display: inline-flex; }
.meet-btn[data-mic][aria-pressed="false"], .meet-btn[data-cam][aria-pressed="false"],
.meet-btn[data-pre-mic][aria-pressed="false"], .meet-btn[data-pre-cam][aria-pressed="false"] { background: #d93025; }
.meet-btn[data-screen-share][aria-pressed="true"], .meet-btn[data-hand][aria-pressed="true"] { background: #8ab4f8; color: #0f1115; }
.meet-dot { position: absolute; top: 8px; right: 8px; width: 9px; height: 9px; border-radius: 50%; background: #8ab4f8; }
.meet-badge { position: absolute; top: 2px; right: 0; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: #d93025; color: #fff; font-size: 11px; line-height: 18px; text-align: center; }

.meet-call { flex: 1; display: flex; flex-direction: column; height: 100dvh; min-height: 0; }
.meet-top { display: flex; align-items: center; gap: 12px; padding: 10px 16px; font-size: 14px; }
.meet-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 40vw; }
.meet-clock { color: #9aa3b5; font-variant-numeric: tabular-nums; }
.meet-rec { display: inline-flex; align-items: center; gap: 5px; color: #ff6b5e; font-weight: 600; font-size: 12px; }
.meet-conn { color: #f5c26b; font-size: 12px; }
.meet-body-row { flex: 1; display: flex; min-height: 0; gap: 12px; padding: 0 12px; }
.meet-stage { flex: 1; display: flex; flex-direction: column; gap: 10px; min-width: 0; min-height: 0; }
.meet-spot { flex: 1; position: relative; background: #000; border-radius: 12px; overflow: hidden; min-height: 0; }
.meet-spot video { width: 100%; height: 100%; object-fit: contain; }
.meet-grid {
  /* Columns and rows by head count, and each tile as big as fits both the
     width and the height of the stage (16:9) -- the Meet / Zoom grid. */
  --cols: 1; --rows: 1;
  flex: 1; display: grid; gap: 10px; min-height: 0;
  grid-template-columns: repeat(var(--cols), minmax(0, calc((100dvh - 170px) / var(--rows) * 16 / 9 - 10px)));
  justify-content: center; align-content: center;
}
.meet-grid[data-n="2"] { --cols: 2; }
.meet-grid[data-n="3"], .meet-grid[data-n="4"] { --cols: 2; --rows: 2; }
.meet-grid[data-n="5"], .meet-grid[data-n="6"] { --cols: 3; --rows: 2; }
.meet-grid[data-n="7"], .meet-grid[data-n="8"], .meet-grid[data-n="9"] { --cols: 3; --rows: 3; }
.meet-grid[data-n="10"], .meet-grid[data-n="11"], .meet-grid[data-n="12"] { --cols: 4; --rows: 3; }
.meet-grid[data-n="13"], .meet-grid[data-n="14"], .meet-grid[data-n="15"], .meet-grid[data-n="16"] { --cols: 4; --rows: 4; }
@media (max-width: 760px) {
  .meet-stage { overflow: auto; }
  .meet-grid { grid-template-columns: repeat(min(var(--cols), 2), minmax(0, 1fr)); align-content: start; }
  .meet-grid[data-n="2"] { --cols: 1; }
}
.has-spot .meet-grid { flex: 0 0 auto; display: flex; overflow-x: auto; gap: 8px; height: 120px; }
.has-spot .meet-grid .meet-tile { width: 200px; flex: none; aspect-ratio: auto; height: 100%; }
.meet-tile { position: relative; background: #1b1f27; border-radius: 12px; overflow: hidden; aspect-ratio: 16 / 9; min-height: 0; max-height: 100%; border: 2px solid transparent; transition: border-color 0.15s; }
.meet-tile.is-speaking { border-color: #8ab4f8; }
.meet-tile.is-poor::after { content: 'Poor connection'; position: absolute; top: 8px; right: 8px; font-size: 11px; background: rgba(0,0,0,.6); padding: 2px 6px; border-radius: 6px; color: #f5c26b; }
.meet-tile video { width: 100%; height: 100%; object-fit: cover; display: none; }
.meet-tile.has-video video { display: block; }
.meet-tile video.is-mirrored { transform: scaleX(-1); }
.meet-avatar { position: absolute; inset: 0; margin: auto; width: min(84px, 42%); height: auto; aspect-ratio: 1; border-radius: 50%; background: #5b5fc7; color: #fff; display: flex; align-items: center; justify-content: center; font-size: clamp(13px, 2.4vw, 30px); font-weight: 600; }
.meet-tile.has-video .meet-avatar { display: none; }
.has-spot .meet-avatar { width: 48px; height: 48px; font-size: 18px; }
.meet-tile-name { position: absolute; left: 8px; bottom: 8px; display: inline-flex; align-items: center; gap: 5px; background: rgba(0,0,0,.55); padding: 3px 8px; border-radius: 6px; font-size: 12px; color: #fff; max-width: calc(100% - 16px); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.meet-tile-mic { color: #ff6b5e; display: inline-flex; }

.meet-side { width: 340px; flex: none; background: #fff; color: #14161c; border-radius: 12px; display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
@media (max-width: 760px) { .meet-side { position: fixed; inset: 0 0 76px 0; width: auto; border-radius: 0; z-index: 5; } }
.meet-side .muted { color: #6b7280; }
.meet-side-head { display: flex; align-items: center; padding: 8px 8px 0 12px; border-bottom: 1px solid #e5e7eb; }
.meet-tabs { display: flex; gap: 4px; flex: 1; }
.meet-tabs button { background: none; border: 0; border-bottom: 2px solid transparent; padding: 8px 10px; font: inherit; color: #4b5563; cursor: pointer; }
.meet-tabs button[aria-selected="true"] { color: var(--c-accent); border-bottom-color: var(--c-accent); font-weight: 600; }
.meet-icon { background: none; border: 0; padding: 6px; color: #4b5563; cursor: pointer; border-radius: 6px; }
.meet-icon:hover { background: #f3f4f6; }
.meet-pane { flex: 1; display: flex; flex-direction: column; min-height: 0; overflow: auto; }
.meet-chat-log { flex: 1; overflow: auto; padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.meet-chat-msg { font-size: 14px; }
.meet-chat-head { font-size: 12px; margin-bottom: 2px; }
.meet-chat-msg div:last-child { white-space: pre-wrap; word-break: break-word; }
.meet-chat-form { display: flex; gap: 6px; padding: 10px; border-top: 1px solid #e5e7eb; }
.meet-chat-form input { flex: 1; min-width: 0; border: 1px solid #d1d5db; border-radius: 999px; padding: 8px 12px; font: inherit; }
.meet-section-label { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: #6b7280; padding: 12px 12px 4px; font-weight: 600; }
.meet-person { display: flex; align-items: center; gap: 8px; padding: 6px 12px; flex-wrap: wrap; }
.meet-avatar-sm { width: 28px; height: 28px; border-radius: 50%; background: #5b5fc7; color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 600; flex: none; }
.meet-person-name { font-size: 14px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.meet-person-state { font-size: 12px; color: #6b7280; }
.meet-person-actions { display: flex; gap: 4px; flex-wrap: wrap; }
.meet-mini { font: inherit; font-size: 12px; padding: 3px 8px; border-radius: 6px; border: 1px solid #d1d5db; background: #fff; color: #14161c; cursor: pointer; }
.meet-mini:hover { background: #f3f4f6; }
.meet-mini.is-primary { background: var(--c-accent-solid); border-color: var(--c-accent); color: #fff; }
.meet-mini.is-danger { color: #b91c1c; }
.meet-lobby { background: #fffbeb; border-bottom: 1px solid #fde68a; }
.meet-mod-row { padding: 10px 12px 0; }
.meet-side .meet-secondary { background: #fff; color: #14161c; border-color: #d1d5db; }

.meet-bar { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 12px 16px; flex-wrap: wrap; }
.meet-bar-group { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.meet-leave { display: inline-flex; align-items: center; gap: 6px; height: 48px; padding: 0 20px; border-radius: 999px; border: 0; background: #d93025; color: #fff; font: inherit; font-weight: 600; cursor: pointer; }
.meet-leave:hover { background: #b3261e; }
.meet-end { height: 48px; padding: 0 16px; border-radius: 999px; border: 1px solid #d93025; background: transparent; color: #ff8a80; font: inherit; cursor: pointer; }
.meet-end:hover { background: rgba(217,48,37,.15); }
@media (max-width: 560px) { .meet-btn { width: 42px; height: 42px; } .meet-leave span { display: none; } .meet-title { max-width: 50vw; } }

.meet-pop { background: #fff; color: #14161c; border: 0; border-radius: 12px; padding: 6px; box-shadow: 0 10px 30px rgba(0,0,0,.4); margin: 0; inset: auto auto 84px 16px; position: fixed; }
.meet-pop:not(.meet-dialog) > button, .meet-pop:not(.meet-dialog) > a { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 9px 12px; font: inherit; color: inherit; border-radius: 8px; cursor: pointer; text-decoration: none; }
.meet-pop:not(.meet-dialog) > button:hover, .meet-pop:not(.meet-dialog) > a:hover { background: #f3f4f6; }
.meet-react:popover-open { display: flex; gap: 2px; padding: 6px; }
.meet-react button { font-size: 26px; padding: 6px; width: auto; }
.meet-devices-pop { inset: auto auto 84px 50%; transform: translateX(-50%); width: min(380px, calc(100vw - 32px)); padding: 14px; }
.meet-devices-pop .meet-field { color: #374151; }
.meet-devices-pop .meet-field select { background: #fff; color: #14161c; border-color: #d1d5db; }
.meet-toast { position: fixed; left: 50%; top: 56px; transform: translateX(-50%); background: #2a303b; color: #fff; padding: 10px 16px; border-radius: 10px; box-shadow: 0 6px 20px rgba(0,0,0,.35); font-size: 14px; max-width: calc(100vw - 32px); z-index: 10; }
.meet-reactions-fly { position: fixed; inset: 0; pointer-events: none; overflow: hidden; z-index: 9; }
.meet-fly { --x: 50; position: absolute; bottom: 90px; left: calc(var(--x, 50) * 1%); font-size: 40px; animation: meet-fly 3s ease-out forwards; }
@keyframes meet-fly { 0% { transform: translateY(0); opacity: 1; } 100% { transform: translateY(-60vh); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .meet-fly { animation-duration: 0.01s; } }

/* Meetings, second round: breakouts, captions, lock, pin. */
.meet-lockbadge { font-size: 12px; color: #f5c26b; }
.meet-breakout-banner { display: inline-flex; align-items: center; gap: 10px; font-size: 13px; color: #8ab4f8; }
.meet-breakout-banner .meet-secondary { padding: 5px 12px; font-size: 13px; }
.meet-tile { cursor: pointer; }
.meet-tile.is-pinned { border-color: #f5c26b; }
.meet-cc { position: fixed; left: 50%; bottom: 92px; transform: translateX(-50%); width: min(820px, calc(100vw - 32px)); background: rgba(0,0,0,.78); color: #fff; padding: 10px 16px; border-radius: 10px; font-size: 17px; line-height: 1.45; z-index: 8; }
.meet-cc:empty { display: none; }
.meet-dialog { inset: 50% auto auto 50%; transform: translate(-50%, -50%); width: min(460px, calc(100vw - 32px)); max-height: 80vh; overflow: auto; padding: 16px; }
.meet-dialog-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.meet-dialog .meet-field { color: #374151; margin-bottom: 8px; }
.meet-dialog .meet-field select, .meet-bo-person select { background: #fff; color: #14161c; border: 1px solid #d1d5db; border-radius: 8px; padding: 6px 8px; font: inherit; }
.meet-dialog-row { margin: 6px 0 10px; }
.meet-bo-people { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; max-height: 40vh; overflow: auto; }
.meet-bo-person { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 14px; }
.meet-bo-room { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 0; border-bottom: 1px solid #e5e7eb; }
.meet-small { font-size: 12px; }
.meet-dialog .meet-join, .meet-dialog .meet-leave { width: 100%; justify-content: center; margin-top: 8px; }
.meet-dialog .meet-chat-form { padding: 10px 0; border-top: 0; }
.meet-mini:hover { color: #14161c; }
.meet-mini.is-primary:hover { background: var(--c-accent-solid-hover); color: #fff; }
.meet-mini.is-danger:hover { color: #b91c1c; }
.meet-icon:hover { color: #14161c; }
.meet-bo-person span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.meet-bo-person select { flex: 0 0 150px; }

/* Shared whiteboard in a meeting. */
.meet-wb { position: relative; flex: 1; display: flex; flex-direction: column; background: #fff; border-radius: 12px; overflow: hidden; min-height: 0; }
.meet-wb-tools { display: flex; align-items: center; gap: 6px; padding: 8px 10px; border-bottom: 1px solid #e5e7eb; flex-wrap: wrap; color: #14161c; }
.meet-wb-tools .spacer { flex: 1; }
.meet-wb-sep { width: 1px; height: 22px; background: #e5e7eb; margin: 0 4px; }
.meet-wb-color { width: 28px; height: 28px; border-radius: 50%; padding: 3px; border: 2px solid transparent; background: none; cursor: pointer; }
.meet-wb-color.is-on { border-color: #14161c; }
.meet-wb-color span { display: block; width: 100%; height: 100%; border-radius: 50%; }
.meet-wb-color .sw-black { background: #111827; }
.meet-wb-color .sw-red { background: #dc2626; }
.meet-wb-color .sw-blue { background: #2563eb; }
.meet-wb-color .sw-green { background: #16a34a; }
.meet-wb-color .sw-yellow { background: #f59e0b; }
.meet-wb-tools .meet-mini[aria-pressed="true"] { background: #e0e7ff; border-color: var(--c-accent); }
/* Always 16:9, so every screen sees the same picture in the same place. */
.meet-wb canvas { flex: 0 1 auto; width: min(100%, calc((100dvh - 340px) * 16 / 9)); height: auto; aspect-ratio: 16 / 9; margin: auto; touch-action: none; cursor: crosshair; background: #fff; border: 1px solid #f3f4f6; }
.has-wb .meet-spot { display: none; }
.has-wb .meet-grid { flex: 0 0 auto; display: flex; overflow-x: auto; gap: 8px; height: 110px; }
.has-wb .meet-grid .meet-tile { width: 180px; flex: none; aspect-ratio: auto; height: 100%; }
.has-wb .meet-avatar { width: 44px; font-size: 16px; }

/* Account -> Which notifications you get: one table per section, the two
   tick-box columns narrow and centred. */
.topic-form .table-wrap { margin-bottom: 1rem; }
.topic-table { width: 100%; }
.topic-caption { text-align: left; font-weight: 600; padding: 0 0 0.35rem; color: var(--c-text); }
.topic-table .topic-label { font-weight: 400; text-align: left; }
.topic-table .topic-label label { cursor: pointer; }
.topic-table .topic-col { width: 6.5rem; text-align: center; }
.topic-table input[type="checkbox"] { width: 1.1rem; height: 1.1rem; cursor: pointer; }
@media (max-width: 560px) {
  .topic-table .topic-col { width: 4.25rem; }
}

/* ===== HR & pay (resources/views/hr) ===================================== */
.hr-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 0.75rem; margin-bottom: 0.75rem; }
.hr-tile { border: 1px solid var(--c-border); border-radius: var(--radius); padding: 0.75rem 0.9rem; background: var(--c-surface-2); display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.hr-tile-label { font-size: 0.8rem; color: var(--c-text-2); }
.hr-tile strong { font-size: 1.1rem; font-variant-numeric: tabular-nums; }
.hr-tile-sub { font-size: 0.78rem; }

/* The slip itself: screen, review and paper share it. */
.slip { display: flex; flex-direction: column; gap: 1rem; }
.slip-head { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; align-items: flex-start; }
.slip-name { font-size: 1.15rem; font-weight: 650; }
.slip-period { text-align: right; }
.slip-month { font-size: 1.05rem; font-weight: 620; }
.slip-facts { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 0.5rem; margin: 0; }
.slip-facts > div { border: 1px solid var(--c-border); border-radius: var(--radius-sm); padding: 0.4rem 0.6rem; }
.slip-facts dt { font-size: 0.75rem; color: var(--c-text-2); }
.slip-facts dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; }
.slip-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; align-items: start; }
.slip-table { width: 100%; border: 1px solid var(--c-border); border-radius: var(--radius); border-collapse: separate; border-spacing: 0; overflow: hidden; }
.slip-table caption { text-align: left; font-weight: 620; padding: 0 0 0.35rem; }
.slip-table th, .slip-table td { padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--c-border); vertical-align: top; }
.slip-table th { font-weight: 450; text-align: left; }
.slip-table td { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.slip-table tfoot th, .slip-table tfoot td { font-weight: 650; border-bottom: 0; background: var(--c-surface-2); }
.slip-sub { display: block; font-size: 0.78rem; color: var(--c-text-2); }
.slip-net { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; padding: 0.85rem 1rem; border-radius: var(--radius); background: var(--c-accent-soft); color: var(--c-accent-text); }
.slip-net strong { font-size: 1.35rem; font-variant-numeric: tabular-nums; }
.slip-sales summary { cursor: pointer; color: var(--c-text-2); }
.slip-sales .table-wrap { margin-top: 0.5rem; }
.slip-claw td { color: var(--c-danger); }
.slip-footer, .slip-small { font-size: 0.8rem; color: var(--c-text-3); margin: 0; }
@media (max-width: 720px) {
  .slip-cols { grid-template-columns: 1fr; }
  .slip-period { text-align: left; }
}

/* Reviewing a slip: the slip and its edit controls side by side when wide. */
.slip-review { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; }
@media (min-width: 1700px) { .slip-review { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; } }
.slip-line-form { flex-wrap: nowrap; }
.slip-line-form input[name="amount"] { width: 8.5rem; }
.slip-line-form input[name="note"] { flex: 1; min-width: 6rem; }
.slip-add-title { font-size: 0.95rem; margin: 1.25rem 0 0.5rem; }
@media (max-width: 720px) { .slip-line-form { flex-wrap: wrap; } }

/* Slab and tier editors inside the rule dialogs. */
.slab-table input { width: 100%; min-width: 6rem; }
.fx-new input { width: 5.5rem; }
.fx-new input[name="new_rate"] { width: 7rem; }
.leave-decide input[name="note"] { min-width: 8rem; }

/* The printable slip page. */
.slip-print-page { background: #fff; color: #111; }
.slip-print-bar { display: flex; justify-content: flex-end; padding: 1rem; max-width: 900px; margin: 0 auto; }
.slip-print { max-width: 900px; margin: 0 auto; padding: 0 1rem 2rem; }
.slip-print-org { display: flex; justify-content: space-between; align-items: baseline; border-bottom: 2px solid #111; padding-bottom: 0.5rem; margin-bottom: 1rem; font-size: 1.1rem; }
.slip-print .slip-net { background: #f1f1f4; color: #111; }
@media print {
  .slip-print-bar { display: none; }
  .slip-print { padding: 0; max-width: none; }
  .slip-print-page { font-size: 11pt; }
  .slip-table, .slip-facts > div { break-inside: avoid; }
}
/* Long rule dialogs (tax slabs, tiers): the form scrolls inside the dialog
   rather than running off the screen. Only while open -- a display rule on
   the closed popover would show it (the bug .meet-react had). */
.hr-dialog { width: min(560px, calc(100vw - 2rem)); max-height: calc(100vh - 2rem); }
.hr-dialog:popover-open { display: flex; flex-direction: column; }
.hr-dialog .pop-dialog-body { overflow-y: auto; min-height: 0; }
/* HR card headers carry several actions; on a narrow screen they wrap
   under the title instead of running off the edge. */
.hr-head { flex-wrap: wrap; row-gap: 0.5rem; }
.hr-head .card-actions { flex-wrap: wrap; }

/* HR bulk bars: wrap on narrow screens; the action's own fields sit inline. */
.hr-bulk { flex-wrap: wrap; gap: 0.5rem; }
.hr-bulk select, .hr-bulk input[type="text"] { width: auto; max-width: 100%; min-width: 0; }
.hr-bulk-field { display: inline-flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.hr-bulk-field[hidden] { display: none; }
@media (max-width: 640px) {
  .hr-bulk > *, .hr-bulk-field, .hr-bulk-field > input, .hr-bulk-field > select { flex: 1 1 100%; }
}

/* Signup: a wider card for two columns, and the bot trap kept off-screen
   (not display:none, which some bots skip). */
.auth-card.auth-card-wide { max-width: 640px; }
.signup-trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.platform-sub { display: block; }
.platform-suspend { flex-wrap: nowrap; gap: 0.4rem; }
.platform-suspend input[type="text"] { width: 9rem; min-width: 0; }
@media (max-width: 640px) { .platform-suspend { flex-wrap: wrap; } .platform-suspend input[type="text"] { width: 100%; } }

/* The company's own logo and name in the sidebar (App\Org\Branding). The
   logo is a square PNG with transparency, so it sits on the dark rail as is,
   on a soft tile for logos drawn in dark ink. */
.brand-logo {
  width: 26px; height: 26px; flex: 0 0 26px;
  border-radius: 7px; object-fit: contain;
  background: rgba(255, 255, 255, 0.92); padding: 2px;
}
.brand-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
.brand-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.brand-sub { font-size: 0.68rem; font-weight: 520; color: var(--c-nav-text); letter-spacing: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Settings: the look card. */
.brand-preview { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.9rem; }
.brand-preview img { width: 48px; height: 48px; border-radius: 10px; border: 1px solid var(--c-border); background: var(--c-surface-2); object-fit: contain; }
.accent-row { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.accent-row input[type="color"] { width: 3rem; height: 2.2rem; padding: 2px; border: 1px solid var(--c-input-border); border-radius: var(--radius-sm); background: var(--c-surface); cursor: pointer; }

/* --- Pay rules: country templates (App\Hr\TaxTemplates) ---------------- */

.template-pick, .template-save { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem 0.75rem; }
.template-pick .field, .template-save .field { flex: 1 1 16rem; min-width: 0; margin-bottom: 0; }
.template-pick .form-actions, .template-save .form-actions { margin-top: 0; }
.template-save { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--c-border); }
.template-details { margin-top: 0.85rem; }
.template-details summary { cursor: pointer; font-size: 0.875rem; color: var(--c-accent); }
.template-about { padding: 0.75rem 0; border-bottom: 1px solid var(--c-border); }
.template-about h3 { font-size: 0.92rem; margin: 0 0 0.3rem; }
.template-rules { margin: 0 0 0.35rem; padding-left: 1.1rem; font-size: 0.86rem; }
.template-about a { overflow-wrap: anywhere; }
.template-own { list-style: none; margin: 0.75rem 0 0; padding: 0; }
.template-own li { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; padding: 0.35rem 0; border-bottom: 1px solid var(--c-border); }

/* --- Server screen (/server, App\Server) ---------------------------------- */

/* Tabs scroll sideways on a narrow screen rather than wrapping or overflowing. */
.tabs { overflow-x: auto; scrollbar-width: none; }
.tabs a { white-space: nowrap; }
.tabs-sm { margin-bottom: 0; border-bottom: 0; }
.tabs-sm a { padding: 0.3rem 0.6rem; font-size: 0.8rem; }

.server-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(13.5rem, 1fr)); gap: 0.85rem; margin-bottom: 1rem; }
.server-tile { padding: 0.95rem 1.05rem; margin: 0; display: flex; flex-direction: column; gap: 0.35rem; min-width: 0; }
.server-tile-label { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--c-text-3); font-weight: 600; }
.server-tile-value { font-size: 1.55rem; font-weight: 650; color: var(--c-text); line-height: 1.15; }
.server-tile-sub { font-size: 0.82rem; color: var(--c-text-2); overflow-wrap: anywhere; }
.server-tile meter, .server-tiles meter { width: 100%; }
meter { width: 8rem; max-width: 100%; height: 0.6rem; }

.server-alert-list { list-style: none; margin: 0; padding: 0.85rem 1.05rem 0.95rem; display: grid; gap: 0.45rem; font-size: 0.9rem; }

.server-spark { display: grid; grid-template-columns: 6.5rem 1fr; align-items: center; gap: 0.75rem; margin-bottom: 0.6rem; }
.server-chart { position: relative; border-radius: 8px; }
.server-chart:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 4px; }
.spark-plot { position: relative; height: 4.5rem; background: var(--c-surface-2, transparent); border-radius: 6px; cursor: crosshair; touch-action: pan-y; }
.spark-plot svg { width: 100%; height: 100%; display: block; }
/* The moment being read: a guide through every chart, a dot on each line,
   and the box with every value (app.js, "Server screen"). Positions are set
   from script, which the content security policy allows; nothing here is
   an inline style attribute. */
.spark-guide { position: absolute; top: 0; bottom: 0; width: 1px; margin-left: -0.5px; background: var(--c-text-3); pointer-events: none; }
.spark-dot { position: absolute; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 50%; background: var(--c-accent-solid); box-shadow: 0 0 0 2px var(--c-surface, #fff); pointer-events: none; }
.spark-dot-mem { background: var(--c-success); }
.spark-dot-disk { background: var(--c-warn); }
.spark-tip { position: absolute; z-index: 5; min-width: 12.5rem; max-width: calc(100% - 1rem); padding: 0.55rem 0.7rem; background: var(--c-surface, #fff); color: var(--c-text); border: 1px solid var(--c-border); border-radius: 8px; box-shadow: 0 8px 24px rgba(15, 23, 42, 0.16); font-size: 0.82rem; pointer-events: none; }
.spark-tip-time { font-weight: 600; margin-bottom: 0.3rem; color: var(--c-text); }
.spark-tip-row { display: flex; justify-content: space-between; gap: 1rem; padding: 0.08rem 0; color: var(--c-text-2); }
.spark-tip-row span::before { content: ""; display: inline-block; width: 0.55rem; height: 0.55rem; border-radius: 50%; margin-right: 0.4rem; background: var(--c-border); vertical-align: 0.05rem; }
.spark-tip-cpu span::before { background: var(--c-accent-solid); }
.spark-tip-memory span::before { background: var(--c-success); }
.spark-tip-disk span::before { background: var(--c-warn); }
.spark-tip-row strong { color: var(--c-text); font-variant-numeric: tabular-nums; }
.spark-tip-why { margin-top: 0.35rem; padding-top: 0.35rem; border-top: 1px solid var(--c-border); color: var(--c-text-2); max-width: 22rem; white-space: normal; line-height: 1.35; }
.server-head-note { font-size: 0.8rem; white-space: nowrap; }
.server-more summary { cursor: pointer; color: var(--c-accent); font-size: 0.78rem; }
.server-two > .card.collapsible { margin-bottom: 1rem; }
.server-spark-label { font-size: 0.85rem; color: var(--c-text-2); }
.spark-grid { stroke: var(--c-border); stroke-width: 1; stroke-dasharray: 4 4; vector-effect: non-scaling-stroke; }
.spark-line { fill: none; stroke: var(--c-accent); stroke-width: 2; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.spark-mem { stroke: var(--c-success); }
.spark-disk { stroke: var(--c-warn); }
@media (max-width: 560px) {
  .server-spark { grid-template-columns: 1fr; gap: 0.2rem; }
}

.server-two { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: 0 1rem; }
.server-two > .card { min-width: 0; }
.server-path { font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace); font-size: 0.8rem; overflow-wrap: anywhere; word-break: break-word; }
.server-agent { max-width: 16rem; overflow-wrap: anywhere; }
.server-h3 { font-size: 0.95rem; margin: 0 0 0.35rem; }
.server-kv { list-style: none; margin: 0; padding: 0; font-size: 0.875rem; }
.server-kv li { display: flex; justify-content: space-between; gap: 0.75rem; padding: 0.25rem 0; border-bottom: 1px solid var(--c-border); overflow-wrap: anywhere; }
.server-checks { margin: 0.4rem 0 0; padding-left: 1.1rem; display: grid; gap: 0.35rem; font-size: 0.9rem; }
.server-search { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 0.25rem 0.75rem; align-items: end; }
.server-search .field { margin-bottom: 0.4rem; min-width: 0; }
.server-search .checkbox, .server-search .form-actions { margin: 0 0 0.5rem; }
.server-daypick { display: flex; align-items: center; gap: 0.5rem; }
.server-daypick select { width: auto; }
.server-when { padding: 0.9rem 1.05rem; }
.server-when-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem 0.75rem; }
.server-when-form .field { margin-bottom: 0; min-width: 0; flex: 0 1 18rem; }
.server-when-form .form-actions { margin-top: 0; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.server-when .alert { margin: 0.6rem 0 0; }
.spark-plot { cursor: pointer; }
.spark-at-row { margin: 0.5rem 0 0; min-height: 1.3rem; font-size: 0.85rem; }

/* --- Settings -> Sales process (App\Crm\SalesProcess) ------------------------ */

.process-list { list-style: none; margin: 0; padding: 0 1.05rem; }
/* Settings > Sales process: the template picker */
.deal-invoice { font-size: 0.78rem; font-weight: 600; color: var(--c-accent-text); text-decoration: none; }
.deal-invoice:hover { text-decoration: underline; }
.template-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 0.75rem; margin: 0.75rem 0; }
.template-card { display: grid; gap: 0.4rem; padding: 0.85rem 0.95rem; border: 1px solid var(--c-border); border-radius: var(--radius); cursor: pointer; background: var(--c-surface); }
.template-card:has(input:checked) { border-color: var(--c-accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--c-accent) 30%, transparent); }
.template-card input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.template-card:has(input:focus-visible) { outline: 2px solid var(--c-accent); outline-offset: 2px; }
.template-name { font-weight: 600; }
.template-for { font-size: 0.86rem; color: var(--c-text-2); }
.template-stages { display: flex; flex-wrap: wrap; gap: 0.25rem; }
.template-stages .badge { font-size: 0.72rem; }
.template-statuses { font-size: 0.8rem; color: var(--c-text-2); }
.process-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; padding: 0.55rem 0; border-bottom: 1px solid var(--c-border); }
.process-row:last-child { border-bottom: 0; }
.process-order { display: flex; gap: 0.15rem; }
.process-arrow { padding: 0.25rem; line-height: 0; }
.process-arrow:disabled { opacity: 0.35; cursor: default; }
.process-edit { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; flex: 1 1 22rem; min-width: 0; }
.process-edit input[type="text"] { flex: 1 1 12rem; min-width: 0; }
.process-edit select { width: auto; }
.process-check { margin: 0; white-space: nowrap; }
.process-meta { font-size: 0.82rem; color: var(--c-text-2); white-space: nowrap; min-width: 8.5rem; text-align: right; }
@media (max-width: 640px) {
  /* The name and its settings first; the arrows, count and Delete share the line under it. */
  .process-edit { order: 1; flex-basis: 100%; }
  .process-order { order: 2; }
  .process-meta { order: 3; min-width: 0; text-align: left; margin-left: auto; }
  .process-row > .ghost, .process-row > .inline-form, .process-keep { order: 4; }
}
.process-keep { font-size: 0.78rem; color: var(--c-text-3); white-space: nowrap; }
.process-name { flex: 1 1 12rem; font-weight: 550; }
.process-add { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem 0.75rem; }
.process-add .field { margin-bottom: 0; flex: 1 1 14rem; min-width: 0; }
.process-add .form-actions, .process-add .checkbox { margin: 0; }

/* --- Customers -> Import (App\Crm\Import) -------------------------------- */

.import-back { margin: 0 0 0.75rem; font-size: 0.875rem; }
.import-upload { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem 0.75rem; }
.import-upload .field { flex: 1 1 20rem; margin-bottom: 0; min-width: 0; }
.import-upload .form-actions { margin: 0; }
.import-samples { max-width: 22rem; overflow-wrap: anywhere; font-size: 0.82rem; }
.import-form select { max-width: 100%; }
.import-options { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: 1rem 1.5rem; }
.import-options .fieldset { margin: 0; }
.import-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; margin: 0.25rem 0 1.25rem; }
.import-progress { width: 100%; height: 0.75rem; }
.import-counts { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: 0.75rem; margin: 0.75rem 0 1rem; }
.import-counts div { padding: 0.6rem 0.75rem; border: 1px solid var(--c-border); border-radius: var(--radius-sm, 6px); }
.import-counts dt { font-size: 0.78rem; color: var(--c-text-2); }
.import-counts dd { margin: 0.15rem 0 0; font-size: 1.35rem; font-weight: 650; }

/* Round refresh button (partials/refresh_button), as in Gmail and Google Ads. */
.tabs-row { display: flex; align-items: center; gap: 0.5rem; }
.tabs-row > .tabs { flex: 1 1 auto; min-width: 0; }
.refresh-btn { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 2.25rem; height: 2.25rem; padding: 0; border: 1px solid transparent; border-radius: 50%; background: transparent; color: var(--c-text-2); cursor: pointer; }
.refresh-btn:hover { background: var(--c-sunken); color: var(--c-text); }
.refresh-btn:focus-visible { outline: 2px solid var(--c-accent-solid); outline-offset: 2px; }
.refresh-btn.is-spinning svg { animation: refresh-spin 0.8s linear infinite; }
@keyframes refresh-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .refresh-btn.is-spinning svg { animation: none; } .refresh-btn.is-spinning { opacity: 0.6; } }

/* Billing (App\Billing): Platform > Billing setup and Invoices, a company's Billing. */
.billing-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(13.5rem, 1fr)); gap: 0.85rem; margin-bottom: 1rem; }
.billing-tile { padding: 0.95rem 1.05rem; margin: 0; display: flex; flex-direction: column; gap: 0.35rem; min-width: 0; }
.billing-tile-label { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--c-text-3); font-weight: 600; }
.billing-tile-value { font-size: 1.45rem; font-weight: 650; color: var(--c-text); line-height: 1.2; }
.billing-tile-sub { font-size: 0.82rem; color: var(--c-text-2); }
.billing-terms-ask { border-color: var(--c-accent-solid); }
.billing-accept { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; }
.pm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: 0.85rem; }
.pm-card { border: 1px solid var(--c-border); border-radius: 10px; padding: 0.85rem 0.95rem; background: var(--c-surface); display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; }
.pm-card.is-on { border-color: var(--c-accent-solid); box-shadow: inset 3px 0 0 var(--c-accent-solid); }
.pm-head { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.25rem; }
.pm-card textarea { min-height: 5.5rem; }
.invoice-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-bottom: 1rem; }
.invoice-actions .inline-form { margin: 0; }
.invoice-tabs { padding: 0 1rem; }
.invoice-edit { max-width: 860px; margin-left: auto; margin-right: auto; }
.invoice-edit-lines { width: 100%; }
.invoice-edit-lines td { padding: 0.25rem; }
.invoice-edit-lines input { width: 100%; }
.invoice-edit-lines .num-input { max-width: 8rem; text-align: right; margin-left: auto; display: block; }
.terms-editor { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.85rem; line-height: 1.5; }
.mono-cell { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.82rem; overflow-wrap: anywhere; }
.legal-doc { max-width: 820px; margin: 0 auto; }
.legal-body { line-height: 1.65; color: var(--c-text); }
.legal-hash { overflow-wrap: anywhere; margin-top: 1.5rem; }
.verify-card { max-width: 640px; margin: 0 auto; }
.verify-form { display: flex; gap: 0.5rem; margin: 1rem 0; flex-wrap: wrap; }
.verify-form input { flex: 1 1 14rem; }
.verify-facts { display: grid; grid-template-columns: max-content 1fr; gap: 0.35rem 1rem; margin: 1rem 0; }
.verify-facts dt { color: var(--c-text-2); }
.verify-facts dd { margin: 0; font-weight: 600; }
.verify-hash { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.8rem; overflow-wrap: anywhere; font-weight: 400; }
.stripe-steps { padding-left: 1.2rem; display: grid; gap: 0.6rem; margin: 0.5rem 0 1rem; }
.stripe-perms { margin: 0.4rem 0 0; padding-left: 1.1rem; }
.stripe-connect { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.stripe-connect input { flex: 1 1 18rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.pay-card { border-color: var(--c-accent-solid); }
.pay-card-body { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; }
.dispute-alert { display: flex; justify-content: space-between; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.dispute-alert .inline-form { margin: 0; }
