/* Capability Mapper — Catppuccin palette, two themes:
   dark (default) = Mocha, light = Latte. Switched via data-theme on <html>
   (toggle in the top bar, persisted in localStorage). Every color flows from
   these two blocks — no hardcoded hex below them, and alpha shades are built
   with color-mix() so both themes inherit them for free. Any new color must
   be defined in BOTH blocks.
   --relation is the red that draws the level-to-level relations. */

:root {                      /* Catppuccin Mocha */
  --ink: #181825;            /* mantle — page background */
  --panel: #1e1e2e;          /* base — cards, panels */
  --panel-2: #313244;        /* surface0 — inputs, chips */
  --panel-3: #45475a;        /* surface1 — hover */
  --line: #313244;           /* surface0 — borders */
  --deep: #11111b;           /* crust — text on accent, band labels */
  --text: #cdd6f4;
  --dim: #a6adc8;            /* subtext0 */
  --placeholder: #6c7086;    /* overlay0 */
  --accent: #b4befe;         /* lavender — links, focus */
  --relation: #f38ba8;       /* red — the relation lines between levels */
  --ok: #a6e3a1;             /* green — success, confidence */
  /* One colour per NAFv4 layer, following the NAF grid's own scheme: green
     Concepts, purple Service, blue Logical, orange Physical Resource. The
     accent and warn roles above are deliberately lavender and yellow so no
     UI colour collides with a layer colour. */
  --naf-c: #a6e3a1;          /* green — Concepts */
  --naf-s: #cba6f7;          /* mauve — Service Specifications */
  --naf-l: #89b4fa;          /* blue — Logical Specifications */
  --naf-p: #fab387;          /* peach — Physical Resource Specifications */
  --naf-a: #9399b2;          /* overlay2 — Architecture Foundation (metadata) */
  --warn: #f9e2af;           /* yellow */
  --radius: 10px;
  --font-ui: "Space Grotesk", system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;
}

:root[data-theme="light"] {  /* Catppuccin Latte */
  --ink: #e6e9ef;
  --panel: #eff1f5;
  --panel-2: #ccd0da;
  --panel-3: #bcc0cc;
  --line: #ccd0da;
  --deep: #dce0e8;
  --text: #4c4f69;
  --dim: #6c6f85;
  --placeholder: #9ca0b0;
  --accent: #7287fd;
  --relation: #d20f39;
  --ok: #40a02b;
  --naf-c: #40a02b;
  --naf-s: #8839ef;
  --naf-l: #1e66f5;
  --naf-p: #fe640b;
  --naf-a: #7c7f93;
  --warn: #df8e1d;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 15px;
  line-height: 1.5;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

h1, h2, h3 { font-weight: 600; line-height: 1.25; }
h1 { font-size: 22px; margin: 0 0 4px; }
h2 { font-size: 17px; margin: 24px 0 8px; }
.mono { font-family: var(--font-mono); }
.dim { color: var(--dim); }
.small { font-size: 13px; }

/* ---------- top bar ---------- */

.topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 20px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: 0.2px;
}
.brand:hover { text-decoration: none; }

.topbar nav {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
  flex-wrap: wrap;
}
.topbar nav a {
  padding: 5px 10px;
  border-radius: 7px;
  color: var(--dim);
  font-size: 14px;
}
.topbar nav a:hover { background: var(--panel-2); color: var(--text); text-decoration: none; }
.topbar nav a.active { background: var(--panel-2); color: var(--text); }

/* ---------- buttons, inputs ---------- */

.btn {
  font: inherit;
  font-size: 14px;
  padding: 6px 12px;
  border-radius: 7px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--text);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.btn:hover { background: var(--panel-3); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--deep); font-weight: 600; }
.btn-primary:hover { background: color-mix(in srgb, var(--accent) 85%, var(--text)); }
.btn-ghost { background: transparent; }
.btn-ghost:hover { background: var(--panel-2); }
.btn-danger { color: var(--relation); }
.btn-danger:hover { background: color-mix(in srgb, var(--relation) 18%, transparent); }
.btn-icon { padding: 4px 7px; font-size: 13px; line-height: 1; }
.btn-sm { padding: 3px 8px; font-size: 13px; }

input[type="text"], input[type="password"], input[type="search"], textarea, select {
  font: inherit;
  font-size: 14px;
  width: 100%;
  padding: 7px 10px;
  border-radius: 7px;
  border: 1px solid var(--line);
  background: var(--ink);
  color: var(--text);
}
textarea { resize: vertical; min-height: 64px; }
::placeholder { color: var(--placeholder); }

label { display: block; font-size: 13px; color: var(--dim); margin-bottom: 4px; }
.field { margin-bottom: 14px; }
.row { display: flex; gap: 10px; }
.row > * { flex: 1; }

/* ---------- flashes ---------- */

.flash {
  margin: 12px auto;
  width: min(1100px, 94vw);
  padding: 9px 13px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--panel);
  font-size: 14px;
}
.flash-ok { border-color: color-mix(in srgb, var(--ok) 55%, var(--line)); }
.flash-error { border-color: color-mix(in srgb, var(--relation) 55%, var(--line)); }

/* ---------- generic page shell (settings, taxonomy, login) ---------- */

main.page { width: min(900px, 94vw); margin: 0 auto; padding: 24px 0 64px; flex: 1; }

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px;
  margin-bottom: 16px;
}

/* ---------- login ---------- */

.login-wrap { flex: 1; display: grid; place-items: center; padding: 40px 16px; }
.login-card { width: min(360px, 92vw); }

/* ---------- the map ---------- */

main.map {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 14px 20px 28px;
  gap: 12px;
}

/* Title on the left, controls on the right. The title block is allowed to
   shrink (min-width: 0) so its help text wraps instead of shoving the
   controls onto a row of their own. */
.map-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.map-head > .map-title { flex: 1 1 380px; min-width: 0; }
.map-head .map-controls { flex: 0 0 auto; }
.map-head .spacer { margin-left: auto; }

.hint {
  font-size: 13px;
  color: var(--dim);
  padding: 6px 10px;
  border: 1px dashed var(--line);
  border-radius: 7px;
}

/* ---------- find & gap filter ---------- */

/* Find, filter and the actions stay together as one group so the header wraps
   as a unit instead of stranding a control on its own row. */
.map-controls { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }

.map-find { position: relative; flex: 0 1 230px; min-width: 170px; }
.map-find input { padding-right: 84px; }
.find-count {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 11.5px;
  pointer-events: none;
}

.map-head select {
  width: auto;
  max-width: 260px;
  font-size: 13.5px;
  padding: 6px 9px;
}
/* An active find or filter is dimming most of the map, which is easy to
   forget you did — so the control that caused it says so. */
.map-head select.is-active,
.map-find input.is-active {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
}

/* The canvas scrolls in both directions; the SVG relation layer is sized to
   its full scroll extent so lines stay glued to the cards while panning. */
.canvas {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    radial-gradient(circle at 1px 1px, var(--line) 1px, transparent 0) 0 0 / 22px 22px,
    var(--panel);
  /* Dragging the background pans the map. */
  cursor: grab;
  overscroll-behavior: contain;
}
.canvas.panning { cursor: grabbing; }
/* While panning, nothing inside should try to select or start its own drag. */
.canvas.panning * { user-select: none; }

/* The left padding clears the layer rail, which is absolutely positioned over
   the same origin the relation lines are measured from. */
.canvas-inner { position: relative; min-width: max-content; padding: 6px 18px 26px 58px; }

#relations {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  overflow: visible;
}

.relation-line {
  fill: none;
  stroke: var(--relation);
  stroke-width: 1.8;
  opacity: 0.5;
}
/* Selecting a card traces its whole chain: the lines on the chain get bolder,
   everything else fades rather than disappears, so the shape of the map is
   still readable while you follow one thread through it. */
.relation-line.on-chain { stroke-width: 3; opacity: 1; }
.relation-line.off-chain { opacity: 0.1; }

/* ---------- NAFv4 layer rail ---------- */

/* The layer belongs to a run of bands, not to a single band, so it is drawn
   as a bracket down the left edge spanning every band that shares it. Width
   is mirrored by RAIL in app.js, which positions the groups. */
.layer-rail { position: absolute; top: 0; left: 0; width: 58px; pointer-events: none; }

.layer-group {
  position: absolute;
  left: 4px;
  right: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 10px 0;
  border: 1px solid color-mix(in srgb, var(--kind) 40%, transparent);
  border-right: 0;
  /* Open on the right: it brackets the bands rather than boxing them in. */
  border-radius: 10px 0 0 10px;
  background: color-mix(in srgb, var(--kind) 9%, transparent);
  color: var(--kind);
  text-decoration: none;
  pointer-events: auto;
  overflow: hidden;
}
.layer-group:hover {
  text-decoration: none;
  background: color-mix(in srgb, var(--kind) 18%, transparent);
  border-color: color-mix(in srgb, var(--kind) 70%, transparent);
}
/* A layer with no bands is still drawn — "nothing here yet" is information —
   but it recedes so it doesn't read as an equal part of the map. */
.layer-group.is-empty {
  border-style: dashed;
  background: transparent;
  opacity: 0.55;
}

.lg-code { font-family: var(--font-mono); font-size: 17px; font-weight: 700; line-height: 1; }
.lg-name {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
}
.lg-count {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-family: var(--font-mono);
  font-size: 9.5px;
  opacity: 0.75;
  white-space: nowrap;
}

/* ---------- layer groups & level bands ---------- */

/* One block per NAFv4 layer, holding the bands the user defined inside it.
   The tint makes the layer legible as a region even where the rail is
   scrolled out of view. */
.layer-band {
  position: relative;
  padding: 10px 0 12px;
  background: color-mix(in srgb, var(--kind) 4%, transparent);
  border-radius: 0 10px 10px 0;
}
.layer-band + .layer-band { margin-top: 10px; }

.layer-empty {
  padding: 10px 2px 4px;
  color: var(--dim);
  font-size: 13px;
  max-width: 68ch;
}

.band { position: relative; padding: 14px 0 18px; }
.band + .band { border-top: 1px dashed var(--line); }

.band-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}

/* Relation lines pass behind the band headers, so each label carries its own
   opaque backdrop: the lines stay continuous between bands but never run
   through the text. */
.band-name, .band-kind, .band-desc {
  background: var(--panel);
  border-radius: 20px;
  padding: 1px 8px;
}
.band-name { font-size: 15px; font-weight: 600; }
.band-kind {
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 2px 7px;
  border: 1px solid;
}
.band-desc { font-size: 13px; color: var(--dim); }
.band-tools { margin-left: auto; display: flex; gap: 4px; opacity: 0; transition: opacity 0.12s; }
.band:hover .band-tools, .band-tools:focus-within { opacity: 1; }

/* One colour per NAFv4 layer, tinting the band label and its cards' top edge
   so which layer a card belongs to reads at a glance. */
.kind-C { --kind: var(--naf-c); }
.kind-S { --kind: var(--naf-s); }
.kind-L { --kind: var(--naf-l); }
.kind-P { --kind: var(--naf-p); }
.kind-A { --kind: var(--naf-a); }
.band-kind { color: var(--kind); border-color: color-mix(in srgb, var(--kind) 45%, transparent); }

/* Cards are positioned by the layout pass in app.js, not packed by flex: each
   one is pulled under the cards it relates to so the map reads as a topology
   instead of four left-aligned rows. The row's height is set from JS too,
   because absolutely positioned children don't give it one.

   The selector below is deliberately specific enough to beat `.card`'s own
   `position: relative` further down — at equal specificity the later rule
   would win and the cards would stack diagonally. */
.cards { position: relative; min-height: 84px; }
.cards > .card,
.cards > .add-card { position: absolute; top: 0; left: 0; }

/* ---------- card ---------- */

.card {
  position: relative;
  width: 224px;
  flex: 0 0 auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-top: 3px solid var(--kind, var(--line));
  border-radius: var(--radius);
  padding: 10px 11px 11px;
  cursor: pointer;
  transition: border-color 0.12s, opacity 0.12s, transform 0.12s;
}
.card:hover { border-color: var(--panel-3); }
.card.dragging { opacity: 0.4; }
.card.drop-before { box-shadow: -3px 0 0 var(--accent); }
.card.drop-after { box-shadow: 3px 0 0 var(--accent); }

.card.selected {
  border-color: var(--relation);
  box-shadow: 0 0 0 1px var(--relation);
}
.card.on-chain { border-color: color-mix(in srgb, var(--relation) 60%, var(--line)); }
.card.off-chain { opacity: 0.32; }

/* Find/filter dims rather than hides: a gap only means something in context,
   and removing the surrounding cards would take that context away. */
.card.filtered-out { opacity: 0.15; }
.card.filtered-in { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.card.find-focus { animation: find-pulse 1.2s ease-out; }

@keyframes find-pulse {
  0%, 100% { box-shadow: 0 0 0 1px var(--accent); }
  30% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 45%, transparent); }
}

.card-name { font-weight: 600; font-size: 14px; word-break: break-word; }
.card-desc {
  font-size: 12.5px;
  color: var(--dim);
  margin-top: 4px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card-c3 {
  margin-top: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--dim);
  border-top: 1px solid var(--line);
  padding-top: 7px;
  word-break: break-word;
}
.card-c3 .c3-id { color: var(--kind, var(--accent)); }
.card-c3.unmapped { color: var(--placeholder); font-style: italic; font-family: var(--font-ui); }

.card-meta { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 4px; }
.chip {
  font-family: var(--font-mono);
  font-size: 10.5px;
  background: var(--panel-2);
  border-radius: 20px;
  padding: 2px 7px;
  color: var(--dim);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chip b { color: var(--text); font-weight: 600; }

.card-tools {
  position: absolute;
  top: 6px;
  right: 6px;
  display: flex;
  gap: 2px;
  opacity: 0;
  transition: opacity 0.12s;
}
.card:hover .card-tools, .card-tools:focus-within { opacity: 1; }
.card-tools .btn { background: var(--panel); }

.card-count {
  position: absolute;
  bottom: -9px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 0 6px;
  color: var(--dim);
}

/* The + that appends a card to a band, and its empty-band sibling. */
.add-card {
  width: 46px;
  flex: 0 0 auto;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  background: transparent;
  color: var(--dim);
  font-size: 22px;
  cursor: pointer;
  display: grid;
  place-items: center;
  min-height: 84px;
}
.add-card:hover { border-color: var(--accent); color: var(--accent); }
.add-card.wide { width: 100%; max-width: 260px; font-size: 14px; gap: 6px; }

/* One per layer, so adding a band always says which layer it lands in. Quiet
   until hovered: with four of them on screen they must not compete with the
   map itself. */
.add-band {
  margin: 8px 0 0;
  border: 1px dashed color-mix(in srgb, var(--kind, var(--line)) 35%, transparent);
  border-radius: var(--radius);
  background: transparent;
  color: var(--placeholder);
  font: inherit;
  font-size: 13px;
  padding: 7px 9px;
  width: 100%;
  text-align: left;
  cursor: pointer;
}
.add-band:hover { border-color: var(--kind, var(--accent)); color: var(--kind, var(--accent)); }

/* ---------- modal ---------- */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--deep) 72%, transparent);
  display: grid;
  place-items: start center;
  padding: 5vh 16px;
  overflow: auto;
  z-index: 50;
}
.modal-backdrop[hidden] { display: none; }

.modal {
  width: min(620px, 96vw);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 20px;
}
.modal h2 { margin: 0 0 14px; font-size: 18px; }
.modal-actions { display: flex; gap: 8px; margin-top: 18px; align-items: center; }
.modal-actions .spacer { margin-left: auto; }

.error-text { color: var(--relation); font-size: 13px; }

/* ---------- metadata editor ---------- */

.meta-rows { display: flex; flex-direction: column; gap: 6px; }
.meta-row { display: flex; gap: 6px; align-items: center; }
.meta-row input:first-child { flex: 0 0 34%; font-family: var(--font-mono); font-size: 13px; }

/* ---------- C3 picker ---------- */

.picker { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.picker-results { max-height: 232px; overflow: auto; }

.picker-row {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  background: transparent;
  border: 0;
  border-top: 1px solid var(--line);
  padding: 7px 10px;
  cursor: pointer;
  color: var(--text);
}
.picker-row:first-child { border-top: 0; }
.picker-row:hover { background: var(--panel-2); }
.picker-row.chosen { background: color-mix(in srgb, var(--accent) 16%, transparent); }
.picker-row .p-path { font-size: 12px; color: var(--dim); }
.picker-row .p-name { font-size: 13.5px; font-weight: 600; }
.picker-row .p-id { font-family: var(--font-mono); font-size: 11px; color: var(--accent); }
.picker-row .p-desc {
  font-size: 12px;
  color: var(--dim);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Local additions are marked everywhere they appear: mistaking one for an
   endorsed taxonomy node is the one error this tool must not encourage. */
.tag-local {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--warn);
  border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent);
  border-radius: 20px;
  padding: 0 5px;
  margin-left: 6px;
  white-space: nowrap;
}

/* A mapping that no longer resolves in the shipped baseline. Not an error —
   it was true when it was made — but it needs a human to re-map it. */
.tag-stale {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--relation);
  border: 1px solid color-mix(in srgb, var(--relation) 50%, transparent);
  border-radius: 20px;
  padding: 0 5px;
  margin-left: 6px;
  white-space: nowrap;
}

/* ---------- relations editor ---------- */

/* Relations are chips you remove and a search you add from — a checkbox list
   of every card on the map stops being usable a few dozen cards in. */
.rel-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }
.rel-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-left: 3px solid var(--kind, var(--line));
  border-radius: 20px;
  padding: 2px 4px 2px 10px;
}
.rel-chip button {
  border: 0;
  background: transparent;
  color: var(--dim);
  cursor: pointer;
  font: inherit;
  line-height: 1;
  padding: 2px 5px;
  border-radius: 50%;
}
.rel-chip button:hover { background: var(--panel-3); color: var(--relation); }
.rel-empty { font-size: 13px; color: var(--placeholder); margin-bottom: 8px; }

.rel-results { max-height: 168px; overflow: auto; border: 1px solid var(--line); border-radius: 8px; margin-top: 6px; }
.rel-results:empty { display: none; }
.rel-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  text-align: left;
  font: inherit;
  font-size: 13.5px;
  background: transparent;
  border: 0;
  border-top: 1px solid var(--line);
  padding: 6px 10px;
  cursor: pointer;
  color: var(--text);
}
.rel-row:first-child { border-top: 0; }
.rel-row:hover { background: var(--panel-2); }
.rel-row .rel-band {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--kind, var(--dim));
  border: 1px solid color-mix(in srgb, var(--kind, var(--line)) 45%, transparent);
  border-radius: 20px;
  padding: 0 6px;
  flex: 0 0 auto;
}
.rel-row .rel-dim { color: var(--dim); font-size: 12px; margin-left: auto; }

/* ---------- drag to link ---------- */

/* The handle is how a relation is drawn: press it and drag onto any card on
   another band. Dragging the card BODY reorders within the band instead, so
   the two gestures never collide. */
.link-handle {
  position: absolute;
  bottom: -7px;
  left: 50%;
  transform: translateX(-50%);
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 2px solid var(--relation);
  background: var(--panel);
  cursor: crosshair;
  opacity: 0;
  transition: opacity 0.12s, transform 0.12s;
  z-index: 3;
}
.card:hover .link-handle, .link-handle:focus-visible { opacity: 1; }
.link-handle:hover { transform: translateX(-50%) scale(1.3); background: var(--relation); }

body.linking { cursor: crosshair; }
body.linking .card { cursor: crosshair; }
/* While a link is being drawn, only the cards it could legally land on stay
   lit — the source's own band cannot be both ends of a relation. */
body.linking .card.link-target { border-color: var(--relation); box-shadow: 0 0 0 1px var(--relation); }
body.linking .card.link-invalid { opacity: 0.3; }
body.linking .card.link-hover { background: color-mix(in srgb, var(--relation) 18%, var(--panel)); }

.relation-draft {
  fill: none;
  stroke: var(--relation);
  stroke-width: 2.4;
  stroke-dasharray: 6 4;
}

/* An invisible fat path over each line, so a 1.8px curve is still easy to
   grab when you want to delete it. */
.relation-hit { fill: none; stroke: transparent; stroke-width: 14; pointer-events: stroke; cursor: pointer; }
#relations.interactive { pointer-events: none; }
#relations.interactive .relation-hit { pointer-events: stroke; }
.relation-line.hovered { stroke-width: 3.4; opacity: 1; }

/* ---------- AI suggestions ---------- */

.suggestions { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.suggestion {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 10px;
  display: flex;
  gap: 9px;
  align-items: flex-start;
  font-size: 13.5px;
}
.suggestion .conf {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ok);
  flex: 0 0 auto;
  padding-top: 2px;
}
.suggestion .reason { color: var(--dim); font-size: 12.5px; }

.spinner {
  width: 13px;
  height: 13px;
  border: 2px solid color-mix(in srgb, var(--text) 30%, transparent);
  border-top-color: var(--text);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- taxonomy browser ---------- */

.tax-tree { list-style: none; padding-left: 0; margin: 0; }
.tax-tree ul { list-style: none; margin: 0; padding-left: 16px; border-left: 1px solid var(--line); }
.tax-node { padding: 4px 0; }
.tax-node > .t-head { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.tax-node .t-id { font-family: var(--font-mono); font-size: 11.5px; color: var(--accent); }
.tax-node .t-name { font-weight: 600; font-size: 14px; }
.tax-node .t-desc { font-size: 12.5px; color: var(--dim); max-width: 70ch; }

/* ---------- NAFv4 grid ---------- */

main.page.wide { width: min(1320px, 96vw); }

.naf-grid { border-collapse: separate; border-spacing: 3px; width: 100%; font-size: 12.5px; }
.naf-grid th, .naf-grid td { vertical-align: top; text-align: left; }
.naf-grid thead th {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--dim);
  padding: 4px 6px;
  white-space: nowrap;
}
.naf-col-key { color: var(--accent); }
.naf-corner { width: 210px; }

.naf-layer {
  width: 210px;
  background: var(--panel-2);
  border-left: 3px solid var(--kind, var(--line));
  border-radius: 8px;
  padding: 8px 10px;
}
.naf-layer-code { color: var(--kind); font-size: 14px; font-weight: 700; margin-right: 5px; }
.naf-layer-name { font-weight: 600; font-size: 13px; }
.naf-layer-desc { display: block; color: var(--dim); font-size: 11.5px; margin-top: 3px; }
.naf-layer-count { display: block; font-size: 11px; color: var(--kind); margin-top: 5px; }
.naf-layer-count.dim { color: var(--placeholder); }

.naf-grid td {
  background: var(--panel-2);
  border-radius: 8px;
  padding: 7px 8px;
  min-width: 96px;
  opacity: 0.55;
}
.naf-grid td.naf-empty { background: transparent; }
/* The cells this tool actually fills are the point of the page, so they are
   the only ones drawn at full strength. */
.naf-grid td.naf-covered {
  opacity: 1;
  background: color-mix(in srgb, var(--kind) 18%, var(--panel-2));
  border: 1px solid color-mix(in srgb, var(--kind) 55%, transparent);
  padding: 6px 7px;
}
.naf-code { display: block; color: var(--accent); font-size: 11px; }
.naf-covered .naf-code { color: var(--kind); font-weight: 700; }
.naf-name { display: block; margin-top: 2px; }

.naf-bands { width: 100%; border-collapse: separate; border-spacing: 0 4px; }
.naf-bands td { padding: 5px 8px; background: var(--panel-2); }
.naf-bands td:first-child { border-radius: 8px 0 0 8px; border-left: 3px solid var(--kind, var(--line)); }
.naf-bands td:last-child { border-radius: 0 8px 8px 0; }

footer {
  padding: 14px 20px;
  border-top: 1px solid var(--line);
  color: var(--placeholder);
  font-size: 12.5px;
}

@media (max-width: 720px) {
  .card { width: 190px; }
  main.map { padding: 12px 10px 20px; }
}
