/* Deliberately dependency-free: the air-gapped bundle cannot pull a CSS framework, and
   the node's cores are committed to inference, so there is no build step here either.

   Brand: the palette follows Accenture's public identity - core purple #A100FF on white,
   with the chevron as the mark. The corporate typeface (Graphik) is licensed and cannot
   be fetched from a CDN on an air-gapped box, so this falls back to the platform UI font,
   which on the target Windows estate is Segoe UI.

   Contrast is checked, not assumed: #A100FF on white is 5.3:1 and passes WCAG AA for
   body text, but only 4.0:1 on black - hence a separate lighter purple for dark mode. */

:root {
  --purple: #a100ff;
  --purple-ink: #7500c0;   /* hover / pressed, and text on tinted fills */
  --purple-deep: #460073;
  --purple-tint: #f6efff;  /* section fills */
  --purple-line: #e3d0f7;

  --bg: #f7f6f4;
  --card: #ffffff;
  --ink: #16151a;
  --muted: #5d5b66;
  --line: #dededa;
  --line-soft: #ecebe8;

  --accent: var(--purple);
  --accent-bg: var(--purple-tint);
  --danger: #b3261e; --danger-bg: #fdecea;
  /* Named separately from --danger: this marks a destructive *command* on the always-dark
     pre.cmd block (which never follows the page theme), not an alert on a themed surface -
     same red family, different role, so it gets its own token rather than reusing one by value. */
  --danger-command: #e2544a;
  --ok: #1f6b3a;     --ok-bg: #e8f5ec;
  --warn: #8a5300;   --warn-bg: #fdf1dd;

  --r: 8px;
  --shadow: 0 1px 2px rgba(22, 21, 26, .05), 0 1px 12px rgba(22, 21, 26, .04);
  --shadow-lg: 0 12px 40px rgba(22, 21, 26, .18), 0 2px 8px rgba(22, 21, 26, .10);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--ink);
  font: 400 15px/1.6 "Segoe UI Variable Text", "Segoe UI", -apple-system, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* Visible focus everywhere. Removing it would fail an accessibility review and make the
   keyboard path through the admin dialog unusable. */
:focus-visible {
  outline: 2px solid var(--purple);
  outline-offset: 2px;
  border-radius: 3px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Visible only once focused - the appbar carries four buttons before <main>, so a keyboard
   user otherwise tabs through all of them on every page load before reaching content. */
.skip-link {
  position: absolute; left: 10px; top: -48px; z-index: 100;
  background: var(--purple); color: #fff; padding: 9px 16px;
  border-radius: 6px; font-weight: 600; font-size: 13px; text-decoration: none;
  transition: top .15s ease-out;
}
.skip-link:focus { top: 10px; }

.hidden { display: none !important; }

/* --- app bar ----------------------------------------------------------- */

.appbar {
  background: var(--card);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 10;
}
.appbar-in {
  padding: 10px 28px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.brand { display: inline-flex; align-items: baseline; gap: 8px; min-width: 0; }
.chev { color: var(--purple); font-weight: 700; }
.brand-name {
  font-weight: 600; font-size: 15px; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.appbar-act { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

.whoami { display: inline-flex; align-items: center; gap: 9px; margin-right: 4px; }
.avatar {
  width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0;
  background: var(--purple); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600; letter-spacing: .02em;
}
.whoami-txt { display: flex; flex-direction: column; line-height: 1.25; }
.whoami-name { font-size: 13px; font-weight: 500; }
.whoami-sub { font-size: 11px; color: var(--muted); }

/* --- layout and cards --------------------------------------------------- */

.wrap { max-width: 880px; width: 100%; margin: 0 auto; padding: 24px 20px 48px;
  flex: 1; }

/* --- footer ------------------------------------------------------------- */

.appfoot { background: var(--card); border-top: 1px solid var(--line); }
.appfoot-in {
  padding: 14px 28px; display: flex; align-items: center;
  justify-content: space-between; gap: 12px 24px; flex-wrap: wrap;
  font-size: 12px; color: var(--muted);
}
.foot-l { display: inline-flex; align-items: baseline; gap: 8px; }
.foot-name { font-weight: 500; color: var(--ink); }
.env {
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .06em; color: var(--purple-ink);
  background: var(--purple-tint); border: 1px solid var(--purple-line);
  border-radius: 4px; padding: 1px 6px;
}
.foot-r { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dot { opacity: .5; }

h1 { font-size: 22px; font-weight: 600; letter-spacing: -.02em; margin: 0 0 6px; }
h2 { font-size: 16px; font-weight: 600; margin: 24px 0 8px; }
h3 { font-size: 14px; font-weight: 600; margin: 0 0 10px; }
.sub { color: var(--muted); font-size: 13px; margin: 0 0 20px; }

.card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  padding: 20px; margin-bottom: 16px; box-shadow: var(--shadow);
}
.card-h { font-size: 15px; font-weight: 600; margin: 0 0 16px; }
.signin { max-width: 440px; margin: 40px auto 16px; }
.signin-h { font-size: 20px; }

.or {
  display: flex; align-items: center; gap: 12px;
  color: var(--muted); font-size: 12px; margin: 18px 0;
}
.or::before, .or::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* --- form controls ------------------------------------------------------ */

.field { margin-bottom: 16px; }
.field:last-child { margin-bottom: 0; }
.field-row { display: flex; gap: 12px; align-items: flex-end; margin-top: 4px; }
.field-row > .field { margin-bottom: 0; }
.field-row > .field.grow { flex: 1; min-width: 0; }
.grow { flex: 1; margin-bottom: 0; }

label { display: block; font-size: 13px; font-weight: 500; margin: 0 0 6px; }

input[type=text], input[type=password], input[type=search], textarea, select {
  width: 100%; padding: 9px 11px; font: inherit; color: var(--ink);
  background: var(--card); border: 1px solid var(--line); border-radius: 6px;
  transition: border-color .12s, box-shadow .12s;
}
input[type=text]:hover, input[type=password]:hover, input[type=search]:hover,
textarea:hover { border-color: #c4c3bf; }
input[type=text]:focus, input[type=password]:focus, input[type=search]:focus,
textarea:focus {
  outline: none; border-color: var(--purple);
  box-shadow: 0 0 0 3px rgba(161, 0, 255, .14);
}
::placeholder { color: #9a988f; }
textarea { min-height: 150px; resize: vertical; font-size: 14px; }

.hint { font-size: 12px; color: var(--muted); margin: 6px 0 0; }

/* Feedback row. A class rather than inline styles: the CSP carries no `unsafe-inline`,
   so a `style=` attribute here would be refused by the browser and only show up in a
   user's console. `test_ui_carries_nothing_that_needs_unsafe_inline` fails the build. */
.feedback { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.feedback .hint { margin: 0; }

/* The report form, revealed under the buttons when someone answers "No". */
.fb-report { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 14px; }
.fb-report.hidden { display: none; }
.fb-field { display: block; font-size: 13px; font-weight: 500; margin: 12px 0 6px; }
.fb-report select,
.fb-report input,
.fb-report textarea { width: 100%; }
.fb-report .feedback { margin-top: 14px; }

fieldset.roles { border: 0; padding: 0; margin: 0 0 16px; }
fieldset.roles legend { font-size: 13px; font-weight: 500; padding: 0; margin-bottom: 8px; }
.roles-row { display: flex; gap: 10px; }
.roles-row .check { flex: 1; margin-bottom: 0; }
.check {
  display: flex; gap: 10px; align-items: flex-start; font-weight: 400;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 6px;
  margin-bottom: 8px; cursor: pointer; transition: border-color .12s, background .12s;
}
.check:hover { border-color: var(--purple-line); background: var(--purple-tint); }
.check input { margin: 3px 0 0; accent-color: var(--purple); flex-shrink: 0; }
.check strong { display: block; font-size: 13px; font-weight: 600; }
.check .hint { margin-top: 1px; }

.pw-meter {
  height: 3px; background: var(--line-soft); border-radius: 2px;
  overflow: hidden; margin-top: 7px;
}
.pw-meter > i {
  display: block; height: 100%; width: 0; background: var(--purple);
  transition: width .15s linear, background .15s;
}
.pw-meter > i.short { background: var(--danger); }

/* Disclosure. Native <details> so the open/closed state, keyboard handling and the
   screen-reader announcement come from the browser rather than from script. */
.adv { border-top: 1px solid var(--line-soft); padding-top: 12px; margin-top: 4px; }
.adv > summary {
  cursor: pointer; font-size: 13px; font-weight: 500; color: var(--purple-ink);
  list-style: none; display: flex; align-items: center; gap: 8px;
  padding: 4px 2px; border-radius: 4px; width: fit-content;
}
.adv > summary::-webkit-details-marker { display: none; }
.adv > summary::before {
  content: ""; width: 6px; height: 6px; flex-shrink: 0;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg); transition: transform .15s;
}
.adv[open] > summary::before { transform: rotate(45deg); }
.adv > summary:hover { color: var(--purple); }
.adv-note { font-weight: 400; color: var(--muted); font-size: 12px; }
.adv > div { margin-top: 12px; }

.ask-act { display: flex; justify-content: flex-end; margin-top: 16px; }

/* --- buttons ------------------------------------------------------------ */

button, .btn {
  font: inherit; font-weight: 500; font-size: 14px; padding: 9px 18px;
  border-radius: 6px; border: 1px solid transparent; cursor: pointer;
  background: var(--purple); color: #fff;
  transition: background .12s, border-color .12s, color .12s, transform .1s ease-out;
}
button:disabled, .btn:disabled,
button[aria-disabled="true"], .btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
/* Tactile press feedback: every button gets it, not just primary - this app had none at all. */
button:not(:disabled):not([aria-disabled="true"]):active,
.btn:not(:disabled):not([aria-disabled="true"]):active { transform: scale(.97); }
.btn.primary { background: var(--purple); border-color: var(--purple); color: #fff; }
.btn.primary:hover:not(:disabled) { background: var(--purple-ink); border-color: var(--purple-ink); }

button.ghost, .btn.ghost {
  background: transparent; color: var(--purple-ink); border-color: var(--line);
}
button.ghost:hover:not(:disabled), .btn.ghost:hover:not(:disabled) {
  background: var(--purple-tint); border-color: var(--purple-line); color: var(--purple-ink);
}
.btn.block { display: block; width: 100%; }
.btn.icon-only {
  background: transparent; color: var(--muted); border: 0;
  padding: 6px 9px; font-size: 15px; line-height: 1; border-radius: 6px;
}
.btn.icon-only:hover { background: var(--line-soft); color: var(--ink); }
.btn.danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn.danger:hover:not(:disabled) { background: #8f1e17; border-color: #8f1e17; }
.btn.sm { padding: 4px 11px; font-size: 12px; }
.ico { font-size: 12px; }

/* --- alerts and badges -------------------------------------------------- */

.alert { padding: 10px 13px; border-radius: 6px; font-size: 13px; margin-top: 14px;
  border: 1px solid transparent; }
.err { background: var(--danger-bg); border-color: #f0c2bd; color: var(--danger); }
.ok  { background: var(--ok-bg);     border-color: #b9dcc5; color: var(--ok); }

.badge { display: inline-block; font-size: 11px; font-weight: 600; padding: 2px 9px;
  border-radius: 11px; vertical-align: middle; letter-spacing: .01em;
  white-space: nowrap; font-variant-numeric: tabular-nums; }
.b-ok { background: var(--ok-bg); color: var(--ok); }
.b-warn { background: var(--warn-bg); color: var(--warn); }
.b-danger { background: var(--danger-bg); color: var(--danger); }
.b-info { background: var(--purple-tint); color: var(--purple-ink); }

.chip {
  display: inline-block; font-size: 11px; font-family: ui-monospace, monospace;
  background: var(--line-soft); color: var(--ink); border: 1px solid var(--line);
  padding: 1px 7px; border-radius: 4px; margin: 1px 3px 1px 0;
}

.attn { background: var(--warn-bg); border: 1px solid #ecd79a; border-radius: 6px;
  padding: 10px 13px; margin-bottom: 14px; }
.attn-h { font-size: 12px; font-weight: 600; color: var(--warn); margin: 0 0 6px; }
.attn-item { display: block; width: 100%; text-align: left; background: none; border: 0;
  padding: 3px 0; font-family: inherit; font-size: 13px; color: var(--ink); cursor: pointer; }
.attn-item:hover, .attn-item:focus-visible { color: var(--purple); text-decoration: underline; }
.cite {
  display: inline-block; font-size: 11px; font-family: ui-monospace, monospace;
  background: var(--purple-tint); color: var(--purple-ink);
  border: 1px solid var(--purple-line);
  padding: 1px 6px; border-radius: 4px; margin-right: 4px;
}

/* --- answer view -------------------------------------------------------- */

ol.actions { padding-left: 0; list-style: none; margin: 0; counter-reset: a; }
ol.actions > li { counter-increment: a; border-top: 1px solid var(--line-soft); padding: 14px 0; }
ol.actions > li:first-child { border-top: 0; }
ol.actions > li::before {
  content: counter(a); display: inline-block; width: 21px; height: 21px;
  line-height: 21px; text-align: center; background: var(--purple); color: #fff;
  border-radius: 50%; font-size: 11px; font-weight: 600; margin-right: 9px;
}
.act-why { margin-top: 6px; }
/* Answer prose (root cause, action text) can run as long as the corpus article it's drawn
   from; cap it to a comfortable reading measure instead of the full card width. */
.card > p { max-width: 70ch; }
pre.cmd {
  background: #1b1a20; color: #f2f0f6; padding: 12px 14px; border-radius: 6px;
  font: 13px/1.5 ui-monospace, "Cascadia Code", monospace; overflow-x: auto;
  margin: 10px 0 0; white-space: pre-wrap; word-break: break-all;
}
pre.cmd.destructive { border-left: 3px solid var(--danger-command); }
.cmdbar { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.cmdbar button { padding: 4px 11px; font-size: 12px; }
.kv { display: flex; gap: 18px; flex-wrap: wrap; font-size: 12px; color: var(--muted);
  margin-top: 10px; font-variant-numeric: tabular-nums; }

.wait-head { display: flex; align-items: center; gap: 8px; }
.spin {
  display: inline-block; width: 13px; height: 13px; border: 2px solid var(--line);
  border-top-color: var(--purple); border-radius: 50%; animation: s .8s linear infinite;
  flex-shrink: 0;
}
@keyframes s { to { transform: rotate(360deg); } }
.bar { height: 4px; background: var(--line-soft); border-radius: 2px; overflow: hidden;
  margin-top: 12px; }
.bar > i { display: block; height: 100%; background: var(--purple); width: 0;
  transition: width .9s linear; }

/* --- access control dialog ---------------------------------------------- */

.dlg {
  width: min(840px, calc(100vw - 32px));
  max-height: min(97vh, 980px);
  padding: 0; border: 0; border-radius: 12px;
  background: var(--card); color: var(--ink);
  box-shadow: var(--shadow-lg);
  display: none; flex-direction: column; overflow: hidden;
}
.dlg[open] { display: flex; }
.dlg::backdrop { background: rgba(22, 21, 26, .55); backdrop-filter: blur(2px); }

.dlg-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding: 12px 20px 10px; border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, var(--purple-tint), var(--card));
  flex-shrink: 0;
}
.dlg-h { font-size: 17px; font-weight: 600; margin: 0; letter-spacing: -.01em; }
.dlg-head .hint { margin-top: 3px; }
.dlg-body { padding: 14px 20px; overflow-y: auto; flex: 1; }
.dlg-foot {
  padding: 12px 20px; border-top: 1px solid var(--line);
  background: var(--bg); flex-shrink: 0;
}
.dlg-foot .hint { margin: 0; }

.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.toolbar input[type=search] { flex: 1; min-width: 0; }
.tally { font-size: 12px; color: var(--muted); white-space: nowrap; }

.tbl-wrap { border: 1px solid var(--line); border-radius: var(--r); overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; font-size: 14px; }
.tbl th {
  text-align: left; font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .05em; color: var(--muted); background: var(--bg);
  padding: 9px 14px; border-bottom: 1px solid var(--line); white-space: nowrap;
}
.tbl td { padding: 11px 14px; border-top: 1px solid var(--line-soft); vertical-align: top; }
.tbl tbody tr:first-child td { border-top: 0; }
.tbl tbody tr:hover { background: #faf8fd; }
.tbl tr.is-me { background: var(--purple-tint); }
.tbl tr.is-me:hover { background: #f1e6fe; }
.u-name { font-weight: 500; }
/* A long unbroken email has no natural break point; under table-layout:fixed that would
   otherwise force the Person column wide the same way the Actions column used to. */
.u-email { overflow-wrap: anywhere; }
.u-you {
  font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
  color: var(--purple-ink); background: #fff; border: 1px solid var(--purple-line);
  border-radius: 4px; padding: 0 5px; margin-left: 7px; vertical-align: 1px;
}
/* table-layout:fixed, scoped to this one table rather than the generic .tbl class (the
   audit/bulk-results tables also carry .tbl, with a different shape - fixed widths sized
   for this one would be wrong there). Without this, table-layout:auto let any single
   unbreakable piece of content - the Resend invite button once a third action existed,
   a long email once it was shown under the username - grow its column past its declared
   width, which grew the whole table past its container and surfaced as a horizontal
   scrollbar cropping the last button off-screen, reported live at a sub-840px window
   width (the dialog's own cap, not reachable in a very wide test window). Fixed width
   makes every column a hard ceiling instead of a hint, so excess content wraps onto a
   second line within its own cell rather than widening the table. */
#user-table { table-layout: fixed; }
#user-table th:nth-child(2) { width: 112px; }
#user-table th:nth-child(3) { width: 124px; }
#user-table th:nth-child(4) { width: 220px; }
/* Badges wrap rather than force the Roles column wide - two can co-occur (e.g. "Must
   change password" next to "Invite pending"), same reasoning as the table itself. */
#user-table td:nth-child(3) { white-space: normal; }
.acts { text-align: right; width: 220px; }
.acts button { margin: 4px 0 0 6px; }
.acts button { margin-left: 6px; }
.confirm { display: inline-flex; align-items: center; gap: 8px; justify-content: flex-end; }
.confirm-q { font-size: 12px; color: var(--danger); font-weight: 500; }
.empty { padding: 22px 14px; text-align: center; color: var(--muted); font-size: 13px;
  margin: 0; }

.editor {
  margin-top: 14px; padding: 14px 18px; border-radius: var(--r);
  background: var(--purple-tint); border: 1px solid var(--purple-line);
}
.editor .check { background: var(--card); }
.editor-h { font-size: 14px; font-weight: 600; margin: 0 0 10px; color: var(--purple-deep); }
.editor-act { display: flex; justify-content: flex-end; gap: 10px; margin-top: 4px; }

/* Tighter rhythm than the default .field/.check spacing, scoped to this one form: it
   packs 3-7 fields plus two role checkboxes and an invite toggle into one dialog, and
   that stacked up enough to need scrolling just to reach the checkboxes - reported live
   twice (once for the whole form, once again for the email field invite mode reveals).
   The list above (toolbar/needs-attention/table) is hidden entirely while this form is
   open (see openEditor/openBulkEditor) so the form gets the full dialog body instead of
   whatever space that left over, but on a short window the form's own height is still
   the binding constraint, which is what the rest of this block chips away at. */
#u-form .field { margin-bottom: 9px; }
#u-form fieldset.roles { margin-bottom: 9px; }
#u-form fieldset.roles legend { margin-bottom: 6px; }
#u-form .check { padding: 7px 9px; margin-bottom: 6px; }
#u-invite-row { margin-bottom: 6px; }

@media (max-width: 620px) {
  .appbar-in { flex-wrap: wrap; }
  .whoami-sub { display: none; }
  .toolbar { flex-wrap: wrap; }
  .toolbar input[type=search] { order: 3; flex-basis: 100%; }
  .field-row, .roles-row { flex-direction: column; align-items: stretch; }
  .appbar-in, .appfoot-in { padding-left: 16px; padding-right: 16px; }
  .appfoot-in { flex-direction: column; align-items: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* --- dark mode ----------------------------------------------------------
   #a100ff only reaches 4.0:1 on near-black, which fails AA, so dark mode uses a lighter
   tint of the same hue (7.2:1) rather than the core brand purple. */
@media (prefers-color-scheme: dark) {
  :root {
    --purple: #ce8aff;
    --purple-ink: #ddaeff;
    --purple-deep: #ecd5ff;
    --purple-tint: #241733;
    --purple-line: #4a2d66;

    --bg: #131217;
    --card: #1c1b21;
    --ink: #f2f0f6;
    --muted: #a8a5b3;
    --line: #35333d;
    --line-soft: #2a2830;

    --danger: #f5a29b; --danger-bg: #3c1512;
    --ok: #9ad3ae;     --ok-bg: #12301d;
    --warn: #f0c584;   --warn-bg: #3a2708;
    --shadow: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-lg: 0 12px 40px rgba(0, 0, 0, .6);
  }
  .avatar { color: #1c1b21; }
  .btn.primary { color: #17131c; }
  .btn.primary:hover:not(:disabled) { background: var(--purple-ink); }
  ol.actions > li::before { color: #17131c; }
  .err { border-color: #6b2620; }
  .ok { border-color: #235c36; }
  .attn { border-color: #6b4b1c; }
  .tbl tbody tr:hover { background: #221f29; }
  .tbl tr.is-me:hover { background: #2c1d3d; }
  /* --danger is redefined above to a pale salmon (#f5a29b) for alert TEXT on dark
     backgrounds - correct for .err, wrong for a solid button fill. Reusing it here left
     white button text on that pale salmon at ~2:1 contrast, failing WCAG AA (needs 4.5:1).
     .btn.primary got the equivalent fix when dark mode shipped; this one was missed.
     Measured: white-on-#b3261e is 6.5:1. */
  .btn.danger { background: #b3261e; border-color: #b3261e; color: #fff; }
  input[type=text]:hover, input[type=password]:hover, input[type=search]:hover,
  textarea:hover { border-color: #4b4956; }
}
