:root {
  --accent: #00c8f0;
  --bg: #090a0d;
  --bg-2: #111318;
  --panel: #171a21;
  --panel-2: #20242d;
  --text: #f5f5f6;
  --muted: #a6adbb;
  --line: #303540;
  --danger: #ff5b5b;
  --ok: #2dd48f;
  --warn: #ffd166;
  --radius: 18px;
  --shadow: 0 18px 60px rgba(0,0,0,.32);
  font-family: "Segoe UI", Inter, system-ui, -apple-system, BlinkMacSystemFont, Arial, sans-serif;
}

* { box-sizing: border-box; }
body {
  margin: 0;
  color: var(--text);
  background:
    radial-gradient(circle at top right, color-mix(in srgb, var(--accent) 20%, transparent), transparent 34rem),
    linear-gradient(180deg, #07080b, var(--bg));
  min-height: 100vh;
}
a { color: inherit; }
/* Added 2026-08-18 (Brandon, direct: "a red Emulating XXXX bar at the
   top"). Deliberately not position:sticky -- .app-header below already
   owns that role (top:0, z-index:10); stacking two sticky bars at the
   same top would need a second z-index and a height offset for no real
   benefit, since the point of this bar is being unmistakable at the top
   of the page, not persistently visible while scrolled deep into a form. */
/* Install banner, 2026-08-22 (Trube, via Tally: iPhone users get no
   native install prompt, so give them a banner/button; hide once
   installed). Same non-sticky reasoning as .emulation-bar right below --
   this is about being seen once at the top, not persistently occupying
   space while scrolled into a form. [hidden] is toggled by
   install-banner.js entirely client-side (platform detection + the real
   beforeinstallprompt/appinstalled events can't be known server-side). */
.install-banner {
  display: flex;
  align-items: center;
  gap: .75rem;
  background: var(--accent);
  color: #000;
  text-align: left;
  padding: .6rem 1rem;
  font-weight: 600;
}
.install-banner .ttcp-install-banner-text { flex: 1; }
.install-banner button {
  border: none;
  border-radius: 999px;
  padding: .3rem .9rem;
  font-weight: 700;
  cursor: pointer;
}
.install-banner #ttcp-install-banner-btn { background: #000; color: #fff; }
.install-banner #ttcp-install-banner-dismiss { background: transparent; color: #000; font-size: 1.1rem; padding: 0 .4rem; }

.emulation-bar {
  background: var(--danger);
  color: #fff;
  text-align: center;
  padding: .6rem 1rem;
  font-weight: 700;
}
.emulation-bar a {
  color: #fff;
  text-decoration: underline;
  margin-left: .75rem;
  font-weight: 800;
}
/* Added 2026-08-19: collapsible shared-mailbox setup instructions on the
   Account page (Outlook desktop / Android / iOS). Collapsed by default so
   the mailbox links above stay the focus. */
/* Added 2026-08-20: mailboxes a user has permission to but cannot open yet
   (no Exchange licence / no mailbox of their own). Deliberately plain text,
   not buttons -- a link that always errors is worse than no link. */
.pending-mailboxes { list-style: none; padding: 0; margin: .35rem 0 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.pending-mailboxes li {
  border: 1px dashed var(--line);
  border-radius: 8px;
  padding: .35rem .7rem;
  color: var(--muted);
}
.mailbox-help { margin-top: 1.25rem; }
.mailbox-help details {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: .6rem .85rem;
  margin-bottom: .6rem;
}
.mailbox-help summary { cursor: pointer; font-weight: 700; }
.mailbox-help details[open] summary { margin-bottom: .5rem; }
.mailbox-help-body ol { margin: .4rem 0 .6rem 1.1rem; padding: 0; }
.mailbox-help-body li { margin-bottom: .35rem; }
.mailbox-help-body p { margin: .6rem 0 .2rem; }
.mailbox-help-body code {
  background: rgba(255, 255, 255, .08);
  padding: .1rem .35rem;
  border-radius: 4px;
  word-break: break-all;
}
.directory-emulate { display: inline-block; margin: 0; }
.btn.compact { padding: .3rem .7rem; font-size: .85rem; }
.app-header {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: .9rem clamp(1rem, 4vw, 3rem);
  background: rgba(9,10,13,.88);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(14px);
}
.brand {
  display: flex;
  align-items: center;
  gap: .85rem;
  text-decoration: none;
}
.brand img {
  width: 140px;
  max-height: 54px;
  object-fit: contain;
}
.brand span { display: flex; flex-direction: column; }
.brand small, .hero-user small, .card-copy small { color: var(--muted); }
.top-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: .35rem;
}
.top-nav a {
  text-decoration: none;
  color: var(--muted);
  border: 1px solid transparent;
  border-radius: 999px;
  padding: .55rem .8rem;
}
.top-nav a:hover { color: var(--text); border-color: var(--line); background: var(--panel); }
.app-main {
  width: min(1180px, calc(100% - 2rem));
  margin: 0 auto;
  padding: 2rem 0 4rem;
}
.hero {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 1.25rem;
  align-items: end;
  padding: clamp(1.4rem, 4vw, 2.5rem);
  border: 1px solid var(--line);
  border-radius: calc(var(--radius) + 8px);
  background: linear-gradient(135deg, rgba(255,255,255,.055), rgba(255,255,255,.02));
  box-shadow: var(--shadow);
}
.hero h1 {
  font-size: clamp(2rem, 6vw, 4.5rem);
  line-height: .95;
  margin: .2rem 0 .9rem;
  letter-spacing: -.06em;
}
.hero p { max-width: 55rem; color: var(--muted); font-size: 1.05rem; }
.eyebrow {
  margin: 0;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: .14em;
  font-weight: 800;
  font-size: .78rem;
}
.hero-user, .panel, .action-card, .login-panel {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--panel) 92%, transparent);
}
.hero-user { padding: 1rem; min-width: 220px; }
.hero-user strong, .hero-user small { display: block; }
h2 { margin: 2rem 0 .9rem; }
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}
.action-card {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1rem;
  min-height: 118px;
  padding: 1rem;
  text-decoration: none;
  transition: transform .14s ease, border-color .14s ease, background .14s ease;
}
.action-card:hover { transform: translateY(-2px); border-color: var(--accent); background: var(--panel-2); }
.card-icon {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 1rem;
  background: color-mix(in srgb, var(--accent) 16%, var(--panel));
  color: var(--accent);
  font-weight: 900;
  font-size: 1.3rem;
}
.action-card.primary .card-icon { background: var(--accent); color: white; }
.action-card.danger .card-icon { background: var(--danger); color: white; }
.card-copy strong { display: block; font-size: 1.08rem; margin-bottom: .25rem; }
.card-cta { color: var(--muted); font-weight: 700; }
.panel, .login-panel { padding: 1.25rem; }
.form-shell { max-width: 980px; margin: 0 auto; }
.form-heading { margin-bottom: 1rem; }
.form-heading h1, .login-panel h1 { margin: .25rem 0; font-size: clamp(2rem, 5vw, 3.5rem); letter-spacing: -.05em; }
.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}
label { display: grid; gap: .45rem; color: var(--muted); font-weight: 650; }
input, select, textarea {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--text);
  background: #101219;
  padding: .8rem .9rem;
  font: inherit;
}
textarea { resize: vertical; }
.wide { grid-column: 1 / -1; }
.check { display: flex; align-items: center; gap: .65rem; }
.check input { width: auto; }
.checkbox-panel {
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 1rem;
}
.checkbox-panel legend {
  color: var(--text);
  font-weight: 900;
  padding: 0 .35rem;
}
.checkbox-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: .65rem;
}
.check.option {
  align-items: flex-start;
  border: 1px solid color-mix(in srgb, var(--line) 75%, transparent);
  border-radius: 12px;
  padding: .7rem;
  background: #101219;
  color: var(--text);
}
.check.option.is-excluded {
  /* punch #143, 2026-09-07: the person being offboarded, greyed out in the
     delegate list the moment they're chosen at the top of the form. */
  opacity: .45;
  cursor: not-allowed;
  text-decoration: line-through;
}
.manual-delegate { margin-top: .85rem; }
.hint { color: var(--muted); margin: .15rem 0 .85rem; }
.form-actions { grid-column: 1 / -1; display: flex; justify-content: flex-end; gap: .75rem; margin-top: .75rem; }
.btn, button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: .75rem 1rem;
  color: var(--text);
  background: var(--panel-2);
  text-decoration: none;
  font-weight: 800;
  cursor: pointer;
}
.btn.primary, button.primary { background: var(--accent); border-color: var(--accent); color: white; }
.btn.danger, button.danger { background: var(--danger); border-color: var(--danger); color: white; }
.btn.secondary { background: transparent; }
/* Real incident, 2026-08-17 (Brandon, direct): an admin submitted the
   offboard form, saw the button pick up a colored focus ring while it was
   still processing (a normal browser default-focus outline, not an error),
   and clicked it three or four more times thinking it had failed, then
   backed out without it ever actually submitting. Two real causes fixed
   together: (1) no :focus-visible style was defined anywhere in this file,
   so buttons fell back to the browser's own default outline color, which
   on some browsers/OS accessibility settings renders reddish/orange --
   easy to mistake for .btn.danger below. Given this site's own accent
   color instead. (2) assets/js/form-submit.js now disables the button and
   relabels it "Submitting..." on click -- .is-submitting below is that
   pending state, deliberately styled nothing like .btn.danger so it can't
   be misread as an error. */
.btn:focus-visible, button:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}
.btn.is-submitting, button.is-submitting {
  cursor: wait;
  opacity: .75;
  background: var(--panel-2);
  border-color: var(--line);
  color: var(--muted);
}
.flash {
  margin: 0 0 1rem;
  padding: .9rem 1rem;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--panel);
}
.flash.success, .badge.ok { border-color: color-mix(in srgb, var(--ok) 55%, var(--line)); color: var(--ok); }
.badge.error { color: var(--danger); }
.flash.warning { border-color: color-mix(in srgb, var(--warn) 55%, var(--line)); color: var(--warn); }
.flash.error { border-color: color-mix(in srgb, var(--danger) 55%, var(--line)); color: var(--danger); }
.danger-box { border: 1px solid color-mix(in srgb, var(--danger) 50%, var(--line)); border-radius: 14px; padding: 1rem; color: var(--text); }
.signature-preview {
  /* Transparent, 2026-09-02 (Brandon direct: "the signature is adding a
     white box around the sig... make that invisible"). This wrapper is
     always empty on page load -- signature.js fills it entirely with the
     generated signature table, which carries its own explicit inline
     colors per-tenant (see signature.json), so nothing here ever needed
     the old white fill/dark text for contrast. Harmless either way for
     what gets copied to the clipboard (the "Copy signature" button copies
     this div's innerHTML, not the div itself, so this box never reached a
     real pasted signature) -- purely how it looked while editing here. */
  background: transparent;
  border-radius: 14px;
  padding: 1rem;
  overflow: auto;
}
.clean-list { margin: .5rem 0 1rem; }
/* Added 2026-08-17 for the Account page (Brandon, direct: "everything's
   being crammed into a small column when we can stretch it out across the
   page... plenty of room on a desktop"). Real dl/dt/dd stacks one field per
   full-width line by default -- this replaces that with a responsive grid
   of label+value pairs, several per row on desktop, collapsing to one
   column on narrow viewports via auto-fit (no separate mobile rule needed,
   but added to the existing breakpoint below for consistency with the
   site's other grids anyway). */
.profile-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1rem 1.5rem; margin: .5rem 0 1rem; }
.profile-field .field-label { display: block; color: var(--muted); font-size: .8rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; margin-bottom: .2rem; }
.profile-field .field-value { color: var(--text); font-weight: 650; word-break: break-word; }
.kb-article { margin-bottom: 1rem; }
.button-list { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: .75rem; }
.button-list.vertical { display: grid; }
.admin-table { display: grid; gap: .65rem; }
.admin-row { display: grid; grid-template-columns: 1fr 1.2fr 1.5fr auto; gap: .65rem; align-items: center; }
.admin-row-head { color: var(--muted); padding: 0 .1rem; }
/* Added 2026-08-18: Extra Accounts admin table needs 6 columns
   (Person/Service/Account/Notes/Added/Delete), the base .admin-row above
   is a fixed 4-column grid -- override just the column count here rather
   than genericizing .admin-row itself, which every other admin table
   still relies on staying 4-column. */
.admin-row-extra-accounts {
  grid-template-columns: 1.2fr 1fr 1fr 1.5fr 1fr auto;
  /* 2026-09-11 (Brandon, direct: "word wrap the notes column ... left
     justify ... I don't like stuff centered or wonky"). Two real causes,
     both from the base .admin-row rule: align-items: center there
     vertically centers every cell against the row's tallest cell -- fine
     when all cells are one line, but once Account/Notes wraps to two
     lines (a long URL, a longer identifier) the single-line cells next to
     it visibly float away from the top instead of lining up with the
     first line of text. start (not center) keeps every cell's first line
     level regardless of how tall its neighbors get. */
  align-items: start;
}
.admin-row-extra-accounts form { margin: 0; }
/* Added 2026-08-18 (Brandon, direct: "left align all the columns") --
   explicit per-cell override rather than relying on the default text
   alignment, since the Delete cell's <button> gets the browser's own
   centered-text default otherwise, which reads as inconsistent against
   the plainly-left-aligned text cells next to it. */
.admin-row-extra-accounts > * {
  text-align: left;
  /* 2026-09-11: the other real cause -- a long unbroken string (a URL in
     Notes, an identifier with no spaces) doesn't wrap at all by default;
     it overflows its 1fr/1.5fr column and either gets clipped or forces
     the column wider than its neighbors, which is what actually read as
     "wonky" here, not a text-align problem. anywhere (not the default
     normal) breaks mid-word/mid-URL when there's nowhere else to break --
     the only way a 60-character URL fits a narrow column at all. */
  overflow-wrap: anywhere;
}
/* 2026-09-11: the text-align: left above never actually moved the Delete
   button's label -- .btn/button is display: inline-flex with
   justify-content: center (see that rule below), and text-align has no
   effect on flex-item alignment along the main axis. justify-content is
   the property that actually controls it; text-align kept too since the
   button's own text still needs it if that display value ever changes. */
.admin-row-extra-accounts button { text-align: left; justify-content: flex-start; }
/* Added 2026-09-03: EOM reports admin table needs 3 columns
   (Label/File/Delete), same reasoning as .admin-row-extra-accounts above --
   override just the column count rather than touching the base 4-column
   .admin-row every other admin table still relies on. */
.admin-row-eom-reports { grid-template-columns: 1fr 2fr auto; }
.admin-row-eom-reports label { display: block; font-size: .85rem; margin-top: .25rem; }
/* Added 2026-09-11: "Not on M365" people table on the Extra Accounts admin
   page (Name/Notes/Added/Delete) -- same 4 columns as the base .admin-row,
   so no column-count override needed, just the same form/alignment
   normalization .admin-row-extra-accounts already applies above. */
/* 2026-09-11: same wrap/alignment fix as .admin-row-extra-accounts above,
   same reasoning (this table's own Notes column can run just as long). */
.admin-row-extra-people { align-items: start; }
.admin-row-extra-people form { margin: 0; }
.admin-row-extra-people > * { text-align: left; overflow-wrap: anywhere; }
.admin-row-extra-people button { text-align: left; justify-content: flex-start; }
.admin-split { display: grid; grid-template-columns: minmax(220px, 320px) 1fr; gap: 1rem; align-items: start; }
.admin-editor textarea { min-height: 18rem; font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; }
.check.compact { display: inline-flex; align-items: center; gap: .4rem; margin: 0; }
.signature-settings-preview { background: white; border-radius: 14px; padding: 1rem; }
.signature-settings-preview img { max-width: 260px; max-height: 96px; object-fit: contain; }
.kb-link-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.kb-link {
  display: block;
  min-height: 100%;
  text-decoration: none;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: color-mix(in srgb, var(--panel-2) 72%, transparent);
  padding: 1rem;
}
.kb-link:hover { border-color: var(--accent); background: var(--panel-2); }
.kb-link strong { display: block; color: var(--text); margin-bottom: .4rem; }
.kb-link small { display: block; color: var(--muted); line-height: 1.45; }
/* Added 2026-08-17 (Brandon, direct: sort links for the directory page). */
.directory-sort { margin: 0 0 1rem; color: var(--muted); font-weight: 650; }
.directory-sort a { color: var(--muted); text-decoration: none; margin-right: .5rem; }
.directory-sort a:hover { color: var(--text); }
.directory-sort a.active { color: var(--accent); }
.directory-sort a.directory-admin-only.active { color: var(--danger); }
/* Added 2026-09-11: Person/Service filter dropdowns above the Extra
   Accounts "On file" table -- reuses .directory-sort right above for the
   sort links themselves, this is just the filter row's own layout (the
   base `label { display: grid }` rule already styles each select). */
.admin-filter-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 1rem; margin: 0 0 1rem; }
.admin-filter-row label { flex: 0 1 220px; min-width: 160px; }
.admin-filter-row .btn { flex: 0 0 auto; }
.directory-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: .9rem;
}
.directory-card {
  display: grid;
  gap: .25rem;
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 1rem;
  background: #101219;
}
.directory-card small, .directory-card span { color: var(--muted); }
/* Added 2026-08-17 (Brandon, direct): admin-only fields (Last logged in /
   Last on portal) colored to visually stand apart from the rest of the
   card, since a regular employee never sees these at all -- an admin
   viewing their own team's directory should be able to tell at a glance
   which lines are the admin-only ones. */
.directory-card .directory-admin-only { color: var(--danger); }
/* Added 2026-08-20: manager line on each directory card. scroll-margin-top
   on the card keeps a jumped-to person clear of the sticky .app-header
   (top:0, z-index:10) instead of hiding under it. */
.directory-card { scroll-margin-top: 5rem; }
.directory-card .directory-manager { color: var(--muted); }
.directory-card .directory-manager a { color: var(--accent); text-decoration: underline; }
.directory-card:target {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
/* Contact List, added 2026-08-24 -- filter bar, disabled state, notes
   preview, per-contact meta line, edit icon, and the detail/share page.
   Reuses .directory-* wherever the shape is already the same (both
   Directory and Contacts rows render into the same .directory-grid). */
.directory-filter { margin: 0 0 1rem; color: var(--muted); font-weight: 650; }
.directory-filter a { color: var(--muted); text-decoration: none; margin-right: .5rem; }
.directory-filter a:hover { color: var(--text); }
.directory-filter a.active { color: var(--accent); }
.directory-card-disabled { opacity: .55; }
.disabled-badge {
  display: inline-block;
  padding: .1rem .5rem;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--danger) 55%, var(--line));
  color: var(--danger);
  font-size: .75rem;
  font-weight: 700;
  width: fit-content;
}
/* Subtle name-color distinction for Contacts vs Directory, added
   2026-08-24 (Trube, direct: "something subtle"). A gentle accent tint on
   an otherwise-identical card, not a loud color swap. */
.directory-card strong.contact-name { color: color-mix(in srgb, var(--accent) 55%, var(--text)); }
.directory-notes-preview { font-style: italic; }
.directory-card .contact-meta { font-style: italic; }
.contact-edit-icon { text-decoration: none; }
.contact-detail p { margin: .35rem 0; }
.contact-detail .disabled-badge { margin-bottom: .5rem; }
.contact-share { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.contact-share input[readonly] { background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 8px; padding: .4rem .6rem; }
.break-glass, .config-warning { margin-top: 1rem; color: var(--muted); }
.app-footer {
  display: flex;
  justify-content: center;
  gap: 1rem;
  color: var(--muted);
  border-top: 1px solid var(--line);
  padding: 1.5rem;
}
pre { white-space: pre-wrap; overflow: auto; }
/* Email Templates preview panel, added 2026-08-15. Real bug fixed same day:
   first version hardcoded a light background (#fff / a light fallback for
   the undefined --surface-alt) with no matching text color, so it inherited
   this site's real (light/near-white) --text against a light background --
   invisible. Uses the site's actual dark-theme tokens now, same pattern as
   .kb-link's nested-panel-on-panel elsewhere in this file. */
.email-preview { background: var(--panel); border: 1px dashed var(--line); color: var(--text); }
.email-preview-headers { display: grid; grid-template-columns: max-content 1fr; gap: .25rem 1rem; margin: 0 0 1rem; }
.email-preview-headers dt { font-weight: 600; color: var(--muted); }
.email-preview-headers dd { margin: 0; color: var(--text); }
.email-preview-body { background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; padding: 1rem; font-family: inherit; font-size: 0.95rem; color: var(--text); }
@media (max-width: 820px) {
  .app-header { align-items: flex-start; flex-direction: column; }
  .top-nav { justify-content: flex-start; }
  .hero { grid-template-columns: 1fr; }
  .card-grid, .form-grid, .directory-grid, .admin-split, .admin-row, .admin-row-extra-accounts, .profile-fields { grid-template-columns: 1fr; }
  .brand img { width: 110px; }
  .form-actions { flex-direction: column-reverse; }
  .btn, button { width: 100%; }
}

/* Essential Service mode (punch #997): paused cards stay visible, dimmed, no hover lift. The "Paused" label and the note
   carry the meaning so it never relies on color alone; text stays at full contrast. */
.action-card.paused { opacity: .72; border-style: dashed; cursor: not-allowed; }
.action-card.paused:hover { transform: none; border-color: var(--line); background: inherit; }
.action-card.paused .card-icon { background: var(--panel-2); color: var(--muted); }
.paused-note { display: block; margin-top: .35rem; font-weight: 700; color: var(--text); }
