/*
 * geoadmin.css — "Cartographic control surface"
 * A scoped admin design system. Everything lives under .gx-page and uses
 * .gx-* component classes, so it can be adopted by any admin page without
 * disturbing the surrounding SmartAdmin/Bootstrap shell.
 *
 * Thesis: geometry and status are instrument data, not decoration.
 * Grotesque UI type + monospace for every coordinate, id, and count.
 */

/*
 * Tokens live on :root (not .gx-page) so the toast — which may render on an
 * admin page that has no .gx-page wrapper — can still resolve them. Custom
 * properties are inert until a .gx-* rule references them, so this changes
 * nothing on non-geoadmin pages.
 */
:root {
  /* palette — survey paper, topographic ink, benchmark teal */
  --gx-paper:      #F7F8F6;
  --gx-surface:    #FFFFFF;
  --gx-surface-2:  #F1F4F1;
  --gx-ink:        #1B2A2E;
  --gx-slate:      #5C6B70;
  --gx-slate-soft: #8A979B;
  --gx-hairline:   #DDE3E0;
  --gx-hairline-2: #EAEEEB;
  --gx-accent:     #0E7C86;
  --gx-accent-ink: #0A5A61;
  --gx-accent-wash:#E3F0F0;

  /* map-legend status hues */
  --gx-add:        #2E7D5B;
  --gx-add-wash:   #E4F0EA;
  --gx-update:     #B5761F;
  --gx-update-wash:#F6EEDD;
  --gx-delete:     #B23A3A;
  --gx-delete-wash:#F5E2E1;

  /* type */
  --gx-font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --gx-font-mono: ui-monospace, "SF Mono", "JetBrains Mono", "Roboto Mono", Menlo, Consolas, monospace;

  --gx-radius: 8px;
  --gx-radius-sm: 5px;
  --gx-shadow: 0 1px 2px rgba(27,42,46,.05), 0 1px 3px rgba(27,42,46,.06);
  --gx-shadow-lift: 0 4px 16px rgba(27,42,46,.10);
}

.gx-page {
  background: var(--gx-paper);
  color: var(--gx-ink);
  font-family: var(--gx-font-ui);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  padding: 0 0 64px;
  min-height: 100%;
}

.gx-page *,
.gx-page *::before,
.gx-page *::after { box-sizing: border-box; }

/* ---- graticule status bar: states the pipeline truth ---- */
.gx-statusbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 24px;
  background:
    linear-gradient(var(--gx-hairline-2) 1px, transparent 1px) 0 0 / 100% 14px,
    var(--gx-surface);
  border-bottom: 1px solid var(--gx-hairline);
}
.gx-statusbar__mark {
  width: 26px; height: 26px; flex: none;
  border: 1.5px solid var(--gx-accent);
  border-radius: 50%;
  position: relative;
}
.gx-statusbar__mark::before,
.gx-statusbar__mark::after {
  content: ""; position: absolute; background: var(--gx-accent);
}
.gx-statusbar__mark::before { left: 50%; top: 3px; bottom: 3px; width: 1.5px; transform: translateX(-50%); }
.gx-statusbar__mark::after  { top: 50%; left: 3px; right: 3px; height: 1.5px; transform: translateY(-50%); }
.gx-statusbar__text { display: flex; flex-direction: column; gap: 1px; }
.gx-statusbar__title {
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gx-slate); font-weight: 600;
}
.gx-statusbar__note { font-size: 13px; color: var(--gx-ink); }
.gx-statusbar__note strong { color: var(--gx-accent-ink); }
.gx-statusbar__spacer { flex: 1; }
.gx-statusbar__count {
  font-family: var(--gx-font-mono);
  font-size: 13px; color: var(--gx-slate);
  border: 1px solid var(--gx-hairline);
  border-radius: 999px; padding: 3px 12px; background: var(--gx-paper);
}
.gx-statusbar__count b { color: var(--gx-ink); }

/* ---- layout shell ---- */
.gx-wrap { max-width: 1680px; margin: 0 auto; padding: 24px 20px 0; }
.gx-head { margin-bottom: 22px; }
.gx-eyebrow {
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--gx-accent-ink); font-weight: 600; margin: 0 0 6px;
}
.gx-title { font-size: 26px; font-weight: 700; letter-spacing: -.01em; margin: 0; color: var(--gx-ink); }
.gx-sub { color: var(--gx-slate); margin: 6px 0 0; font-size: 14px; }

.gx-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: 20px; align-items: start; }

/* ---- card ---- */
.gx-card {
  background: var(--gx-surface);
  border: 1px solid var(--gx-hairline);
  border-radius: var(--gx-radius);
  box-shadow: var(--gx-shadow);
  overflow: hidden;
}
.gx-card__head {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--gx-hairline-2);
}
.gx-card__head .gx-eyebrow { margin: 0; }
.gx-card__head-icon {
  width: 18px; height: 18px; color: var(--gx-accent);
}
.gx-card__spacer { flex: 1; }
.gx-card__body { padding: 18px; }
.gx-card__body--flush { padding: 0; }

/* ---- toolbar / filters ---- */
.gx-toolbar {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px;
  padding: 16px 18px; border-bottom: 1px solid var(--gx-hairline-2);
  background: var(--gx-surface);
}
.gx-field { display: flex; flex-direction: column; gap: 5px; }
.gx-label {
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--gx-slate); font-weight: 600;
}
.gx-input, .gx-select {
  font: inherit; color: var(--gx-ink);
  background: var(--gx-surface);
  border: 1px solid var(--gx-hairline);
  border-radius: var(--gx-radius-sm);
  padding: 8px 11px; height: 38px; min-width: 150px;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.gx-input:hover, .gx-select:hover { border-color: var(--gx-slate-soft); }
.gx-input:focus-visible, .gx-select:focus-visible,
.gx-input:focus, .gx-select:focus {
  outline: none; border-color: var(--gx-accent);
  box-shadow: 0 0 0 3px var(--gx-accent-wash);
}
.gx-toolbar__spacer { flex: 1; }

/* ---- buttons ---- */
.gx-btn {
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-weight: 600; font-size: 13px;
  border: 1px solid var(--gx-hairline);
  background: var(--gx-surface); color: var(--gx-ink);
  border-radius: var(--gx-radius-sm);
  padding: 8px 15px; height: 38px; cursor: pointer;
  text-decoration: none; white-space: nowrap;
  transition: background .12s ease, border-color .12s ease, color .12s ease, box-shadow .12s ease, transform .06s ease;
}
.gx-btn:hover { border-color: var(--gx-slate-soft); background: var(--gx-surface-2); color: var(--gx-ink); text-decoration: none; }
.gx-btn:active { transform: translateY(1px); }
.gx-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--gx-accent-wash); }
.gx-btn--primary { background: var(--gx-accent); border-color: var(--gx-accent); color: #fff; }
.gx-btn--primary:hover { background: var(--gx-accent-ink); border-color: var(--gx-accent-ink); color: #fff; }
.gx-btn--danger { color: var(--gx-delete); border-color: var(--gx-delete-wash); background: var(--gx-delete-wash); }
.gx-btn--danger:hover { background: var(--gx-delete); border-color: var(--gx-delete); color: #fff; }
.gx-btn--ghost { background: transparent; border-color: transparent; color: var(--gx-slate); }
.gx-btn--ghost:hover { background: var(--gx-surface-2); color: var(--gx-ink); border-color: transparent; }
.gx-btn--sm { height: 30px; padding: 4px 11px; font-size: 12px; }
.gx-btn[disabled] { opacity: .45; cursor: not-allowed; }

/* ---- data table with action spine ---- */
.gx-tablewrap { overflow-x: auto; }
.gx-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.gx-table thead th {
  text-align: left; font-size: 11px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--gx-slate); font-weight: 600;
  padding: 11px 16px; border-bottom: 1px solid var(--gx-hairline);
  white-space: nowrap; background: var(--gx-surface);
}
.gx-table thead th.gx-num { text-align: right; }
.gx-table tbody td {
  padding: 13px 16px; border-bottom: 1px solid var(--gx-hairline-2);
  vertical-align: middle;
}
.gx-table tbody td.gx-num { text-align: right; }
.gx-table tbody tr { transition: background .1s ease; }
.gx-table tbody tr:hover { background: var(--gx-surface-2); }
.gx-table tbody tr:last-child td { border-bottom: none; }
.gx-table tbody tr.gx-rowlink { cursor: pointer; }

/* the signature: colored action spine on the leading cell */
.gx-table tbody td:first-child {
  box-shadow: inset 3px 0 0 var(--gx-spine, var(--gx-hairline));
  padding-left: 18px;
}
.gx-row--add    { --gx-spine: var(--gx-add); }
.gx-row--update { --gx-spine: var(--gx-update); }
.gx-row--delete { --gx-spine: var(--gx-delete); }

.gx-place { font-weight: 600; color: var(--gx-ink); }
.gx-place a { color: var(--gx-ink); text-decoration: none; }
.gx-place a:hover { color: var(--gx-accent-ink); text-decoration: underline; }
.gx-uid { font-family: var(--gx-font-mono); font-size: 12px; color: var(--gx-slate-soft); margin-top: 2px; }

/* compact ancestor trail inside a cell — identifies the place by lineage */
.gx-trail { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; font-size: 12px; color: var(--gx-slate); margin-top: 3px; }
.gx-trail__sep { color: var(--gx-slate-soft); }

/* ---- change set: one chip per field a patch sets ---- */
.gx-changes { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.gx-chip--accent { color: var(--gx-accent-ink); background: var(--gx-accent-wash); border-color: #cfe4e4; }
.gx-chip--delete { color: var(--gx-delete);     background: var(--gx-delete-wash); border-color: #eccbca; }

/* ---- expand toggle + detail row (the values a patch writes) ---- */
.gx-expand {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; vertical-align: middle;
  border: 1px solid var(--gx-hairline); border-radius: var(--gx-radius-sm);
  background: var(--gx-surface); color: var(--gx-slate); cursor: pointer;
  transition: border-color .12s ease, background .12s ease, color .12s ease;
}
.gx-expand:hover { border-color: var(--gx-slate-soft); color: var(--gx-ink); }
.gx-expand:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--gx-accent-wash); }
.gx-expand svg { width: 14px; height: 14px; transition: transform .12s ease; }
.gx-expand[aria-expanded="true"] { border-color: var(--gx-accent); color: var(--gx-accent-ink); }
.gx-expand[aria-expanded="true"] svg { transform: rotate(90deg); }

.gx-patch, .gx-enh { cursor: pointer; }
.gx-detail > td { background: var(--gx-surface-2); padding: 14px 18px; border-bottom: 1px solid var(--gx-hairline); }
.gx-detail > td:first-child { box-shadow: none; padding: 0; }
/* --full: the detail row is an editor, not an indented read-out of the row above,
   so it spans every column instead of spending the widest one on a spacer cell.
   Restores the padding the spacer rule zeroes — without this the content renders
   flush against the table edge. */
.gx-detail--full > td:first-child { padding: 14px 18px; }
.gx-detail .gx-dl { max-width: 860px; }

/* ---- badges ---- */
.gx-badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--gx-font-mono); font-size: 11px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase;
  padding: 3px 9px 3px 8px; border-radius: 999px;
  border: 1px solid transparent;
}
/* the base rule sets display, which outranks the user-agent [hidden] { display: none } —
   without this the hidden attribute toggles nothing. Any .gx-* that sets display needs it. */
.gx-badge[hidden] { display: none; }
.gx-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.gx-badge--add    { color: var(--gx-add);    background: var(--gx-add-wash);    border-color: #cfe4d8; }
.gx-badge--update { color: var(--gx-update); background: var(--gx-update-wash); border-color: #ecdcbe; }
.gx-badge--delete { color: var(--gx-delete); background: var(--gx-delete-wash); border-color: #eccbca; }

/* ---- mono data primitives ---- */
.gx-mono { font-family: var(--gx-font-mono); font-size: 13px; color: var(--gx-ink); font-variant-numeric: tabular-nums; }
.gx-muted { color: var(--gx-slate-soft); }
.gx-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--gx-font-mono); font-size: 12px; color: var(--gx-slate);
  background: var(--gx-paper); border: 1px solid var(--gx-hairline);
  border-radius: 5px; padding: 2px 8px;
}
.gx-chip svg { width: 12px; height: 12px; color: var(--gx-accent); }

/* ---- empty state ---- */
.gx-empty { text-align: center; padding: 56px 24px; }
.gx-empty__mark { width: 46px; height: 46px; color: var(--gx-slate-soft); margin: 0 auto 14px; }
.gx-empty__title { font-size: 16px; font-weight: 600; margin: 0 0 4px; }
.gx-empty__note { color: var(--gx-slate); margin: 0 0 18px; }

/* ---- map / drawing surface ---- */
.gx-map { width: 100%; height: 460px; background: var(--gx-surface-2); }
.gx-drawbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 12px 14px; border-top: 1px solid var(--gx-hairline-2);
  background: var(--gx-surface);
}
.gx-readout {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--gx-font-mono); font-size: 12px; color: var(--gx-slate);
  margin-left: auto;
}
.gx-readout b { color: var(--gx-ink); }
.gx-readout__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--gx-slate-soft); }
.gx-readout__dot--live { background: var(--gx-add); box-shadow: 0 0 0 3px var(--gx-add-wash); }

.gx-instr {
  display: flex; gap: 9px; align-items: flex-start;
  padding: 11px 14px; margin: 0;
  background: var(--gx-accent-wash); color: var(--gx-accent-ink);
  border-bottom: 1px solid #cfe4e4; font-size: 13px;
}
.gx-instr svg { width: 16px; height: 16px; flex: none; margin-top: 1px; }

/* ---- form column ---- */
.gx-form { display: flex; flex-direction: column; gap: 15px; }
.gx-form .gx-field { gap: 6px; }
.gx-form .gx-input, .gx-form .gx-select, .gx-form textarea.gx-input { width: 100%; }
.gx-form textarea.gx-input { height: auto; min-height: 72px; resize: vertical; padding: 9px 11px; }
.gx-form__foot { display: flex; align-items: center; gap: 10px; margin-top: 4px; }
.gx-form__hint { color: var(--gx-slate-soft); font-size: 12px; }

/* ---- form row (2-up field grid within a form; add --3 for a 3-up row) ---- */
.gx-formrow { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; }
.gx-formrow--3 { grid-template-columns: repeat(3, 1fr); }

/* ---- segmented choice (radio group) ---- */
.gx-choice { display: inline-flex; flex-wrap: wrap; gap: 8px; }
.gx-choice__opt {
  display: inline-flex; align-items: center; gap: 8px;
  height: 38px; padding: 0 14px;
  border: 1px solid var(--gx-hairline); border-radius: var(--gx-radius-sm);
  background: var(--gx-surface); color: var(--gx-slate);
  font-size: 13px; font-weight: 600; cursor: pointer;
  transition: border-color .12s ease, background .12s ease, color .12s ease;
}
.gx-choice__opt:hover { border-color: var(--gx-slate-soft); color: var(--gx-ink); }
.gx-choice__opt input { accent-color: var(--gx-accent); margin: 0; }
.gx-choice__opt:has(input:checked) { border-color: var(--gx-accent); background: var(--gx-accent-wash); color: var(--gx-accent-ink); }
.gx-choice__opt:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--gx-accent-wash); }

/* ---- vertical stack utility ---- */
.gx-stack { display: flex; flex-direction: column; gap: 10px; }

/* ---- mono output block (wraps; for response bodies / logs) ---- */
.gx-output { font-family: var(--gx-font-mono); font-size: 12px; line-height: 1.6; color: var(--gx-ink); white-space: pre-wrap; word-break: break-word; margin: 0; }

/* ---- breadcrumb ---- */
.gx-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; font-size: 12px; color: var(--gx-slate); margin: 0 0 16px; }
.gx-crumbs a { color: var(--gx-slate); text-decoration: none; }
.gx-crumbs a:hover { color: var(--gx-accent-ink); }
.gx-crumbs__sep { color: var(--gx-slate-soft); }
.gx-crumbs__here { color: var(--gx-ink); font-weight: 600; }

/* ---- definition list ---- */
.gx-dl { display: grid; grid-template-columns: max-content 1fr; gap: 9px 20px; align-items: baseline; margin: 0; }
.gx-dl dt { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--gx-slate); font-weight: 600; }
.gx-dl dd { margin: 0; color: var(--gx-ink); min-width: 0; overflow-wrap: anywhere; }

/* ---- stat tiles ---- */
.gx-stats { display: flex; flex-wrap: wrap; gap: 10px; }
.gx-stat { display: flex; flex-direction: column; gap: 3px; padding: 11px 15px; border: 1px solid var(--gx-hairline); border-radius: var(--gx-radius-sm); background: var(--gx-surface); min-width: 132px; }
.gx-stat__label { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--gx-slate); font-weight: 600; }
.gx-stat__value { font-family: var(--gx-font-mono); font-size: 19px; font-variant-numeric: tabular-nums; color: var(--gx-ink); line-height: 1.1; }
.gx-stat--warn .gx-stat__value { color: var(--gx-update); }
.gx-stat--alert .gx-stat__value { color: var(--gx-delete); }
.gx-stat__link { font-size: 12px; color: var(--gx-accent-ink); text-decoration: none; margin-top: 2px; }
.gx-stat__link:hover { text-decoration: underline; }

/* ---- zone grid (child places) ---- */
.gx-zonegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px; }
.gx-zone { display: flex; align-items: center; gap: 8px; padding: 9px 12px; border: 1px solid var(--gx-hairline); border-radius: var(--gx-radius-sm); text-decoration: none; color: var(--gx-ink); background: var(--gx-surface); font-size: 13px; transition: border-color .12s, background .12s; }
.gx-zone:hover { border-color: var(--gx-accent); background: var(--gx-surface-2); color: var(--gx-ink); text-decoration: none; }
.gx-zone__name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gx-zone__type { margin-left: auto; font-family: var(--gx-font-mono); font-size: 11px; color: var(--gx-slate-soft); white-space: nowrap; }

/* ---- mono textarea (coordinate / json input) ---- */
.gx-textarea-mono { font-family: var(--gx-font-mono); font-size: 12.5px; line-height: 1.6; width: 100%; min-height: 340px; resize: vertical; color: var(--gx-ink); background: var(--gx-surface); border: 1px solid var(--gx-hairline); border-radius: var(--gx-radius-sm); padding: 11px 12px; tab-size: 2; }
.gx-textarea-mono:focus-visible, .gx-textarea-mono:focus { outline: none; border-color: var(--gx-accent); box-shadow: 0 0 0 3px var(--gx-accent-wash); }

/* ---- toast: transient action feedback ---- */
.gx-toast-wrap {
  position: fixed; top: 18px; right: 18px; z-index: 1080;
  display: flex; flex-direction: column; gap: 10px;
  width: 340px; max-width: calc(100vw - 36px);
  /* set here too: the wrap may live on <body> of a page with no .gx-page */
  font-family: var(--gx-font-ui);
}
.gx-toast {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 13px 14px;
  background: var(--gx-surface);
  border: 1px solid var(--gx-hairline); border-left-width: 3px;
  border-radius: var(--gx-radius); box-shadow: var(--gx-shadow-lift);
  animation: gx-toast-in .16s ease;
}
.gx-toast--success { border-left-color: var(--gx-add); }
.gx-toast--error   { border-left-color: var(--gx-delete); }
.gx-toast--warn    { border-left-color: var(--gx-update); }
.gx-toast--info    { border-left-color: var(--gx-accent); }
.gx-toast__icon { width: 18px; height: 18px; flex: none; margin-top: 1px; }
.gx-toast--success .gx-toast__icon { color: var(--gx-add); }
.gx-toast--error   .gx-toast__icon { color: var(--gx-delete); }
.gx-toast--warn    .gx-toast__icon { color: var(--gx-update); }
.gx-toast--info    .gx-toast__icon { color: var(--gx-accent); }
.gx-toast__body { flex: 1; min-width: 0; }
.gx-toast__title { font-weight: 600; font-size: 14px; margin: 0 0 2px; color: var(--gx-ink); }
.gx-toast__note { font-size: 13px; color: var(--gx-slate); margin: 0; overflow-wrap: anywhere; }
.gx-toast__note a { color: var(--gx-accent-ink); font-weight: 600; }
.gx-toast__close { flex: none; border: none; background: none; padding: 0 2px; margin: -2px -2px 0 0; font-size: 18px; line-height: 1; color: var(--gx-slate-soft); cursor: pointer; }
.gx-toast__close:hover { color: var(--gx-ink); }
@keyframes gx-toast-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

/* ---- statusbar actions (status control + utilities on the right) ---- */
.gx-statusbar__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.gx-statusbar__status {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--gx-font-mono); font-size: 12px; letter-spacing: .04em;
  text-transform: uppercase; font-weight: 600;
  border: 1px solid var(--gx-hairline); border-radius: 999px;
  padding: 4px 11px; background: var(--gx-paper); color: var(--gx-slate);
}
.gx-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--gx-slate-soft); flex: none; }
.gx-dot--on  { background: var(--gx-add);    box-shadow: 0 0 0 3px var(--gx-add-wash); }
.gx-dot--off { background: var(--gx-delete); box-shadow: 0 0 0 3px var(--gx-delete-wash); }

/* ---- inline alert banner (persistent page notices) ---- */
.gx-alert {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 12px 15px; margin: 0 0 16px;
  border: 1px solid var(--gx-hairline); border-left-width: 3px;
  border-radius: var(--gx-radius-sm);
  background: var(--gx-surface); color: var(--gx-ink); font-size: 13.5px;
}
.gx-alert:last-child { margin-bottom: 0; }
.gx-alert__icon { width: 17px; height: 17px; flex: none; margin-top: 1px; color: var(--gx-slate); }
.gx-alert--info   { border-left-color: var(--gx-accent); background: var(--gx-accent-wash); color: var(--gx-accent-ink); }
.gx-alert--info   .gx-alert__icon { color: var(--gx-accent); }
.gx-alert--warn   { border-left-color: var(--gx-update); background: var(--gx-update-wash); color: #6f4a12; }
.gx-alert--warn   .gx-alert__icon { color: var(--gx-update); }
.gx-alert--danger { border-left-color: var(--gx-delete); background: var(--gx-delete-wash); color: #7d2626; }
.gx-alert--danger .gx-alert__icon { color: var(--gx-delete); }

/* ---- meter (a proportion read as a slim bar) ---- */
.gx-meter { height: 8px; border-radius: 999px; background: var(--gx-surface-2); border: 1px solid var(--gx-hairline); overflow: hidden; }
.gx-meter__fill { height: 100%; background: var(--gx-accent); border-radius: inherit; transition: width .3s ease; }
.gx-meter--good  .gx-meter__fill { background: var(--gx-add); }
.gx-meter--warn  .gx-meter__fill { background: var(--gx-update); }
.gx-meter--alert .gx-meter__fill { background: var(--gx-delete); }

/* ---- tabs (a range/segment switch above content) ---- */
.gx-tabs { display: flex; flex-wrap: wrap; gap: 2px; border-bottom: 1px solid var(--gx-hairline); margin: 0 0 16px; }
.gx-tab {
  appearance: none; border: none; background: none; cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--gx-slate);
  padding: 8px 13px; border-bottom: 2px solid transparent; margin-bottom: -1px;
  text-decoration: none; transition: color .12s ease, border-color .12s ease;
}
.gx-tab:hover { color: var(--gx-ink); text-decoration: none; }
.gx-tab--active { color: var(--gx-accent-ink); border-bottom-color: var(--gx-accent); }

/* ---- steps (a numbered rail showing progress through a multi-step form) ---- */
.gx-steps { display: flex; flex-wrap: wrap; gap: 2px; margin: 0 0 20px; padding: 0; list-style: none; }
.gx-steps__step {
  flex: 1 1 150px; display: flex; align-items: center; gap: 10px;
  padding: 11px 14px;
  border: 1px solid var(--gx-hairline); border-radius: var(--gx-radius-sm);
  background: var(--gx-surface-2); color: var(--gx-slate-soft);
  font-size: 13px; font-weight: 600;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.gx-steps__num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; flex: none;
  border: 1px solid var(--gx-hairline); border-radius: 999px;
  background: var(--gx-surface); color: var(--gx-slate-soft);
  font-family: var(--gx-font-mono); font-size: 12px;
}
.gx-steps__step--done { background: var(--gx-surface); color: var(--gx-slate); }
.gx-steps__step--done .gx-steps__num {
  background: var(--gx-add-wash); color: var(--gx-add); border-color: var(--gx-add);
}
.gx-steps__step--current {
  background: var(--gx-accent-wash); color: var(--gx-accent-ink); border-color: var(--gx-accent);
}
.gx-steps__step--current .gx-steps__num {
  background: var(--gx-accent); color: #fff; border-color: var(--gx-accent);
}

/* ---- visibility utility (so panels don't depend on Bootstrap's .hidden) ---- */
.gx-hidden { display: none !important; }

/* ---- in-card section heading + divider ---- */
.gx-subhead { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--gx-slate); font-weight: 600; margin: 0 0 12px; }
.gx-divider { border: none; border-top: 1px solid var(--gx-hairline-2); margin: 20px 0; }

/* ---- key/value line list (label left, value right) — leaner than gx-dl ---- */
.gx-facts { display: flex; flex-direction: column; }
.gx-fact { display: flex; align-items: baseline; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--gx-hairline-2); }
.gx-fact:last-child { border-bottom: none; }
.gx-fact__label { color: var(--gx-slate); font-size: 13px; flex: 1; min-width: 0; }
.gx-fact__value { font-family: var(--gx-font-mono); font-size: 13px; color: var(--gx-ink); font-variant-numeric: tabular-nums; text-align: right; }
.gx-fact__value--accent { color: var(--gx-accent-ink); }
.gx-fact__value--good   { color: var(--gx-add); }
.gx-fact__value--muted  { color: var(--gx-slate-soft); font-family: var(--gx-font-ui); }

/* ---- chart host (themed Highcharts renders into this) ---- */
.gx-chart { width: 100%; min-height: 300px; }
.gx-chart text { font-family: var(--gx-font-ui) !important; }

/* ---- pager (client-side pagination footer under a table) ---- */
.gx-pager {
  display: flex; align-items: center; justify-content: flex-end; gap: 12px;
  padding: 12px 16px; border-top: 1px solid var(--gx-hairline-2);
}
.gx-pager__info { font-family: var(--gx-font-mono); font-size: 12px; color: var(--gx-slate); font-variant-numeric: tabular-nums; }

/* ---- collapsible log session (native <details>) ---- */
.gx-log { border: 1px solid var(--gx-hairline); border-radius: var(--gx-radius-sm); background: var(--gx-surface); margin-bottom: 10px; overflow: hidden; }
.gx-log:last-child { margin-bottom: 0; }
.gx-log > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 11px;
  padding: 11px 14px; font-size: 13px; color: var(--gx-ink);
  transition: background .12s ease;
}
.gx-log > summary::-webkit-details-marker { display: none; }
.gx-log > summary::before {
  content: ""; width: 7px; height: 7px; flex: none; margin-right: 1px;
  border-right: 1.5px solid var(--gx-slate); border-bottom: 1.5px solid var(--gx-slate);
  transform: rotate(-45deg); transition: transform .12s ease;
}
.gx-log[open] > summary::before { transform: rotate(45deg); }
.gx-log > summary:hover { background: var(--gx-surface-2); }
.gx-log > summary:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--gx-accent-wash); }
.gx-log__time { font-family: var(--gx-font-mono); font-weight: 600; }
.gx-log__count { margin-left: auto; font-family: var(--gx-font-mono); font-size: 12px; color: var(--gx-slate-soft); }
.gx-log__body { border-top: 1px solid var(--gx-hairline-2); }

/* ---- badge / row variants: report lifecycle beyond add/update/delete ---- */
.gx-badge--accent { color: var(--gx-accent-ink); background: var(--gx-accent-wash); border-color: #cfe4e4; }
.gx-badge--muted  { color: var(--gx-slate); background: var(--gx-surface-2); border-color: var(--gx-hairline); }
.gx-row--accent   { --gx-spine: var(--gx-accent); }

/* ---- publish state (flags a saved description that isn't live everywhere yet;
   the reached-everywhere state shows no badge at all) ---- */
.gx-badge--warn { color: var(--gx-update); background: var(--gx-update-wash); border-color: #ecdcbe; }

/* ---- prose textarea (non-mono; reasons, messages, descriptions) ----
   unscoped from .gx-page so it also applies to the modal, which renders on
   <body> outside the page wrapper */
textarea.gx-input { height: auto; min-height: 84px; resize: vertical; line-height: 1.5; padding: 9px 11px; }
/* --tall: the textarea IS the task, not a footnote to a form — an editor someone
   writes body copy in (place descriptions). Still resizable; this is the floor.
   Both classes in the selector on purpose: `.gx-form textarea.gx-input` above sets
   min-height too and outranks a lone `.gx-input--tall`, so inside a .gx-form the
   modifier would silently do nothing. This ties on specificity and wins on order. */
textarea.gx-input.gx-input--tall { min-height: 220px; }

/* ---- button row (action clusters in table cells / form feet) ---- */
.gx-btnrow { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }

/* ---- thumbnail grid (listing images) ---- */
.gx-imggrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(116px, 1fr)); gap: 8px; }
.gx-imggrid img { width: 100%; height: 92px; object-fit: cover; display: block; border: 1px solid var(--gx-hairline); border-radius: var(--gx-radius-sm); }

/* ---- modal (confirm / resolve dialog) ---- */
.gx-modal {
  position: fixed; inset: 0; z-index: 1090; display: none;
  align-items: flex-start; justify-content: center;
  padding: 8vh 16px 16px; background: rgba(27,42,46,.42);
}
.gx-modal.is-open { display: flex; }
.gx-modal, .gx-modal *, .gx-modal *::before, .gx-modal *::after { box-sizing: border-box; }
.gx-modal__panel {
  width: 100%; max-width: 468px;
  background: var(--gx-surface); border: 1px solid var(--gx-hairline);
  border-radius: var(--gx-radius); box-shadow: var(--gx-shadow-lift);
  overflow: hidden; animation: gx-toast-in .16s ease;
}
.gx-modal__head { display: flex; align-items: center; gap: 10px; padding: 14px 18px; border-bottom: 1px solid var(--gx-hairline-2); }
.gx-modal__title { font-size: 15px; font-weight: 700; color: var(--gx-ink); margin: 0; }
.gx-modal__close { margin-left: auto; border: none; background: none; font-size: 20px; line-height: 1; color: var(--gx-slate-soft); cursor: pointer; padding: 0 2px; }
.gx-modal__close:hover { color: var(--gx-ink); }
.gx-modal__body { padding: 18px; }
.gx-modal__foot { display: flex; justify-content: flex-end; gap: 10px; padding: 14px 18px; border-top: 1px solid var(--gx-hairline-2); }

/* ---- responsive ---- */
@media (max-width: 900px) {
  .gx-grid { grid-template-columns: 1fr; }
  .gx-map { height: 340px; }
  .gx-formrow, .gx-formrow--3 { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .gx-wrap { padding: 18px 14px 0; }
  .gx-statusbar { padding: 12px 14px; }
  .gx-statusbar__count { display: none; }
  .gx-title { font-size: 22px; }
}

/* respect reduced motion (also covers a toast rendered outside .gx-page) */
@media (prefers-reduced-motion: reduce) {
  .gx-page *, .gx-toast-wrap * { transition: none !important; animation: none !important; }
}
