/*
 * Nokato Admin Portal design tokens and shell styling.
 *
 * `--nokato-*` custom properties are the semantic authoring source (see
 * nokatohq/docs/admin_portal/design.md). Each one maps one-way onto the
 * Bootstrap 5.3 `--bs-*` variable it customizes, so Bootstrap's own component
 * CSS renders with Nokato values without a second parallel style system.
 *
 * Bootstrap 5.3 declares most component variables (`--bs-btn-*`,
 * `--bs-card-*`, `--bs-table-*`, `--bs-modal-*`, and so on) on the component
 * selector itself. A root-level `--bs-*` override therefore never reaches
 * them, so this file sets those variables on the component selector, as
 * design.md's Bootstrap compatibility contract requires. The loading order
 * matters: this file follows bootstrap.min.css, so an equal-specificity rule
 * here wins.
 *
 * The CSP forbids inline styles, so every visual value lives in this file.
 * Never add an `@import` or an external `url()` here: style-src and img-src
 * allow only the pinned CDN origins and `data:` images.
 */

:root,
[data-bs-theme="light"] {
  color-scheme: light;

  --nokato-primary: #2b58f2;
  --nokato-primary-deep: #1e40ba;
  --nokato-secondary: #56636b;
  --nokato-success: #1f6b59;
  --nokato-warning: #8b4f12;
  --nokato-danger: #b7353d;
  --nokato-info: #2b58f2;
  --nokato-background: #eef2f3;
  --nokato-surface: #f9fbfb;
  --nokato-surface-raised: #ffffff;
  --nokato-surface-muted: #e7edef;
  --nokato-ink: #13202a;
  --nokato-ink-soft: #56636b;
  --nokato-ink-faint: #66737b;
  --nokato-id-ink: #b23e82;
  --nokato-border: #d8e0e2;
  --nokato-border-strong: #c7d2d5;
  --nokato-navigation: #111d25;
  --nokato-navigation-soft: #1c2a34;
  --nokato-navigation-ink: #ffffff;
  --nokato-navigation-muted: #c3d2d8;
  --nokato-accent-lime: #d7f35f;
  --nokato-accent-lime-hover: #e4fa89;
  --nokato-on-accent-lime: #1d2c1a;
  --nokato-brand-wash: #e8eeff;
  --nokato-brand-ink: #1e40ba;
  --nokato-review-wash: #fff1dd;
  --nokato-review-ink: #8b4f12;
  --nokato-failure-wash: #fde8e9;
  --nokato-failure-ink: #b7353d;
  --nokato-ready-wash: #e3f5ef;
  --nokato-ready-ink: #1f6b59;
  --nokato-focus-ring: rgba(43, 88, 242, 0.25);
  --nokato-shadow-sm: 0 1px 2px rgba(17, 29, 37, 0.06), 0 1px 1px rgba(17, 29, 37, 0.04);

  --nokato-radius-control: 0.5625rem;
  --nokato-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --nokato-duration-fast: 150ms;
  --nokato-duration-toast: 180ms;
  --nokato-sidebar-width: 15.25rem;
  --nokato-topbar-height: 4.5rem;
  /* The content column is left-aligned and capped. The Support pages hold
     the widest grid, so they take the wider cap. */
  --nokato-page-max: 92.5rem;
  --nokato-page-max-wide: 120rem;
  --nokato-page-padding: 2.375rem;
  --nokato-section-gap: 1.625rem;

  /* Bootstrap color-mode adapter: getbootstrap.com/docs/5.3/customize/css-variables */
  --bs-primary: var(--nokato-primary);
  --bs-primary-rgb: 43, 88, 242;
  --bs-secondary: var(--nokato-secondary);
  --bs-secondary-rgb: 86, 99, 107;
  --bs-success: var(--nokato-success);
  --bs-success-rgb: 31, 107, 89;
  --bs-warning: var(--nokato-warning);
  --bs-warning-rgb: 139, 79, 18;
  --bs-danger: var(--nokato-danger);
  --bs-danger-rgb: 183, 53, 61;
  --bs-info: var(--nokato-info);
  --bs-info-rgb: 43, 88, 242;
  --bs-light: var(--nokato-surface);
  --bs-light-rgb: 249, 251, 251;
  --bs-dark: var(--nokato-navigation);
  --bs-dark-rgb: 17, 29, 37;
  --bs-body-bg: var(--nokato-background);
  --bs-body-bg-rgb: 238, 242, 243;
  --bs-body-color: var(--nokato-ink);
  --bs-body-color-rgb: 19, 32, 42;
  --bs-body-font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --bs-body-font-size: 0.875rem;
  --bs-body-font-weight: 400;
  --bs-body-line-height: 1.45;
  --bs-font-monospace: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  --bs-border-color: var(--nokato-border);
  --bs-border-color-translucent: var(--nokato-border);
  --bs-border-radius: 0.75rem;
  --bs-border-radius-sm: 0.5rem;
  --bs-border-radius-lg: 1.125rem;
  --bs-border-radius-pill: 50rem;
  --bs-box-shadow-sm: var(--nokato-shadow-sm);
  --bs-link-color: var(--nokato-primary);
  --bs-link-color-rgb: 43, 88, 242;
  --bs-link-hover-color: var(--nokato-primary-deep);
  --bs-link-hover-color-rgb: 30, 64, 186;
  --bs-focus-ring-color: var(--nokato-focus-ring);
  --bs-emphasis-color: var(--nokato-ink);
  --bs-emphasis-color-rgb: 19, 32, 42;
  --bs-secondary-color: var(--nokato-ink-soft);
  --bs-secondary-color-rgb: 86, 99, 107;
  --bs-tertiary-color: var(--nokato-ink-faint);
  --bs-tertiary-bg: var(--nokato-surface-muted);
  --bs-secondary-bg: var(--nokato-surface-muted);
  --bs-code-color: var(--nokato-id-ink);
  --bs-form-control-bg: var(--nokato-surface-raised);

  /* Semantic feedback: alerts read these subtle/emphasis roles. */
  --bs-info-bg-subtle: var(--nokato-brand-wash);
  --bs-info-border-subtle: var(--nokato-primary);
  --bs-info-text-emphasis: var(--nokato-brand-ink);
  --bs-success-bg-subtle: var(--nokato-ready-wash);
  --bs-success-border-subtle: var(--nokato-success);
  --bs-success-text-emphasis: var(--nokato-ready-ink);
  --bs-warning-bg-subtle: var(--nokato-review-wash);
  --bs-warning-border-subtle: var(--nokato-warning);
  --bs-warning-text-emphasis: var(--nokato-review-ink);
  --bs-danger-bg-subtle: var(--nokato-failure-wash);
  --bs-danger-border-subtle: var(--nokato-danger);
  --bs-danger-text-emphasis: var(--nokato-failure-ink);
}

/* Dark mode remaps the semantic roles rather than inverting the palette. The
   selector sits on the document root (design.md, Colors). Every Bootstrap
   variable set in the light block above is set again here, because that block
   also matches the root element and would otherwise override Bootstrap's own
   dark values. */
[data-bs-theme="dark"] {
  color-scheme: dark;

  --nokato-background: #0d161c;
  --nokato-surface: #14212a;
  --nokato-surface-raised: #192934;
  --nokato-surface-muted: #22343e;
  --nokato-ink: #eff6f7;
  --nokato-ink-soft: #a6b9c0;
  --nokato-ink-faint: #7d929a;
  --nokato-id-ink: #e685b5;
  --nokato-border: #2d424c;
  --nokato-border-strong: #405762;
  --nokato-brand-wash: #1e2e6b;
  --nokato-brand-ink: #b7c6ff;
  --nokato-review-wash: #4d341a;
  --nokato-review-ink: #f5c277;
  --nokato-failure-wash: #4c2428;
  --nokato-failure-ink: #ff9da2;
  --nokato-ready-wash: #183e34;
  --nokato-ready-ink: #7de0c0;
  --bs-link-color: var(--nokato-brand-ink);
  --bs-link-color-rgb: 183, 198, 255;
  --bs-link-hover-color: var(--nokato-ink);
  --bs-link-hover-color-rgb: 239, 246, 247;
  --nokato-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.32), 0 1px 1px rgba(0, 0, 0, 0.2);

  --bs-body-bg: var(--nokato-background);
  --bs-body-bg-rgb: 13, 22, 28;
  --bs-body-color: var(--nokato-ink);
  --bs-body-color-rgb: 239, 246, 247;
  --bs-border-color: var(--nokato-border);
  --bs-border-color-translucent: var(--nokato-border);
  --bs-emphasis-color: var(--nokato-ink);
  --bs-emphasis-color-rgb: 239, 246, 247;
  --bs-secondary-color: var(--nokato-ink-soft);
  --bs-secondary-color-rgb: 166, 185, 192;
  --bs-tertiary-color: var(--nokato-ink-faint);
  --bs-tertiary-bg: var(--nokato-surface-muted);
  --bs-secondary-bg: var(--nokato-surface-muted);
  --bs-form-control-bg: var(--nokato-surface-raised);
  --bs-code-color: var(--nokato-id-ink);
}

html {
  min-width: 320px;
}

body {
  background-color: var(--nokato-background);
}

/* Links are quiet at rest and underline on interaction (design.md, Colors).
   Bootstrap 5.3 hard-codes `text-decoration: underline` on every `a`, so the
   `--bs-link-decoration` variable alone does not change it. */
a {
  text-decoration: none;
}

a:hover,
a:focus-visible {
  text-decoration: underline;
}

.btn:not(.btn-link):hover,
.nav-link:hover,
.page-link:hover,
.dropdown-item:hover,
a.btn:not(.btn-link):focus-visible {
  text-decoration: none;
}

/* Headings use the restrained weight range (design.md, Typography): 600 for
   panel titles, 650 only for the page title and metric values. */
h1,
h2,
h3,
h4,
h5,
h6,
.h1,
.h2,
.h3,
.h4,
.h5,
.h6 {
  font-weight: 600;
  letter-spacing: 0;
}

h4,
.h4 {
  font-size: 1.125rem;
}

h5,
.h5 {
  font-size: 1rem;
}

h6,
.h6 {
  font-size: 0.875rem;
}

/* Section heading between groups of panels, such as Telemetry. */
.portal-section-title {
  font-size: 1.375rem;
  font-weight: 600;
}

strong,
b {
  font-weight: 600;
}

hr {
  color: var(--nokato-border);
  opacity: 1;
}

/* Bootstrap's `code` rule sets font-size in `em`; identifiers use the
   typography.mono size, colored by --bs-code-color (colors.id-ink). Table
   cells keep an identifier on one line so it stays whole and copyable. */
code {
  font-size: 0.75rem;
}

.table code,
.table time {
  white-space: nowrap;
}

/* Nokato ink-hierarchy text utilities: the three-step reading hierarchy from
   design.md (colors.ink, colors.ink-soft, colors.ink-faint), used instead of
   an inline style attribute the Administrator CSP's style-src blocks. */
.text-nokato-ink-soft {
  color: var(--nokato-ink-soft);
}

.text-nokato-ink-faint {
  color: var(--nokato-ink-faint);
}

.portal-id {
  color: var(--nokato-id-ink);
  font-family: var(--bs-font-monospace);
  font-size: 0.75rem;
}

/* Explanatory copy under the page title. */
.portal-intro {
  margin-bottom: 1.25rem;
  color: var(--nokato-ink-soft);
}

.portal-inline-icon {
  width: 1rem;
  height: 1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.15em;
}

/* Keyboard focus is always visible and uses colors.focus-ring. Bootstrap's own
   :focus rules on form controls set a stock blue, so the controls are named
   with the same specificity and follow it in the cascade. */
a:focus-visible,
button:focus-visible,
textarea:focus-visible,
.nav-link:focus-visible,
.btn:focus-visible,
.page-link:focus-visible,
.form-check-input:focus-visible {
  outline: none;
  box-shadow: 0 0 0 0.25rem var(--nokato-focus-ring);
}

.form-control:focus,
.form-select:focus {
  border-color: var(--nokato-primary);
  outline: none;
  box-shadow: 0 0 0 0.25rem var(--nokato-focus-ring);
}

/* A checkbox or radio is its own boundary, so it takes a raised fill and
   colors.border-strong; Bootstrap would give it the canvas fill and the
   default hairline, which disappears on the work surface. */
.form-check-input {
  --bs-form-check-bg: var(--nokato-surface-raised);
  border-color: var(--nokato-border-strong);
}

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

/* ---- Buttons (design.md, Buttons and actions) ---------------------------- */

.btn {
  --bs-btn-font-size: 0.8125rem;
  --bs-btn-font-weight: 600;
  --bs-btn-line-height: 1.2;
  --bs-btn-padding-x: 1rem;
  --bs-btn-padding-y: 0.5rem;
  --bs-btn-border-radius: var(--nokato-radius-control);
  --bs-btn-box-shadow: none;
  --bs-btn-focus-box-shadow: 0 0 0 0.25rem var(--nokato-focus-ring);
  display: inline-flex;
  min-height: 2.5rem;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  letter-spacing: 0;
}

.btn-sm {
  --bs-btn-font-size: 0.8125rem;
  --bs-btn-padding-x: 0.75rem;
  --bs-btn-padding-y: 0.25rem;
  --bs-btn-border-radius: var(--nokato-radius-control);
  min-height: 2rem;
}

.btn-primary {
  --bs-btn-color: #ffffff;
  --bs-btn-bg: var(--nokato-primary);
  --bs-btn-border-color: var(--nokato-primary);
  --bs-btn-hover-color: #ffffff;
  --bs-btn-hover-bg: var(--nokato-primary-deep);
  --bs-btn-hover-border-color: var(--nokato-primary-deep);
  --bs-btn-focus-shadow-rgb: 43, 88, 242;
  --bs-btn-active-color: #ffffff;
  --bs-btn-active-bg: var(--nokato-primary-deep);
  --bs-btn-active-border-color: var(--nokato-primary-deep);
  --bs-btn-active-shadow: none;
  --bs-btn-disabled-color: #ffffff;
  --bs-btn-disabled-bg: var(--nokato-primary);
  --bs-btn-disabled-border-color: var(--nokato-primary);
}

.btn-outline-secondary {
  --bs-btn-color: var(--nokato-ink);
  --bs-btn-bg: var(--nokato-surface-raised);
  --bs-btn-border-color: var(--nokato-border);
  --bs-btn-hover-color: var(--nokato-ink);
  --bs-btn-hover-bg: var(--nokato-surface-muted);
  --bs-btn-hover-border-color: var(--nokato-border-strong);
  --bs-btn-focus-shadow-rgb: 43, 88, 242;
  --bs-btn-active-color: var(--nokato-ink);
  --bs-btn-active-bg: var(--nokato-surface-muted);
  --bs-btn-active-border-color: var(--nokato-border-strong);
  --bs-btn-active-shadow: none;
  --bs-btn-disabled-color: var(--nokato-ink-faint);
  --bs-btn-disabled-bg: var(--nokato-surface-raised);
  --bs-btn-disabled-border-color: var(--nokato-border);
}

.btn-outline-danger {
  --bs-btn-color: var(--nokato-failure-ink);
  --bs-btn-bg: var(--nokato-surface-raised);
  --bs-btn-border-color: var(--nokato-danger);
  --bs-btn-hover-color: #ffffff;
  --bs-btn-hover-bg: var(--nokato-danger);
  --bs-btn-hover-border-color: var(--nokato-danger);
  --bs-btn-focus-shadow-rgb: 183, 53, 61;
  --bs-btn-active-color: #ffffff;
  --bs-btn-active-bg: var(--nokato-danger);
  --bs-btn-active-border-color: var(--nokato-danger);
  --bs-btn-disabled-color: var(--nokato-ink-faint);
  --bs-btn-disabled-border-color: var(--nokato-border);
}

.btn-danger {
  --bs-btn-color: #ffffff;
  --bs-btn-bg: var(--nokato-danger);
  --bs-btn-border-color: var(--nokato-danger);
  --bs-btn-hover-color: #ffffff;
  --bs-btn-hover-bg: #9a2b32;
  --bs-btn-hover-border-color: #9a2b32;
  --bs-btn-focus-shadow-rgb: 183, 53, 61;
  --bs-btn-active-color: #ffffff;
  --bs-btn-active-bg: #9a2b32;
  --bs-btn-active-border-color: #9a2b32;
  --bs-btn-active-shadow: none;
  --bs-btn-disabled-color: #ffffff;
  --bs-btn-disabled-bg: var(--nokato-danger);
  --bs-btn-disabled-border-color: var(--nokato-danger);
}

/* The one "evidence, on demand" action, such as Download JSON: colors.accent-
   lime appears only where the Administrator can trust or export platform data. */
.btn-accent {
  --bs-btn-color: var(--nokato-on-accent-lime);
  --bs-btn-bg: var(--nokato-accent-lime);
  --bs-btn-border-color: var(--nokato-accent-lime);
  --bs-btn-hover-color: var(--nokato-on-accent-lime);
  --bs-btn-hover-bg: var(--nokato-accent-lime-hover);
  --bs-btn-hover-border-color: var(--nokato-accent-lime-hover);
  --bs-btn-focus-shadow-rgb: 215, 243, 95;
  --bs-btn-active-color: var(--nokato-on-accent-lime);
  --bs-btn-active-bg: var(--nokato-accent-lime-hover);
  --bs-btn-active-border-color: var(--nokato-accent-lime-hover);
  --bs-btn-active-shadow: none;
}

/* Ghost action: the theme link foreground without a surrounding container, such as
   Decide, Retry, or Open in a table row. */
.btn-link {
  --bs-btn-color: var(--bs-link-color);
  --bs-btn-hover-color: var(--bs-link-hover-color);
  --bs-btn-active-color: var(--bs-link-hover-color);
  --bs-btn-disabled-color: var(--nokato-ink-faint);
  --bs-btn-focus-shadow-rgb: 43, 88, 242;
  text-decoration: none;
}

.btn-link:hover {
  text-decoration: underline;
}

.btn .portal-inline-icon {
  flex: none;
}

/* ---- Forms (design.md, Forms and overlays) ------------------------------- */

.form-label {
  margin-bottom: 0.375rem;
  color: var(--nokato-ink);
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.25;
}

.form-control,
.form-select {
  min-height: 2.375rem;
  border-color: var(--nokato-border);
  border-radius: var(--nokato-radius-control);
  background-color: var(--nokato-surface-raised);
  color: var(--nokato-ink);
  font-size: 0.875rem;
  line-height: 1.45;
}

.form-control {
  padding: 0.4375rem 0.75rem;
}

.form-select {
  padding-top: 0.4375rem;
  padding-bottom: 0.4375rem;
}

.form-control::placeholder {
  color: var(--nokato-ink-faint);
}

/* A field the administrator has touched, or that a refused submit named, shows as
   invalid. :user-invalid waits for that interaction, so an empty form does not
   open in error. */
.form-control:user-invalid,
.form-select:user-invalid {
  border-color: var(--nokato-danger);
}

.form-control:user-invalid:focus,
.form-select:user-invalid:focus {
  border-color: var(--nokato-danger);
  box-shadow: 0 0 0 0.25rem rgba(183, 53, 61, 0.25);
}

.form-control:disabled,
.form-select:disabled {
  background-color: var(--nokato-surface-muted);
}

.form-text {
  color: var(--nokato-ink-soft);
  font-size: 0.75rem;
}

textarea.form-control {
  resize: none;
}

/* ---- Panels (design.md, Elevation & Depth) ------------------------------- */

/* Grouped panels are bordered and unshadowed; only genuinely raised surfaces
   (metric tiles, the profile popover, toasts) carry .shadow-sm. */
.card {
  --bs-card-bg: var(--nokato-surface-raised);
  --bs-card-color: var(--nokato-ink);
  --bs-card-border-color: var(--nokato-border);
  --bs-card-border-radius: var(--bs-border-radius-lg);
  --bs-card-inner-border-radius: calc(var(--bs-border-radius-lg) - 1px);
  --bs-card-spacer-x: 1.5rem;
  --bs-card-spacer-y: 1.5rem;
  --bs-card-cap-bg: var(--nokato-surface-muted);
  box-shadow: none;
}

/* ---- Tables (design.md, Navigation and data display) --------------------- */

.table {
  --bs-table-bg: transparent;
  --bs-table-color: var(--nokato-ink-soft);
  --bs-table-border-color: var(--nokato-border);
  --bs-table-hover-bg: var(--nokato-surface);
  --bs-table-hover-color: var(--nokato-ink-soft);
  --bs-table-striped-bg: transparent;
}

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

.table > thead > tr > th {
  color: var(--nokato-ink);
  font-weight: 600;
  white-space: nowrap;
}

/* Absolutely positioned cell content, such as a .visually-hidden label,
   would otherwise escape the scroll container and widen the whole page. */
.table-responsive {
  position: relative;
}

/* A prose column, such as a metric definition, keeps a readable measure; the
   table scrolls inside its .table-responsive wrapper instead of squeezing it. */
.portal-col-wide {
  min-width: 22rem;
}

.portal-col-medium {
  min-width: 14rem;
}

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

/* ---- Status badges (design.md, Colors) ----------------------------------- */

/* A status pairs semantic color with text and a leading dot, so color never
   carries the meaning alone. */
.badge {
  --bs-badge-padding-x: 0.625rem;
  --bs-badge-padding-y: 0.3125rem;
  --bs-badge-font-size: 0.6875rem;
  --bs-badge-font-weight: 600;
  --bs-badge-border-radius: var(--bs-border-radius-pill);
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  line-height: 1.2;
  white-space: nowrap;
}

.badge[class*="status-"]::before {
  width: 0.375rem;
  height: 0.375rem;
  flex: none;
  border-radius: 50%;
  background: currentColor;
  content: "";
}

.badge.status-review {
  background: var(--nokato-review-wash);
  color: var(--nokato-review-ink);
}

.badge.status-failure {
  background: var(--nokato-failure-wash);
  color: var(--nokato-failure-ink);
}

.badge.status-ready {
  background: var(--nokato-ready-wash);
  color: var(--nokato-ready-ink);
}

.badge.status-neutral {
  background: var(--nokato-surface-muted);
  color: var(--nokato-ink-soft);
}

/* ---- Feedback: alerts, toasts, modals ------------------------------------ */

/* Alerts read the *-subtle / *-text-emphasis roles set on the root above. */
.alert {
  --bs-alert-padding-x: 1rem;
  --bs-alert-padding-y: 0.75rem;
  --bs-alert-border-radius: var(--bs-border-radius-sm);
  border-width: 0 0 0 3px;
}

.toast {
  --bs-toast-bg: var(--nokato-surface-raised);
  --bs-toast-color: var(--nokato-ink);
  --bs-toast-font-size: 0.8125rem;
  --bs-toast-padding-x: 1rem;
  --bs-toast-padding-y: 0.75rem;
  --bs-toast-border-color: var(--nokato-border);
  --bs-toast-border-radius: var(--bs-border-radius);
  --bs-toast-box-shadow: var(--nokato-shadow-sm);
}

.toast.fade {
  transition: opacity var(--nokato-duration-toast) var(--nokato-ease-out);
}

/* A toast is a transient echo of the persistent alert; its tone dot repeats
   the alert's semantic color. */
.portal-toast .toast-body {
  display: flex;
  flex: 1;
  align-items: flex-start;
  gap: 0.625rem;
  padding: var(--bs-toast-padding-y) var(--bs-toast-padding-x);
}

.portal-toast .toast-body::before {
  width: 0.5rem;
  height: 0.5rem;
  flex: none;
  margin-top: 0.3125rem;
  border-radius: 50%;
  background: var(--nokato-primary);
  content: "";
}

.portal-toast-danger .toast-body::before {
  background: var(--nokato-danger);
}

/* Dialogs follow the design system Dialog: 26rem wide, radius lg, shadow-sm
   and no border. The title and description share the header; the body holds
   only extra fields; the actions sit bottom-right with no divider. */
.modal {
  --bs-modal-width: 26rem;
  --bs-modal-bg: var(--nokato-surface-raised);
  --bs-modal-color: var(--nokato-ink);
  --bs-modal-border-width: 0;
  --bs-modal-border-radius: var(--bs-border-radius-lg);
  --bs-modal-inner-border-radius: var(--bs-border-radius-lg);
  --bs-modal-box-shadow: var(--nokato-shadow-sm);
  --bs-modal-header-padding: 1.5rem 1.5rem 0;
  --bs-modal-header-border-width: 0;
  --bs-modal-padding: 1rem 1.5rem 0;
  --bs-modal-footer-border-width: 0;
  --bs-modal-footer-gap: 0.5rem;
  --bs-modal-title-line-height: 1.3;
}

.modal-content {
  box-shadow: var(--bs-modal-box-shadow);
}

.modal-header {
  flex-direction: column;
  align-items: stretch;
  gap: 0.75rem;
}

.modal-header:has(> .btn-close) {
  flex-direction: row;
  align-items: flex-start;
  justify-content: space-between;
}

.modal-title {
  font-size: 1.25rem;
  font-weight: 600;
}

.admin-modal-description {
  margin: 0;
  color: var(--nokato-ink-soft);
}

/* Bootstrap gives each footer action a half-gap margin, so the padding is
   a quarter rem short of the 1.5rem dialog edge. */
.modal-footer {
  padding: 1rem 1.25rem 1.25rem;
}

.modal-backdrop {
  --bs-backdrop-bg: #111d25;
  --bs-backdrop-opacity: 0.45;
}

/* ---- Pagination (design.md, Page navigation) ----------------------------- */

.pagination {
  --bs-pagination-padding-x: 0.5rem;
  --bs-pagination-padding-y: 0;
  --bs-pagination-font-size: 0.75rem;
  --bs-pagination-color: var(--nokato-ink);
  --bs-pagination-bg: var(--nokato-surface-raised);
  --bs-pagination-border-color: var(--nokato-border);
  --bs-pagination-border-radius: var(--bs-border-radius-sm);
  --bs-pagination-hover-color: var(--nokato-ink);
  --bs-pagination-hover-bg: var(--nokato-surface-muted);
  --bs-pagination-hover-border-color: var(--nokato-border-strong);
  --bs-pagination-focus-color: var(--nokato-ink);
  --bs-pagination-focus-bg: var(--nokato-surface-muted);
  --bs-pagination-focus-box-shadow: 0 0 0 0.25rem var(--nokato-focus-ring);
  --bs-pagination-active-color: #ffffff;
  --bs-pagination-active-bg: var(--nokato-primary);
  --bs-pagination-active-border-color: var(--nokato-primary);
  --bs-pagination-disabled-color: var(--nokato-ink-faint);
  --bs-pagination-disabled-bg: var(--nokato-surface-raised);
  --bs-pagination-disabled-border-color: var(--nokato-border);
  gap: 0.25rem;
}

.pagination .page-link {
  display: grid;
  min-width: 2rem;
  height: 2rem;
  place-items: center;
  border-radius: var(--bs-pagination-border-radius);
}

.pagination .page-item:not(:first-child) .page-link {
  margin-left: 0;
}

/* The pager row under a grid: the row summary on the left, the buttons on the
   right. It wraps, so a narrow card stacks the buttons under the summary. */
.portal-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  margin-top: 1rem;
}

.portal-pager-summary {
  margin: 0;
  color: var(--nokato-ink-soft);
  font-size: 0.8125rem;
}

/* ---- Section tabs, such as Failures and Work & Notifications ------------- */

.portal-tabs {
  --bs-nav-link-padding-x: 0.875rem;
  --bs-nav-link-padding-y: 0;
  --bs-nav-link-font-size: 0.8125rem;
  --bs-nav-link-font-weight: 600;
  --bs-nav-link-color: var(--nokato-primary);
  --bs-nav-link-hover-color: var(--nokato-primary-deep);
  gap: 0.5rem;
}

.portal-tabs .nav-link {
  display: inline-flex;
  min-height: 2rem;
  align-items: center;
  border: 1px solid transparent;
  border-radius: var(--nokato-radius-control);
}

.portal-tabs .nav-link[aria-current="page"] {
  border-color: var(--nokato-border-strong);
  background: var(--nokato-surface-raised);
  color: var(--nokato-ink);
}

/* ---- Command rail --------------------------------------------------------- */

/* A persistent dark surface at lg and above, an offcanvas below it; both
   share this markup (design.md, Layout). Bootstrap's `.offcanvas-lg` and its
   body set `background-color: transparent !important` at lg, so the rail
   restates its surface with !important as well. */
.portal-rail {
  --bs-offcanvas-width: var(--nokato-sidebar-width);
  --bs-offcanvas-bg: var(--nokato-navigation);
  --bs-offcanvas-color: var(--nokato-navigation-ink);
  --bs-offcanvas-border-width: 0;
  color: var(--nokato-navigation-ink);
}

@media (min-width: 992px) {
  .portal-rail {
    position: sticky;
    top: 0;
    display: flex;
    flex: none;
    flex-direction: column;
    width: var(--nokato-sidebar-width);
    height: 100vh;
    overflow-y: auto;
    background-color: var(--nokato-navigation) !important;
  }

  /* Bootstrap sets flex-grow: 0 on the lg offcanvas body, which would leave
     the profile row directly under the navigation instead of pinned to the
     bottom of the rail. */
  .portal-rail .offcanvas-body {
    flex: 1 1 auto;
    gap: 1.5rem;
    background-color: var(--nokato-navigation) !important;
  }
}

.portal-brand {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}

.portal-brand-mark {
  display: grid;
  width: 2rem;
  height: 2rem;
  flex: none;
  place-items: center;
  border-radius: var(--bs-border-radius-sm);
  background: var(--nokato-accent-lime);
  color: var(--nokato-on-accent-lime);
  font-weight: 600;
}

.admin-rail-brand {
  padding: 0.5rem;
  line-height: 1.2;
}

.portal-brand-caption {
  color: var(--nokato-navigation-muted);
  font-size: 0.8125rem;
}

.portal-nav-label {
  padding: 0 0.75rem;
  margin-bottom: 0.5rem;
  color: var(--nokato-navigation-muted);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Nav groups sit 1.5rem apart, the same gap as the brand and the profile. */
.portal-nav .nav + .portal-nav-label {
  margin-top: 1.5rem;
}

.portal-nav .nav-link {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  min-height: 2.5rem;
  padding: 0.625rem 0.75rem;
  border-radius: var(--nokato-radius-control);
  color: var(--nokato-navigation-muted);
  font-size: 0.875rem;
  transition: background var(--nokato-duration-fast) var(--nokato-ease-out),
    color var(--nokato-duration-fast) var(--nokato-ease-out);
}

.portal-nav .nav-link:hover {
  background: rgba(255, 255, 255, 0.07);
  color: var(--nokato-navigation-ink);
}

.portal-nav .nav-link[aria-current="page"] {
  background: var(--nokato-navigation-soft);
  color: var(--nokato-navigation-ink);
  font-weight: 600;
}

.portal-nav .nav-link.disabled {
  color: var(--nokato-navigation-muted);
  opacity: 0.55;
  pointer-events: none;
}

.portal-nav-icon {
  display: grid;
  width: 1.0625rem;
  height: 1.0625rem;
  flex: none;
  place-items: center;
}

.portal-nav-icon svg {
  width: 1.0625rem;
  height: 1.0625rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The cue that an item opens outside the console, in a new tab. */
.portal-nav-external {
  display: grid;
  margin-left: auto;
  place-items: center;
  opacity: 0.7;
}

.portal-nav-external svg {
  width: 0.875rem;
  height: 0.875rem;
}

/* The open-ticket count on the Support item: a primary pill. */
.portal-nav-count {
  display: inline-flex;
  min-width: 1.25rem;
  height: 1.25rem;
  align-items: center;
  justify-content: center;
  margin-left: auto;
  padding: 0 0.375rem;
  border-radius: var(--bs-border-radius-pill);
  background: var(--nokato-primary);
  color: #ffffff;
  font-size: 0.6875rem;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* Account controls live in the rail footer (design.md, Navigation and page
   inventory), not the top bar. */
.portal-profile-dropdown {
  padding-top: 0.75rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.portal-profile-toggle {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  width: 100%;
  padding: 0.5rem;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--nokato-radius-control);
  background: transparent;
  color: var(--nokato-navigation-ink);
  text-align: left;
  font-size: 0.75rem;
  transition: background var(--nokato-duration-fast) var(--nokato-ease-out),
    border-color var(--nokato-duration-fast) var(--nokato-ease-out);
}

.portal-profile-toggle:hover,
.portal-profile-toggle.show {
  border-color: rgba(255, 255, 255, 0.18);
  background: var(--nokato-navigation-soft);
  color: var(--nokato-navigation-ink);
}

.portal-profile-avatar {
  display: grid;
  width: 1.875rem;
  height: 1.875rem;
  flex: none;
  place-items: center;
  border-radius: 50%;
  background: var(--nokato-surface-muted);
  color: var(--nokato-ink);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
}

.portal-profile-role {
  color: var(--nokato-navigation-muted);
  font-size: 0.6875rem;
}

@keyframes ot-slide-up {
  from {
    opacity: 0;
    transform: translateY(0.375rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.dropdown-menu.portal-profile-menu {
  --bs-dropdown-bg: var(--nokato-navigation-soft);
  --bs-dropdown-border-color: rgba(255, 255, 255, 0.12);
  --bs-dropdown-border-radius: var(--bs-border-radius);
  --bs-dropdown-inner-border-radius: calc(var(--bs-border-radius) - 1px);
  --bs-dropdown-color: var(--nokato-navigation-ink);
  --bs-dropdown-font-size: 0.8125rem;
  --bs-dropdown-link-color: var(--nokato-navigation-ink);
  --bs-dropdown-link-hover-color: var(--nokato-navigation-ink);
  --bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.08);
  --bs-dropdown-divider-bg: rgba(255, 255, 255, 0.12);
  --bs-dropdown-divider-margin-y: 0.125rem;
  --bs-dropdown-box-shadow: var(--nokato-shadow-sm);
  width: 100%;
  min-width: 0;
  padding: 0.375rem;
  animation: ot-slide-up var(--nokato-duration-fast) var(--nokato-ease-out);
}

.portal-profile-menu .dropdown-item {
  padding: 0.5rem 0.625rem;
  border-radius: var(--bs-border-radius-sm);
}

/* ---- Top bar and content -------------------------------------------------- */

/* Flex children default to min-width: auto, so a wide table would otherwise
   stretch the whole column past the viewport instead of scrolling inside its
   own .table-responsive wrapper. */
.portal-main {
  min-width: 0;
  min-height: 100vh;
}

.portal-topbar {
  display: flex;
  min-height: var(--nokato-topbar-height);
  align-items: center;
  gap: 0.75rem;
  padding-inline: 1.5rem;
  background: var(--nokato-surface);
  border-bottom: 1px solid var(--nokato-border);
}

/* A long ticket identifier wraps inside the breadcrumb instead of pushing
   the theme selector off a narrow screen. */
.admin-topbar-crumbs {
  min-width: 0;
  flex: 1;
}

.portal-topbar .portal-theme-switch {
  flex: none;
}

/* Below lg the bar keeps the menu button, the brand, and the theme buttons
   on its first row, and the breadcrumb takes its own full-width strip. */
@media (max-width: 991.98px) {
  .portal-topbar {
    display: grid;
    grid-template-areas:
      "menu brand theme"
      "crumbs crumbs crumbs";
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-rows: var(--nokato-topbar-height) auto;
    gap: 0 0.75rem;
    padding-inline: 0;
  }

  .admin-menu-btn {
    grid-area: menu;
    width: 2.75rem;
    height: 2.75rem;
    min-height: 2.75rem;
    margin-left: 1rem;
  }

  .admin-topbar-brand {
    grid-area: brand;
    min-width: 0;
    gap: 0.5rem;
    color: var(--nokato-ink);
    font-weight: 600;
  }

  .admin-topbar-brand .portal-brand-mark {
    width: 1.75rem;
    height: 1.75rem;
    font-size: 0.8125rem;
  }

  .portal-topbar .portal-theme-switch {
    grid-area: theme;
    margin-right: 1rem;
  }

  .admin-topbar-crumbs {
    grid-area: crumbs;
    padding: 0.625rem 1rem;
    border-top: 1px solid var(--nokato-border);
  }

  .portal-breadcrumb {
    row-gap: 0.25rem;
  }
}

.portal-breadcrumb {
  --bs-breadcrumb-divider-color: var(--nokato-border-strong);
  --bs-breadcrumb-item-padding-x: 0.5rem;
  --bs-breadcrumb-item-active-color: var(--nokato-ink);
  color: var(--nokato-ink-faint);
  font-size: 0.75rem;
}

.portal-breadcrumb .breadcrumb-item a {
  color: inherit;
}

.portal-breadcrumb .breadcrumb-item a:hover {
  color: var(--nokato-ink);
}

.portal-breadcrumb .breadcrumb-item.active {
  font-weight: 600;
}

/* Theme selector: three separate icon buttons, the selected one tinted. */
.portal-theme-switch {
  display: flex;
  gap: 0.5rem;
}

.portal-icon-btn {
  --bs-btn-padding-x: 0;
  --bs-btn-padding-y: 0;
  width: 2.25rem;
  min-height: 2.25rem;
  height: 2.25rem;
  padding: 0;
}

.portal-icon-btn[aria-pressed="true"] {
  background: var(--nokato-surface-muted);
}

.portal-content {
  max-width: var(--nokato-page-max);
  padding: var(--nokato-page-padding) var(--nokato-page-padding) 3.5rem;
}

.admin-content-wide {
  max-width: var(--nokato-page-max-wide);
}

@media (max-width: 767.98px) {
  .portal-content {
    padding-inline: 1rem;
  }
}

/* Nokato token map of typography.heading (design.md): the page title on
   every authenticated page, in place of Bootstrap's h1 defaults. */
.portal-page-title {
  margin-bottom: 1.25rem;
  font-size: 2.5rem;
  font-weight: 650;
  line-height: 1.05;
}

/* Explanatory copy with one page-level action beside it, such as
   Register a Merchant. */
.portal-intro-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.portal-intro-row .portal-intro {
  margin-bottom: 0;
}

.portal-intro-row .btn {
  flex: none;
}

/* A filter row wraps naturally: fields take a comfortable width, and the
   action stays beside the last field until the row runs out of room. */
.portal-filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1rem;
}

.portal-field {
  flex: 1 1 10rem;
  min-width: 0;
  max-width: 14rem;
}

.portal-field-wide {
  flex-basis: 13rem;
  max-width: 18rem;
}

/* A date and time field needs room for the value and the picker icon. */
.portal-field-datetime {
  flex-basis: 13.5rem;
  max-width: 17rem;
}

.portal-field-narrow {
  flex: 0 0 5.5rem;
}

.portal-filter-action {
  display: flex;
  flex: none;
  align-items: center;
  gap: 0.5rem;
}

@media (max-width: 575.98px) {
  .portal-field,
  .portal-field-wide {
    flex-basis: 100%;
    max-width: none;
  }

  .portal-field-narrow {
    flex-basis: 5.5rem;
  }
}

/* Filter controls collapse behind a Filters button below lg and stay expanded
   at lg and above. */
.portal-filters-toggle {
  margin-bottom: 1rem;
}

@media (min-width: 992px) {
  .portal-filters.collapse {
    display: block;
  }
}

/* ---- Overview ------------------------------------------------------------- */

.portal-metrics {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
  margin-bottom: var(--nokato-section-gap);
}

@media (min-width: 768px) {
  .portal-metrics {
    grid-template-columns: repeat(3, minmax(0, 17.5rem));
  }
}

.portal-metric {
  --bs-card-spacer-x: 1.25rem;
  --bs-card-spacer-y: 1.25rem;
  border-radius: var(--bs-border-radius);
  box-shadow: var(--nokato-shadow-sm);
}

.portal-metric-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
  color: var(--nokato-ink-soft);
  font-size: 0.875rem;
  font-weight: 400;
}

.portal-metric-value {
  margin-bottom: 0.75rem;
  font-size: 1.9375rem;
  font-weight: 650;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* Icon chip with a tinted semantic surface (design.md, Shapes). */
.portal-chip {
  display: grid;
  width: 1.75rem;
  height: 1.75rem;
  flex: none;
  place-items: center;
  border-radius: var(--bs-border-radius-sm);
  background: var(--nokato-brand-wash);
  color: var(--nokato-brand-ink);
}

.portal-chip .portal-inline-icon {
  width: 0.875rem;
  height: 0.875rem;
  vertical-align: 0;
}

.portal-chip-lg {
  width: 1.875rem;
  height: 1.875rem;
}

.portal-chip-lg .portal-inline-icon {
  width: 0.9375rem;
  height: 0.9375rem;
}

.portal-chip-failure {
  background: var(--nokato-failure-wash);
  color: var(--nokato-failure-ink);
}

.portal-chip-review {
  background: var(--nokato-review-wash);
  color: var(--nokato-review-ink);
}

.portal-chip-ready {
  background: var(--nokato-ready-wash);
  color: var(--nokato-ready-ink);
}

/* Detail pages put every section in one card (design.md, Layout). A divider
   separates the sections, and the last block in a card or section drops its
   bottom margin so the padding, not a stray paragraph margin, sets the edge. */
.portal-section + .portal-section {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--nokato-border);
}

.card-body > :last-child,
.portal-section > :last-child {
  margin-bottom: 0;
}

/* A form-only page, such as Account, keeps its card to a readable measure
   instead of stretching a single field across the whole work area. */
.portal-card-narrow {
  max-width: 32rem;
}

/* Ordered attention items (design.md, Layout): a tinted icon chip, a title
   with its severity as text, safe detail, and time with the correlation
   identifier. A list wraps naturally where a wide table would scroll. */
.portal-attention {
  padding: 0;
  margin: 0;
  list-style: none;
}

.portal-attention-item {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 1rem 0;
  border-top: 1px solid var(--nokato-border);
}

.portal-attention-item:first-child {
  padding-top: 0.25rem;
  border-top: 0;
}

.portal-attention-item:last-child {
  padding-bottom: 0;
}

.portal-attention-copy {
  min-width: 0;
  flex: 1;
}

.portal-attention-title {
  color: var(--nokato-ink);
  font-size: 0.8125rem;
  font-weight: 600;
}

.portal-attention-title .badge {
  margin-left: 0.25rem;
  vertical-align: 0.0625rem;
}

.portal-attention-detail {
  margin-top: 0.1875rem;
  color: var(--nokato-ink-soft);
  font-size: 0.8125rem;
  line-height: 1.4;
}

.portal-attention-meta {
  margin-top: 0.3125rem;
  color: var(--nokato-ink-faint);
  font-size: 0.75rem;
}

.portal-attention-meta code {
  overflow-wrap: anywhere;
}

/* ---- Authentication pages, outside the rail ------------------------------ */

/* Sign-in and recovery pages carry no privileged navigation: the brand pins
   top-left and the theme selector top-right, independent of the centered
   card. */
.portal-auth-shell {
  position: relative;
  display: flex;
  min-height: 100vh;
  align-items: center;
  justify-content: center;
  /* The top padding clears the pinned brand and theme selector when the card
     is taller than the viewport, such as on a phone. */
  padding: 5rem 1rem var(--nokato-page-padding);
}

.portal-auth-brand {
  position: absolute;
  top: 1.5rem;
  left: 1.5rem;
  max-width: calc(100% - 10.5rem);
}

.portal-auth-theme {
  position: absolute;
  top: 1.5rem;
  right: 1.5rem;
}

.portal-auth-card {
  width: 100%;
  max-width: 26rem;
}

.portal-auth-title {
  margin-bottom: 0.75rem;
  font-size: 1.75rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.02em;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* ---- Wish Market directories (Buyers, Wishes, Support) ------------------- */

[hidden] {
  display: none !important;
}

/* One grouped panel holds the filters, the bulk bar, the grid and its
   footer, stacked 1rem apart. */
.admin-grid > .card-body {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.admin-grid .portal-pager {
  margin-top: 0;
}

/* The ticket action form only carries hidden fields for the buttons that
   name it, so it takes no space in the stack. */
.admin-actions-form {
  display: contents;
}

/* Filter fields keep their natural width: text inputs a fixed measure,
   selects their content, and the date preset at least 12rem. */
.admin-grid-filters {
  gap: 1rem;
}

.admin-grid-filters .portal-field {
  flex: 0 1 auto;
  max-width: none;
}

.admin-grid-filters .admin-field-text {
  width: 13.5rem;
}

.admin-grid-filters .form-select {
  width: auto;
  max-width: 100%;
}

/* A date filter is one dropdown. The button shows a calendar icon, the
   current range and the select chevron. The panel lists the presets as radio
   rows, then the custom From and To dates side by side. */
.admin-date-toggle {
  display: flex;
  min-width: 12rem;
  align-items: center;
  gap: 0.5rem;
  color: var(--nokato-ink-soft);
  text-align: left;
}

.admin-date-toggle.admin-date-set {
  color: var(--nokato-ink);
}

.admin-date-toggle[aria-expanded="true"] {
  border-color: var(--nokato-border-strong);
}

.admin-date-toggle > .portal-inline-icon {
  width: 0.9375rem;
  height: 0.9375rem;
  flex: none;
  color: var(--nokato-ink-faint);
}

.admin-date-toggle > span {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-date-menu {
  --bs-dropdown-min-width: 0;
  --bs-dropdown-font-size: 0.875rem;
  --bs-dropdown-padding-x: 0.5rem;
  --bs-dropdown-padding-y: 0.5rem;
  --bs-dropdown-spacer: 0.375rem;
  --bs-dropdown-bg: var(--nokato-surface-raised);
  --bs-dropdown-border-color: var(--nokato-border);
  --bs-dropdown-border-radius: var(--bs-border-radius);
  --bs-dropdown-box-shadow: var(--nokato-shadow-sm);
  width: 18rem;
  max-width: calc(100vw - 2.5rem);
  box-shadow: var(--bs-dropdown-box-shadow);
}

.admin-date-presets {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 0.125rem;
  margin: 0;
  padding: 0;
  border: 0;
}

/* The radio stays focusable for keyboard use; its label is the visible row. */
.admin-date-radio {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.admin-date-option {
  display: flex;
  height: 2.25rem;
  align-items: center;
  justify-content: space-between;
  padding: 0 0.625rem;
  border-radius: var(--bs-border-radius-sm);
  color: var(--nokato-ink);
  cursor: pointer;
  transition: background var(--nokato-duration-fast) ease-out;
}

.admin-date-option:hover {
  background: var(--nokato-background);
}

.admin-date-option .portal-inline-icon {
  display: none;
  width: 0.875rem;
  height: 0.875rem;
}

.admin-date-radio:checked + .admin-date-option {
  background: var(--nokato-brand-wash);
  color: var(--nokato-brand-ink);
  font-weight: 600;
}

.admin-date-radio:checked + .admin-date-option .portal-inline-icon {
  display: inline-block;
}

.admin-date-radio:focus-visible + label {
  box-shadow: 0 0 0 0.25rem var(--nokato-focus-ring);
}

.admin-date-caption {
  margin-top: 0.375rem;
  padding: 0.375rem 0.625rem 0;
  border-top: 1px solid var(--nokato-border);
  color: var(--nokato-ink-faint);
  cursor: pointer;
  font-size: 0.6875rem;
  font-weight: 600;
}

.admin-date-custom {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0.5rem;
  padding: 0.375rem 0.625rem 0.25rem;
}

.admin-date-custom .admin-detail-field > label {
  color: var(--nokato-ink);
  font-size: 0.6875rem;
  font-weight: 600;
}

.admin-date-custom .form-control {
  padding: 0.4375rem 0.5rem;
  font-size: 0.8125rem;
}

/* Without JavaScript the dropdown cannot open, so its panel renders open. */
html:not(.admin-js) .admin-date-toggle {
  display: none;
}

html:not(.admin-js) .admin-date-menu {
  position: static;
  display: block;
  margin-top: 0;
  box-shadow: none;
}

/* Filters collapse behind Show filters at 1024px and below. Without
   JavaScript the collapse never opens, so the filters stay expanded. */
.admin-grid-filters-toggle {
  display: none;
  align-self: flex-start;
  min-height: 2.75rem;
}

.admin-grid-filters-toggle > span {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.admin-grid-filters-toggle .admin-toggle-open,
.admin-grid-filters-toggle[aria-expanded="true"] .admin-toggle-closed {
  display: none;
}

.admin-grid-filters-toggle[aria-expanded="true"] .admin-toggle-open {
  display: inline-flex;
}

@media (max-width: 1024px) {
  html.admin-js .admin-grid-filters-toggle {
    display: inline-flex;
  }

  html.admin-js .admin-grid .portal-filters.collapse:not(.show) {
    display: none;
  }
}

/* Grid rows: hairline dividers, a canvas-tinted hover and a brand-wash
   selection. Bootstrap paints cell fills through --bs-table-bg-state. */
.admin-directory-table {
  margin: 0;
}

.admin-directory-table > :not(caption) > * > * {
  padding: 0.625rem 0.75rem;
}

.admin-directory-table > thead > tr > th {
  border-bottom-color: var(--nokato-border-strong);
}

.admin-directory-table > tbody > tr > * {
  transition: box-shadow var(--nokato-duration-fast) ease-out;
}

.admin-directory-table > tbody > tr:hover > * {
  --bs-table-bg-state: var(--nokato-background);
}

.admin-directory-table > tbody > tr:has([data-select-row]:checked) > * {
  --bs-table-bg-state: var(--nokato-brand-wash);
}

/* Identifiers keep colors.id-ink inside links too; Bootstrap would give a
   linked code element the link color. */
.admin-grid a > code,
.admin-wish-modal a > code {
  color: var(--nokato-id-ink);
}

.table td.admin-cell-ink {
  color: var(--nokato-ink);
}

.admin-cell-action,
.admin-cell-check {
  width: 1%;
}

.admin-directory-table .form-check-input {
  width: 1rem;
  height: 1rem;
  margin: 0;
  vertical-align: middle;
}

.admin-empty {
  margin: 0;
  padding: 1rem 0.75rem;
  color: var(--nokato-ink-soft);
}

.admin-truncate {
  display: block;
  max-width: 22rem;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-truncate-sm {
  max-width: 16rem;
}

.admin-wish-cell {
  display: inline-flex;
  max-width: 100%;
  align-items: center;
  gap: 0.5rem;
}

/* Sortable headers: a 13px neutral sort icon in ink-faint, or the active
   direction arrow in primary. */
.admin-sort {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  color: inherit;
}

.admin-sort:hover {
  color: inherit;
  text-decoration: none;
}

.admin-sort .portal-inline-icon {
  width: 0.8125rem;
  height: 0.8125rem;
  color: var(--nokato-ink-faint);
  vertical-align: 0;
}

.admin-sort-active .portal-inline-icon {
  color: var(--nokato-primary);
}

/* The row action: a 2rem square eye button with a 15px icon. */
.admin-row-btn {
  width: 2rem;
  height: 2rem;
  min-height: 2rem;
  flex: none;
}

.admin-row-btn .portal-inline-icon {
  width: 0.9375rem;
  height: 0.9375rem;
}

.admin-test-flag,
.admin-type,
.admin-priority,
.admin-comment-flag {
  display: inline-flex;
  vertical-align: middle;
}

.admin-test-flag,
.admin-type-buyer,
.admin-comment-flag {
  color: var(--nokato-primary);
}

.admin-type {
  color: var(--nokato-ink-faint);
}

.admin-type-buyer {
  color: var(--nokato-primary);
}

.admin-priority-low {
  color: var(--nokato-ink-faint);
}

.admin-priority-normal {
  color: var(--nokato-ink-soft);
}

.admin-priority-high {
  color: var(--nokato-review-ink);
}

.admin-priority-urgent {
  color: var(--nokato-failure-ink);
}

/* Count and state badges share the design-system Badge metrics. */
.admin-count,
.admin-status {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.3125rem 0.625rem;
  border-radius: var(--bs-border-radius-pill);
  background: var(--nokato-surface-muted);
  color: var(--nokato-ink-soft);
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
}

.admin-count,
.admin-count:hover {
  background: var(--nokato-brand-wash);
  color: var(--nokato-brand-ink);
  text-decoration: none;
}

.admin-count-zero {
  background: var(--nokato-surface-muted);
  color: var(--nokato-ink-soft);
}

.admin-status-open {
  background: var(--nokato-review-wash);
  color: var(--nokato-review-ink);
}

.admin-status-live,
.admin-status-replied {
  background: var(--nokato-brand-wash);
  color: var(--nokato-brand-ink);
}

.admin-status-granted,
.admin-status-ready {
  background: var(--nokato-ready-wash);
  color: var(--nokato-ready-ink);
}

.admin-status-dot::before {
  width: 0.375rem;
  height: 0.375rem;
  flex: none;
  border-radius: 50%;
  background: currentColor;
  content: "";
}

.admin-status .portal-inline-icon {
  width: 0.75rem;
  height: 0.75rem;
  vertical-align: 0;
}

.admin-ticket-counts,
.admin-status-group {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.admin-status-group {
  justify-content: flex-end;
}

/* Live wishes: active offers as a solid primary pill, or an outlined grey
   pill at zero. */
.admin-offer-count {
  display: inline-flex;
  min-width: 1.375rem;
  height: 1.375rem;
  box-sizing: border-box;
  align-items: center;
  justify-content: center;
  padding: 0 0.375rem;
  border: 1px solid var(--nokato-primary);
  border-radius: var(--bs-border-radius-pill);
  background: var(--nokato-primary);
  color: #ffffff;
  font-size: 0.75rem;
  font-weight: 600;
}

.admin-offer-count-zero {
  border-color: var(--nokato-border);
  background: var(--nokato-surface);
  color: var(--nokato-ink-faint);
}

/* Wish status pill tabs with a count bubble. */
.admin-wish-tabs {
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}

.admin-wish-tabs .nav-link {
  display: inline-flex;
  min-height: 2.25rem;
  align-items: center;
  gap: 0.5rem;
  padding: 0 0.875rem;
  border: 1px solid var(--nokato-border);
  border-radius: var(--bs-border-radius-pill);
  background: var(--nokato-surface-raised);
  color: var(--nokato-ink-soft);
  font-size: 0.8125rem;
  font-weight: 600;
  transition: background var(--nokato-duration-fast) ease-out,
    color var(--nokato-duration-fast) ease-out;
}

.admin-wish-tabs .nav-link:hover {
  background: var(--nokato-surface-muted);
  color: var(--nokato-ink);
}

.admin-wish-tabs .nav-link.active {
  border-color: var(--nokato-primary);
  background: var(--nokato-primary);
  color: #ffffff;
}

.admin-wish-tabs .portal-inline-icon {
  width: 0.9375rem;
  height: 0.9375rem;
}

.admin-tab-count {
  display: inline-flex;
  min-width: 1.125rem;
  height: 1.125rem;
  box-sizing: border-box;
  align-items: center;
  justify-content: center;
  padding: 0 0.3125rem;
  border-radius: var(--bs-border-radius-pill);
  background: var(--nokato-surface);
  color: var(--nokato-ink-soft);
  font-size: 0.6875rem;
  font-weight: 600;
}

.admin-wish-tabs .nav-link.active .admin-tab-count {
  background: rgba(255, 255, 255, 0.22);
  color: #ffffff;
}

/* Support bulk bar, shown once a row is checked. */
.admin-bulk-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 0.75rem;
  border-radius: var(--nokato-radius-control);
  background: var(--nokato-brand-wash);
  font-size: 0.8125rem;
}

.admin-bulk-count {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  margin-right: auto;
  color: var(--nokato-brand-ink);
  font-weight: 600;
}

.admin-bulk-clear {
  padding: 0;
  border: 0;
  background: none;
  color: var(--bs-link-color);
  font: inherit;
  font-weight: 400;
  text-decoration: underline;
}

/* Buyer details: label and value rows in a design-system Dialog. */
.admin-dialog-list {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0.625rem 1rem;
  margin: 0;
}

.admin-dialog-list dt {
  color: var(--nokato-ink-faint);
  font-weight: 400;
}

.admin-dialog-list dd {
  margin: 0;
  color: var(--nokato-ink);
  font-weight: 600;
  text-align: right;
  overflow-wrap: anywhere;
}

/* Without JavaScript a detail modal renders open from the URL. */
.admin-auto-modal,
.modal:target {
  display: block;
  overflow-y: auto;
  background: rgba(17, 29, 37, 0.45);
}

/* Wish details: a wide read-only modal with a raised header strip and a
   surface body holding one or two columns of panels. */
.admin-wish-modal {
  --bs-modal-margin: 1rem;
}

.admin-modal-live {
  --bs-modal-width: 68rem;
}

.admin-modal-granted {
  --bs-modal-width: 56rem;
}

.admin-modal-closed {
  --bs-modal-width: 32rem;
}

.admin-wish-modal .modal-content {
  overflow: hidden;
  background: var(--nokato-surface);
}

.admin-wish-modal .modal-header {
  flex-direction: row;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1.25rem 1.5rem;
  border-bottom: 1px solid var(--nokato-border);
  background: var(--nokato-surface-raised);
}

.admin-modal-heading {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 0.25rem;
}

.admin-wish-modal .modal-title {
  font-weight: 650;
}

.admin-wish-detail {
  display: grid;
  grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
  align-items: start;
  gap: 1.25rem;
  padding: 1.25rem 1.5rem 1.5rem;
}

.admin-wish-detail-granted {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.admin-wish-detail-closed {
  grid-template-columns: minmax(0, 1fr);
}

.admin-detail-section {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 0.625rem;
}

.admin-detail-section h3,
.admin-detail-section h4 {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
}

.admin-detail-panel,
.admin-detail-rows {
  min-width: 0;
  border: 1px solid var(--nokato-border);
  border-radius: var(--bs-border-radius);
  background: var(--nokato-surface-raised);
}

.admin-detail-rows {
  margin: 0;
  padding: 0.25rem 1rem;
}

.admin-detail-rows > div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.625rem 0;
}

.admin-detail-rows > div + div {
  border-top: 1px solid var(--nokato-border);
}

.admin-detail-rows dt {
  color: var(--nokato-ink-faint);
  font-weight: 400;
}

.admin-detail-rows dd {
  min-width: 0;
  margin: 0;
  color: var(--nokato-ink);
  font-weight: 600;
  text-align: right;
  overflow-wrap: anywhere;
}

.admin-detail-rows > .admin-detail-stacked {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.375rem;
}

.admin-detail-stacked dd {
  color: var(--nokato-ink-soft);
  font-weight: 400;
  line-height: 1.5;
  text-align: left;
  white-space: pre-wrap;
}

.admin-detail-empty {
  margin: 0;
  padding: 1rem;
  color: var(--nokato-ink-soft);
}

.admin-evidence-link {
  align-self: flex-start;
  min-height: 0;
  padding: 0;
}

.admin-offer-heading {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.admin-offers-table > .table > :not(caption) > * > * {
  padding: 0.5rem 0.75rem;
}

.admin-offers-table > .table > thead > tr > th {
  border-bottom-color: var(--nokato-border-strong);
}

.admin-offers-table > .table > tbody > tr:last-child > * {
  border-bottom: 0;
}

.admin-accepted-offer {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1rem;
}

.admin-accepted-offer > p,
.admin-detail-field p {
  margin: 0;
  color: var(--nokato-ink-soft);
  line-height: 1.5;
}

/* A small caption above a value, such as Product page link. */
.admin-detail-field {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 0.25rem;
}

.admin-detail-field > span:first-child,
.admin-detail-field > label {
  color: var(--nokato-ink-faint);
  font-size: 0.75rem;
}

.admin-detail-field > a {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.admin-detail-field > a .portal-inline-icon {
  width: 0.8125rem;
  height: 0.8125rem;
  flex: none;
}

.admin-coupon {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--nokato-border);
  border-radius: var(--nokato-radius-control);
  background: var(--nokato-surface);
}

.admin-stars {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.admin-star-row {
  display: flex;
  gap: 0.125rem;
  color: var(--nokato-border-strong);
}

.admin-star-row .admin-star-filled {
  color: var(--nokato-primary);
}

.admin-stars strong {
  color: var(--nokato-ink);
}

/* Support ticket view. */
.admin-ticket {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/* A ghost action with no vertical padding, so it sits tight above the
   ticket heading. */
.admin-back-link {
  min-height: 0;
  padding: 0 0.375rem;
}

.admin-back-link .portal-inline-icon {
  width: 0.9375rem;
  height: 0.9375rem;
}

.admin-ticket-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}

.admin-ticket-title {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 0.5rem;
}

.admin-ticket-title .portal-page-title {
  margin: 0;
}

.admin-ticket-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.625rem;
  margin: 0;
}

.admin-ticket-actions {
  display: flex;
  gap: 0.5rem;
}

.admin-ticket-columns {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(17.5rem, 1fr);
  align-items: start;
  gap: 1rem;
}

.admin-ticket-columns .card-body {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.admin-ticket-columns h2 {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 600;
}

.admin-conversation {
  padding: 0.875rem 0;
}

.admin-conversation-meta {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
}

.admin-conversation-meta strong {
  color: var(--nokato-ink);
  font-size: 0.8125rem;
}

.admin-conversation-meta time,
.admin-reply-meta {
  color: var(--nokato-ink-faint);
  font-size: 0.75rem;
}

.admin-conversation .admin-message {
  margin: 0.375rem 0 0;
  color: var(--nokato-ink-soft);
}

.admin-message {
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.admin-reply,
.admin-reply-form,
.admin-comment-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.admin-reply {
  padding-top: 1rem;
  border-top: 1px solid var(--nokato-border);
}

.admin-reply h3 {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
}

.admin-ticket .admin-detail-field {
  gap: 0.375rem;
}

.admin-ticket .admin-detail-field > span:first-child,
.admin-ticket .admin-detail-field > label {
  font-size: 0.6875rem;
  font-weight: 600;
}

.admin-readonly {
  display: flex;
  min-height: 2.375rem;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--nokato-border);
  border-radius: var(--nokato-radius-control);
  background: var(--nokato-surface);
  color: var(--nokato-ink-soft);
}

.admin-readonly .portal-inline-icon {
  width: 0.875rem;
  height: 0.875rem;
}

.admin-readonly-message {
  display: block;
  line-height: 1.45;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.admin-ticket textarea.form-control {
  min-height: 5.5rem;
  padding: 0.625rem 0.75rem;
  resize: vertical;
}

.admin-ticket-details {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 0.625rem 1rem;
  margin: 0;
}

.admin-ticket-details dt {
  color: var(--nokato-ink-faint);
  font-size: 0.6875rem;
  font-weight: 600;
}

.admin-ticket-details dd {
  margin: 0;
  color: var(--nokato-ink);
  overflow-wrap: anywhere;
}

.admin-ticket-type {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

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

/* At 760px and below each grid row becomes a stacked card and the Wish
   details columns stack. */
@media (max-width: 760px) {
  .admin-directory-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .admin-directory-table,
  .admin-directory-table tbody,
  .admin-directory-table tr,
  .admin-directory-table td {
    display: block;
    width: 100%;
  }

  .admin-directory-table tr {
    padding: 0.5rem;
    margin-bottom: 0.75rem;
    border: 1px solid var(--nokato-border);
    border-radius: var(--bs-border-radius);
  }

  .admin-directory-table > :not(caption) > * > td {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    border: 0;
    overflow-wrap: anywhere;
    text-align: right;
  }

  .admin-directory-table td[data-label]::before {
    flex-shrink: 0;
    color: var(--nokato-ink-soft);
    content: attr(data-label);
  }

  .admin-directory-table .admin-cell-action {
    width: 100%;
  }

  .admin-truncate {
    max-width: 65vw;
  }

  .admin-grid-filters .portal-field,
  .admin-grid-filters .admin-field-text,
  .admin-grid-filters .form-select {
    width: 100%;
  }

  .admin-wish-detail,
  .admin-wish-detail-granted {
    grid-template-columns: minmax(0, 1fr);
    padding: 1rem;
  }

  .admin-ticket-actions {
    flex-wrap: wrap;
  }
}

html:not(.admin-js) .portal-filters.collapse {
  display: block;
}

html:not(.admin-js) [data-select-all],
html:not(.admin-js) [data-selection-clear],
html:not(.admin-js) [data-selection-count],
html:not(.admin-js) .portal-filters-toggle {
  display: none;
}
