/* newuser.css — onboarding form styling on the docs/portal design system.
   Bootstrap is dropped: this provides the (small) subset of layout/component
   classes the form markup uses. Classes are `nu-`-prefixed (idea #2024) — this
   surface and the authenticated SPA (src/css/portal.css, `cp-`-prefixed) each
   hand-roll their own Bootstrap-shaped primitives, so a bare `.btn`/`.card`/
   `.text-danger` etc. used to mean two different, independently-drifting
   things depending which page you were editing. Disjoint prefixes make that
   impossible now — see clientPortal/classAudit.guard.js for the mechanical
   check that a used class is always backed by a real rule.
   Tokens below are GENERATED (design/tokens/dark-plus.json, `npm run
   tokens:gen`) — this file used to hand-hardcode its own stale copy of the
   old pre-migration GitHub-dark palette, frozen while every other clientPortal
   surface had already flipped to Dark+; do not hand-edit the values. */

:root {
    /* BEGIN GENERATED TOKENS — source: design/tokens/dark-plus.json (npm run tokens:gen) */
    --bg-input: #3c3c3c;
    --accent-chrome: #007acc;
    --focus-ring: #007fd4;
    --selection-bg: #264f78;
    --link-color: #3794ff;
    --link-hover: #4daafc;
    --border-strong: #474747;
    --success-subtle: rgba(137, 209, 133, .16);
    --danger-subtle: rgba(241, 76, 76, .16);
    --warning-subtle: rgba(204, 167, 0, .16);
    --purple: #c586c0;
    --purple-subtle: rgba(197, 134, 192, .18);
    --teal: #4ec9b0;
    --teal-subtle: rgba(78, 201, 176, .18);
    --yellow-sc: #dcdcaa;
    --orange: #d18616;
    /* END GENERATED TOKENS */
  --bg-primary: #1e1e1e;
  --bg-secondary: #252526;
  --bg-tertiary: #2d2d30;
  --bg-elevated: #333333;
  --text-primary: #d4d4d4;
  --text-secondary: #9d9d9d;
  --text-muted: #808080;
  --accent-color: #3794ff;
  --accent-hover: #4daafc;
  --accent-subtle: rgba(55, 148, 255, .12);
  --border-color: #3c3c3c;
  --border-subtle: #2d2d30;
  --success: #89d185;
  --danger: #f14c4c;
  --warning: #cca700;
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .25);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, .32);
  --shadow-lg: 0 8px 28px rgba(0, 0, 0, .42);
  --transition: 0.15s ease;
}

/* --- Base ------------------------------------------------------------------ */
* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5 { font-weight: 600; color: var(--text-primary); margin: 0 0 12px; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.05rem; }
a { color: var(--accent-color); text-decoration: none; }
a:hover { color: var(--accent-hover); }
hr { border: 0; border-top: 1px solid var(--border-color); margin: 16px 0; }
small, .nu-small { font-size: 0.8rem; }

/* --- Layout / containers --------------------------------------------------- */
.nu-container { width: 100%; margin: 0 auto; padding: 16px; }
.newuser-form-container,
.response-container { max-width: 980px; margin: 0 auto; padding: 20px; }

.nu-row { display: flex; flex-wrap: wrap; gap: 16px; }
.nu-row > [class*="col-"] { flex: 1 1 0; min-width: 0; }
/* Same specificity as the fallback above (.nu-row > [class]) so these actually win by
   source order — a bare .nu-col-6 { } rule here would lose the flex/min-width fight to
   the fallback and render as an invisible no-op (real bug fixed under idea #2024: the
   First/Middle/Last name row used col-md-5/col-md-2/col-md-5, both entirely unbacked
   classes, so all three rendered as equal-width columns instead of a 5:2:5 split). */
.nu-row > .nu-col-6 { flex: 1 1 calc(50% - 8px); min-width: 220px; }
.nu-row > .nu-col-5 { flex: 5 1 140px; min-width: 140px; }
.nu-row > .nu-col-2 { flex: 2 1 70px; min-width: 70px; }

.nu-d-flex { display: flex; }
.nu-d-none { display: none !important; }
.nu-d-block { display: block; }
.nu-flex-column { flex-direction: column; }
.nu-items-center { align-items: center; }
.nu-items-start { align-items: flex-start; }
.nu-justify-center { justify-content: center; }
.nu-justify-between { justify-content: space-between; }
.nu-text-center { text-align: center; }
.nu-w-100 { width: 100%; }
.nu-gap-2 { gap: 8px; }
.nu-gap-3 { gap: 16px; }

/* spacing utilities (subset the form uses) */
.nu-me-2 { margin-right: 8px; }
.nu-ms-2 { margin-left: 8px; }
.nu-mt-1 { margin-top: 4px; }
.nu-mt-2 { margin-top: 8px; }
.nu-mt-3 { margin-top: 16px; }
.nu-mb-0 { margin-bottom: 0; }
.nu-mb-1 { margin-bottom: 4px; }
.nu-mb-2 { margin-bottom: 8px; }
.nu-mb-3 { margin-bottom: 16px; }
.nu-mb-4 { margin-bottom: 24px; }
.nu-p-2 { padding: 8px; }
.nu-p-3 { padding: 16px; }
.nu-p-4 { padding: 24px; }
.nu-py-2 { padding-top: 8px; padding-bottom: 8px; }
.nu-py-3 { padding-top: 16px; padding-bottom: 16px; }
.nu-rounded { border-radius: var(--radius-md); }
.nu-list-unstyled { list-style: none; padding-left: 0; margin: 0; }
.nu-fw-semibold { font-weight: 600; }
.nu-d-grid { display: grid; }
.nu-shadow-sm { box-shadow: var(--shadow-sm); }
.nu-shadow { box-shadow: var(--shadow-md); }
.nu-alert-heading { font-weight: 600; margin: 0 0 4px; }

/* --- Text colours ---------------------------------------------------------- */
.nu-text-primary { color: var(--accent-color) !important; }   /* bootstrap "primary" = brand/accent */
.nu-text-secondary { color: var(--text-secondary) !important; }
.nu-text-muted { color: var(--text-muted) !important; }
.nu-text-light { color: var(--text-primary) !important; }
.nu-text-success { color: var(--success) !important; }
.nu-text-danger { color: var(--danger) !important; }
.nu-text-warning { color: var(--warning) !important; }
.nu-text-info { color: var(--accent-color) !important; }

/* --- Cards ----------------------------------------------------------------- */
.nu-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  margin-bottom: 16px;
  overflow: hidden;
}
.nu-card-header {
  background: var(--bg-tertiary);
  border-bottom: 1px solid var(--border-color);
  padding: 10px 16px;
  font-weight: 600;
}
.nu-card-body { padding: 16px; }
.nu-card-title { font-size: 0.95rem; font-weight: 600; margin: 0 0 4px; display: flex; align-items: center; }
.nu-card-title i, .nu-card-header i { color: var(--accent-color); }
.nu-card-text { color: var(--text-secondary); margin: 0; }
.welcome-card { border-left: 3px solid var(--accent-color); }

/* --- Alerts ---------------------------------------------------------------- */
.nu-alert { padding: 12px 16px; border-radius: var(--radius-md); border: 1px solid var(--border-color); margin-bottom: 16px; }
.nu-alert-info { background: var(--accent-subtle); border-color: rgba(88, 166, 255, .35); color: var(--text-primary); }
.nu-alert-success { background: rgba(63, 185, 80, .12); border-color: rgba(63, 185, 80, .35); }
.nu-alert-warning { background: rgba(210, 153, 34, .12); border-color: rgba(210, 153, 34, .35); }
.nu-alert-danger { background: rgba(248, 81, 73, .12); border-color: rgba(248, 81, 73, .35); }

/* --- Badges ---------------------------------------------------------------- */
.nu-badge {
  display: inline-block; padding: 3px 8px; border-radius: 10px;
  font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em;
}
.nu-bg-success { background: rgba(63, 185, 80, .2); color: var(--success); }
.nu-bg-warning { background: rgba(210, 153, 34, .2); color: var(--warning); }
.nu-bg-secondary { background: rgba(139, 148, 158, .2); color: var(--text-secondary); }
.nu-bg-dark { background: var(--bg-tertiary); color: var(--text-secondary); }

/* --- M365 licence picker (idea #1999) --------------------------------------
   Own styles on purpose. This page loads NO Bootstrap — only fontawesome +
   this file — so Bootstrap-only utilities (text-bg-*, d-block, small,
   fst-italic, border-top) render as nothing. And .nu-check here is a
   single-line TOGGLE SWITCH, which cannot lay out a multi-line radio card. */
.license-option {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 12px; margin-bottom: 8px;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color); border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}
.license-option:hover { border-color: var(--accent-color); }
.license-option.selected { border-color: var(--accent-color); background: var(--accent-subtle); }
.license-option input[type="radio"] {
  flex: none; width: 16px; height: 16px; margin: 2px 0 0;
  accent-color: var(--accent-color); cursor: pointer;
}
.license-option-body { flex: 1; min-width: 0; }
.license-option-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.license-option-name { font-weight: 600; color: var(--text-primary); font-size: 0.9rem; }
.license-option-desc { color: var(--text-secondary); font-size: 0.8rem; line-height: 1.45; }
.license-option-best { color: var(--text-muted); font-size: 0.78rem; font-style: italic; margin-top: 4px; }

/* Billing impact — the client is choosing something that may cost them money,
   so say which it is rather than hedging about seat counts. */
.license-bill {
  display: inline-block; padding: 3px 8px; border-radius: 10px;
  font-size: 0.68rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.03em; white-space: nowrap;
}
.license-bill-included { background: rgba(63, 185, 80, .2); color: var(--success); }
.license-bill-extra { background: rgba(210, 153, 34, .2); color: var(--warning); }

/* --- Forms ----------------------------------------------------------------- */
.nu-label { display: block; font-size: 0.78rem; font-weight: 500; color: var(--text-secondary); margin-bottom: 6px; }
.nu-input, .nu-select {
  width: 100%; padding: 8px 12px;
  background: var(--bg-tertiary); color: var(--text-primary);
  border: 1px solid var(--border-color); border-radius: var(--radius-sm);
  font-size: 0.9rem; font-family: inherit; transition: border-color var(--transition), box-shadow var(--transition);
  outline: none;
}
.nu-select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--text-muted) 50%), linear-gradient(135deg, var(--text-muted) 50%, transparent 50%); background-position: calc(100% - 16px) center, calc(100% - 11px) center; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 32px; }
.nu-select[multiple] { background-image: none; padding-right: 12px; }
.nu-input::placeholder { color: var(--text-muted); }
.nu-input:focus, .nu-select:focus { border-color: var(--accent-color); box-shadow: 0 0 0 3px var(--accent-subtle); }
.nu-input.nu-is-valid, .nu-select.nu-is-valid { border-color: var(--success); }
.nu-input.nu-is-invalid, .nu-select.nu-is-invalid { border-color: var(--danger); }
/* Computed, not typed (e.g. the Full Name field, derived from First/Middle/Last) — reads as
   non-interactive rather than looking like a normal editable input. */
.nu-input[readonly] { background: var(--bg-elevated); color: var(--text-secondary); cursor: default; }
.nu-input[readonly]:focus { box-shadow: none; }
.nu-invalid-feedback { display: none; color: var(--danger); font-size: 0.75rem; margin-top: 4px; }
.nu-is-invalid ~ .nu-invalid-feedback { display: block; }
/* Helper text under a field. Used in four places in the form and never defined — the markup
   was written against Bootstrap, but this page does NOT load Bootstrap (only FontAwesome and
   this stylesheet), so every unbacked utility class silently did nothing. */
.nu-help-text { display: block; margin-top: 4px; font-size: 0.75rem; color: var(--text-muted); }
.nu-input-sm { padding: 5px 9px; font-size: 0.82rem; }

.nu-input-group { display: flex; }
.nu-input-group .nu-input { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.nu-input-group .nu-btn { border-top-left-radius: 0; border-bottom-left-radius: 0; }
/* A trailing <select> in an input group — the e-mail domain picker (idea #2043). .nu-input-group
   only styled .nu-input and .nu-btn, so a select rendered detached with its own rounded corners.
   Scoped to the group so a standalone .nu-select elsewhere is untouched. */
.nu-input-group .nu-select {
  border-top-left-radius: 0; border-bottom-left-radius: 0; border-left: none;
  flex: 0 1 auto; min-width: 0; max-width: 55%;
}
.nu-input-group .nu-input { flex: 1 1 auto; min-width: 0; }

/* Checkbox / toggle — matches the portal toggle */
.nu-check { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.nu-check-label { color: var(--text-secondary); font-size: 0.85rem; cursor: pointer; user-select: none; }
.nu-check-input {
  appearance: none; -webkit-appearance: none; width: 34px; height: 18px; flex: 0 0 auto;
  background: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 9px;
  position: relative; cursor: pointer; transition: all var(--transition); margin: 0;
}
.nu-check-input::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px;
  background: var(--text-muted); border-radius: 50%; transition: all var(--transition);
}
.nu-check-input:checked { background: var(--accent-color); border-color: var(--accent-color); }
.nu-check-input:checked::after { left: 18px; background: #fff; }
.nu-check-input:focus { box-shadow: 0 0 0 3px var(--accent-subtle); }

/* --- Buttons --------------------------------------------------------------- */
.nu-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 16px; border: 1px solid transparent; border-radius: var(--radius-sm);
  font-size: 0.9rem; font-weight: 500; font-family: inherit; cursor: pointer;
  transition: background var(--transition), border-color var(--transition), transform var(--transition);
  background: var(--bg-tertiary); color: var(--text-primary); text-decoration: none;
}
.nu-btn:hover { border-color: var(--accent-color); }
.nu-btn:active { transform: scale(0.99); }
.nu-btn:disabled { opacity: .6; cursor: not-allowed; }
.nu-btn-sm { padding: 4px 10px; font-size: 0.8rem; }
.nu-btn-primary { background: var(--accent-color); border-color: var(--accent-color); color: #0d1117; font-weight: 600; }
.nu-btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.nu-btn-secondary { background: var(--bg-tertiary); color: var(--text-secondary); }
.nu-btn-outline-secondary { background: transparent; border-color: var(--border-color); color: var(--text-secondary); }
.nu-btn-outline-secondary:hover { border-color: var(--accent-color); color: var(--text-primary); }
.nu-btn-outline-success { background: transparent; border-color: var(--success); color: var(--success); }
.nu-btn-outline-success:hover { background: rgba(63, 185, 80, .12); }
.nu-btn-outline-danger { background: transparent; border-color: var(--danger); color: var(--danger); }
.nu-btn-outline-danger:hover { background: rgba(248, 81, 73, .12); }

/* --- Spinner --------------------------------------------------------------- */
.nu-spinner-border {
  display: inline-block; width: 2rem; height: 2rem; vertical-align: -0.125em;
  border: 0.25em solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: nu-spin 0.75s linear infinite;
}
@keyframes nu-spin { to { transform: rotate(360deg); } }
.nu-visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* --- Password rule list ---------------------------------------------------- */
.rule { color: var(--danger); }
.rule.valid { color: var(--success); }
.rule i { width: 1em; }

/* --- Email gate / status cards --------------------------------------------- */
.gate-card { max-width: 420px; width: 100%; }

/* --- Group checkbox pickers (idea #2017) ------------------------------------
   AD / Google / M365 group selection. Checkboxes replaced the old ctrl+click
   multi-selects, which meant every option is now on the page at once — and one
   real domain offers 109 groups, so the list has to scroll and be filterable or
   it is a worse wall than the control it replaced. */
.cns-group-checks {
  max-height: 260px; overflow-y: auto;
  border: 1px solid var(--border-color); border-radius: 6px;
  padding: 8px 10px; background: var(--bg-tertiary);
}
.cns-group-checks .nu-check { margin-bottom: 6px; }
.cns-group-checks .nu-check:last-child { margin-bottom: 0; }
/* The group NAME is the thing being chosen, so it carries the weight; the description is
   supporting detail. Without the contrast the two lines read as equals — which is half of why
   a repeated name looked like a duplicate rather than a name plus its description. */
.cns-group-checks .nu-check-label { cursor: pointer; line-height: 1.35; font-weight: 500; }
/* The description sits directly under the name inside the SAME label, so without a margin the
   two lines run together.
   `display: block` is set HERE and not left to the d-block utility class on the element: this
   page does not load Bootstrap, so d-block was doing nothing and the description rendered
   inline, running straight on from the name. A component that only works when some utility
   class happens to exist is a trap — this rule stands on its own. */
.cns-group-desc { display: block; margin-top: 2px; font-size: .8rem; line-height: 1.3; font-weight: 400; }
.cns-group-filter { margin-bottom: 8px; }
/* Shown when a filter hides every row, so the box never looks simply broken. */
.cns-group-noresult { color: var(--text-secondary); font-size: .85rem; padding: 4px 0; }
