:root {
  --ink: #101828;
  --muted: #5b6675;
  --faint: #8792a2;
  --paper: #f4f6f8;
  --card: #ffffff;
  --rule: #dfe3e8;
  --rule-soft: #eceff2;
  --accent: #0b4f6c;
  --accent-ink: #ffffff;
  --accent-soft: #e7eff3;
  --danger: #b42318;
  --danger-soft: #fdeceb;
  --good-bg: #e7f6ec; --good-ink: #10562c;
  --warn-bg: #fdf3e2; --warn-ink: #7a4106;
  --bad-bg: #fdeceb;  --bad-ink: #8a1a12;
  --chip-bg: #eef0f3; --chip-ink: #344054;
  --focus: #2f80b5;
  --lift: 0 8px 24px rgb(16 24 40 / 14%);
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #e6e9ee;
    --muted: #9aa5b4;
    --faint: #7d8797;
    --paper: #0e1319;
    --card: #161c24;
    --rule: #2a323d;
    --rule-soft: #212832;
    --accent: #2d7fa6;
    --accent-ink: #ffffff;
    --accent-soft: #16303d;
    --danger: #d9534a;
    --danger-soft: #2b1412;
    --good-bg: #10281a; --good-ink: #86e0a6;
    --warn-bg: #2a1e0c; --warn-ink: #f0c48a;
    --bad-bg: #2b1412;  --bad-ink: #f4a9a2;
    --chip-bg: #1e242e; --chip-ink: #b9c1cd;
    --focus: #6fb3cf;
    --lift: 0 8px 24px rgb(0 0 0 / 45%);
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

#app.booting { padding: 40px; color: var(--faint); }

:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }

/* ---- layout ---- */
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 12px 24px; background: var(--card); border-bottom: 1px solid var(--rule);
  position: sticky; top: 0; z-index: 5;
}
.brand a { color: var(--ink); font-weight: 650; text-decoration: none; letter-spacing: -0.01em; }
.topbar-nav { display: flex; align-items: center; gap: 14px; font-size: 0.88rem; }

.content { max-width: 940px; margin: 0 auto; padding: 26px 24px 64px; }
.stack { display: flex; flex-direction: column; gap: 18px; }
.stack.narrow { max-width: 620px; }

.centred-card { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.centred-card .card { width: 100%; max-width: 380px; }

.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.page-head h1 { margin: 0 0 3px; font-size: 1.5rem; letter-spacing: -0.02em; }
.page-head-actions { display: flex; align-items: center; gap: 8px; }
.crumb a { color: var(--muted); text-decoration: none; font-size: 0.88rem; }
.crumb a:hover { color: var(--ink); }

/* ---- cards ---- */
.card {
  background: var(--card); border: 1px solid var(--rule); border-radius: 10px; padding: 20px;
}
.card.subtle { background: transparent; }
.card.danger { border-color: color-mix(in srgb, var(--danger) 35%, var(--rule)); }
.card h1 { margin: 0 0 4px; font-size: 1.25rem; letter-spacing: -0.02em; }
.card h2 {
  margin: 0 0 14px; font-size: 0.72rem; font-weight: 650;
  letter-spacing: 0.09em; text-transform: uppercase; color: var(--faint);
}

.banner { padding: 12px 16px; border-radius: 8px; font-size: 0.9rem; }
.banner.bad  { background: var(--bad-bg);  color: var(--bad-ink); }
.banner.warn { background: var(--warn-bg); color: var(--warn-ink); }
.callout {
  margin: 4px 0 0; padding: 11px 14px; border-radius: 8px;
  background: var(--accent-soft); color: var(--muted); font-size: 0.85rem;
}

/* ---- forms ---- */
.field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 15px; }
.field-row { display: flex; gap: 14px; flex-wrap: wrap; }
.field-row .field { flex: 1 1 150px; }
/* A row action takes only the width it needs, and sits at the foot of its
   column so that it lines up with the inputs beside it rather than with their
   labels. */
.field-row .field.remove { flex: 0 0 auto; justify-content: flex-end; }
/* Each box of the printed certificate is one fieldset, numbered to match. */
fieldset.box {
  border: 1px solid var(--rule); border-radius: 8px; padding: 14px 16px 0; margin: 0 0 16px;
}
fieldset.box > legend {
  padding: 0 6px; font-size: 0.7rem; font-weight: 650;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--faint);
}
label { font-size: 0.84rem; color: var(--muted); font-weight: 500; }
.hint { font-size: 0.78rem; color: var(--faint); }
.field-error { font-size: 0.78rem; color: var(--danger); }

input, select, textarea {
  font: inherit; color: var(--ink); background: var(--card);
  border: 1px solid var(--rule); border-radius: 7px; padding: 8px 10px; width: 100%;
}
textarea { resize: vertical; }
input[aria-invalid], textarea[aria-invalid] { border-color: var(--danger); }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--focus); outline-offset: -1px; border-color: transparent; }

button, .button {
  font: inherit; font-weight: 500; cursor: pointer; text-decoration: none; display: inline-block;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--rule); border-radius: 7px; padding: 8px 14px;
}
button:hover, .button:hover { border-color: var(--faint); }
button.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
button.danger { background: var(--danger); border-color: var(--danger); color: #fff; }
button:disabled { opacity: 0.55; cursor: not-allowed; }
button.link {
  background: none; border: none; padding: 0; color: var(--muted); text-decoration: underline; font-weight: 400;
}
button.link:hover { color: var(--ink); }

.actions { display: flex; gap: 9px; flex-wrap: wrap; margin-top: 16px; }
.inline-form { display: flex; gap: 9px; flex-wrap: wrap; align-items: flex-start; }
.inline-form input { flex: 1 1 260px; }

/* ---- the country picker ---- */
/* The box is a plain input and keeps its look; the list is drawn over whatever
   follows it, so a box near the foot of a fieldset does not push it open. */
.combo { position: relative; }
.combo > input { padding-right: 32px; }
.combo-toggle {
  position: absolute; top: 0; right: 0; height: 100%;
  display: flex; align-items: center; padding: 0 10px;
  background: none; border: none; border-radius: 0 7px 7px 0;
  color: var(--faint); font-size: 0.7rem;
}
.combo-toggle:hover { color: var(--ink); }
.combo-list {
  position: absolute; z-index: 10; top: calc(100% + 4px); left: 0; right: 0;
  margin: 0; padding: 4px; list-style: none;
  max-height: 258px; overflow-y: auto; overscroll-behavior: contain;
  background: var(--card); border: 1px solid var(--rule); border-radius: 8px; box-shadow: var(--lift);
}
.combo-option {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding: 6px 9px; border-radius: 6px; cursor: pointer;
}
.combo-option.is-active { background: var(--accent-soft); }
.combo-name { min-width: 0; overflow-wrap: anywhere; }
.combo-hit { font-weight: 650; color: var(--accent); }
.combo-code { flex: none; color: var(--faint); font-size: 0.74rem; letter-spacing: 0.06em; }
.combo-empty { padding: 8px 9px; color: var(--muted); font-size: 0.85rem; }
/* The server's field errors land beside the box they belong to, which for this
   control is inside the wrapper rather than a child of the field. */
.combo .field-error { display: block; margin-top: 5px; }

/* ---- toolbar and table ---- */
.toolbar { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; }
.toolbar input[type="search"] { flex: 1 1 260px; width: auto; }
.toolbar select { width: auto; }
.spacer { flex: 1; }

.grid { width: 100%; border-collapse: collapse; background: var(--card); border: 1px solid var(--rule); border-radius: 10px; overflow: hidden; }
.grid th {
  text-align: left; font-size: 0.7rem; font-weight: 650; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--faint); padding: 11px 14px; border-bottom: 1px solid var(--rule);
}
.grid td { padding: 12px 14px; border-bottom: 1px solid var(--rule-soft); }
.grid tbody tr:last-child td { border-bottom: none; }
.row-link { cursor: pointer; }
.row-link:hover td { background: var(--accent-soft); }

.pager { display: flex; align-items: center; gap: 12px; justify-content: center; padding-top: 4px; }
.empty { padding: 44px 20px; text-align: center; color: var(--muted); background: var(--card); border: 1px solid var(--rule); border-radius: 10px; }
.results { display: flex; flex-direction: column; gap: 12px; }

/* ---- data rows ---- */
.rows { margin: 0; display: grid; gap: 11px; }
.rows .row { display: grid; grid-template-columns: 160px 1fr; gap: 14px; align-items: baseline; }
.rows dt { color: var(--muted); font-size: 0.85rem; }
.rows dd { margin: 0; overflow-wrap: anywhere; }

.timeline { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; font-size: 0.87rem; }
.timeline li { display: grid; grid-template-columns: 190px 1fr auto; gap: 12px; align-items: baseline; }
.timeline .when { color: var(--faint); font-size: 0.82rem; }
.timeline .what { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: 0.85em; }

/* ---- notifications ---- */
/* Fixed to the viewport and outside #app, so a message outlives the re-render
   or the navigation that the action which raised it triggers. */
.toasts {
  position: fixed; top: 14px; right: 14px; z-index: 20;
  display: flex; flex-direction: column; gap: 9px;
  width: min(380px, calc(100vw - 28px));
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 12px 11px 13px; font-size: 0.89rem;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--rule); border-left: 3px solid var(--faint);
  border-radius: 8px; box-shadow: var(--lift);
  animation: toast-in 140ms ease-out;
}
.toast.good { border-left-color: var(--good-ink); }
.toast.bad  { border-left-color: var(--danger); }
.toast-text { flex: 1; overflow-wrap: anywhere; }
.toast-close {
  background: none; border: none; padding: 0 2px; line-height: 1.1;
  color: var(--faint); font-size: 1.1rem;
}
.toast-close:hover { color: var(--ink); border-color: transparent; }
/* pointer-events off while fading: a message on its way out must not swallow a
   click meant for what is underneath it. */
.toast.leaving { opacity: 0; pointer-events: none; transform: translateX(10px); transition: opacity 160ms ease, transform 160ms ease; }

@keyframes toast-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .toast { animation: none; }
  .toast.leaving { transition: none; }
}

/* ---- bits ---- */
.chip {
  display: inline-block; padding: 3px 9px; border-radius: 999px;
  font-size: 0.74rem; font-weight: 600; background: var(--chip-bg); color: var(--chip-ink);
}
.chip.good { background: var(--good-bg); color: var(--good-ink); }
.chip.warn { background: var(--warn-bg); color: var(--warn-ink); }
.chip.bad  { background: var(--bad-bg);  color: var(--bad-ink); }
.chip + .chip { margin-left: 5px; }

.pre { white-space: pre-line; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.mono { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: 0.92em; }
.small { font-size: 0.82em; }
.muted { color: var(--muted); }
.error { color: var(--danger); background: var(--danger-soft); padding: 10px 13px; border-radius: 7px; margin: 0 0 14px; font-size: 0.89rem; }

@media (max-width: 720px) {
  .toasts { top: auto; bottom: 14px; left: 14px; right: 14px; width: auto; }
  .rows .row, .timeline li { grid-template-columns: 1fr; gap: 2px; }
  .grid thead { display: none; }
  .grid, .grid tbody, .grid tr, .grid td { display: block; width: 100%; }
  .grid tr { border-bottom: 1px solid var(--rule); padding: 6px 0; }
  .grid td { border: none; padding: 4px 14px; }
}
