/* HobbyArmory Admin Console.
   Same design system as the image submission admin, mirroring AppColors in the
   app (lib/theme.dart): #050A10 → #0F172A background, teal #00E5FF, glass. */

:root {
  --bg-start: #050A10;
  --bg-end: #0F172A;

  --teal: #00E5FF;
  --teal-dim: rgba(0, 229, 255, 0.14);

  --glass-bg: rgba(255, 255, 255, 0.06);
  --glass-bg-strong: rgba(255, 255, 255, 0.09);
  --glass-border: rgba(255, 255, 255, 0.15);
  --glass-border-soft: rgba(255, 255, 255, 0.08);

  --text: #FFFFFF;
  --text-70: rgba(255, 255, 255, 0.7);
  --text-50: rgba(255, 255, 255, 0.5);
  --text-30: rgba(255, 255, 255, 0.3);

  --ok: #34D399;
  --warn: #FFB300;
  --danger: #F87171;

  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 24px;

  --shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  background: var(--bg-end);
  background-image:
    radial-gradient(1100px 620px at 12% -8%, rgba(0, 229, 255, 0.10), transparent 62%),
    radial-gradient(900px 520px at 92% 4%, rgba(0, 188, 212, 0.07), transparent 58%),
    linear-gradient(165deg, var(--bg-start) 0%, var(--bg-end) 100%);
  background-attachment: fixed;
  color: var(--text);
  min-height: 100vh;
  padding: 24px;
  -webkit-font-smoothing: antialiased;
}

.container { max-width: 1180px; margin: 0 auto; }

.glass {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
}

/* ── Login ─────────────────────────────────────────────────────────────── */

.login-shell {
  min-height: calc(100vh - 48px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.login-card {
  width: 100%;
  max-width: 400px;
  padding: 40px 36px;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  text-align: center;
}

.login-mark {
  width: 56px; height: 56px;
  margin: 0 auto 20px;
  display: grid; place-items: center;
  border-radius: 18px;
  background: var(--teal-dim);
  border: 1px solid rgba(0, 229, 255, 0.35);
  color: var(--teal);
}

.login-card h1 { font-size: 22px; font-weight: 700; letter-spacing: -0.3px; }
.login-card > p { margin-top: 8px; color: var(--text-50); font-size: 14px; }

.login-fields { margin-top: 26px; text-align: left; display: flex; flex-direction: column; gap: 10px; }

.divider {
  display: flex; align-items: center; gap: 12px;
  margin: 18px 0;
  color: var(--text-30); font-size: 12px;
}
.divider::before, .divider::after {
  content: ''; flex: 1; height: 1px; background: var(--glass-border-soft);
}

.btn-google {
  width: 100%;
  padding: 13px;
  background: #fff; border: none; border-radius: 12px;
  color: #1f2430; font-weight: 600; font-size: 15px; font-family: inherit;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.btn-google:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 10px 24px rgba(0,0,0,0.4); }
.btn-google:disabled { opacity: 0.6; cursor: not-allowed; }

/* ── Header + nav ──────────────────────────────────────────────────────── */

header {
  display: flex; justify-content: space-between; align-items: center;
  gap: 20px; flex-wrap: wrap;
  margin-bottom: 22px; padding-bottom: 20px;
  border-bottom: 1px solid var(--glass-border-soft);
}

.title-group { display: flex; align-items: center; gap: 14px; }

.title-mark {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border-radius: 13px;
  background: var(--teal-dim);
  border: 1px solid rgba(0, 229, 255, 0.3);
  color: var(--teal);
  flex-shrink: 0;
}

h1 { font-size: 24px; font-weight: 750; letter-spacing: -0.4px; }
.subtitle { margin-top: 2px; font-size: 13px; color: var(--text-50); }

.header-right { display: flex; align-items: center; gap: 10px; }

.icon-btn {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: 11px;
  color: var(--text-70);
  cursor: pointer;
  transition: all 0.2s var(--ease);
}
.icon-btn:hover { color: var(--text); background: var(--glass-bg-strong); border-color: rgba(255,255,255,0.25); }

.tabs {
  display: flex; gap: 6px; padding: 5px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--glass-border-soft);
  border-radius: 13px;
  margin-bottom: 26px;
  flex-wrap: wrap;
}

.tab {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 18px;
  background: transparent; border: none; border-radius: 9px;
  color: var(--text-50);
  font-size: 14px; font-weight: 600; font-family: inherit;
  cursor: pointer;
  transition: all 0.2s var(--ease);
}
.tab:hover { color: var(--text); background: rgba(255,255,255,0.05); }
.tab.active { color: var(--bg-start); background: var(--teal); box-shadow: 0 4px 16px rgba(0,229,255,0.28); }

.tab .count {
  padding: 1px 7px; border-radius: 999px;
  background: rgba(255,255,255,0.1);
  font-size: 12px; font-weight: 700;
}
.tab.active .count { background: rgba(5,10,16,0.22); }

.panel { display: none; }
.panel.active { display: block; }

/* ── Cards ─────────────────────────────────────────────────────────────── */

.card {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border-soft);
  border-radius: var(--radius);
  padding: 22px;
  margin-bottom: 18px;
}

.card h2 {
  font-size: 15px; font-weight: 700;
  margin-bottom: 4px;
  display: flex; align-items: center; gap: 9px;
}

.card .hint { font-size: 13px; color: var(--text-50); margin-bottom: 16px; line-height: 1.5; }

.card.danger { border-color: rgba(248, 113, 113, 0.3); background: rgba(248, 113, 113, 0.05); }
.card.danger h2 { color: var(--danger); }

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 14px;
  margin-bottom: 18px;
}

.stat {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border-soft);
  border-radius: var(--radius);
  padding: 18px 20px;
}
.stat .value { font-size: 30px; font-weight: 750; letter-spacing: -1px; line-height: 1.1; }
.stat .label { margin-top: 5px; font-size: 12px; color: var(--text-50); text-transform: uppercase; letter-spacing: 0.7px; }
.stat.accent .value { color: var(--teal); }
.stat.warn .value { color: var(--warn); }

/* ── Forms ─────────────────────────────────────────────────────────────── */

label.field { display: block; font-size: 12px; color: var(--text-50); margin-bottom: 6px; font-weight: 600; }

input, select, textarea {
  width: 100%;
  padding: 11px 13px;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border-soft);
  border-radius: 11px;
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
  transition: all 0.2s var(--ease);
}
input::placeholder, textarea::placeholder { color: var(--text-30); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: rgba(0, 229, 255, 0.5);
  background: var(--glass-bg-strong);
}
select option { background: #0B1220; color: #fff; }
textarea { resize: vertical; min-height: 150px; line-height: 1.55; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }

.row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.row > * { flex: 1; min-width: 150px; }
.row > .shrink { flex: 0 0 auto; min-width: 0; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 18px;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: 11px;
  color: var(--text);
  font-size: 14px; font-weight: 600; font-family: inherit;
  cursor: pointer; white-space: nowrap;
  transition: all 0.2s var(--ease);
}
.btn:hover:not(:disabled) { background: var(--glass-bg-strong); transform: translateY(-1px); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; transform: none; }

.btn-primary { background: var(--teal); border-color: var(--teal); color: var(--bg-start); font-weight: 700; }
.btn-primary:hover:not(:disabled) { background: #4DEEFF; }

.btn-ok { background: rgba(52,211,153,0.15); border-color: rgba(52,211,153,0.45); color: var(--ok); }
.btn-ok:hover:not(:disabled) { background: rgba(52,211,153,0.24); }

.btn-danger { background: rgba(248,113,113,0.13); border-color: rgba(248,113,113,0.4); color: var(--danger); }
.btn-danger:hover:not(:disabled) { background: rgba(248,113,113,0.22); }

.btn-row { display: flex; gap: 9px; flex-wrap: wrap; }

/* ── Result banners ────────────────────────────────────────────────────── */

.result {
  margin-top: 14px; padding: 11px 14px;
  border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 500; line-height: 1.5;
  display: none;
}
.result.ok { display: block; background: rgba(52,211,153,0.13); color: var(--ok); border: 1px solid rgba(52,211,153,0.3); }
.result.err { display: block; background: rgba(248,113,113,0.13); color: var(--danger); border: 1px solid rgba(248,113,113,0.3); }
.result.info { display: block; background: var(--teal-dim); color: var(--teal); border: 1px solid rgba(0,229,255,0.3); }

/* ── User detail ───────────────────────────────────────────────────────── */

.detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 0 26px;
  margin-bottom: 4px;
}

.detail-row {
  display: flex; justify-content: space-between; align-items: center; gap: 14px;
  padding: 9px 0;
  border-bottom: 1px solid rgba(255,255,255,0.045);
}
.detail-row .label { color: var(--text-50); font-size: 13px; flex-shrink: 0; }
.detail-row .value { font-size: 13px; font-weight: 500; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.detail-row .value.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--text-70); }

.pill {
  display: inline-block;
  padding: 3px 10px; border-radius: 999px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px;
}
.pill.ok { background: rgba(52,211,153,0.16); color: var(--ok); border: 1px solid rgba(52,211,153,0.32); }
.pill.warn { background: rgba(255,179,0,0.15); color: var(--warn); border: 1px solid rgba(255,179,0,0.32); }
.pill.danger { background: rgba(248,113,113,0.15); color: var(--danger); border: 1px solid rgba(248,113,113,0.32); }
.pill.muted { background: rgba(255,255,255,0.07); color: var(--text-50); border: 1px solid var(--glass-border-soft); }

.counts { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.count-chip {
  padding: 7px 12px;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border-soft);
  border-radius: 10px;
  font-size: 12px; color: var(--text-70);
}
.count-chip b { color: var(--text); font-weight: 700; }

/* ── Tables ────────────────────────────────────────────────────────────── */

.table-wrap { overflow-x: auto; margin-top: 14px; }

table { width: 100%; border-collapse: collapse; font-size: 13px; }
th {
  text-align: left; padding: 9px 12px;
  color: var(--text-50); font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.7px;
  border-bottom: 1px solid var(--glass-border-soft);
  white-space: nowrap;
}
td { padding: 11px 12px; border-bottom: 1px solid rgba(255,255,255,0.04); }
tbody tr { cursor: pointer; transition: background 0.15s var(--ease); }
tbody tr:hover { background: rgba(255,255,255,0.035); }
td.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--text-50); }

.empty { padding: 40px 20px; text-align: center; color: var(--text-30); font-size: 14px; }

/* ── Stats ─────────────────────────────────────────────────────────────── */

/* Nothing in the stats table opens anything, so it keeps the normal cursor. */
#stats-wrap tbody tr { cursor: default; }

.bar-row {
  display: flex; align-items: center; gap: 12px;
  padding: 5px 0;
  font-size: 13px;
}
.bar-label { color: var(--text-50); width: 68px; flex-shrink: 0; font-size: 12px; }
.bar-track {
  flex: 1;
  height: 8px; border-radius: 999px;
  background: rgba(255,255,255,0.06);
  overflow: hidden;
}
.bar-fill {
  display: block; height: 100%;
  border-radius: 999px;
  background: var(--teal);
  min-width: 2px;
}
.bar-value { width: 46px; flex-shrink: 0; text-align: right; font-weight: 600; }

/* ── Inbox ─────────────────────────────────────────────────────────────── */

.report-item {
  border: 1px solid var(--glass-border-soft);
  border-radius: var(--radius-sm);
  padding: 15px 17px;
  margin-bottom: 10px;
  background: var(--glass-bg);
  transition: border-color 0.2s var(--ease);
}
.report-item:hover { border-color: var(--glass-border); }
.report-item.resolved { opacity: 0.55; }

.report-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 8px; }
.report-title { font-weight: 650; font-size: 14px; }
.report-meta { font-size: 12px; color: var(--text-50); margin-bottom: 10px; }
.report-body {
  font-size: 13px; color: var(--text-70); line-height: 1.6;
  background: rgba(0,0,0,0.22);
  border-radius: 8px; padding: 11px 13px;
  white-space: pre-wrap; word-break: break-word;
  max-height: 240px; overflow-y: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
}
.report-actions { display: flex; gap: 8px; margin-top: 11px; flex-wrap: wrap; }

/* ── Broadcast ─────────────────────────────────────────────────────────── */

.preview {
  margin-top: 14px;
  border: 1px solid var(--glass-border-soft);
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
}
.preview iframe { width: 100%; height: 100%; border: none; display: block; background: #fff; }

/* ── Broadcast preview ────────────────────────────────────────────────────
   The stage is grey and the message sits on white inside it, because that is
   the one thing every mail client agrees on: the body is a sheet of paper on
   a background the sender does not control. A preview painted edge to edge
   hides where the message actually ends. */
.preview { padding: 0; background: #d9dde3; resize: vertical; overflow: auto; height: 460px; }
.preview-stage {
  margin: 0 auto; height: 100%; max-width: 600px; background: #fff;
  transition: max-width 0.18s var(--ease);
}

.preview-bar {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  flex-wrap: wrap; margin: 12px 0 8px;
}
.preview-subject { font-size: 13px; color: var(--text-70); min-width: 0; }
.preview-from { color: var(--text-50); }
.preview-from::after { content: " · "; }
.preview-widths { display: flex; gap: 6px; }

.warn-box {
  margin-top: 14px; padding: 12px 14px;
  background: rgba(255, 179, 0, 0.1);
  border: 1px solid rgba(255, 179, 0, 0.3);
  border-radius: var(--radius-sm);
  color: var(--warn);
  font-size: 13px; line-height: 1.55;
}

.spinner {
  width: 15px; height: 15px;
  border: 2px solid rgba(255,255,255,0.2);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (max-width: 700px) {
  body { padding: 16px; }
  header { flex-direction: column; align-items: flex-start; }
  .detail-grid { grid-template-columns: 1fr; }
  .row > * { min-width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ── Dialogs ───────────────────────────────────────────────────────────
   Native <dialog> so Escape, focus trapping and inertness come for free.
   ::backdrop is the only part that needs painting. */

.dlg {
  /* The UA centres a modal dialog with `margin: auto`, which the global
     `* { margin: 0 }` reset at the top of this file silently overrides — so
     without this the dialog opens in the top-left corner. */
  margin: auto;
  padding: 0;
  border: 1px solid var(--glass-border);
  border-radius: var(--radius);
  background: #0B1220;
  color: var(--text);
  box-shadow: var(--shadow);
  width: min(620px, calc(100vw - 32px));
  max-height: min(88vh, 900px);
  overflow: hidden;
}
.dlg.wide { width: min(880px, calc(100vw - 32px)); }

/* Where the pipeline got its answer. Worth a click before approving, so the
   links are in the header rather than buried at the bottom of the form. */
.dlg-sources { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 8px; font-size: 12.5px; }
.dlg-sources a { color: var(--teal); text-decoration: none; }
.dlg-sources a:hover { text-decoration: underline; }

.ai-note {
  margin-top: 12px; padding: 10px 13px; border-radius: var(--radius-sm);
  background: var(--teal-dim); border: 1px solid rgba(0,229,255,0.25);
  font-size: 12.5px; line-height: 1.55; color: var(--text-70);
}
.ai-note b { color: var(--teal); font-weight: 650; }
.dlg::backdrop { background: rgba(3, 7, 12, 0.72); backdrop-filter: blur(3px); }

.dlg-inner { display: flex; flex-direction: column; max-height: inherit; }

.dlg-head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 16px;
  padding: 20px 22px 16px;
  border-bottom: 1px solid var(--glass-border-soft);
}
.dlg-head h2 { font-size: 17px; font-weight: 700; letter-spacing: -0.2px; }
.dlg-sub { margin-top: 4px; font-size: 12.5px; color: var(--text-50); }

.dlg-body { padding: 20px 22px; overflow-y: auto; flex: 1; }

.dlg-h3 {
  font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.8px;
  color: var(--text-50); margin-bottom: 10px;
}

.dlg-foot {
  padding: 14px 22px 18px;
  border-top: 1px solid var(--glass-border-soft);
  background: rgba(0, 0, 0, 0.22);
}
.dlg-foot .btn-row { justify-content: flex-end; margin-top: 0; }
.dlg-foot .result { margin-bottom: 0; }
.dlg-foot .result:not(.ok):not(.err):not(.info) { display: none; }
.dlg-foot .result.ok, .dlg-foot .result.err, .dlg-foot .result.info { margin-bottom: 12px; }

/* ── Outcome picker ────────────────────────────────────────────────────
   The chosen outcome is both the email template and the instruction the
   pipeline reads, so it is one control, not two. */

.choice-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 8px; }

.choice {
  text-align: left;
  padding: 11px 13px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--glass-border-soft);
  background: var(--glass-bg);
  color: var(--text-70);
  cursor: pointer;
  font: inherit;
  transition: all 0.18s var(--ease);
}
.choice:hover { background: var(--glass-bg-strong); border-color: var(--glass-border); color: var(--text); }
.choice strong { display: block; font-size: 13.5px; font-weight: 650; color: var(--text); }
.choice span { display: block; margin-top: 3px; font-size: 11.5px; color: var(--text-50); line-height: 1.45; }
.choice.on { border-color: var(--teal); background: var(--teal-dim); }
.choice.on strong { color: var(--teal); }
.choice:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }

.check { display: flex; align-items: center; gap: 9px; font-size: 13px; color: var(--text-70); margin-top: 9px; cursor: pointer; }
.check input { width: auto; flex: 0 0 auto; accent-color: var(--teal); }

.field-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; }

/* ── Pipeline questions ────────────────────────────────────────────────
   An unanswered question blocks approval, so it has to read as a blocker
   rather than as another field. */

.q {
  border: 1px solid rgba(255, 179, 0, 0.32);
  background: rgba(255, 179, 0, 0.08);
  border-radius: var(--radius-sm);
  padding: 13px 15px;
  margin-bottom: 10px;
}
.q.answered { border-color: rgba(52, 211, 153, 0.34); background: rgba(52, 211, 153, 0.07); }
.q-text { font-size: 13.5px; font-weight: 600; line-height: 1.5; }
.q-why { font-size: 12px; color: var(--text-50); margin-top: 4px; line-height: 1.5; }
.q-opts { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 10px; }
.q-opt {
  padding: 6px 12px; border-radius: 999px; cursor: pointer; font: inherit; font-size: 12.5px;
  border: 1px solid var(--glass-border-soft); background: var(--glass-bg); color: var(--text-70);
  transition: all 0.18s var(--ease);
}
.q-opt:hover { background: var(--glass-bg-strong); color: var(--text); }
.q-opt.on { border-color: var(--teal); background: var(--teal-dim); color: var(--teal); font-weight: 650; }
.q-opt:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }

/* ── Queue items ───────────────────────────────────────────────────────
   Confidence is a stripe as well as a word: a low-confidence proposal has
   to be spottable in a list without reading any of it. */

.queue-item {
  border: 1px solid var(--glass-border-soft);
  border-left: 3px solid var(--text-30);
  border-radius: var(--radius-sm);
  padding: 15px 17px;
  margin-bottom: 10px;
  background: var(--glass-bg);
  transition: border-color 0.2s var(--ease);
}
.queue-item:hover { border-color: var(--glass-border); }
.queue-item.conf-high { border-left-color: var(--ok); }
.queue-item.conf-medium { border-left-color: var(--warn); }
.queue-item.conf-low { border-left-color: var(--danger); }
.queue-item.done { opacity: 0.55; }

.queue-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.queue-title { font-weight: 650; font-size: 14px; }
.queue-meta { font-size: 12px; color: var(--text-50); margin-top: 5px; }
.queue-line {
  margin-top: 10px; font-size: 12px; line-height: 1.6;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--text-70);
  background: rgba(0, 0, 0, 0.22); border-radius: 8px; padding: 10px 12px;
  word-break: break-word;
}
.queue-flags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.queue-actions { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }

@media (max-width: 640px) {
  .dlg { width: 100vw; max-width: 100vw; max-height: 100vh; border-radius: 0; border: none; }
  .choice-grid, .field-grid { grid-template-columns: 1fr; }
}

/* An advisory question states an assumption; a blocking one is a fork. They
   must not look alike — the whole point is that only one of them stops you. */
.q.advisory { border-color: var(--glass-border-soft); background: var(--glass-bg); }
.q-tag {
  display: inline-block; font-size: 10px; font-weight: 700; letter-spacing: 0.6px;
  padding: 1px 6px; border-radius: 4px; margin-right: 6px; vertical-align: 1px;
  background: rgba(255,255,255,0.1); color: var(--text-50);
}

/* ── Publish run ───────────────────────────────────────────────────────
   The work happens on the Mac, so the console can only report. Showing the
   log matters more than a spinner would: when a publish fails it fails inside
   one of five scripts, and which one is the whole answer. */
.run-panel {
  border: 1px solid var(--glass-border-soft);
  border-radius: var(--radius-sm);
  background: rgba(0,0,0,0.24);
  padding: 14px 16px;
  margin-bottom: 14px;
}
.run-panel.ok { border-color: rgba(52,211,153,0.45); }
.run-panel.err { border-color: rgba(248,113,113,0.45); }
.run-head { display: flex; align-items: center; gap: 10px; font-size: 13.5px; font-weight: 650; }
.run-log {
  margin-top: 10px; max-height: 260px; overflow: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px; line-height: 1.55; color: var(--text-70);
  white-space: pre-wrap; word-break: break-word;
}

.stale-note {
  padding: 9px 12px; margin-bottom: 10px;
  border: 1px solid rgba(255,179,0,0.32); background: rgba(255,179,0,0.09);
  border-radius: var(--radius-sm); color: var(--warn);
  font-size: 12.5px; line-height: 1.5;
}

/* ── Corrections ──────────────────────────────────────────────────────────
   A fix proposal answers a different question from a new set: not "is this
   right" but "is this change right". So the report and the diff sit above the
   form, and the diff is the only place in the console where the OLD value is
   shown as prominently as the new one — reviewing a correction without seeing
   what it replaces is just reading a set row again. */
.fix-block { margin-top: 12px; }
.fix-report {
  padding: 10px 13px; border-radius: var(--radius-sm);
  background: rgba(255,82,82,0.08); border: 1px solid rgba(255,82,82,0.26);
  font-size: 12.5px; line-height: 1.55; color: var(--text-70);
  white-space: pre-wrap; word-break: break-word;
}
.fix-report b { color: var(--danger); font-weight: 650; }
.fix-diff { margin-top: 10px; display: grid; gap: 8px; }
.fix-row {
  display: grid; grid-template-columns: 92px 1fr; gap: 4px 12px;
  padding: 9px 12px; border-radius: var(--radius-sm);
  background: rgba(0,0,0,0.22); border: 1px solid var(--glass-border-soft);
}
.fix-field {
  grid-row: span 2; align-self: center;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.6px;
  color: var(--text-50);
}
.fix-was, .fix-now {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; line-height: 1.5; word-break: break-word;
}
.fix-was { color: var(--text-50); text-decoration: line-through; }
.fix-now { color: var(--ok); }
.fix-none {
  padding: 9px 12px; border-radius: var(--radius-sm);
  border: 1px solid rgba(255,179,0,0.32); background: rgba(255,179,0,0.09);
  color: var(--warn); font-size: 12.5px; line-height: 1.5;
}

/* ── Paints queue ──────────────────────────────────────────────────────────
   A staged paint is judged on one thing a table cannot show: the colour. So
   the row leads with a large swatch and the maker's own photograph side by
   side, and the hex field is the only control that matters. */

.paint-row {
  display: grid;
  grid-template-columns: 76px 84px 1fr;
  gap: 16px;
  align-items: start;
  padding: 16px;
  border: 1px solid var(--glass-border-soft);
  border-radius: var(--radius-sm);
  background: var(--glass-bg);
  margin-bottom: 10px;
}

/* The swatch is the answer, so it is the biggest thing on the row. Checkerboard
   behind it, because an empty swatch and a white paint must not look the same. */
.paint-swatch {
  width: 76px;
  height: 76px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--glass-border);
  background-image:
    linear-gradient(45deg, rgba(255,255,255,0.09) 25%, transparent 25%),
    linear-gradient(-45deg, rgba(255,255,255,0.09) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, rgba(255,255,255,0.09) 75%),
    linear-gradient(-45deg, transparent 75%, rgba(255,255,255,0.09) 75%);
  background-size: 12px 12px;
  background-position: 0 0, 0 6px, 6px -6px, -6px 0;
  position: relative;
  overflow: hidden;
}
.paint-swatch span {
  position: absolute;
  inset: 0;
  display: block;
}
.paint-swatch.empty::after {
  content: "no colour";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 10px;
  letter-spacing: 0.4px;
  color: var(--text-30);
  text-transform: uppercase;
}

/* The maker's photo. Usually a bottle, which is exactly why the pipeline would
   not read a colour off it — but it is what a person eyeballs the paint by. */
.paint-photo {
  width: 84px;
  height: 84px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--glass-border-soft);
  background: rgba(255,255,255,0.04);
  object-fit: contain;
  display: block;
}

.paint-photo[data-paint-zoom] { cursor: zoom-in; }
/* Enlarged for the eyedropper: it spans the whole row under the swatch and the
   text, so the paint can be aimed at rather than guessed at. */
.paint-photo.zoomed {
  grid-column: 1 / -1;
  grid-row: 2;
  width: 100%;
  height: 360px;
  cursor: zoom-out;
  background: #fff;
}

.paint-row:has(.paint-photo.zoomed) .paint-main { grid-column: 2 / -1; grid-row: 1; }

.paint-main h3 { font-size: 15px; font-weight: 650; letter-spacing: -0.2px; }
.paint-meta { margin-top: 3px; font-size: 12px; color: var(--text-50); }
.paint-why {
  margin-top: 8px;
  font-size: 12.5px;
  color: var(--text-70);
  line-height: 1.5;
}
.paint-why a { color: var(--teal); text-decoration: none; }
.paint-why a:hover { text-decoration: underline; }
.paint-controls {
  margin-top: 12px;
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.paint-controls input[type="text"] {
  width: 112px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  text-transform: uppercase;
}
/* The native picker is 40px of chrome we cannot restyle, so it is made small
   and sits against the text field as one control. */
.paint-controls input[type="color"] {
  width: 42px;
  height: 38px;
  padding: 2px;
  cursor: pointer;
}
.paint-group-head {
  margin: 20px 0 10px;
  font-size: 12px;
  font-weight: 650;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-50);
}
.paint-group-head:first-child { margin-top: 0; }

@media (max-width: 620px) {
  .paint-row { grid-template-columns: 60px 1fr; }
  .paint-swatch { width: 60px; height: 60px; }
  .paint-photo { display: none; }
}

/* A colour report is a comparison, so it is drawn as one: what the app shows
   now, what the reporter says it should be, and the decision, left to right. */
.report-swatches {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.report-chip { text-align: center; }
.report-chip i {
  display: block;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--glass-border);
}
.report-chip b {
  display: block;
  margin-top: 5px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-50);
}
.report-chip code {
  display: block;
  font-size: 10.5px;
  color: var(--text-30);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.report-arrow { color: var(--text-30); font-size: 18px; align-self: center; }
