/* ── Admin panel ────────────────────────────────────────────────────────── */

.admin-page {
  max-width: 1100px;
  margin: 0 auto;
  padding: 1.5rem 1rem 4rem;
}

.admin-h1 {
  font-size: 1.5rem;
  margin: 1.25rem 0 1rem;
  color: var(--text-primary);
}

.admin-nav {
  display: flex;
  gap: 1rem;
  border-bottom: 1px solid var(--border-default);
  padding-bottom: 0.5rem;
  margin-bottom: 1rem;
}

.admin-nav-link {
  color: var(--text-secondary);
  text-decoration: none;
  font-weight: 500;
  padding: 0.25rem 0.5rem;
  border-radius: var(--radius-sm);
}

.admin-nav-link:hover {
  background: var(--bg-elevated);
  color: var(--text-primary);
}

.admin-grid {
  display: grid;
  gap: 1rem;
}

.admin-grid--2col {
  grid-template-columns: 1fr;
}

@media (min-width: 800px) {
  .admin-grid--2col {
    grid-template-columns: 1fr 1.5fr;
  }
}

.admin-card {
  padding: 1rem 1.25rem;
}

.admin-card h2 {
  font-size: 1rem;
  margin: 0 0 0.75rem;
  color: var(--text-primary);
}

/* Subsection heading inside an admin card — pushes itself away from
   the previous block so it reads as a new section, not a sibling line. */
.admin-card-h2--spaced {
  margin-top: 1.25rem;
}

/* Acknowledged-issue row in the admin issues table — visually fades
   the row and strikes through to indicate the issue is settled. */
.issue-row--ack {
  opacity: 0.6;
  text-decoration: line-through;
}

/* Constrained reading column for admin prose blocks. */
.admin-prose {
  max-width: 60ch;
}

/* Result banners with a left accent — green for OK, red for error. */
.admin-card--success {
  border-left: 4px solid var(--accent-green, #2a8a3f);
  margin-top: 1rem;
}
.admin-card--error {
  border-left: 4px solid var(--accent-red, #c53030);
  margin-top: 1rem;
}

/* Tight error-message paragraph inside an admin card. */
.admin-card-error-msg {
  margin: 0.25rem 0 0;
}

/* Constrained-width admin form layout. */
.admin-form--narrow {
  max-width: 36rem;
  margin-top: 1.5rem;
}

/* Vertical stack of fields inside an admin form. */
.admin-form-stack {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* Wraps an .admin-table that can outgrow the viewport on narrow widths.
   Provides clean horizontal scroll instead of letting the table bleed
   past the page or force the body to scroll horizontally. The fade on
   the right edge hints that there's more content off-screen. */
.admin-table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  position: relative;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-elevated);
}

.admin-table-scroll > .admin-table {
  margin: 0;
}

/* Strip the table's own outer border so the wrapper owns it. */
.admin-table-scroll > .admin-table th:first-child,
.admin-table-scroll > .admin-table td:first-child {
  padding-left: 0.75rem;
}
.admin-table-scroll > .admin-table th:last-child,
.admin-table-scroll > .admin-table td:last-child {
  padding-right: 0.75rem;
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.admin-table th,
.admin-table td {
  text-align: left;
  padding: 0.5rem 0.5rem;
  border-bottom: 1px solid var(--border-default);
  vertical-align: top;
}

.admin-table th {
  font-weight: 600;
  color: var(--text-secondary);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.admin-table--counts td:first-child { width: 40%; }
.admin-table--counts td:nth-child(2) { width: 30%; }

.admin-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.admin-cell-date {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}

.admin-filter {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  align-items: end;
  margin-bottom: 1rem;
  padding: 0.75rem 1rem;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
}

.admin-filter label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.admin-filter select,
.admin-filter input {
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--bg-base);
  color: var(--text-primary);
  font: inherit;
}

.admin-filter-search input {
  min-width: 240px;
}

.admin-status-line {
  display: flex;
  gap: 1rem;
  align-items: center;
  margin-bottom: 1.25rem;
}

.admin-order-id {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 0.95em;
  background: var(--bg-elevated);
  padding: 0.1em 0.4em;
  border-radius: var(--radius-sm);
}

.admin-dl {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 0.4rem 0.75rem;
  margin: 0;
  font-size: 0.9rem;
}

.admin-dl dt {
  color: var(--text-secondary);
  font-weight: 500;
}

.admin-dl dd {
  margin: 0;
  color: var(--text-primary);
  word-break: break-all;
}

.admin-error-msg {
  padding: 0.5rem 0.75rem;
  background: var(--color-danger-bg, #fee2e2);
  color: var(--color-danger, #b91c1c);
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
}

.admin-readonly-note {
  margin-top: 1.5rem;
  font-style: italic;
  font-size: 0.85rem;
}

.admin-actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin: 0.5rem 0 1.5rem;
}

.admin-action-form {
  margin: 0;
}

.admin-toggle-form {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 0.75rem 0;
}

.admin-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  font-size: 0.95rem;
  color: var(--text-primary);
}

.admin-toggle input[type="checkbox"] {
  width: 1.1rem;
  height: 1.1rem;
}

.admin-card--narrow {
  max-width: 560px;
}

.admin-edit-form {
  margin-top: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.admin-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.admin-field label {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--text-primary);
}

.admin-input-prefix {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--bg-base);
  overflow: hidden;
  max-width: 200px;
}

.admin-input-prefix-symbol {
  padding: 0.5rem 0.75rem;
  background: var(--bg-elevated);
  color: var(--text-secondary);
  border-right: 1px solid var(--border-default);
  font-weight: 600;
}

.admin-input-prefix input {
  border: 0;
  padding: 0.5rem 0.75rem;
  background: transparent;
  color: var(--text-primary);
  font: inherit;
  flex: 1;
  min-width: 0;
}

.admin-input-prefix input:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
}

/* Tiny "not set" hint that appears below a Discount price input when
   either discount column on a product is $0 — discount users silently
   fall back to regular pricing in that case, so we surface it instead
   of letting the admin think the feature is wired up. */
.admin-discount-unset-hint {
  margin-top: 0.25rem;
  font-size: 0.6875rem;
  color: var(--color-warning, #C99030);
  font-style: italic;
  text-align: right;
  letter-spacing: 0.02em;
}

.admin-field-hint {
  font-size: 0.8rem;
  color: var(--text-muted);
}

.admin-form-actions {
  display: flex;
  gap: 0.75rem;
  justify-content: flex-end;
  margin-top: 0.5rem;
}

.admin-table--products td:nth-child(4),
.admin-table--products td:nth-child(5) {
  font-variant-numeric: tabular-nums;
}

/* Inline-editable products grid (/admin/products). The grid is wider than
   most admin tables, so wrap it in a horizontal-scroll container and let
   the header stick to the top of the viewport while scrolling vertically. */
.admin-products-grid-wrap {
  overflow-x: auto;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-base);
}

.admin-table--products-grid {
  font-size: 0.88rem;
  min-width: 1100px;
}

.admin-table--products-grid th,
.admin-table--products-grid td {
  vertical-align: middle;
  padding: 0.5rem 0.55rem;
}

.admin-table--products-grid thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-elevated);
  white-space: nowrap;
}

.admin-table--products-grid tbody tr + tr td {
  border-top: 1px solid var(--border-default);
}

.admin-product-name {
  font-weight: 600;
  color: var(--text-primary);
}

.admin-product-meta {
  font-size: 0.75rem;
  color: var(--text-secondary);
  line-height: 1.3;
}

.admin-product-meta code {
  font-size: 0.75rem;
}

.admin-input-prefix--compact {
  max-width: 140px;
  margin-left: auto; /* right-align with the .admin-num cells */
}

.admin-input-prefix--compact .admin-input-prefix-symbol {
  padding: 0.35rem 0.5rem;
  font-size: 0.85rem;
}

.admin-input-prefix--compact input {
  padding: 0.35rem 0.5rem;
  font-size: 0.9rem;
  text-align: right;
  width: 6rem;
}

.admin-product-output {
  display: inline-block;
  min-width: 4.5rem;
  padding: 0.3rem 0.55rem;
  background: var(--bg-elevated);
  border-radius: var(--radius-sm);
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--text-secondary);
}

.admin-product-active-cell {
  text-align: center;
}

.admin-product-active-cell .admin-toggle {
  justify-content: center;
}

.btn-sm {
  padding: 0.3rem 0.7rem;
  font-size: 0.85rem;
}

/* Save-all button container: sits below the table and stays sticky to
   the bottom of the viewport for long product lists so the operator
   doesn't have to scroll back up after editing the last row. The
   sticky background keeps the button readable when content scrolls
   underneath it. */
.admin-products-saveall {
  position: sticky;
  bottom: 0;
  display: flex;
  justify-content: flex-end;
  gap: 0.75rem;
  align-items: center;
  padding: 0.85rem 0.5rem 0.6rem;
  margin-top: 0.5rem;
  background: linear-gradient(to top, var(--bg-base) 70%, transparent);
  z-index: 2;
}

/* Unsaved-changes hint on the Save-all button. Switches the label to
   "Save all (unsaved changes)" via JS and bumps the visual emphasis a
   notch so the operator notices their pending edits. */
.btn--unsaved {
  box-shadow: 0 0 0 2px var(--color-danger-border-strong, rgba(242, 132, 130, 0.35));
}

/* Validation-error markers on the bulk grid. The offending row gets a
   subtle red wash and the inline-error <li>s render on a follow-up <tr>
   spanning the full width. */
.admin-product-row--error > td {
  background: var(--color-danger-subtle, #fee);
}

.admin-product-row--error input[type="number"] {
  border-color: var(--color-danger, #c33);
}

.admin-product-row-errors > td {
  background: var(--color-danger-subtle, #fee);
  padding-top: 0;
}

.admin-product-error {
  margin: 0;
  padding: 0.35rem 0 0.35rem 1.25rem;
  list-style: disc;
  color: var(--color-danger, #c33);
  font-size: 0.82rem;
}

.admin-flash {
  padding: 0.6rem 0.85rem;
  border-radius: var(--radius-sm);
  margin-bottom: 0.75rem;
  font-size: 0.92rem;
}

.admin-flash--ok {
  background: var(--color-success-bg, #dcfce7);
  color: var(--color-success, #15803d);
  border: 1px solid var(--color-success, #15803d);
}

.admin-flash--error {
  background: var(--color-danger-subtle, rgba(242, 132, 130, 0.1));
  color: var(--color-danger, #c33);
  border: 1px solid var(--color-danger-border, rgba(242, 132, 130, 0.2));
}

.admin-shipping-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.admin-shipping-row {
  align-items: flex-start;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-default);
  background: var(--bg-base);
}

.admin-shipping-label {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.admin-shipping-hint {
  font-size: 0.8rem;
}

.admin-gc-report {
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border-default);
}

.admin-gc-report h3 {
  font-size: 0.95rem;
  margin: 0 0 0.5rem;
  color: var(--text-primary);
}

.admin-gc-report h4 {
  font-size: 0.85rem;
  margin: 0.5rem 0 0.25rem;
  color: var(--text-secondary);
}

.admin-table--gc {
  margin-bottom: 0.5rem;
}

.admin-gc-keys ul {
  margin: 0.25rem 0 0.5rem 1rem;
  font-size: 0.85rem;
  list-style: disc;
}

.admin-gc-running-note {
  font-size: 0.85rem;
  margin: 0.5rem 0 0;
  line-height: 1.5;
}

.gc-spinner {
  display: inline-block;
  width: 12px;
  height: 12px;
  border: 2px solid var(--border-default, #e5e7eb);
  border-top-color: var(--color-primary, #2563eb);
  border-radius: 50%;
  animation: gc-spin 0.8s linear infinite;
  vertical-align: middle;
  margin-right: 4px;
}

@keyframes gc-spin {
  to { transform: rotate(360deg); }
}

/* Status pills — color-coded by order state. Falls back to muted for any
   status without an explicit rule. */
.status-pill {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: var(--bg-elevated);
  color: var(--text-secondary);
  border: 1px solid var(--border-default);
  white-space: nowrap;
}

.status-pill--pending    { background: #f3f4f6; color: #6b7280; }
.status-pill--paid       { background: #fef3c7; color: #92400e; }
.status-pill--approved   { background: #fde68a; color: #78350f; }
.status-pill--processing { background: #c7d2fe; color: #3730a3; }
.status-pill--submitted  { background: #dbeafe; color: #1e40af; }
.status-pill--printing   { background: #e0e7ff; color: #3730a3; }
.status-pill--shipped    { background: #d1fae5; color: #065f46; }
.status-pill--delivered  { background: #d1fae5; color: #047857; }
.status-pill--cancelled  { background: #f3f4f6; color: #4b5563; }
.status-pill--refunded   { background: #f5d0fe; color: #86198f; }
.status-pill--error      { background: #fee2e2; color: #b91c1c; }
.status-pill--failed     { background: #fee2e2; color: #991b1b; }
.status-pill--admin      { background: #ede9fe; color: #5b21b6; }

/* Order RPI environment badge — distinguishes orders routed to the RPI
   sandbox vs. production environment. Production is a quiet, neutral pill
   so it fades into the background on healthy/normal orders. Sandbox uses
   the brand terracotta accent so test-environment orders pop visually and
   can't be mistaken for live customer traffic. */
.order-mode-badge {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
  border: 1px solid transparent;
  vertical-align: middle;
  line-height: 1.4;
}

.order-mode-badge--production {
  background: var(--color-success-subtle);
  color: var(--color-success-text);
  border-color: var(--color-success);
}

.order-mode-badge--sandbox {
  background: var(--mp-color-accent-soft);
  color: var(--mp-color-accent-dark);
  border-color: var(--mp-color-accent);
}

/* Larger variant used in the order detail page header so the mode is
   immediately legible next to the order ID. */
.order-mode-badge--lg {
  font-size: 0.8rem;
  padding: 0.25rem 0.75rem;
  margin-left: 0.5rem;
}

/* Reserves the layout slot for the badge while hiding it visually.
   Used for the Issues nav-link badge when UnackedAlertCount is 0 so the
   nav doesn't reflow when alerts toggle. */
.status-pill--hidden {
  visibility: hidden;
}

/* Inline admin notices (refund flash messages, manual-refund warnings). */
.admin-notice {
  display: block;
  margin: 0.75rem 0;
  padding: 0.75rem 1rem;
  border-radius: 6px;
  border: 1px solid transparent;
  font-size: 0.92rem;
}
.admin-notice--success {
  background: #d1fae5;
  color: #065f46;
  border-color: #a7f3d0;
}
.admin-notice--warning {
  background: #fef3c7;
  color: #92400e;
  border-color: #fde68a;
}

/* ── Admin layout helpers (extracted from inline styles) ── */

/* Compact intro paragraph that follows a card heading. Tightens the
   default <p> margin so card content reads as one block. */
.admin-page .muted--intro,
.admin-page p.muted--intro {
  margin-top: 0;
}

/* Tighter intro paragraph that immediately follows the page <h1>.
   Pulls up against the heading and pads down before the next block. */
.admin-page p.muted--page-intro {
  margin-top: -0.5rem;
  margin-bottom: 1rem;
}

/* Sub-text inside .muted blocks (status lines, footer hints). */
.admin-page .muted--small {
  font-size: 0.85rem;
}
.admin-page .muted--meta {
  font-size: 0.875rem;
  margin-bottom: 0.75rem;
}

/* Strip the trailing margin from a small note so the next block sits
   flush below it (used at the bottom of admin cards). */
.admin-page .muted--noflow {
  margin-bottom: 0;
}

/* Inline row inside an admin card: label + control on one line. */
.admin-inline-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

/* Numeric "label width column" used by backup settings inputs to keep
   labels aligned even as the input width changes. */
.admin-input-row .admin-input-label {
  min-width: 11rem;
}
.admin-input-row .admin-input-num {
  width: 6rem;
}

/* Status-pill colour variants for the System page mode toggles.
   Hex values match the warning/success Tailwind palette to stay
   consistent with the issues table. */
.status-pill--ok {
  background: #bbf7d0;
  color: #14532d;
  padding: 0.25rem 0.75rem;
  border-radius: 9999px;
  font-weight: 600;
  font-size: 0.875rem;
}
.status-pill--warn {
  background: #fde68a;
  color: #78350f;
  padding: 0.25rem 0.75rem;
  border-radius: 9999px;
  font-weight: 600;
  font-size: 0.875rem;
}

/* Right-side hint after a button in a form row ("(creds required)"). */
.admin-form-hint {
  margin-left: 0.5rem;
  font-size: 0.85rem;
}

/* Inline status indicator next to a count ("Backfill in progress…"). */
.admin-running-note {
  margin-left: 0.75rem;
  color: var(--color-warning);
}

/* Warning callout inside a backup status block. */
.admin-status-warning {
  margin-top: 0.5rem;
  color: var(--color-warning);
}

/* "Run now" form sits below the status block. */
.admin-run-now {
  margin-top: 0.75rem;
}

/* Common margin-bottom for inline flash banners inside cards. */
.admin-page .flash {
  margin-bottom: 1rem;
}
