/* DarkSpark components: panels, tables, chips, buttons, rails, provenance. */

/* ---------------------------------------------------------------- panel */

.panel {
  background: var(--ds-surface);
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-radius-lg);
  overflow: hidden;
}
.panel__head {
  display: flex;
  align-items: center;
  gap: var(--ds-gap);
  padding: 10px var(--ds-pad);
  background: linear-gradient(180deg, var(--ds-surface-2), var(--ds-surface));
  border-bottom: 1px solid var(--ds-line);
}
.panel__title {
  font-size: var(--ds-fs-md);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.panel__title small {
  color: var(--ds-text-faint);
  font-weight: 400;
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
  margin-left: 8px;
}
.panel__actions {
  margin-left: auto;
  display: flex;
  gap: 6px;
}
.panel__body {
  padding: var(--ds-pad);
}
.panel__body--flush {
  padding: 0;
}

.grid {
  display: grid;
  gap: var(--ds-gap);
}
.grid--2 {
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
}
.grid--3 {
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.grid--4 {
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}

/* ---------------------------------------------------------------- stat */

.stat {
  background: var(--ds-surface);
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-radius-lg);
  padding: 13px var(--ds-pad);
  position: relative;
  overflow: hidden;
}
.stat::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 2px;
  background: var(--stat-accent, var(--ds-accent));
  box-shadow: 0 0 12px var(--stat-accent, var(--ds-accent));
}
.stat__label {
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ds-text-faint);
}
.stat__value {
  font-size: var(--ds-fs-3xl);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
  margin-top: 4px;
  letter-spacing: -0.02em;
}
.stat__value small {
  font-size: var(--ds-fs-lg);
  color: var(--ds-text-faint);
  font-weight: 400;
}
.stat__foot {
  margin-top: 5px;
  font-size: var(--ds-fs-sm);
  color: var(--ds-text-dim);
}

/* ---------------------------------------------------------------- chips */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 7px;
  border-radius: 3px;
  border: 1px solid var(--chip-c, var(--ds-line-bright));
  background: color-mix(in srgb, var(--chip-c, var(--ds-line-bright)) 12%, transparent);
  color: var(--chip-c, var(--ds-text-dim));
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
  letter-spacing: 0.05em;
  white-space: nowrap;
  text-transform: uppercase;
}
.chip--ok {
  --chip-c: var(--ds-ok);
}
.chip--warn {
  --chip-c: var(--ds-warn);
}
.chip--err {
  --chip-c: var(--ds-err);
}
.chip--info {
  --chip-c: var(--ds-cyan);
}
.chip--violet {
  --chip-c: var(--ds-violet);
}
.chip--magenta {
  --chip-c: var(--ds-magenta);
}
.chip--mute {
  --chip-c: var(--ds-text-ghost);
}

.dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--dot-c, var(--ds-text-ghost));
  box-shadow: 0 0 6px var(--dot-c, transparent);
  flex: 0 0 auto;
}
.dot--ok {
  --dot-c: var(--ds-ok);
}
.dot--warn {
  --dot-c: var(--ds-warn);
}
.dot--err {
  --dot-c: var(--ds-err);
}
.dot--idle {
  --dot-c: var(--ds-text-ghost);
  box-shadow: none;
}
.dot--pulse {
  animation: ds-pulse 1.6s ease-in-out infinite;
}
@keyframes ds-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}

/* ---------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: var(--ds-radius);
  border: 1px solid var(--ds-line-bright);
  background: var(--ds-surface-2);
  color: var(--ds-text-dim);
  font-family: inherit;
  font-size: var(--ds-fs-sm);
  cursor: pointer;
  transition: all var(--ds-t-fast) var(--ds-ease);
  white-space: nowrap;
}
.btn:hover {
  color: var(--ds-text);
  border-color: var(--ds-line-hot);
  background: var(--ds-surface-3);
}
.btn svg {
  width: 13px;
  height: 13px;
}
.btn--primary {
  border-color: var(--ds-accent-dim);
  background: var(--ds-accent-wash);
  color: var(--ds-accent);
}
.btn--primary:hover {
  background: color-mix(in srgb, var(--ds-accent) 18%, transparent);
  border-color: var(--ds-accent);
  color: var(--ds-text);
  box-shadow: var(--ds-glow-sm);
}
.btn--danger {
  border-color: color-mix(in srgb, var(--ds-red) 45%, transparent);
  color: var(--ds-red);
  background: color-mix(in srgb, var(--ds-red) 8%, transparent);
}
.btn--ghost {
  background: transparent;
  border-color: transparent;
}
.btn--ghost:hover {
  border-color: var(--ds-line-bright);
}
.btn--sm {
  padding: 3px 8px;
  font-size: var(--ds-fs-xs);
}

/* ---------------------------------------------------------------- table */

.tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--ds-fs-md);
}
.tbl th {
  text-align: left;
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ds-text-faint);
  font-weight: 500;
  padding: 7px var(--ds-pad);
  border-bottom: 1px solid var(--ds-line);
  background: var(--ds-surface-2);
  position: sticky;
  top: 0;
  z-index: 2;
}
.tbl td {
  padding: 0 var(--ds-pad);
  height: var(--ds-row-h);
  border-bottom: 1px solid color-mix(in srgb, var(--ds-line) 55%, transparent);
  color: var(--ds-text-dim);
  vertical-align: middle;
}
.tbl tbody tr {
  transition: background var(--ds-t-fast) var(--ds-ease);
  cursor: default;
}
.tbl tbody tr:hover {
  background: var(--ds-surface-2);
}
.tbl tbody tr:hover td {
  color: var(--ds-text);
}
.tbl--click tbody tr {
  cursor: pointer;
}
.tbl .num {
  font-family: var(--ds-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.tbl .mono {
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-sm);
}
.tbl .strong {
  color: var(--ds-text);
  font-weight: 500;
}

/* ---------------------------------------------------------------- meter */

.meter {
  height: 4px;
  border-radius: 2px;
  background: var(--ds-surface-3);
  overflow: hidden;
  position: relative;
}
.meter__fill {
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--meter-c, var(--ds-accent)), color-mix(in srgb, var(--meter-c, var(--ds-accent)) 55%, transparent));
  box-shadow: 0 0 8px var(--meter-c, var(--ds-accent));
  transition: width var(--ds-t-slow) var(--ds-ease);
}
.meter--ok {
  --meter-c: var(--ds-ok);
}
.meter--warn {
  --meter-c: var(--ds-warn);
}
.meter--err {
  --meter-c: var(--ds-err);
}

/* --------------------------------------------------- provenance (Prism) */

/* The signature interaction: every value says which API produced it. */
.prov {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}
.prov__val {
  color: var(--ds-text);
}
.prov__src {
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 1px 5px;
  border-radius: 3px;
  border: 1px solid var(--src-c);
  color: var(--src-c);
  background: color-mix(in srgb, var(--src-c) 10%, transparent);
  cursor: help;
}
.prov__src[data-src='graph'] {
  --src-c: var(--ds-cyan);
}
.prov__src[data-src='ews'] {
  --src-c: var(--ds-violet);
}
.prov__src[data-src='exops'] {
  --src-c: var(--ds-acid);
}
.prov__src[data-src='csom'] {
  --src-c: var(--ds-magenta);
}
.prov__src[data-src='pnp'] {
  --src-c: var(--ds-amber);
}
.prov__src[data-src='sprest'] {
  --src-c: var(--ds-blue);
}
.prov--conflict .prov__val {
  color: var(--ds-conflict);
  text-decoration: underline dotted var(--ds-conflict);
  text-underline-offset: 3px;
}

/* ---------------------------------------------------------------- misc */

.kv {
  display: grid;
  grid-template-columns: minmax(140px, max-content) 1fr;
  gap: 5px var(--ds-pad);
  font-size: var(--ds-fs-md);
}
.kv dt {
  color: var(--ds-text-faint);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-sm);
}
.kv dd {
  margin: 0;
  color: var(--ds-text);
}

.code {
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-sm);
  background: var(--ds-void);
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-radius);
  padding: 10px 12px;
  overflow: auto;
  color: var(--ds-text-dim);
  white-space: pre;
  line-height: 1.55;
}
.code b {
  color: var(--ds-accent);
  font-weight: 500;
}
.code .c-key {
  color: var(--ds-violet);
}
.code .c-str {
  color: var(--ds-acid);
}
.code .c-num {
  color: var(--ds-amber);
}

.banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px var(--ds-pad);
  border-radius: var(--ds-radius);
  border: 1px solid var(--bn-c, var(--ds-line-bright));
  background: color-mix(in srgb, var(--bn-c, var(--ds-line-bright)) 9%, transparent);
  font-size: var(--ds-fs-md);
  color: var(--ds-text-dim);
}
.banner--demo {
  --bn-c: var(--ds-magenta);
}
.banner--warn {
  --bn-c: var(--ds-amber);
}
/* Used in seven places across mail.js and profiles.js and defined in none of them,
   so every error banner in the product has been rendering in the neutral line colour
   - the one state that most needed to look different looked like all the others. */
.banner--err {
  --bn-c: var(--ds-err);
}
.banner--ok {
  --bn-c: var(--ds-ok);
}
.banner b {
  color: var(--bn-c);
}

.empty {
  padding: 46px 20px;
  text-align: center;
  color: var(--ds-text-faint);
}
.empty__title {
  color: var(--ds-text-dim);
  font-size: var(--ds-fs-lg);
  margin-bottom: 6px;
}

.split {
  display: grid;
  height: 100%;
  min-height: 0;
}
.scroll-y {
  overflow-y: auto;
  min-height: 0;
}
.muted {
  color: var(--ds-text-faint);
}
.mono {
  font-family: var(--ds-mono);
}
.nowrap {
  white-space: nowrap;
}
.row {
  display: flex;
  align-items: center;
  gap: var(--ds-gap);
}
.row--wrap {
  flex-wrap: wrap;
}
.ml-auto {
  margin-left: auto;
}

/* Per-provider accent, so a source chip and its coverage tile agree on colour. */
:root {
  --src-graph: var(--ds-cyan);
  --src-ews: var(--ds-violet);
  --src-exops: var(--ds-acid);
  --src-exostats: #4ade80;
  --src-casmailbox: #22d3ee;
  --src-csom: var(--ds-magenta);
  --src-pnp: var(--ds-amber);
  --src-sprest: var(--ds-blue);
}

.prov__src[data-src='exostats'] { --src-c: var(--src-exostats); }
.prov__src[data-src='casmailbox'] { --src-c: var(--src-casmailbox); }

/* Readiness matrix */
.ready {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--rc, var(--ds-text-faint));
}
.ready::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--rc, var(--ds-text-ghost));
  box-shadow: 0 0 6px var(--rc, transparent);
}
.ready--satisfied { --rc: var(--ds-ok); }
.ready--partial   { --rc: var(--ds-amber); }
.ready--missing   { --rc: var(--ds-red); }
.ready--unknown   { --rc: var(--ds-text-ghost); }
.ready--unknown::before { box-shadow: none; }

/* ---------------------------------------------------------------- forms
   Added for the tenant-profile form. Deliberately in the ui-kit rather than the
   web app's own stylesheet: Portable renders the identical form from the same
   markup, and a second copy of these rules is how the two silently diverge. */

.field {
  margin-bottom: 10px;
}
.field > label {
  display: block;
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ds-text-dim);
  margin-bottom: 4px;
}
.field__hint {
  font-size: var(--ds-fs-xs);
  color: var(--ds-text-faint);
  margin-top: 4px;
  line-height: 1.45;
}
.field--error > label {
  color: var(--ds-red);
}

input[type='text'],
input[type='password'],
input:not([type]),
select,
textarea {
  width: 100%;
  padding: 6px 9px;
  background: var(--ds-void);
  border: 1px solid var(--ds-line);
  border-radius: var(--ds-radius);
  color: var(--ds-text);
  font-family: var(--ds-font);
  font-size: var(--ds-fs-md);
  transition: border-color var(--ds-t-fast) var(--ds-ease), box-shadow var(--ds-t-fast) var(--ds-ease);
}
input.mono,
textarea.mono,
select.mono {
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-sm);
}
textarea {
  resize: vertical;
  line-height: 1.5;
}
input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--ds-accent-dim);
  box-shadow: var(--ds-glow-sm);
}
input::placeholder,
textarea::placeholder {
  color: var(--ds-text-ghost);
}
input:disabled,
select:disabled,
textarea:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.field--error input,
.field--error textarea,
.field--error select {
  border-color: color-mix(in srgb, var(--ds-red) 55%, transparent);
}

/* A credential field is hidden when its kind is not selected, rather than removed,
   so a half-typed secret survives switching kind and switching back. */
.field[hidden] {
  display: none;
}

/* ------------------------------------------------------------------- combobox

   A searchable listbox, because the native <datalist> could not be made to work.
   Three problems, in order of how much they cost:

   1. Browser autofill wins. An unowned text input whose label reads "Mailbox" and
      whose placeholder was "user@contoso.com" trips Chrome's address heuristics and
      every password manager, and the autofill overlay paints ON TOP of the datalist
      popup. The markup carries the full suppression set now, and the address-shaped
      signals are gone - that half is what actually works.
   2. It is unstylable and matches differently in every browser: Chrome matches label
      and value, Firefox only value, neither highlights, neither can show a second
      line. Every field the API returned except two was thrown away for want of
      somewhere to put it.
   3. It cannot say anything. No count, no scope filter, no "these are the ones that
      could not be listed, and why".

   Positioned absolutely inside its own wrapper rather than portalled: the picker
   sits at the top of a full-height column, so the panel has nowhere near enough
   room to reach the scroll container's edge. No getBoundingClientRect, which also
   means it behaves in a test harness that has no layout at all. */

.combo {
  position: relative;
}
.combo__label {
  display: block;
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ds-text-dim);
  margin-bottom: 4px;
}
.combo__input {
  padding-right: 28px;
}
.combo__toggle {
  position: absolute;
  right: 1px;
  bottom: 1px;
  width: 26px;
  height: 28px;
  display: grid;
  place-items: center;
  background: none;
  border: 0;
  border-radius: var(--ds-radius);
  color: var(--ds-text-ghost);
  cursor: pointer;
}
.combo__toggle:hover {
  color: var(--ds-accent);
}
.combo__toggle svg {
  width: 14px;
  height: 14px;
  stroke-width: 1.8;
  transition: transform var(--ds-t-fast) var(--ds-ease);
}
.combo.is-open .combo__toggle svg {
  transform: rotate(180deg);
}

.combo__list {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  margin: 4px 0 0;
  padding: 4px;
  list-style: none;
  max-height: 280px;
  overflow-y: auto;
  background: var(--ds-raised);
  border: 1px solid var(--ds-line-bright);
  border-radius: var(--ds-radius);
  box-shadow: var(--ds-glow-sm), 0 8px 24px rgb(0 0 0 / 55%);
  z-index: var(--ds-z-pop);
}
.combo__list[hidden] {
  display: none;
}

/* Same hover and selected treatment as a folder row, and the same height token, so
   density modes keep working without this knowing they exist. */
.combo__opt {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--ds-row-h);
  padding: 3px 8px;
  border-radius: var(--ds-radius);
  color: var(--ds-text-dim);
  font-size: var(--ds-fs-md);
  cursor: pointer;
}
.combo__opt:hover,
.combo__opt.is-active {
  background: var(--ds-surface-2);
  color: var(--ds-text);
}
.combo__opt.is-active {
  background: var(--ds-accent-wash);
  color: var(--ds-accent);
}
.combo__opt-main {
  flex: 1;
  min-width: 0;
}
.combo__opt-name {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.combo__opt-sub {
  display: block;
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
  color: var(--ds-text-ghost);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.combo__opt .chip {
  flex: 0 0 auto;
}
.combo__opt mark {
  background: none;
  color: var(--ds-accent);
  font-weight: 600;
}
.combo__opt.is-muted .combo__opt-name {
  color: var(--ds-text-faint);
}
.combo__empty {
  padding: 10px;
  font-size: var(--ds-fs-xs);
  color: var(--ds-text-faint);
  line-height: 1.5;
}

/* Scope chips. Counts are always shown, including zero - a filter that silently
   has nothing behind it is indistinguishable from one that is broken. */
.combo__scopes {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
}
.combo__scope {
  padding: 1px 7px;
  border: 1px solid var(--ds-line);
  border-radius: 999px;
  background: none;
  color: var(--ds-text-faint);
  font-family: var(--ds-mono);
  font-size: var(--ds-fs-xs);
  cursor: pointer;
}
.combo__scope:hover {
  border-color: var(--ds-line-bright);
  color: var(--ds-text-dim);
}
.combo__scope.is-on {
  border-color: var(--ds-accent-dim);
  background: var(--ds-accent-wash);
  color: var(--ds-accent);
}

@media (prefers-reduced-motion: reduce) {
  .combo__toggle svg {
    transition: none;
  }
}
