/* ============================================================
   ATOMS: only the pieces the Investigation + Chat screens use.
   All values reference tokens.css. Reusable across both modules.
   ============================================================ */

/* ---------- BUTTONS ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  height:40px;padding:0 16px;border-radius:var(--r-md);
  border:1px solid transparent;background:transparent;
  font-weight:600;font-size:14px;line-height:1;white-space:nowrap;
  cursor:pointer;user-select:none;
  transition:background .15s var(--ease),border-color .15s,color .15s,opacity .15s;
}
.btn svg{width:18px;height:18px;flex:none}
.btn--primary{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.btn--primary:hover{background:var(--accent-hover);border-color:var(--accent-hover)}
.btn--ghost{color:var(--text-secondary);border-color:var(--border-strong)}
.btn--ghost:hover{background:var(--surface-raised);color:var(--text-primary)}
.btn--subtle{color:var(--text-secondary);background:var(--surface-raised)}
.btn--subtle:hover{background:var(--surface-hover);color:var(--text-primary)}
.btn--sm{height:32px;padding:0 12px;font-size:13px}
.btn--sm svg{width:16px;height:16px}
.btn:disabled{opacity:.45;cursor:not-allowed}

/* ---------- ICON BUTTON (composer + toolbar) ---------- */
.icon-btn{
  display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;border-radius:var(--r-full);
  background:var(--surface-raised);color:var(--icon);border:0;cursor:pointer;
  transition:background .15s var(--ease),color .15s;flex:none;
}
.icon-btn svg{width:20px;height:20px}
.icon-btn:hover{background:var(--surface-hover);color:var(--text-primary)}
.icon-btn.is-active{background:var(--surface-hover);color:var(--text-primary)}
.icon-btn--sm{width:32px;height:32px}.icon-btn--sm svg{width:16px;height:16px}
.icon-btn--ghost{background:transparent}
.icon-btn--ghost:hover{background:var(--surface-raised)}
.icon-btn--accent{background:var(--accent);color:var(--on-accent)}
.icon-btn--accent:hover{background:var(--accent-hover)}

/* ---------- CHIP / PILL (source pill, Full Analysis, EN) ---------- */
.chip{
  display:inline-flex;align-items:center;gap:6px;height:36px;padding:0 12px;
  border-radius:var(--r-full);background:var(--surface-raised);border:1px solid var(--border);
  color:var(--text-secondary);font-weight:500;font-size:13px;line-height:1;
  cursor:pointer;transition:background .15s var(--ease),border-color .15s;
}
.chip:hover{background:var(--surface-hover)}
.chip svg{width:16px;height:16px;color:var(--icon-muted);flex:none}
.chip .dot{width:8px;height:8px;border-radius:50%;background:var(--success);flex:none}
.chip .chev{margin-inline-start:2px;width:14px;height:14px}
.chip--static{cursor:default}
.chip--sm{height:30px;font-size:12px;padding:0 10px}

/* ---------- TAG / STATUS BADGE (small) ---------- */
.tag{display:inline-flex;align-items:center;gap:5px;height:22px;padding:0 8px;
  border-radius:var(--r-xs);font-weight:600;font-size:11px;line-height:1}
.tag svg{width:12px;height:12px;flex:none}
.tag--success{background:var(--success-soft);color:var(--success)}
.tag--warning{background:var(--warning-soft);color:var(--warning)}
.tag--danger{background:var(--danger-soft);color:var(--danger)}
.tag--accent{background:var(--accent-soft);color:var(--accent)}
.tag--neutral{background:var(--surface-raised);color:var(--text-muted)}

/* ---------- VERIFY / CONFIDENCE ---------- */
.verify{display:inline-flex;align-items:center;gap:6px;font-weight:600;font-size:13px;line-height:1}
.verify svg{width:15px;height:15px;flex:none}
.verify--verified{color:var(--success)}
.verify--review{color:var(--warning)}
.verify--critical{color:var(--danger)}
/* boxed confidence pill */
.verify.is-pill{padding:5px 10px;border-radius:var(--r-full);border:1px solid currentColor}
.verify--verified.is-pill{background:var(--success-soft)}
.verify--review.is-pill{background:var(--warning-soft)}
.verify--critical.is-pill{background:var(--danger-soft)}

/* ---------- AVATAR ---------- */
.avatar{display:inline-flex;align-items:center;justify-content:center;
  width:28px;height:28px;border-radius:50%;background:var(--surface-hover);
  color:var(--text-secondary);font-weight:600;font-size:11px;line-height:1;
  text-transform:uppercase;flex:none}
.avatar--lg{width:36px;height:36px;font-size:13px}
.avatar--accent{background:var(--accent-soft);color:var(--accent)}

/* ---------- ACCENT ICON BADGE (answer header spark) ---------- */
.icon-badge{display:inline-flex;align-items:center;justify-content:center;
  width:28px;height:28px;border-radius:var(--r-sm);background:var(--accent-soft);
  color:var(--accent);flex:none}
.icon-badge svg{width:16px;height:16px}
.icon-badge--lg{width:32px;height:32px;border-radius:var(--r-md)}
.icon-badge--lg svg{width:18px;height:18px}

/* ---------- INPUT ---------- */
.input{display:flex;align-items:center;gap:8px;height:40px;padding:0 12px;width:100%;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);
  color:var(--text-primary);font-size:14px;font-family:var(--font-sans);
  transition:border-color .15s var(--ease)}
.input::placeholder{color:var(--text-faint)}
/* Focus is a STATE, so it is never the brand colour, the standing rule for every
   state treatment in this kit. It steps the stroke one notch up the neutral ramp
   (--border → --border-hover, the same pair the interactive-surface hover uses,
   Figma Suggestion Card 5925:22628) and changes nothing else: no fill, no ring.
   This used to be var(--accent), an orange ring on focus, which was the one
   place in the app a text field went brand. */
.input:focus,.input:focus-within{outline:none;border-color:var(--border-hover)}
textarea.input{height:auto;min-height:44px;padding:11px 12px;resize:none;line-height:1.5}

/* ---------- MENU / DROPDOWN ---------- */
.menu{background:var(--menu-bg);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:6px;box-shadow:var(--shadow-lg);min-width:210px}
.menu-label{padding:6px 10px 4px;font-weight:600;font-size:11px;line-height:1;
  letter-spacing:.04em;text-transform:uppercase;color:var(--text-faint)}
.menu-item{display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px;border-radius:var(--r-sm);
  background:none;border:0;text-align:start;font-family:var(--font-sans);
  color:var(--text-secondary);font-weight:500;font-size:13px;line-height:1;cursor:pointer;
  transition:background .12s var(--ease),color .12s}
.menu-item:focus-visible{outline:none;background:var(--glass);color:var(--text-primary)}
.menu-item svg{width:16px;height:16px;color:var(--icon-muted);flex:none}
/* live-connection mark, the circle-dot ICON, the same glyph the neonDB chip wears, so an
   open source menu still reads as "this connection is live", not merely "this row is
   selected". Sits in the row's normal 10px flow between the tick and the label, mirroring
   Menu / Action Item's "Show status dot" slot in Figma. --success is theme-aware
   (Emerald/40 → /60 on light). The :hover half stops `.menu-item:hover svg` below from
   greying it out along with the row's other icons. */
.menu-item svg.mi-dot,.menu-item:hover svg.mi-dot{color:var(--success)}
.menu-item .kbd{margin-inline-start:auto;font-size:11px;color:var(--text-faint)}
/* ---- source menu, the top bar's database picker -------------------------------
   Three columns per row: the live dot, the database, and the engine behind it. The engine
   is right-aligned rather than trailing each name, so the column reads down the list instead
   of stepping in and out with the length of the names.
   No new type: the name is the menu-item face, the engine is the same 11px uppercase the
   .menu-label header uses, one step down in colour. Selected uses --glass-2, the same weight
   the sidebar and flyout use for "this is the one you are on"; hover stays --glass. */
.src-menu{min-width:268px}
.src-nm{flex:none}
.src-eng{margin-inline-start:auto;font-weight:600;font-size:11px;line-height:1;
  letter-spacing:.04em;text-transform:uppercase;color:var(--text-faint);white-space:nowrap}
.src-item:hover .src-eng{color:var(--text-muted)}
.src-item.is-sel{background:var(--glass-2);color:var(--text-primary)}
/* the tick is present on every row and only VISIBLE on the active one, hiding the element
   entirely would let the engine column step right on the unticked rows */
.src-item svg.src-tick{width:16px;height:16px;color:var(--text-primary);flex:none;visibility:hidden}
.src-item.is-sel svg.src-tick,.src-item.is-sel:hover svg.src-tick{visibility:visible;color:var(--text-primary)}
.menu-item:hover{background:var(--glass);color:var(--text-primary)}
.menu-item:hover svg{color:var(--text-primary)}
.menu-item--danger{color:var(--danger)}.menu-item--danger svg{color:var(--danger)}
/* two-line item, label + muted sub-line (widget menu "Reply from here / start a new thread") */
.menu-item--stack{align-items:flex-start}
.menu-item--stack svg{margin-top:1px}
.mi-txt{display:flex;flex-direction:column;gap:3px;min-width:0}
.mi-sub{font-weight:400;font-size:12px;line-height:16px;color:var(--text-faint)}
.menu-item--stack:hover .mi-sub{color:var(--text-muted)}
/* destructive row hovers with the SAME neutral background as every other item -
   the red stays in the label and the icon, not the surface. */
.menu-item--danger:hover{background:var(--glass);color:var(--danger)}
.menu-item--danger:hover svg{color:var(--danger)}
.menu-sep{height:1px;background:var(--border);margin:6px 4px}

/* ---- nav ⋯ menu: Add-to-project submenu ---- */
.nav-more{min-width:200px}
.menu-item.has-sub{position:relative}
.menu-item.has-sub .mi-lbl{flex:1}
.menu-item.has-sub .sub-chev{margin-inline-start:auto;color:var(--icon-muted)}
.submenu{position:absolute;top:-6px;inset-inline-start:calc(100% + 6px);z-index:10;
  background:var(--menu-bg);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:6px;box-shadow:var(--shadow-lg);min-width:236px;
  opacity:0;transform:translateX(-6px);pointer-events:none;transition:opacity .14s var(--ease),transform .14s var(--ease)}
.menu-item.has-sub:hover .submenu,.menu-item.has-sub.sub-open .submenu{opacity:1;transform:none;pointer-events:auto}
.proj-search{display:flex;align-items:center;gap:8px;padding:8px 10px;margin:2px 2px 6px;
  border-radius:var(--r-sm);background:var(--glass);border:1px solid var(--border)}
.proj-search svg{width:16px;height:16px;color:var(--icon-muted);flex:none}
.proj-search input{flex:1;min-width:0;background:none;border:0;outline:none;color:var(--text-primary);
  font-family:var(--font-sans);font-size:13px}
.proj-search input::placeholder{color:var(--text-faint)}
.proj-list{display:flex;flex-direction:column;gap:2px;max-height:220px;overflow-y:auto}
.proj-item{display:flex;align-items:center;width:100%;padding:9px 10px;border:0;border-radius:var(--r-sm);
  background:none;color:var(--text-secondary);font-family:var(--font-sans);font-weight:500;font-size:13px;
  text-align:start;cursor:pointer;transition:background .12s var(--ease),color .12s}
.proj-item:hover{background:var(--glass);color:var(--text-primary)}
.proj-empty{padding:10px;color:var(--text-faint);font-size:12px;text-align:center}

/* ---- confirmation dialog (Delete) ---- */
.dialog-scrim{position:fixed;inset:0;z-index:200;display:grid;place-items:center;
  background:rgba(0,0,0,.5);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);
  animation:scrimIn .16s var(--ease) both}
.dialog{width:min(400px,calc(100vw - 48px));background:var(--menu-bg);border:1px solid var(--border);
  border-radius:var(--r-xl);padding:24px;box-shadow:var(--shadow-2xl);
  display:flex;flex-direction:column;gap:8px;animation:dialogIn .18s var(--ease) both}
.dialog{position:relative}
/* THE CLOSE X. Rename / Save / Confirm-delete all already carry a neutral
   "Cancel" among their own actions, so an X would just be a second way to do
   what Cancel already does. The duplicate-widget dialog is the one exception:
   its two buttons (Keep both, Replace) are both COMMITTING actions, so there was
   no neutral way out of it at all (Ameer, 22 Aug: "what if I want to close?").
   Scoped to .dialog--closeable rather than added to the shared shell, so the
   other four keep their existing, already-correct Cancel-only pattern. */
.dialog__close{position:absolute;top:16px;inset-inline-end:16px}
.dialog__ic{width:44px;height:44px;border-radius:var(--r-full);display:grid;place-items:center;
  background:var(--danger-soft);color:var(--danger);margin-bottom:6px}
.dialog__ic svg{width:20px;height:20px}
.dialog__t{font-weight:600;font-size:16px;color:var(--text-primary)}
/* ICON AND TITLE ON ONE LINE, for a dialog that wants its header read as a
   single row rather than the icon-then-title stack every other dialog here
   uses (Ameer, 24 Aug, of the section dialog specifically: "that heading
   should be aligned with the icon... it should be in one line"). Scoped to
   .dialog__hd rather than changed on .dialog__ic/.dialog__t themselves, which
   every other dialog's stacked header still depends on. The right padding on
   a closeable one clears .dialog__close, which floats in the same top-right
   corner this row now reaches into. */
.dialog__hd{display:flex;align-items:center;gap:10px}
.dialog__hd .dialog__ic{margin-bottom:0;flex:none}
.dialog--closeable .dialog__hd{padding-inline-end:48px}
.dialog__m{font-size:13px;line-height:1.5;color:var(--text-muted)}
.dialog__actions{display:flex;gap:10px;justify-content:flex-end;margin-top:16px}
/* THE OPT-OUT, on the same row as the buttons rather than a line of its own:
   Cancel/Remove stay grouped in their own flex child (.dialog__actions-btns) so
   space-between can push the checkbox to the far side without breaking the
   10px gap those two buttons already share (Ameer, 24 Aug: "add a checkbox in
   the bottom called don't show this again"). Wraps on a narrow dialog rather
   than clipping. */
.dialog__actions--split{justify-content:space-between;align-items:center;flex-wrap:wrap;row-gap:12px}
.dialog__actions-btns{display:flex;gap:10px}
/* a plain checkbox is unreadable at 16px, right of a dark filled dialog on some
   platforms and near-invisible on others - one small drawn box instead, the
   same shrink-to-fit control family as .dlg-input. The real input stays in the
   DOM (clickable target, keyboard/focus, screen readers), just visually
   collapsed rather than removed, so the label's own click still toggles it. */
.dlg-check{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text-muted);cursor:pointer;user-select:none}
.dlg-check input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.dlg-check__box{flex:none;width:16px;height:16px;border-radius:5px;border:1px solid var(--border);
  background:var(--glass);display:grid;place-items:center;color:transparent;transition:.12s var(--ease)}
.dlg-check__box svg{width:11px;height:11px}
.dlg-check input:checked + .dlg-check__box{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.dlg-check:hover .dlg-check__box{border-color:var(--ink-2)}
.dlg-check input:focus-visible + .dlg-check__box{outline:2px solid var(--border-hover);outline-offset:2px}
/* the duplicate-on-drop dialog: the two cards side by side, so the choice being
   offered (replace the top one with the bottom one) is something you can SEE, not
   just something the sentence above claims */
.dup-preview{display:flex;flex-direction:column;gap:8px;margin-top:2px}
.dup-preview__card{display:flex;align-items:center;gap:9px;padding:10px 12px;
  border-radius:10px;background:var(--glass);border:1px solid var(--line);
  font-size:13px;font-weight:600;color:var(--ink)}
.dup-preview__ic{flex:none;display:grid;place-items:center;width:26px;height:26px;
  border-radius:7px;background:var(--glass-2);color:var(--ricon)}
.dup-preview__ic svg{width:14px;height:14px}
.dup-preview__card .tag{margin-inline-start:auto}
.dlg-btn{height:38px;padding:0 16px;border-radius:var(--r-md);font-family:var(--font-sans);
  font-weight:600;font-size:14px;cursor:pointer;border:1px solid transparent;transition:.12s var(--ease)}
.dlg-btn--ghost{background:var(--glass);border-color:var(--border);color:var(--text-primary)}
.dlg-btn--ghost:hover{background:var(--glass-2)}
/* destructive button follows --danger: Red/40 on dark, Red/60 on light. White label.
   This is the reference, Figma is matched to it, not the other way round. */
.dlg-btn--danger{background:var(--danger);color:#fff}
.dlg-btn--danger:hover{filter:brightness(1.08)}
/* rename dialog, neutral icon chip, a text field, and a primary Update button */
/* non-destructive dialogs (Rename, and any future one), a neutral grey chip with a
   plain icon. Only the DELETE dialog keeps the red treatment, because it is destructive. */
.dialog__ic--neutral{background:var(--surface-raised);color:var(--text-primary)}
/* matches the sidebar's inline rename field (.nx-rename), glass fill, neutral stroke.
   Deliberately NOT an accent-coloured focus ring. */
/* DEFAULT vs FOCUSED must read as two different states, not one. This was resting
   at --ink (near-white) AND focusing to --ink again - literally the same colour, so
   a person could not tell which field had the caret without clicking into it and
   watching nothing change (Ameer, 22 Aug: "why both active and default looking the
   same"). --border/--ink is the pattern .ds-input already uses correctly (the Save
   drawer's fields, and every Data Source field): quiet stroke at rest, ink on
   focus. .dlg-input now matches it, which fixes every dialog built on this one
   shared field - Rename, the Share drawer's invite email, and the section dialog -
   in the one place, rather than three separate patches. */
.dlg-input{height:40px;width:100%;margin-top:12px;padding:0 12px;border-radius:var(--r-md);
  background:var(--glass);border:1px solid var(--border);color:var(--ink);
  font-family:var(--font-sans);font-size:14px;outline:none;transition:.12s var(--ease)}
.dlg-input:focus{outline:none;border-color:var(--ink);background:var(--glass-2)}
/* a textarea on the same recipe, for a dialog field that wants more than one
   line (the section subheading). */
.dlg-input--ta{height:auto;min-height:60px;padding:10px 12px;line-height:20px;resize:vertical;font-family:var(--font-sans)}
/* a label above a field, for the dialogs that ask more than one question (the
   single-field ones lean on .dialog__m instead and need nothing here) */
.dlg-label{display:flex;align-items:baseline;gap:6px;margin-top:14px;
  font-size:12px;font-weight:600;letter-spacing:.01em;color:var(--sub)}
.dlg-label__opt{font-size:11px;font-weight:400;color:var(--text-faint)}
.dlg-label + .dlg-input{margin-top:6px}
/* A dialog field is still a required field, and it gets the SAME error state as
   every other one in Spark (.ds-field.has-error in molecules.css, .field.has-error
   in auth.css): --danger stroke plus a 12px message saying what is missing.
   Renaming to nothing used to close the dialog and quietly keep the old name -
   an empty submit that reports nothing is worse than a red field, because the
   user is left believing they renamed it. */
.dlg-input.has-error,.dlg-input.has-error:focus{border-color:var(--danger)}
.dlg-err{display:none;align-items:flex-start;gap:6px;text-align:start;
  font-size:12px;line-height:16px;color:var(--danger)}
.dlg-err.is-on{display:flex;animation:dsErrIn .18s var(--ease) both}
/* how much room is left in a capped field (the section dialog's Name and
   Subheading - see SEC_NAME_MAX / SEC_SUB_MAX in app.js). maxlength on the
   field already makes going over impossible; this just says why typing
   stopped, the same way a character count does on any field with a real cap. */
.dlg-count{margin-top:4px;text-align:end;font-size:11px;color:var(--text-faint)}
.dlg-err svg{width:14px;height:14px;flex:none;margin-top:1px}
.dlg-btn--primary{background:var(--accent);color:var(--on-accent)}
.dlg-btn--primary:hover{background:var(--accent-hover)}
@keyframes scrimIn{from{opacity:0}to{opacity:1}}
@keyframes dialogIn{from{opacity:0;transform:translateY(6px) scale(.98)}to{opacity:1;transform:none}}

/* ---------- POPOVER wrapper (for dropdown positioning) ---------- */
.pop{position:relative}
.pop > .menu{position:absolute;top:calc(100% + 6px);z-index:60;
  opacity:0;transform:translateY(-4px) scale(.98);transform-origin:top;pointer-events:none;
  transition:opacity .14s var(--ease),transform .14s var(--ease)}
.pop.is-open > .menu{opacity:1;transform:none;pointer-events:auto}
.pop--end > .menu{right:0}
[dir="rtl"] .pop--end > .menu{right:auto;left:0}

/* ---------- CARD FRAME (title · ⋮) ---------- */
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:16px;display:flex;flex-direction:column;gap:12px}
.card__head{display:flex;align-items:center;gap:10px}
.card__title{font-weight:600;font-size:15px;color:var(--text-primary);flex:1;min-width:0}
.card__divider{height:1px;background:var(--border);margin:2px 0}

/* ---------- SUGGESTION CARD ---------- */
.suggestion{display:flex;flex-direction:column;gap:6px;padding:14px 16px;text-align:start;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);cursor:pointer;
  transition:background .15s var(--ease),border-color .15s}
.suggestion:hover{background:var(--surface-raised);border-color:var(--border-hover)}
.suggestion__t{font-weight:600;font-size:14px;color:var(--text-primary)}
.suggestion__d{font-size:12px;color:var(--text-muted);line-height:16px}

/* A floated menu is parked on <body> (see floatMenu) so no ancestor stacking context
  , .afoot z1, .history z20, can paint over it. It is positioned inline; these
   rules just restore the visible state that `.pop.is-open > .menu` used to give it. */
.menu--float{opacity:1;transform:none;pointer-events:auto;transform-origin:top;
  animation:menuIn .14s var(--ease)}
@keyframes menuIn{from{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:none}}

/* ---------- SWITCH (.sw), off / on / mixed --------------------------------
   A general control, not something the Access page invented: anywhere the app
   needs "this is on or off for this thing", this is the shape.

   OFF is the standard glass pair: --glass fill, --glass-2 hairline. ON is the
   module accent, see the rule below: this is the one place the neutral-state
   rule does not hold, because a switch has to answer "is this on" from across
   the panel and a neutral fill cannot.

   MIXED is the third state a switch needs the moment it stands for more than
   one thing (the Change access drawer): the knob centres and shows a dash, and
   it says "these differ" rather than lying in either direction. */
.sw{position:relative;flex:none;width:38px;height:22px;padding:0;border-radius:var(--r-full);
  border:1px solid var(--glass-2);background:var(--glass);cursor:pointer;
  transition:background .16s var(--ease),border-color .16s var(--ease)}
.sw__k{position:absolute;top:2px;inset-inline-start:2px;width:16px;height:16px;border-radius:50%;
  background:var(--icon-muted);display:grid;place-items:center;color:var(--surface);
  transition:transform .16s var(--ease),background .16s var(--ease)}
.sw__k svg{width:10px;height:10px}
.sw:hover{background:var(--glass-2)}
/* ON = THE MODULE'S ACCENT, not white. It used to be the --sel-bg/--sel-fg pair,
   a white track with a near-black knob, which on these dark panels read as a
   bright chip punched out of the surface rather than as a control that had been
   switched on (Ameer, 21 Aug: "the background is looking white, I don't want
   that, it should blend with my design"). The accent is already what this app
   uses to say "this one is live" a few rows away, on a pinned answer's pin, so
   the switch now says it the same way, and it tints per module because --accent
   does. The knob stays white against it, which is what keeps the state legible
   at 22px rather than relying on the fill alone. */
.sw.is-on{background:var(--accent);border-color:var(--accent)}
.sw.is-on:hover{background:var(--accent-hover);border-color:var(--accent-hover)}
.sw.is-on .sw__k{background:var(--on-accent,#fff);transform:translateX(16px)}
.sw.is-mix .sw__k{background:var(--icon);color:var(--surface);transform:translateX(8px)}
[dir="rtl"] .sw.is-on .sw__k{transform:translateX(-16px)}
[dir="rtl"] .sw.is-mix .sw__k{transform:translateX(-8px)}
.sw:focus-visible{outline:2px solid var(--border-hover);outline-offset:2px}
.sw:disabled{opacity:.45;cursor:not-allowed}

/* ---------- AVATAR, two variants the Access list needs --------------------
   An invite has no person behind it yet: no name, therefore no initials. It
   gets the mail glyph on a quieter plate instead of two letters cut out of an
   email address, which would read as a name that isn't one. */
.avatar--xs{width:24px;height:24px;font-size:10px}
/* An invite nobody has accepted yet: a DASHED ring, not a solid one. The ring
   is the whole signal, so it survives every size and every surface the avatar
   appears on, and no badge has to be pinned to the corner to say it. */
.avatar--pending{background:transparent;color:var(--icon-muted);
  border:1.5px dashed var(--icon-muted)}
.avatar--pending svg{width:13px;height:13px}
