/* PPAI Connect - Developer Portal. Light mode only. Bootstrap 5.3 is restyled through its CSS variables;
   the layout shell (brand bar, container, footer) is in Pages/Shared/_Layout.cshtml.css. */

/* ---------- Brand ----------
   --ppai-blue is the one value to change to rebrand: every other blue is mixed from it. */
:root {
  --ppai-blue: #3071c5;
  --ppai-blue-strong: color-mix(in srgb, var(--ppai-blue) 82%, #000);
  --ppai-blue-deep: color-mix(in srgb, var(--ppai-blue) 62%, #000);
  --ppai-blue-wash: color-mix(in srgb, var(--ppai-blue) 5%, #fff);
  --ppai-blue-soft: color-mix(in srgb, var(--ppai-blue) 12%, #fff);
  --ppai-blue-line: color-mix(in srgb, var(--ppai-blue) 30%, #fff);
  --ppai-blue-ring: color-mix(in srgb, var(--ppai-blue) 35%, transparent);

  --ink: #1f2733;
  --ink-muted: #5a6572;
  --rule: #dfe3e8;
  --field-rule: #8793a1;
  --surface: #f6f7f9;
}

/* ---------- Bootstrap tokens ---------- */
:root {
  color-scheme: light;

  --bs-primary: var(--ppai-blue);
  --bs-link-color: var(--ppai-blue-strong);
  --bs-link-hover-color: var(--ppai-blue-deep);
  --bs-focus-ring-color: var(--ppai-blue-ring);

  --bs-body-color: var(--ink);
  --bs-body-color-rgb: 31, 39, 51;
  --bs-secondary-color: var(--ink-muted);
  --bs-border-color: var(--rule);
  --bs-tertiary-bg: var(--surface);
  --bs-light-rgb: 246, 247, 249;
  --bs-code-color: var(--ink);

  --bs-body-font-family: "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --bs-font-monospace: "Cascadia Mono", "Cascadia Code", Consolas, ui-monospace, SFMono-Regular, Menlo, monospace;
  --bs-body-line-height: 1.45;

  --bs-border-radius: 0.3rem;
  --bs-border-radius-sm: 0.25rem;
  --bs-border-radius-lg: 0.4rem;
}

/* Bootstrap builds these utilities from an RGB triplet, which cannot be derived from the hex above. */
.text-primary { color: var(--ppai-blue-strong) !important; }
.link-primary { color: var(--ppai-blue-strong) !important; }
.bg-primary { background-color: var(--ppai-blue) !important; }
.border-primary { border-color: var(--ppai-blue) !important; }
.text-bg-primary { color: #fff !important; background-color: var(--ppai-blue) !important; }

/* ---------- Base ----------
   1rem is 14px at the browser's default size, so all of Bootstrap's rem spacing tightens with it. */
html {
  font-size: 87.5%;
}

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

a {
  color: var(--bs-link-color);
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  text-underline-offset: 0.18em;
}

a:hover {
  color: var(--bs-link-hover-color);
  text-decoration-color: currentColor;
}

a:focus-visible, .btn:focus-visible, .form-check-input:focus-visible, .nav-link:focus-visible {
  outline: 2px solid var(--ppai-blue-strong);
  outline-offset: 2px;
  box-shadow: none;
}

hr {
  margin: 0.75rem 0;
  color: var(--rule);
  opacity: 1;
}

/* ---------- Type ---------- */
h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 {
  font-weight: 600;
  line-height: 1.25;
  margin-bottom: 0.5rem;
}

h1, .h1 { font-size: 1.5rem; letter-spacing: -0.01em; }
h2, .h2 { font-size: 1.286rem; }
h3, .h3, h4, .h4 { font-size: 1.143rem; }
h5, .h5 { font-size: 1rem; }
h6, .h6 { font-size: 0.929rem; }

p {
  margin-bottom: 0.75rem;
}

main p {
  max-width: 90ch;
}

.lead {
  font-size: 1.071rem;
  font-weight: 400;
  color: var(--ink-muted);
}

small, .small {
  font-size: 0.857em;
}

code {
  font-size: 0.929em;
  padding: 0.08em 0.35em;
  border-radius: var(--bs-border-radius-sm);
  background-color: rgba(31, 39, 51, 0.06);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

pre {
  font-size: 0.929em;
}

pre code {
  padding: 0;
  background-color: transparent;
}

/* ---------- Buttons ---------- */
.btn {
  --bs-btn-padding-y: 0.32rem;
  --bs-btn-padding-x: 0.8rem;
  --bs-btn-font-weight: 500;
}

.btn-sm {
  --bs-btn-padding-y: 0.12rem;
  --bs-btn-padding-x: 0.5rem;
  --bs-btn-font-size: 0.857rem;
}

.btn-lg {
  --bs-btn-padding-y: 0.45rem;
  --bs-btn-padding-x: 1rem;
  --bs-btn-font-size: 1rem;
  --bs-btn-border-radius: var(--bs-border-radius);
}

.btn-primary {
  --bs-btn-color: #fff;
  --bs-btn-bg: var(--ppai-blue);
  --bs-btn-border-color: var(--ppai-blue);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--ppai-blue-strong);
  --bs-btn-hover-border-color: var(--ppai-blue-strong);
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--ppai-blue-deep);
  --bs-btn-active-border-color: var(--ppai-blue-deep);
  --bs-btn-disabled-color: #fff;
  --bs-btn-disabled-bg: var(--ppai-blue);
  --bs-btn-disabled-border-color: var(--ppai-blue);
}

.btn-outline-primary {
  --bs-btn-color: var(--ppai-blue-strong);
  --bs-btn-border-color: var(--ppai-blue);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--ppai-blue);
  --bs-btn-hover-border-color: var(--ppai-blue);
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--ppai-blue-strong);
  --bs-btn-active-border-color: var(--ppai-blue-strong);
  --bs-btn-disabled-color: var(--ppai-blue-strong);
  --bs-btn-disabled-border-color: var(--ppai-blue);
}

.btn-link {
  --bs-btn-font-weight: 400;
}

/* ---------- Forms ---------- */
.form-label {
  margin-bottom: 0.25rem;
  font-size: 0.929rem;
  font-weight: 500;
}

.form-control, .form-select {
  padding: 0.32rem 0.6rem;
  border-color: var(--field-rule);
}

.form-select {
  padding-right: 2rem;
}

.form-control-sm {
  padding: 0.12rem 0.45rem;
  font-size: 0.929rem;
}

.form-control:focus, .form-select:focus {
  border-color: var(--ppai-blue);
  box-shadow: 0 0 0 0.2rem var(--ppai-blue-ring);
}

.form-check-input {
  border-color: var(--field-rule);
}

.form-check-input:checked {
  background-color: var(--ppai-blue);
  border-color: var(--ppai-blue);
}

.form-text {
  margin-top: 0.2rem;
  font-size: 0.857em;
}

/* Phones zoom the page when a focused field's text is under 16px. */
@media (max-width: 575.98px) {
  .form-control, .form-select {
    font-size: 16px;
  }
}

.form-floating > label {
  font-size: 1rem;
  font-weight: 400;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
  color: var(--bs-secondary-color);
  text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
  text-align: start;
}

/* Validation messages written by jquery.validate.unobtrusive. */
.field-validation-error {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.857em;
}

.input-validation-error, .input-validation-error:focus {
  border-color: var(--bs-form-invalid-border-color);
}

.validation-summary-errors ul {
  padding-left: 1.1rem;
  margin-bottom: 0.5rem;
}

.validation-summary-valid {
  display: none;
}

/* ---------- Tables ---------- */
.table {
  --bs-table-color: var(--ink);
  --bs-table-border-color: var(--rule);
  margin-bottom: 0.75rem;
  font-variant-numeric: tabular-nums;
}

.table > :not(caption) > * > * {
  padding: 0.4rem 0.7rem;
}

.table-sm > :not(caption) > * > * {
  padding: 0.22rem 0.7rem;
}

.table > thead {
  --bs-table-bg: var(--ppai-blue-wash);
}

.table > thead > tr > th {
  font-size: 0.857rem;
  font-weight: 600;
  color: var(--ink-muted);
  white-space: nowrap;
  vertical-align: middle;
  border-bottom-color: var(--ppai-blue-line);
}

.table > thead > tr > th:first-child {
  border-top-left-radius: var(--bs-border-radius);
}

.table > thead > tr > th:last-child {
  border-top-right-radius: var(--bs-border-radius);
}

.table > tbody > tr:hover > * {
  --bs-table-bg-state: var(--ppai-blue-wash);
}

/* Bootstrap colours cells, not rows, so a muted row (a revoked key) has to pass it on. */
.table > tbody > tr.text-muted > * {
  color: var(--ink-muted);
}

.table-responsive {
  margin-bottom: 0.75rem;
}

.table-responsive > .table {
  margin-bottom: 0;
}

/* On a phone a many-column table scrolls sideways instead of squeezing every cell onto several lines. */
@media (max-width: 767.98px) {
  .table-wide {
    min-width: 64rem;
  }
}

/* Revoked keys: closed by default under the active ones, with the count in the summary. */
.revoked-keys {
  margin-bottom: 0.75rem;
}

.revoked-keys > summary {
  width: fit-content;
  padding: 0.15rem 0.4rem 0.15rem 0.1rem;
  font-size: 0.929rem;
  font-weight: 500;
  color: var(--ink-muted);
  border-radius: var(--bs-border-radius-sm);
}

.revoked-keys > summary:hover {
  color: var(--ink);
}

.revoked-keys > summary:focus-visible {
  outline: 2px solid var(--ppai-blue-strong);
  outline-offset: 2px;
}

.revoked-keys[open] > summary {
  margin-bottom: 0.35rem;
}

.revoked-keys > .table-responsive {
  margin-bottom: 0;
}

/* ---------- API calls ---------- */

/* A method and the path it called. A long path breaks anywhere rather than widening the table or the page. */
.call-request {
  overflow-wrap: anywhere;
}

/* What is known about one call: each label beside its value. */
.call-facts {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.3rem 1.25rem;
  margin-bottom: 1.25rem;
}

.call-facts > dt {
  font-weight: 500;
  color: var(--ink-muted);
}

.call-facts > dd {
  margin-bottom: 0;
}

/* A payload as it was sent. Wraps so nothing is hidden off to the side; a long one scrolls inside its box. */
.payload {
  max-height: 32rem;
  padding: 0.6rem 0.8rem;
  margin-bottom: 1.25rem;
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background-color: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--bs-border-radius);
}

/* In the dialog a call opens in, the dialog's body is what scrolls, so a payload is shown at its full height. */
.modal-body .payload {
  max-height: none;
}

.modal-body > .payload:last-child {
  margin-bottom: 0;
}

/* ---------- Badges ----------
   Status badges keep Bootstrap's semantic colours, as a tint with dark text instead of a solid block. */
.badge {
  --bs-badge-padding-x: 0.5em;
  --bs-badge-padding-y: 0.3em;
  --bs-badge-font-size: 0.821rem;
  --bs-badge-font-weight: 600;
  --bs-badge-border-radius: var(--bs-border-radius-sm);
}

.badge.text-bg-success {
  color: var(--bs-success-text-emphasis) !important;
  background-color: var(--bs-success-bg-subtle) !important;
}

.badge.text-bg-warning {
  color: var(--bs-warning-text-emphasis) !important;
  background-color: var(--bs-warning-bg-subtle) !important;
}

.badge.text-bg-danger {
  color: var(--bs-danger-text-emphasis) !important;
  background-color: var(--bs-danger-bg-subtle) !important;
}

.badge.text-bg-secondary {
  color: var(--bs-secondary-text-emphasis) !important;
  background-color: var(--bs-secondary-bg-subtle) !important;
}

.badge.text-bg-light {
  color: var(--ink) !important;
  background-color: var(--surface) !important;
}

/* ---------- Alerts, cards, breadcrumb ---------- */
.alert {
  --bs-alert-padding-x: 0.85rem;
  --bs-alert-padding-y: 0.6rem;
  --bs-alert-margin-bottom: 0.75rem;
}

.alert-info {
  --bs-alert-color: var(--ink);
  --bs-alert-bg: var(--ppai-blue-soft);
  --bs-alert-border-color: var(--ppai-blue-line);
  --bs-alert-link-color: var(--ppai-blue-deep);
}

/* A key or link shown once: wrap it rather than scroll, so the whole value is visible to copy. */
.alert pre {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.card {
  --bs-card-spacer-x: 1rem;
  --bs-card-spacer-y: 0.85rem;
  --bs-card-title-spacer-y: 0.35rem;
  --bs-card-border-color: var(--rule);
}

.breadcrumb {
  --bs-breadcrumb-margin-bottom: 0.35rem;
  --bs-breadcrumb-font-size: 0.857rem;
  --bs-breadcrumb-item-padding-x: 0.4rem;
}

/* ---------- Tabs and pills ---------- */
.nav-tabs {
  --bs-nav-tabs-border-color: var(--rule);
  gap: 1.25rem;
}

.nav-tabs .nav-link {
  padding: 0.4rem 0.1rem;
  font-weight: 500;
  color: var(--ink-muted);
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
}

.nav-tabs .nav-link:hover {
  color: var(--ink);
  border-bottom-color: var(--ppai-blue-line);
}

.nav-tabs .nav-link.active {
  color: var(--ppai-blue-strong);
  background-color: transparent;
  border-bottom-color: var(--ppai-blue);
}

.nav-pills {
  --bs-nav-pills-link-active-bg: var(--ppai-blue);
  --bs-nav-link-padding-y: 0.3rem;
  --bs-nav-link-padding-x: 0.7rem;
}

/* ---------- Page layout ---------- */

/* Title on the left, the page's main action on the right. */
.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin-bottom: 0.75rem;
}

.page-head > h1 {
  margin-bottom: 0;
}

/* The same for a section: its heading on the left, its action on the right, above the section's table. */
.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin-bottom: 0.5rem;
}

.section-head > h2 {
  margin-bottom: 0;
}

/* Forms and prose do not need the full width that the tables use. */
.form-page {
  max-width: 56rem;
}

.auth-form {
  max-width: 24rem;
}

/* A small number does not need a full-width field. */
.key-limit {
  max-width: 10rem;
}

.home-cards {
  max-width: 64rem;
}

/* ---------- A client's page ---------- */

/* The switch across from the client's name. It acts by itself, so it is sized as the page's main control,
   not as one box in a form. */
.client-active {
  margin-bottom: 0;
  font-size: 1.143rem;
  font-weight: 500;
}

.client-active .form-check-input {
  cursor: pointer;
}

/* The notes admins keep about the client, read as its description. Line breaks are kept as they were typed. */
.client-notes {
  white-space: pre-line;
}

/* ---------- Scope picker ---------- */

/* One area of scopes: closed until opened, with its heading saying how many of its scopes are ticked. */
.scope-group > summary {
  padding: 0.4rem 0.6rem;
  cursor: pointer;
  border-radius: var(--bs-border-radius);
}

.scope-group > summary:focus-visible {
  outline: 2px solid var(--ppai-blue-strong);
  outline-offset: 2px;
}

.scope-group > summary > .scope-count {
  float: right;
}

.scope-group-options {
  padding: 0 0.5rem 0.5rem;
}

/* One scope: a box of its own, with room on the left for the checkbox. */
.scope-option {
  padding: 0.3rem 0.6rem 0.3rem 2.1rem;
  margin-bottom: 0.3rem;
  background-color: #fff;
}

.scope-option:last-child {
  margin-bottom: 0;
}

.scope-option:has(.form-check-input:checked) {
  background-color: var(--ppai-blue-wash);
  border-color: var(--ppai-blue-line) !important;
}

/* One client to choose in the "Add key" dialog: a box of its own showing its scopes, like a scope option.
   The same box holds each thing a login can be removed from, in the Users page's "Remove" dialog. */
.client-option, .remove-option {
  padding: 0.45rem 0.7rem 0.45rem 2.1rem;
  margin-bottom: 0.4rem;
  background-color: #fff;
}

.client-option:has(.form-check-input:checked), .remove-option:has(.form-check-input:checked) {
  background-color: var(--ppai-blue-wash);
  border-color: var(--ppai-blue-line) !important;
}

.client-option:has(.form-check-input:disabled) {
  background-color: var(--surface);
}

.scope-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  padding-left: 0;
  list-style: none;
}
