/* IT poff.ee — internal tool styling. Always-on dark theme: calm,
   minimalist, airy, pastel accents. No gradients, shadows, or decoration.
   One accent color carries all interactive meaning; status lives only in
   badge colors.

   Typography: IBM Plex Sans (400/500/600) for everything except data,
   IBM Plex Mono (400) for data — the mono rule, applied via .mono in
   templates: email addresses, OU paths, dates/timestamps, audit action
   strings, chip counts. Self-hosted latin-subset woff2, OFL-licensed
   (see static/fonts/OFL.txt), system stack retained as fallback.

   Two subsets per weight — Latin1 (basic Latin + Latin-1 Supplement:
   ä/ö/ü/õ etc.) and Latin2 (Latin Extended-A: š/ž etc., needed for
   Estonian names — see emailgen's "Šiškin" fixture). Each weight is
   declared as two @font-face rules sharing the same family/weight/style
   but disjoint unicode-range; the browser fetches only the subset file a
   given page actually needs glyphs from. Ranges are copied verbatim from
   the official IBM Plex release CSS (fonts/split/woff2/*.css). */

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("IBM Plex Sans"), local("IBMPlexSans"),
       url("/static/fonts/IBMPlexSans-Regular-Latin1.woff2") format("woff2");
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("IBM Plex Sans"), local("IBMPlexSans"),
       url("/static/fonts/IBMPlexSans-Regular-Latin2.woff2") format("woff2");
  unicode-range: U+0100-0101, U+0104-0130, U+0132-0151, U+0154-017F, U+018F, U+0192, U+01A0-01A1, U+01AF-01B0, U+01FA-01FF, U+0218-021B, U+0237, U+0259, U+1E80-1E85, U+1E9E, U+20A1, U+20A4, U+20A6, U+20A8-20AA, U+20AD-20AE, U+20B1-20B2, U+20B4-20B5, U+20B8-20BA, U+20BD, U+20BF;
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: local("IBM Plex Sans Medium"), local("IBMPlexSans-Medium"),
       url("/static/fonts/IBMPlexSans-Medium-Latin1.woff2") format("woff2");
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: local("IBM Plex Sans Medium"), local("IBMPlexSans-Medium"),
       url("/static/fonts/IBMPlexSans-Medium-Latin2.woff2") format("woff2");
  unicode-range: U+0100-0101, U+0104-0130, U+0132-0151, U+0154-017F, U+018F, U+0192, U+01A0-01A1, U+01AF-01B0, U+01FA-01FF, U+0218-021B, U+0237, U+0259, U+1E80-1E85, U+1E9E, U+20A1, U+20A4, U+20A6, U+20A8-20AA, U+20AD-20AE, U+20B1-20B2, U+20B4-20B5, U+20B8-20BA, U+20BD, U+20BF;
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: local("IBM Plex Sans SemiBold"), local("IBMPlexSans-SemiBold"),
       url("/static/fonts/IBMPlexSans-SemiBold-Latin1.woff2") format("woff2");
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: local("IBM Plex Sans SemiBold"), local("IBMPlexSans-SemiBold"),
       url("/static/fonts/IBMPlexSans-SemiBold-Latin2.woff2") format("woff2");
  unicode-range: U+0100-0101, U+0104-0130, U+0132-0151, U+0154-017F, U+018F, U+0192, U+01A0-01A1, U+01AF-01B0, U+01FA-01FF, U+0218-021B, U+0237, U+0259, U+1E80-1E85, U+1E9E, U+20A1, U+20A4, U+20A6, U+20A8-20AA, U+20AD-20AE, U+20B1-20B2, U+20B4-20B5, U+20B8-20BA, U+20BD, U+20BF;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("IBM Plex Mono"), local("IBMPlexMono"),
       url("/static/fonts/IBMPlexMono-Regular-Latin1.woff2") format("woff2");
  unicode-range: U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("IBM Plex Mono"), local("IBMPlexMono"),
       url("/static/fonts/IBMPlexMono-Regular-Latin2.woff2") format("woff2");
  unicode-range: U+0100-0101, U+0104-0130, U+0132-0151, U+0154-017F, U+018F, U+0192, U+01A0-01A1, U+01AF-01B0, U+01FA-01FF, U+0218-021B, U+0237, U+0259, U+1E80-1E85, U+1E9E, U+20A1, U+20A4, U+20A6, U+20A8-20AA, U+20AD-20AE, U+20B1-20B2, U+20B4-20B5, U+20B8-20BA, U+20BD, U+20BF;
}

:root {
  --bg:        #15171a;  /* page background — soft near-black, never #000 */
  --surface:   #1d2024;  /* cards, table headers, form fields, nav */
  --border:    #2a2e33;  /* subtle borders and row separators */
  --text:      #d6d9dd;  /* body text — off-white, not stark */
  --muted:     #8b919a;  /* secondary text, labels, timestamps */
  --accent:    #8ab4d8;  /* pastel blue: links, buttons, focus rings */
  --accent-bg: #223140;  /* quiet tinted background for primary buttons/flash */
  --ok:        #9ec9a3;  /* pastel sage: active/success badges */
  --danger:    #d89a9a;  /* pastel rose: suspend/delete actions, errors */
  --danger-bg: #3a2626;  /* tinted background for danger buttons */

  /* Type */
  --font-sans: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --fs-meta: 13px;
  --fs-body: 15px;
  --fs-h2:   17px;
  --fs-h1:   24px;

  /* Motion */
  --transition-fast: 120ms ease;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
}

::selection {
  background: var(--accent-bg);
  color: var(--text);
}

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

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

/* Layout */

.container {
  max-width: 1100px;
  margin: 0 auto;
  padding: 2.5rem 2rem 4rem;
}

/* Forms constrained to a comfortable reading width — a form spanning the
   full container reads as unfinished. Applied directly to <form>. */
.form-card {
  max-width: 560px;
}

h1 {
  font-family: var(--font-sans);
  font-size: var(--fs-h1);
  font-weight: 600;
  line-height: 1.25;
  margin: 0 0 1.5rem;
}

h2 {
  font-size: var(--fs-h2);
  font-weight: 500;
  line-height: 1.25;
  margin: 2rem 0 1rem;
  color: var(--text);
}

h3 {
  font-size: var(--fs-body);
  font-weight: 500;
  line-height: 1.25;
  margin: 1.5rem 0 0.75rem;
  color: var(--text);
}

p.muted,
.muted {
  color: var(--muted);
}

main ul {
  margin: 0.5rem 0 1.5rem;
  padding-left: 1.25rem;
}

main li {
  margin: 0.35rem 0;
}

/* Data renders in Plex Mono at 0.92em — the mono rule: email addresses,
   OU paths, dates/timestamps, audit action strings, chip counts. Prose,
   names, labels, and buttons stay Sans. */
.mono {
  font-family: var(--font-mono);
  font-size: 0.92em;
}

/* Numeric/date table columns read better right-aligned. */
.num {
  text-align: right;
}

/* Shared empty-state pattern: centered, quiet, generous padding — an
   empty screen is an invitation to act, not an error. */
.empty-state {
  text-align: center;
  color: var(--muted);
  padding: 3rem 1rem;
}

/* Page header pattern (every page): h1 left, the page's primary action (if
   any) right, on one flex row. A one-line .muted context sentence may
   follow directly below, using normal paragraph spacing. */
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.5rem;
}
.page-header h1 {
  margin: 0;
}
.page-header .badge {
  margin-left: 0.6rem;
  vertical-align: middle;
  font-size: var(--fs-meta);
}

/* Definition grid: label/value pairs (Account section on the user detail
   page), two columns on wide screens, one on narrow. */
.definition-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem 2rem;
  margin: 0 0 2rem;
}
.definition-grid dt {
  font-size: var(--fs-meta);
  font-weight: 500;
  color: var(--muted);
  margin-bottom: 0.2rem;
}
.definition-grid dd {
  margin: 0;
  color: var(--text);
}
@media (max-width: 600px) {
  .definition-grid {
    grid-template-columns: 1fr;
  }
}

/* Section cards: the user detail page's sections (Account, Actions, Mailbox
   access, Groups, Danger zone, History) each sit in a quiet card — surface
   background, hairline border, generous padding — so the page reads as a
   stack of distinct panels rather than one long scroll. The identity header
   stays outside (it's the page header, not a section). h2 lives inside the
   card and its usual top margin is dropped since the card padding already
   provides that space; cards space themselves 24px apart and the last one
   drops its own trailing margin so the page doesn't overhang. */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 24px;
}
.card > h2:first-child {
  margin-top: 0;
}
.card:last-child {
  margin-bottom: 0;
}

/* Danger zone: a card like any other, but its border stays tinted toward
   --danger-bg instead of the neutral --border so it reads as distinct at a
   glance, and picks up the full danger accent on :hover — quiet until then,
   so the section doesn't shout by default. */
.danger-zone {
  border-color: var(--danger-bg);
  transition: border-color var(--transition-fast);
}
.danger-zone h2 {
  color: var(--muted);
  transition: color var(--transition-fast);
}
.danger-zone:hover {
  border-color: var(--danger);
}
.danger-zone:hover h2 {
  color: var(--danger);
}

/* Impersonation banner — full-width, danger-tinted, above the nav so it
   cannot be missed while a superadmin is operating as someone else. Emails
   render in .mono per the mono rule; the stop button reuses the existing
   danger button treatment. */

.impersonation-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 1.5rem;
  background: var(--danger-bg);
  color: var(--danger);
  border-bottom: 1px solid var(--danger);
}

.impersonation-banner p,
.impersonation-banner form {
  margin: 0;
}

/* Nav */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.5rem;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.topbar nav {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.topbar nav a {
  color: var(--muted);
  transition: color var(--transition-fast);
}
.topbar nav a:hover,
.topbar nav a:focus-visible {
  color: var(--text);
  text-decoration: none;
}

.topbar .brand {
  font-weight: 600;
  color: var(--accent);
  margin-right: 0.5rem;
}
.topbar .brand:hover {
  text-decoration: none;
}

.logout-form {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 0;
}

.logout-form .who {
  color: var(--muted);
  font-size: 0.9em;
}

/* Flash messages: slim, icon-free, left-border accent strip — quieter
   than a full background wash but still carries the accent/danger
   meaning at a glance. */

.flash {
  padding: 0.6rem 1rem;
  margin: 0 0 1.5rem;
  background: var(--surface);
  border-left: 3px solid var(--accent);
  color: var(--text);
  border-radius: 0 4px 4px 0;
}

/* Genuine error paths (form validation, delegate-load failures) are a
   template-structural distinction, not a guess: rendered only from
   FormError/DelegatesError fields, never mixed with success text. The
   base-layout ?msg= flash has no such distinction (handlers redirect both
   success and failure strings through the same field) and stays neutral. */
.flash-error {
  border-left-color: var(--danger);
}

/* Soft duplicate-candidate warning on /users/new (base-address collision
   without force_create): quieter than .flash-error — this is a prompt to
   confirm, not a rejected submission — so it uses the accent-tinted
   surface rather than the danger border. */
.warning-panel {
  padding: 0.75rem 1rem;
  margin: 0 0 1.5rem;
  background: var(--accent-bg);
  border-left: 3px solid var(--accent);
  border-radius: 0 4px 4px 0;
  color: var(--text);
}
.warning-panel p {
  margin: 0.35rem 0;
}
.warning-panel p:first-child {
  margin-top: 0;
}
.warning-panel p:last-child {
  margin-bottom: 0;
}

/* Login */

.login-box {
  max-width: 360px;
  margin: 4rem auto;
  padding: 2.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  text-align: center;
}

.login-box h1 {
  font-weight: 600;
}

/* Tables */

table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 1.5rem;
}

th, td {
  text-align: left;
  padding: 12px 0.9rem;
  border-bottom: 1px solid var(--border);
}

th {
  background: var(--surface);
  font-weight: 500;
  font-size: var(--fs-meta);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

tr:last-child td {
  border-bottom: none;
}

tbody tr {
  transition: background-color var(--transition-fast);
}
tbody tr:hover {
  background: var(--surface);
}

/* Forms */

form.inline {
  display: inline;
}

/* Action row: label text (optional), input/select, button on one flex line —
   Reactivate/Save, Add delegate, and Request to add on the user detail page.
   The label loses its usual block stacking and top margin so it sits inline
   with the field it names; the row wraps on narrow viewports rather than
   clipping. Add delegate has no label at all (the button names the action),
   which the flex row handles the same way. */
.action-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
}
.action-row label {
  display: inline;
  margin: 0;
  white-space: nowrap;
}

/* Consecutive action rows keep a 16px (2×8px base) vertical rhythm instead
   of stacking flush — the Actions card's field rows and the danger-zone
   reassignment rows both read as distinct lines this way. */
.action-row + .action-row,
.action-note + .action-row {
  margin-top: 16px;
}

/* The first label of each action row takes a shared minimum width so the
   controls of stacked rows ("Needed until" + date, "Manager" + select)
   start at the same x and read as columns. Mid-row labels (Job title)
   keep their natural width. */
.action-row label:first-of-type {
  min-width: 7em;
}

/* Row controls take deliberate widths instead of ragged content-sizing:
   selects and text inputs flex to fill their line up to a cap, so the two
   field rows align into visual columns. The date input keeps its fixed
   ~11em from the form:not(.form-card) rule below. */
.action-row select {
  flex: 1 1 auto;
  min-width: 12em;
  max-width: 22em;
}
.action-row input[type="text"] {
  flex: 1 1 auto;
  min-width: 10em;
  max-width: 18em;
}

/* Muted helper note tied to the action row above it (pinned-manager,
   no-personal-email): tight 6px offset, meta size. */
.action-note {
  margin: 6px 0 0;
  font-size: var(--fs-meta);
}

/* Utility-action footer on the Actions card: the single-button actions
   (Reset password, Impersonate) share one horizontal row, separated from
   the field rows above by 16px of space and a hairline rule. When the card
   has no field rows (pure-HR variant: footer directly follows the h2) the
   rule and extra space drop — there is nothing to separate from. */
.action-footer {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 16px;
  border-top: 1px solid var(--border);
  padding-top: 16px;
}
.action-footer .action-note {
  margin: 0;
}
h2 + .action-footer {
  margin-top: 0;
  border-top: none;
  padding-top: 0;
}

/* Mailbox access card: the two delegation directions sit side by side —
   left "Delegated to others" (with the add-delegate action row under its
   list), right "Has access to" — instead of stacking into prose. The card
   is IT-only and the container is ~1100px wide, so the width is there to
   use; under 800px the columns stack back to one. The long explanatory
   sentences moved into the h3 title= tooltips. */
.mailbox-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 32px;
}
.mailbox-col > h3 {
  margin: 0 0 8px;
}
@media (max-width: 800px) {
  .mailbox-grid {
    grid-template-columns: 1fr;
    row-gap: 24px;
  }
}

/* Delegation entries as rows, not bullets: mono email left, status +
   Remove right, separated by the same 1px --border hairlines as the
   tool's tables. The list's 16px bottom margin doubles as the rhythm gap
   to the add-delegate action row below it. */
.mailbox-list {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
}
.mailbox-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin: 0;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.mailbox-list li:last-child {
  border-bottom: none;
}
.mailbox-meta {
  display: flex;
  align-items: center;
  gap: 12px;
}
.mailbox-status {
  color: var(--muted);
  font-size: var(--fs-meta);
}
/* Empty rows ("No delegates.", the not-yet-swept sweep note) stay quiet:
   muted text in an ordinary row, consistent with the app's empty states
   without the full-height centered treatment. */
.mailbox-empty {
  color: var(--muted);
}

/* Propagation note: one muted meta line at the card's bottom, spanning
   both columns — the .action-note treatment with card-level spacing. */
.mailbox-note {
  margin: 16px 0 0;
  font-size: var(--fs-meta);
}

label {
  display: block;
  margin: 1rem 0 0.35rem;
  font-weight: 500;
  font-size: var(--fs-meta);
  color: var(--muted);
}

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="date"],
select,
textarea {
  width: 100%;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 1em;
  font-family: inherit;
  background: var(--surface);
  color: var(--text);
  transition: border-color var(--transition-fast);
}

input[type="text"]:focus,
input[type="email"]:focus,
input[type="tel"]:focus,
input[type="date"]:focus,
select:focus,
textarea:focus {
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

input[type="checkbox"] {
  accent-color: var(--accent);
  margin-right: 0.4rem;
}

/* Groups picker on /users/new: the ~100 group checkboxes live in a
   scrollable bordered box under a filter input (app.js hides unchecked
   non-matches; checked rows always stay visible), with a muted
   "N selected" count below. Rows are one label per line on the 8px
   rhythm; the label reset restores body color/weight since these are
   choices, not field captions. */
.group-list {
  max-height: 16rem;
  overflow-y: auto;
  margin-top: 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
}

.group-list label {
  display: block;
  margin: 0;
  padding: 8px;
  font-weight: 400;
  font-size: var(--fs-body);
  color: var(--text);
}

.group-list label:hover {
  background: var(--border);
}

.group-count {
  margin: 8px 0 0;
  font-size: var(--fs-meta);
}

/* Inline/detail action forms (Reactivate/Save, Add delegate, group
   requests — the .action-row and .inline forms on the user detail page)
   size their fields to content instead of stretching to the container: a
   single date or email field spanning ~1100px reads wrong next to its
   button. Only .form-card forms (account creation, new department) keep
   full-width fields, where a wide multi-field form reads as unfinished
   otherwise — see the .form-card comment above. */
form:not(.form-card) input[type="text"],
form:not(.form-card) input[type="email"],
form:not(.form-card) input[type="tel"],
form:not(.form-card) input[type="date"],
form:not(.form-card) select {
  width: auto;
}

form:not(.form-card) input[type="date"] {
  min-width: 11em;
}

form:not(.form-card) input[type="email"] {
  min-width: 22em;
}

/* Required-field marker: muted by default so it doesn't shout, but reads as
   a hint of consequence next to a label. */
.req {
  color: var(--danger);
  font-weight: 400;
}

/* Inline danger note for a status that needs attention without the weight
   of a full .flash-error banner (e.g. the Account grid's "not enrolled —
   required by policy" 2-Step Verification state). */
.status-danger {
  color: var(--danger);
  font-size: 0.9em;
}

/* Buttons */

button,
.button,
input[type="submit"] {
  display: inline-block;
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  font-size: 0.95em;
  font-weight: 500;
  cursor: pointer;
  text-align: center;
  transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}

/* Hover lift via a background shift only — no shadows. --border reads as
   a step lighter than --surface, giving buttons a quiet "raised" feel. */
button:hover,
.button:hover,
input[type="submit"]:hover {
  background: var(--border);
  border-color: var(--accent);
  text-decoration: none;
}

button.secondary,
.button.secondary {
  background: transparent;
  border-color: transparent;
  color: var(--muted);
}
button.secondary:hover,
.button.secondary:hover {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border);
}

button.danger,
.button.danger {
  background: var(--danger-bg);
  border-color: var(--danger-bg);
  color: var(--danger);
}
button.danger:hover,
.button.danger:hover {
  border-color: var(--danger);
}

/* Badges */

.badge {
  display: inline-block;
  padding: 0.15rem 0.6rem;
  border-radius: 3px;
  background: transparent;
  border: 1px solid var(--border);
  font-size: 0.8em;
  color: var(--ok);
}

.badge.suspended {
  color: var(--danger);
  border-color: var(--danger-bg);
}

/* Shared mailbox accounts (members of the SHARED_GROUP Google group):
   quiet informational marker next to the name/status — existing tokens
   only, muted rather than colored. */
.badge.shared {
  color: var(--muted);
  border-color: var(--border);
}

/* Shared-account marker in the users list: a small circled S before the
   name. Plain inline-block typography — no flex on table cells (a flexed
   td stops rendering as a table cell and breaks row borders). */
.shared-mark {
  display: inline-block;
  width: 1.3em;
  height: 1.3em;
  line-height: 1.3em;
  margin-right: 0.4rem;
  border: 1px solid var(--muted);
  border-radius: 50%;
  color: var(--muted);
  font-size: 11px;
  font-weight: 500;
  text-align: center;
  vertical-align: 1px;
}

/* Chips */

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 1.5rem;
}

.chip {
  display: inline-block;
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--muted);
  font-size: var(--fs-meta);
  text-decoration: none;
  transition: color var(--transition-fast), border-color var(--transition-fast);
}

.chip:hover {
  color: var(--text);
}

.chip.selected {
  color: var(--accent);
  border-color: var(--accent);
}

@media (max-width: 600px) {
  .topbar {
    flex-direction: column;
    align-items: flex-start;
  }
  .topbar nav {
    flex-wrap: wrap;
    gap: 0.75rem;
  }
}

/* Bulk create (/users/bulk). Existing tokens only: warning rows get the
   same accent tint as the /users/new duplicate warning-panel (a prompt to
   confirm, not a rejection), blocked/invalid rows the danger tint. */

.paste-template {
  display: inline-block;
  max-width: 100%;
  padding: 0.4rem 0.6rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  white-space: pre;
  overflow-x: auto;
  font-size: var(--fs-meta);
}

/* The 11-column preview table scrolls inside its own container instead of
   stretching the page. */
.table-scroll {
  overflow-x: auto;
  margin-bottom: 1.5rem;
}
.table-scroll table {
  margin-bottom: 0;
}

.preview-table td {
  vertical-align: top;
  padding: 8px 0.5rem;
}
.preview-table td input[type="text"] {
  width: 100%;
  min-width: 6.5em;
}
.preview-table .verdict-msg {
  font-size: var(--fs-meta);
  max-width: 18em;
}
.preview-table tr.row-warning td {
  background: var(--accent-bg);
}
.preview-table tr.row-blocked td,
.preview-table tr.row-invalid td {
  background: var(--danger-bg);
}

.badge.warning {
  color: var(--accent);
  border-color: var(--accent-bg);
}
.badge.blocked,
.badge.invalid {
  color: var(--danger);
  border-color: var(--danger-bg);
}
