/* ==========================================================================
   Tech Dynamix Client Hub, brand system.

   The single stylesheet for the whole hub. No page defines its own styles and
   no element carries a style attribute.

   Color rules that are not negotiable:
   1. Red and green are never paired to carry meaning. Status uses teal,
      orange, red and slate instead.
   2. Color never carries meaning alone. Every status has a text label next
      to it, so the page still reads correctly in grayscale.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens, light
   -------------------------------------------------------------------------- */

:root {
  /* Brand palette, fixed values. Do not reference these directly in rules
     below, use the semantic tokens so dark mode stays a single swap. */
  --td-orange:      #E87722;
  --td-outerspace:  #4A4947;
  --td-violet:      #7566A0;
  --td-teal:        #1E7A8C;
  --td-ink:         #1E2024;
  --td-slate:       #5E6670;
  --td-mist:        #D9DCE1;
  --td-cloud:       #F6F7F8;
  --td-charcoal:    #17191C;
  --td-red:         #E5484D;

  /* Semantic surfaces */
  --bg-page:        var(--td-cloud);
  --bg-panel:       #FFFFFF;
  --bg-input:       #FFFFFF;
  --bg-raised:      var(--td-cloud);
  --bg-rail:        #FFFFFF;

  /* Semantic text */
  --text:           var(--td-ink);
  --text-secondary: var(--td-slate);
  --text-on-rail:   var(--td-ink);
  --text-rail-dim:  var(--td-slate);
  --rail-line:      var(--td-mist);
  --rail-hover:     rgba(30, 32, 36, .055);
  --rail-active-bg: rgba(232, 119, 34, .13);
  --rail-active-text: var(--td-ink);

  /* Lines */
  --border:         var(--td-mist);
  --border-strong:  #BFC4CC;

  /* Accent. Dark ink on orange in both themes. Orange with white text sits
     near 2.6:1 contrast, which fails, so the button ink stays dark. */
  --accent:         var(--td-orange);
  --accent-hover:   #D06A1C;
  --accent-ink:     #2A1B0C;

  --secondary:      var(--td-violet);

  /* Status. Teal, orange, red and slate only. No green anywhere. */
  --status-ok:        var(--td-teal);
  --status-attention: var(--td-orange);
  --status-alert:     var(--td-red);
  --status-neutral:   var(--td-slate);
  --status-ok-bg:        #E4F1F4;
  --status-attention-bg: #FCEEE2;
  --status-alert-bg:     #FBE7E8;
  --status-neutral-bg:   #ECEEF1;

  --focus-ring:     var(--td-violet);
  --shadow-panel:   0 1px 2px rgba(30, 32, 36, .06), 0 1px 3px rgba(30, 32, 36, .04);

  /* Type stacks. Google Fonts first, then a real fallback chain. */
  --font-heading: "Bricolage Grotesque", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-body:    "IBM Plex Sans", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-data:    "Inter", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-mono:    "IBM Plex Mono", "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;

  --radius:       6px;
  --radius-lg:    10px;
  --gap:          16px;
  --rail-width:   232px;
}

/* --------------------------------------------------------------------------
   2. Tokens, dark

   Applied when the operating system asks for dark and the user has not
   explicitly chosen light, or when the toggle has set data-theme="dark".
   -------------------------------------------------------------------------- */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg-page:        #131519;
    --bg-panel:       #1E2024;
    --bg-input:       #2A2E34;
    --bg-raised:      #2A2E34;
    --bg-rail:        #0E1013;

    --text:           #F6F7F8;
    --text-secondary: #9AA2AD;
    --text-on-rail:   #F6F7F8;
    --text-rail-dim:  #9AA2AD;
    --rail-line:      rgba(255, 255, 255, .08);
    --rail-hover:     rgba(255, 255, 255, .07);
    --rail-active-bg: rgba(232, 119, 34, .16);
    --rail-active-text: #FFFFFF;

    --border:         #3A3F47;
    --border-strong:  #4E545D;

    --accent-hover:   #F08A3C;
    --secondary:      #A396CF;

    --status-ok:        #5CC3D8;
    --status-attention: #E87722;
    --status-alert:     #E5484D;
    --status-neutral:   #9AA2AD;
    --status-ok-bg:        #17323A;
    --status-attention-bg: #3A2A18;
    --status-alert-bg:     #3A1F21;
    --status-neutral-bg:   #2A2E34;

    --focus-ring:     #A396CF;
    --shadow-panel:   0 1px 2px rgba(0, 0, 0, .35);
  }
}

:root[data-theme="dark"] {
  --bg-page:        #131519;
  --bg-panel:       #1E2024;
  --bg-input:       #2A2E34;
  --bg-raised:      #2A2E34;
  --bg-rail:        #0E1013;

  --text:           #F6F7F8;
  --text-secondary: #9AA2AD;
  --text-on-rail:   #F6F7F8;
  --text-rail-dim:  #9AA2AD;
  --rail-line:      rgba(255, 255, 255, .08);
  --rail-hover:     rgba(255, 255, 255, .07);
  --rail-active-bg: rgba(232, 119, 34, .16);
  --rail-active-text: #FFFFFF;

  --border:         #3A3F47;
  --border-strong:  #4E545D;

  --accent-hover:   #F08A3C;
  --secondary:      #A396CF;

  --status-ok:        #5CC3D8;
  --status-attention: #E87722;
  --status-alert:     #E5484D;
  --status-neutral:   #9AA2AD;
  --status-ok-bg:        #17323A;
  --status-attention-bg: #3A2A18;
  --status-alert-bg:     #3A1F21;
  --status-neutral-bg:   #2A2E34;

  --focus-ring:     #A396CF;
  --shadow-panel:   0 1px 2px rgba(0, 0, 0, .35);
}

/* --------------------------------------------------------------------------
   3. Reset and base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { color-scheme: light dark; }
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }

body {
  margin: 0;
  background: var(--bg-page);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: 600;
  line-height: 1.2;
  margin: 0 0 .5em;
  letter-spacing: -.01em;
}

h1 { font-size: 1.6rem; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.05rem; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--secondary); text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--accent); }

code, pre, .mono { font-family: var(--font-mono); font-size: .875em; }

pre {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  overflow-x: auto;
}

/* Numbers, dates, IDs and any tabular data render in Inter with lining
   tabular figures so columns align. */
.num, .data, td.num, th.num, time, .id {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums lining-nums;
}

.money { font-family: var(--font-data); font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

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

/* --------------------------------------------------------------------------
   4. Application shell
   -------------------------------------------------------------------------- */

.shell { display: flex; min-height: 100vh; }

.rail {
  width: var(--rail-width);
  flex: 0 0 var(--rail-width);
  background: var(--bg-rail);
  color: var(--text-on-rail);
  border-right: 1px solid var(--rail-line);
  display: flex;
  flex-direction: column;
}

.rail-brand { padding: 20px 18px 16px; border-bottom: 1px solid var(--rail-line); }
.rail-brand img { width: 170px; max-width: 100%; height: auto; }
.rail-brand .wordmark {
  font-family: var(--font-heading);
  font-size: 1.05rem; font-weight: 700; color: var(--text-on-rail);
  text-decoration: none; letter-spacing: -.01em;
}
.rail-brand .wordmark .accent { color: var(--accent); }
.rail-scope { display: block; font-size: .75rem; color: var(--text-rail-dim); margin-top: 2px; }

.rail-nav { padding: 12px 10px; flex: 1; }
.rail-nav-group { margin-bottom: 18px; }
.rail-nav-label {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-rail-dim); padding: 0 8px; margin-bottom: 6px; display: block;
}
.rail-nav a {
  display: block; padding: 7px 8px; border-radius: var(--radius);
  color: var(--text-on-rail); text-decoration: none; font-size: .9rem;
}
.rail-nav a:hover { background: var(--rail-hover); color: var(--text-on-rail); }
.rail-nav a[aria-current="page"] {
  background: var(--rail-active-bg);
  color: var(--rail-active-text);
  box-shadow: inset 2px 0 0 var(--accent);
}

.rail-foot { padding: 12px 14px; border-top: 1px solid var(--rail-line); font-size: .78rem; color: var(--text-rail-dim); }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar {
  display: flex; align-items: center; gap: var(--gap);
  padding: 12px 24px;
  background: var(--bg-panel);
  border-bottom: 1px solid var(--border);
}
.topbar h1 { margin: 0; font-size: 1.15rem; }
.topbar-spacer { flex: 1; }
.topbar-user { font-size: .85rem; color: var(--text-secondary); }

.content { padding: 24px; flex: 1; }
.content-narrow { max-width: 760px; }

.page-foot {
  padding: 16px 24px;
  border-top: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: .78rem;
}

/* --------------------------------------------------------------------------
   5. Panels, tables, forms
   -------------------------------------------------------------------------- */

.panel {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-panel);
  margin-bottom: var(--gap);
}
.panel-head {
  padding: 14px 18px; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: var(--gap);
}
.panel-head h2 { margin: 0; }
.panel-head .topbar-spacer { flex: 1; }
.panel-body { padding: 18px; }
.panel-body > :last-child { margin-bottom: 0; }

.grid { display: grid; gap: var(--gap); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

.table-wrap { overflow-x: auto; }
table.data-table { width: 100%; border-collapse: collapse; font-size: .9rem; }
table.data-table th, table.data-table td {
  text-align: left; padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
table.data-table th {
  font-family: var(--font-body); font-weight: 600; font-size: .75rem;
  text-transform: uppercase; letter-spacing: .05em; color: var(--text-secondary);
  background: var(--bg-raised); white-space: nowrap;
}
table.data-table tbody tr:last-child td { border-bottom: 0; }
table.data-table tbody tr:hover { background: var(--bg-raised); }
table.data-table td.right, table.data-table th.right { text-align: right; }
.table-empty { padding: 28px 18px; text-align: center; color: var(--text-secondary); }

.field { margin-bottom: 14px; }
.field label, .field-label {
  display: block; font-size: .82rem; font-weight: 600;
  margin-bottom: 4px; color: var(--text);
}
.field .hint { display: block; font-size: .76rem; color: var(--text-secondary); margin-top: 4px; }
.field .req { color: var(--status-alert); }
.field-error { color: var(--status-alert); font-weight: 600; }
.field-filters { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; }
.field-filters .field { margin-bottom: 0; }
.field-inline { min-width: 180px; }

input[type="text"], input[type="email"], input[type="url"], input[type="tel"],
input[type="number"], input[type="date"], input[type="password"], input[type="search"],
select, textarea {
  width: 100%; padding: 8px 10px;
  background: var(--bg-input); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  font-family: var(--font-body); font-size: .9rem;
}
input[type="number"], input[type="date"] { font-family: var(--font-data); font-variant-numeric: tabular-nums; }
textarea { min-height: 90px; resize: vertical; }
input:disabled, select:disabled, textarea:disabled {
  background: var(--bg-raised); color: var(--text-secondary); cursor: not-allowed;
}
input[type="file"] { font-size: .85rem; color: var(--text-secondary); }

.field-row { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }

.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: var(--radius);
  font-family: var(--font-body); font-size: .88rem; font-weight: 600;
  border: 1px solid transparent; cursor: pointer; text-decoration: none;
  background: var(--bg-panel); color: var(--text); border-color: var(--border-strong);
}
.btn:hover { border-color: var(--text-secondary); color: var(--text); }
.btn-primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-ink); }
.btn-danger { background: var(--status-alert); color: #FFFFFF; border-color: var(--status-alert); }
.btn-danger:hover { background: #C93B40; border-color: #C93B40; color: #FFFFFF; }
.btn-quiet { background: transparent; border-color: transparent; color: var(--secondary); }
.btn-quiet:hover { background: var(--bg-raised); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }
.btn-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.btn-small { padding: 4px 9px; font-size: .78rem; }

/* Row level controls, so a role change or a removal is one click from the
   table rather than a separate page. */
.inline-form { display: inline-flex; gap: 6px; align-items: center; margin: 0; }
.inline-select { width: auto; min-width: 110px; padding: 4px 8px; font-size: .82rem; }

/* Inputs sitting inside a table cell, so a line item is edited where it is
   read rather than on a separate page. */
table.data-table td input[type="text"],
table.data-table td input[type="number"] { padding: 5px 8px; font-size: .85rem; min-width: 90px; }
.cell-num { max-width: 110px; text-align: right; }
.cell-short { max-width: 130px; }
table.data-table tfoot th {
  background: var(--bg-raised); font-size: .8rem; text-transform: none;
  letter-spacing: 0; color: var(--text); border-top: 1px solid var(--border);
}
.role-key { margin-top: 18px; font-size: .82rem; }
.role-key dt { font-weight: 600; color: var(--text); }

/* --------------------------------------------------------------------------
   6. Status

   Every badge prints a word. The dot is decorative reinforcement, never the
   only signal, so the meaning survives grayscale and color blindness.
   -------------------------------------------------------------------------- */

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 9px 2px 7px; border-radius: 999px;
  font-size: .74rem; font-weight: 600; letter-spacing: .01em;
  border: 1px solid transparent; white-space: nowrap;
}
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }

.badge-ok        { color: var(--status-ok);        background: var(--status-ok-bg);        border-color: var(--status-ok); }
.badge-attention { color: var(--status-attention); background: var(--status-attention-bg); border-color: var(--status-attention); }
.badge-alert     { color: var(--status-alert);     background: var(--status-alert-bg);     border-color: var(--status-alert); }
.badge-neutral   { color: var(--status-neutral);   background: var(--status-neutral-bg);   border-color: var(--status-neutral); }

.notice {
  border: 1px solid var(--border); border-left-width: 3px;
  border-radius: var(--radius); padding: 12px 14px; margin-bottom: var(--gap);
  background: var(--bg-panel);
}
.notice-title { font-weight: 600; margin: 0 0 2px; font-size: .88rem; }
.notice p { font-size: .88rem; margin: 0; }
.notice-ok        { border-left-color: var(--status-ok);        background: var(--status-ok-bg); }
.notice-attention { border-left-color: var(--status-attention); background: var(--status-attention-bg); }
.notice-alert     { border-left-color: var(--status-alert);     background: var(--status-alert-bg); }
.notice-neutral   { border-left-color: var(--status-neutral);   background: var(--status-neutral-bg); }

.stat { padding: 16px 18px; }
.stat-label { font-size: .74rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-secondary); margin-bottom: 4px; }
.stat-value { font-family: var(--font-data); font-variant-numeric: tabular-nums lining-nums; font-size: 1.7rem; font-weight: 600; line-height: 1.1; }
.stat-note { font-size: .78rem; color: var(--text-secondary); margin-top: 4px; }

dl.kv { display: grid; grid-template-columns: minmax(140px, auto) 1fr; gap: 6px 18px; margin: 0; font-size: .9rem; }
dl.kv dt { color: var(--text-secondary); font-size: .82rem; padding-top: 1px; }
dl.kv dd { margin: 0; }
.muted { color: var(--text-secondary); }

/* --------------------------------------------------------------------------
   6b. Logo variants

   Two files, one drawn for light backgrounds and one for dark. Both are
   rendered and CSS shows the correct one, so the swap follows the theme
   toggle as well as the operating system preference. A picture element with
   a prefers-color-scheme source would only follow the operating system.

   The nav rail follows the theme, so its logo uses the same swap.
   -------------------------------------------------------------------------- */

.logo-on-light { display: block; }
.logo-on-dark  { display: none; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .logo-on-light { display: none; }
  :root:not([data-theme="light"]) .logo-on-dark  { display: block; }
}

:root[data-theme="dark"] .logo-on-light { display: none; }
:root[data-theme="dark"] .logo-on-dark  { display: block; }

/* Sizing only. Never set display on a logo image outside the swap rules
   above: a descendant selector such as ".signin-brand img" outranks a
   single class and would show both variants at once. */
.logo-stacked { width: 240px; max-width: 100%; height: auto; margin: 0 auto; }
.logo-inline  { width: 200px; max-width: 100%; height: auto; }

/* --------------------------------------------------------------------------
   7. Theme toggle
   -------------------------------------------------------------------------- */

.theme-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  background: transparent; border: 1px solid var(--border-strong);
  border-radius: var(--radius); padding: 5px 10px;
  color: var(--text-secondary); cursor: pointer;
  font-family: var(--font-body); font-size: .78rem;
}
.theme-toggle:hover { color: var(--text); border-color: var(--text-secondary); }

/* --------------------------------------------------------------------------
   8. Sign in

   Centered card: logo, heading, then one full width button per sign in
   method. Phase 1 has a single method, so the divider and the second button
   below it are styled but unused until the magic link arrives in Phase 2.
   -------------------------------------------------------------------------- */

.signin { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.signin-card { width: 100%; max-width: 420px; }
.signin-card .panel-body { padding: 30px 28px; }

.signin-brand { text-align: center; margin-bottom: 22px; }
.signin-brand .wordmark {
  font-family: var(--font-heading); font-size: 1.4rem; font-weight: 700;
  color: var(--text); text-decoration: none;
}
.signin-brand .wordmark .accent { color: var(--accent); }

.signin-title {
  font-family: var(--font-heading);
  font-size: 1.55rem; font-weight: 700; line-height: 1.2;
  text-align: center; margin: 0 0 22px; letter-spacing: -.02em;
}

.signin-methods { display: flex; flex-direction: column; gap: 10px; }

/* Provider button. Neutral surface with a border rather than the orange
   primary, because Microsoft's brand rules require their mark to sit on a
   white or black button. It is also what the pattern reads as: a choice of
   provider, not the page's primary action. */
.btn-provider {
  width: 100%;
  display: flex; align-items: center; gap: 12px;
  padding: 11px 14px;
  background: var(--bg-panel); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  font-family: var(--font-body); font-size: .92rem; font-weight: 600;
  text-decoration: none; cursor: pointer;
}
.btn-provider:hover { background: var(--bg-raised); border-color: var(--text-secondary); color: var(--text); }
.provider-icon { width: 20px; height: 20px; flex: none; }
.provider-label { flex: 1; text-align: center; }

/* Balances the icon so the label sits centered in the button rather than
   pushed right by it. */
.provider-spacer { width: 20px; flex: none; }

/* A method that exists but is not switched on yet. The button is inert, the
   mark is desaturated, and a text label says why, so the state never rests on
   the greying alone. */
.btn-provider:disabled,
.btn-provider[aria-disabled="true"] {
  opacity: .6;
  cursor: not-allowed;
  background: var(--bg-raised);
  border-style: dashed;
}
.btn-provider:disabled:hover,
.btn-provider[aria-disabled="true"]:hover {
  background: var(--bg-raised);
  border-color: var(--border-strong);
}
.btn-provider:disabled .provider-icon,
.btn-provider[aria-disabled="true"] .provider-icon { filter: grayscale(1); }

.provider-note {
  flex: none; font-size: .7rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-secondary);
}

.signin-divider {
  display: flex; align-items: center; gap: 12px;
  margin: 18px 0; color: var(--text-secondary); font-size: .8rem;
}
.signin-divider::before, .signin-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--border);
}

.signin-form { margin-top: 4px; }
.totp-input {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums lining-nums;
  font-size: 1.5rem; letter-spacing: .35em; text-align: center;
}
.signin-form .field { margin-bottom: 12px; }
.signin-submit { width: 100%; justify-content: center; gap: 10px; }
.signin-submit .provider-label { flex: 0 1 auto; }
.signin-submit:disabled .provider-note { color: var(--accent-ink); opacity: .75; }

.signin-help { text-align: center; font-size: .82rem; color: var(--text-secondary); margin: 18px 0 0; }
.signin-foot { text-align: center; font-size: .76rem; margin-top: 16px; }

/* --------------------------------------------------------------------------
   9. Narrow screens
   -------------------------------------------------------------------------- */

@media (max-width: 860px) {
  .shell { flex-direction: column; }
  .rail { width: 100%; flex: none; }
  .rail-nav { display: flex; flex-wrap: wrap; gap: 4px; }
  .rail-nav-group { margin-bottom: 0; }
  .rail-nav-label { display: none; }
  .content, .topbar { padding-left: 16px; padding-right: 16px; }
}

@media print {
  .rail, .theme-toggle, .btn { display: none; }
  body { background: #FFFFFF; color: #000000; }
}
