/* =============================================================================================
   Back office — A1 to A7.

   Denser than the public site by design: the Foundation sheet allows 14px in admin tables against
   16px minimum on the public side, and forbids the serif display face here entirely. An operator
   lives in these screens all day and needs rows on them, not air.
   ============================================================================================= */

.vs-admin {
  display: grid;
  grid-template-columns: 264px minmax(0, 1fr);
  min-height: 100vh;
  background: var(--color-bg-sand);
}

/* Static settings form: provider panels switch with CSS, so this remains usable even when the
   Blazor circuit or JavaScript is unavailable. Server-side validation remains authoritative. */
#email-settings-form:has(#email-provider-postmark:checked) [data-email-provider="smtp"],
#email-settings-form:has(#email-provider-smtp:checked) [data-email-provider="postmark"] {
  display: none;
}

.vs-email-provider-options {
  gap: var(--space-5);
}

.vs-email-provider-panel {
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
}

.vs-admin__sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding: var(--space-6) var(--space-5);
  background: var(--color-bg-surface);
  border-inline-end: 1px solid var(--color-border);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.vs-admin__brand {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  text-decoration: none;
  color: inherit;
}

.vs-admin__nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.vs-admin__link {
  display: flex;
  align-items: center;
  min-height: var(--touch-target);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-button);
  font-size: var(--text-ui-14);
  font-weight: 600;
  color: var(--color-text-primary);
  text-decoration: none;
}

.vs-admin__link:hover {
  background: var(--color-bg-page);
  color: var(--color-action-primary);
}

/* The active destination is marked with a bar as well as a colour, so the current section is
   identifiable without relying on hue. */
.vs-admin__link.active {
  background: var(--color-action-primary-wash);
  color: var(--color-action-primary);
  box-shadow: inset 3px 0 0 var(--color-action-primary);
}

.vs-admin__account {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border-hairline);
}

.vs-admin__main {
  padding: var(--space-8) var(--space-8) var(--space-12);
  min-width: 0;   /* Lets wide tables scroll inside their container instead of stretching the grid. */
}

.vs-admin__filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: flex-end;
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  padding: var(--space-4) var(--space-5);
}

.vs-admin__filters .vs-field {
  flex: 0 1 200px;
  min-width: 160px;
}

/* Admin tables run at 14px, which the Foundation sheet permits here and nowhere else. */
.vs-admin__main .vs-table {
  font-size: var(--text-ui-14);
}

/* ---------------------------------------------------------------------------------------------
   Dashboard figures
   --------------------------------------------------------------------------------------------- */

.vs-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
}

.vs-kpi {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  padding: var(--space-5);
  text-decoration: none;
  color: inherit;
}

.vs-kpi--link:hover {
  border-color: var(--color-action-primary);
}

.vs-kpi__label {
  font-size: var(--text-caption-12);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.vs-kpi__value {
  font-size: 28px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.vs-kpi__hint {
  font-size: var(--text-caption-12);
  color: var(--color-text-secondary);
  line-height: 1.4;
}

/* ---------------------------------------------------------------------------------------------
   The visibility × state matrix (A2)

   The one cell that is publicly purchasable is marked, because everything else on the screen is a
   number and only that number is the answer to "what can a customer buy right now".
   --------------------------------------------------------------------------------------------- */

.vs-matrix th[scope='row'] {
  background: transparent;
  text-transform: none;
  letter-spacing: normal;
  font-size: var(--text-ui-14);
}

.vs-matrix td {
  font-size: 18px;
  font-variant-numeric: tabular-nums;
}

.vs-matrix__sellable {
  background: var(--color-status-success-bg);
  box-shadow: inset 0 0 0 1.5px var(--color-status-success-border);
  color: var(--color-status-success);
}

@media (max-width: 1024px) {
  .vs-admin {
    grid-template-columns: minmax(0, 1fr);
  }

  .vs-admin__sidebar {
    position: static;
    height: auto;
    border-inline-end: none;
    border-block-end: 1px solid var(--color-border);
  }

  .vs-admin__nav {
    flex-direction: row;
    flex-wrap: wrap;
  }

  .vs-admin__main {
    padding: var(--space-6) var(--space-4) var(--space-8);
  }
}

/* ================================================================================================
   Access administration — the roles x permissions grid.
   ================================================================================================ */

.vs-table__center {
  text-align: center;
}

/* Role columns are narrow and their headings are two lines: the role name, then the "legacy" chip
   where one applies. Centring both keeps the checkbox beneath visually attached to its column. */
.vs-permissions th {
  vertical-align: bottom;
}

.vs-permissions__role {
  display: block;
  font-weight: 700;
}

/* The permission's own row header carries the label and the verb beneath it, so the grid reads as
   "manage inventory / manage visibility" rather than needing a legend somewhere else. */
.vs-permissions tbody th {
  font-weight: 600;
  text-align: start;
}

.vs-permissions tbody th .vs-caption {
  display: block;
  font-weight: 400;
}

/* A checkbox in a grid cell has no visible label -- the column and row headings are the label, and
   the screen-reader text inside restates both. This variant drops the inline label layout the
   ordinary .vs-check assumes while keeping the 44px target around the control. */
.vs-check--bare {
  align-items: center;
  display: inline-flex;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
}

@media (max-width: 768px) {
  /* Targets grow on a phone, and the grid keeps its horizontal scroll inside the card rather than
     letting the page move -- the admin reflow rule from the handoff. */
  .vs-check--bare {
    min-height: 48px;
    min-width: 48px;
  }
}

/* ================================================================================================
   Sortable table headers, and the small bits the user directory needs.
   ================================================================================================ */

/* The control inside a <th>, not the cell itself. A cell is neither focusable nor announced as an
   action, so a click handler on one produces a table only a mouse can sort. */
.vs-sort {
  align-items: center;
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  display: inline-flex;
  font: inherit;
  font-weight: 700;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-1) var(--space-2);
  text-align: start;
}

.vs-sort:hover:not(:disabled) {
  color: var(--color-action-primary);
}

.vs-sort:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
}

.vs-sort:disabled {
  cursor: progress;
}

/* The inactive indicator is present but quiet: it advertises that the column *can* be sorted
   without competing with the one that is. Never the only signal -- aria-sort carries the same
   information, and the active column is also bolder. */
.vs-sort__indicator {
  color: var(--color-text-faint);
  font-size: var(--text-caption-12);
}

.vs-sort--active {
  color: var(--color-action-primary);
}

.vs-sort--active .vs-sort__indicator {
  color: var(--color-action-primary);
}

.vs-row--wrap {
  flex-wrap: wrap;
}

.vs-list {
  margin: 0;
  padding-inline-start: var(--space-5);
}

.vs-list li + li {
  margin-top: var(--space-1);
}

@media (max-width: 768px) {
  /* 48px targets on a phone, per the handoff. The table keeps its own horizontal scroll inside the
     card, so growing the header control never widens the page. */
  .vs-sort {
    min-height: 48px;
  }
}

/* A fare or capacity box. Right-aligned and narrow, because a number the operator is comparing
   down a column is easier to scan against its neighbours than against the label beside it. */
.vs-input--numeric {
  max-width: 12ch;
  text-align: end;
}

/* ================================================================================================
   The shared inventory visibility control.
   ================================================================================================ */

.vs-visibility {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.vs-visibility__control {
  align-items: center;
  display: flex;
  gap: var(--space-2);
}

/* The select sits in a table cell beside dozens of others, so it takes the width of its longest
   option rather than the column. min-height keeps the 44px target the rest of the admin uses. */
.vs-select--compact {
  min-height: 44px;
  width: auto;
}

/* Reserved height, so a confirmation appearing under the control does not push every row below it
   down the page -- which on a 400-seat flight is the whole table jumping. */
.vs-visibility__result {
  display: block;
  min-height: 1.2em;
}

@media (max-width: 768px) {
  .vs-select--compact {
    min-height: 48px;
  }
}

/* A button that reads as a link: used where an inline value filters the list rather than
   navigating. A real link would promise an address it does not have. */
.vs-linkish {
  background: none;
  border: 0;
  color: var(--color-action-primary);
  cursor: pointer;
  display: block;
  font: inherit;
  padding: 0;
  text-align: start;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.vs-linkish:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: 2px;
}

/* A field diff. Wraps rather than scrolling, because it sits inside a table cell that is already
   inside a horizontal scroller and a second axis there is unusable. */
/* The captured request. Wraps rather than scrolls sideways: a payload is read on a laptop next to
   the log it explains, and a horizontal scrollbar inside a table cell is unusable. */
.vs-audit__request {
  margin: var(--space-2) 0 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-1) var(--space-3);
  font-size: var(--text-caption-12);
}

.vs-audit__request dt {
  font-weight: 600;
}

.vs-audit__request dd {
  margin: 0;
  min-width: 0;
}

.vs-audit__payload {
  margin: 0;
  max-height: 18em;
  overflow-y: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-size: var(--text-caption-12);
}

.vs-audit__changes {
  font-family: var(--font-mono);
  font-size: var(--text-caption-12);
  margin: var(--space-2) 0 0;
  white-space: pre-wrap;
  word-break: break-word;
}
