/* ==========================================================================
   Tech map — "Orrery"
   A dark instrument panel set into the page, dark in both the light and
   the dark theme. Linked from index.html after styles.css, and relies on its
   tokens (--kind-*, --font-*, --gutter, --ease-out, --shadow-lg, --map-frame)
   and on the
   .tm-kind--* and .visually-hidden helpers defined there.

   Type: the serif is the pane title only; the sans carries every name and
   control; the mono is reserved for data — periods, counts, eyebrows and
   the key. No font-size here is below 0.75rem (12px), and because the map
   never zooms (SVG units are screen pixels), CSS sizes are what the visitor
   reads. Keep the breakpoints (600px, 900px) in step with splitMQ / miniMQ
   in map.js.
   ========================================================================== */
.techmap {
  --map-bg:          #0b1619;
  --map-surface:     #10252a;   /* the pane: one step up from the ground   */
  --map-raised:      #16323a;   /* row hover                                */
  --map-ink:         #dcebe8;   /* 14.9:1 on bg, 13.5:1 on surface          */
  --map-soft:        #c3d5d2;   /* body copy in the pane, 11:1 on surface    */
  --map-muted:       #93aca9;   /* 7.4:1 on bg, 6.6:1 on surface             */
  --map-line:        #24434a;   /* decorative dividers only (1.7:1)          */
  --map-line-strong: #3f7480;   /* a control's only boundary: 3.5:1 on bg    */
  --map-skill:       #45c3ae;   /* pine signal: 8.1:1 on bg                  */
  --map-hit:         #f4fbf9;   /* search hits — a white ring, not a new hue */
  --tm-stage-h:      clamp(560px, 72vh, 720px);

  grid-column: 1 / -1;   /* spans the block's rail and body columns */
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "bar" "stage" "pane";
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
  background: var(--map-bg);
  color: var(--map-ink);
  /* The map stays dark in both themes. Its edge comes from the page's
     theme tokens: on the light page the dark ground is the separation; on
     the dark page the ground is ~1:1 against the page, so --map-frame is
     brighter there (2.1:1) to keep the instrument's edge. */
  border: 1px solid var(--map-frame, #1c3338);
  border-radius: 14px;
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.techmap :focus-visible { outline: 2px solid var(--map-skill); outline-offset: 2px; }
.techmap__noscript { padding: 1.5rem; color: var(--map-muted); }
/* Without JavaScript the bar, stage and pane would be empty or dead
   controls (a search box that searches nothing), so only the <noscript>
   note shows; the same skills are listed under Capabilities. */
html:not(.js) .techmap__bar,
html:not(.js) .techmap__stage,
html:not(.js) .techmap__pane { display: none; }

/* ---- Bar: back + trail, search, pause ---------------------------------- */
.techmap__bar {
  grid-area: bar;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem 1rem;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--map-line);
  background: linear-gradient(#0e1d21, var(--map-bg));
}
.techmap__crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  min-width: 0;
}
.techmap__trail {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.15rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.techmap__trail li { display: flex; align-items: center; gap: 0.15rem; }
.techmap__trail li + li::before {
  content: "/";
  padding-inline: 0.15rem;
  color: var(--map-line-strong);
  font: 400 0.875rem/1 var(--font-mono);
}
.techmap__trail button,
.techmap__back,
.techmap__motion {
  font: 500 0.875rem/1 var(--font-sans);
  color: var(--map-muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 999px;
  min-height: 36px;
  padding: 0.4rem 0.65rem;
  cursor: pointer;
  transition: color 160ms ease, border-color 160ms ease, background-color 160ms ease;
}
.techmap__trail button {
  max-width: 20ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.techmap__trail button:hover { color: var(--map-ink); background: var(--map-raised); }
.techmap__trail button:active { background: #1d4249; }
.techmap__trail button[aria-current] {
  color: var(--map-ink);
  cursor: default;
}
.techmap__back,
.techmap__motion {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--map-ink);
  border-color: var(--map-line-strong);
  min-height: 40px;
  padding-inline: 0.8rem 0.95rem;
}
.techmap__back svg { width: 1rem; height: 1rem; }
.techmap__motion::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--map-skill);
  box-shadow: 0 0 0 3px rgba(69, 195, 174, 0.2);
}
.techmap.is-paused .techmap__motion::before { background: var(--map-muted); box-shadow: none; }
.techmap__back:hover,
.techmap__motion:hover { border-color: var(--map-skill); background: var(--map-raised); }
.techmap__back:active,
.techmap__motion:active { background: #1d4249; }
.techmap__motion[hidden] { display: none; }

.techmap__tools {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex: 0 1 auto;
}
.techmap__search {
  position: relative;
  display: flex;
  align-items: center;
  width: clamp(284px, 26vw, 320px);
}
.techmap__search-icon {
  position: absolute;
  left: 0.8rem;
  width: 1.05rem;
  height: 1.05rem;
  color: var(--map-muted);
  pointer-events: none;
}
.techmap__search-input {
  width: 100%;
  min-height: 42px;
  padding: 0.5rem 2.6rem 0.5rem 2.35rem;
  font: 400 1rem/1.2 var(--font-sans);
  color: var(--map-ink);
  background: #0f2125;
  border: 1px solid var(--map-line-strong);
  border-radius: 999px;
  transition: border-color 160ms ease, background-color 160ms ease;
}
.techmap__search-input::placeholder { color: var(--map-muted); opacity: 1; }
.techmap__search-input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.techmap__search-input:hover { border-color: var(--map-skill); }
.techmap__search-input:focus { background: #122a2f; }
.techmap__search-input:focus-visible { outline: 2px solid var(--map-skill); outline-offset: 1px; }
.techmap__search-clear {
  position: absolute;
  right: 0.2rem;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  color: var(--map-ink);
  background: transparent;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: background-color 160ms ease;
}
.techmap__search-clear svg { width: 1rem; height: 1rem; }
.techmap__search-clear:hover { background: var(--map-raised); }
.techmap__search-clear:active { background: #1d4249; }
.techmap__search-clear[hidden] { display: none; }

/* ---- Stage ------------------------------------------------------------- */
.techmap__stage {
  grid-area: stage;
  position: relative;
  display: flex;
  flex-direction: column;
  height: 500px;
  overflow: hidden;
  background:
    radial-gradient(120% 70% at 50% 0%, #10272c 0%, transparent 60%),
    var(--map-bg);
}
.techmap__svg { display: block; width: 100%; flex: 1 1 auto; min-height: 0; }

/* Plane: a disc with a visible edge, lit from the far side. */
.tm-floor-in  { stop-color: #1a4247; stop-opacity: 0.9; }
.tm-floor-mid { stop-color: #10272b; stop-opacity: 0.6; }
.tm-floor-out { stop-color: #0b1619; stop-opacity: 0; }
.tm-floor { stroke: #1c363c; stroke-width: 1; }
.tm-orbit { fill: none; stroke: #2b525a; stroke-width: 1; }
.tm-orbit--inner { stroke-dasharray: 2 6; }
.tm-orbit--child { stroke: var(--map-skill); stroke-opacity: 0.45; stroke-dasharray: 1 5; }
.tm-shadow { fill: #020607; }
.tm-stem { stroke: #4b8691; stroke-width: 1; }
.tm-foot { fill: none; stroke: #4b8691; stroke-width: 1; }

/* Spheres: lit from the upper left, so they read as round. */
.tm-sk-a { stop-color: #27605f; }
.tm-sk-b { stop-color: #0b1f23; }
.tm-st-a { stop-color: var(--kind-ink); }
.tm-st-b { stop-color: var(--kind); }
.tm-st-c { stop-color: color-mix(in srgb, var(--kind) 40%, #0b1619); }

/* Nodes. Only the invisible hit circle takes the pointer: every node's
   target is at least 44 × 44 px, whatever size it is drawn. */
.tm-node { cursor: pointer; outline: none; }
.tm-node > * { pointer-events: none; }
.tm-node > .tm-hit { fill: none; stroke: none; pointer-events: visible; }
.tm-node.is-inert { cursor: default; }
.tm-node.is-inert > .tm-hit { pointer-events: none; }

.tm-core { transition: fill 200ms ease, stroke 200ms ease; }
.tm-aura { fill: none; stroke: var(--map-skill); stroke-width: 1.5; stroke-opacity: 0; transition: stroke-opacity 200ms ease, stroke-width 200ms ease; }
.tm-focusring { fill: none; stroke: var(--map-hit); stroke-width: 2; stroke-dasharray: 3 3; opacity: 0; }
.tm-node:focus-visible .tm-focusring { opacity: 1; }
/* The dashed ring above is the focus indicator; a box outline around an
   SVG group would be the bounding box of its hit area, not the body. */
.techmap .tm-node:focus-visible { outline: none; }

/* Tech: a man wearing a support headset inside a thin ring. */
.tm-node--hub .tm-core { fill: var(--map-skill); }
.tm-tech__headset { fill: none; stroke: var(--map-bg); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.tm-node--hub .tm-aura { stroke-opacity: 0.55; stroke-width: 1; }
.tm-pulse { fill: none; stroke: var(--map-skill); stroke-opacity: 0.7; transform-box: fill-box; transform-origin: center; }

.tm-node--skill .tm-core { fill: url(#tm-sphere-skill); stroke: var(--map-skill); stroke-width: 1.5; }
.tm-icon { fill: none; stroke: #d2f5ec; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

.tm-node--planet.tm-kind--professional .tm-core { fill: url(#tm-sphere-professional); }
.tm-node--planet.tm-kind--personal .tm-core     { fill: url(#tm-sphere-personal); }
.tm-node--planet.tm-kind--business .tm-core     { fill: url(#tm-sphere-business); }
.tm-node--planet .tm-aura { stroke: var(--kind); }
.tm-moonring { fill: none; stroke: var(--kind); stroke-opacity: 0.45; stroke-width: 1; stroke-dasharray: 2 4; }
/* A planet with nothing listed yet is dormant: present, but not lit. */
.tm-node--planet.is-dormant .tm-core { opacity: 0.62; }
.tm-node--planet.is-dormant .tm-moonring { stroke-opacity: 0.25; }

.tm-node--moon .tm-core { fill: var(--kind); }
.tm-node--moon .tm-aura { stroke: var(--kind); }
.tm-node--moon.is-placeholder .tm-core { fill: var(--map-bg); stroke: var(--kind); stroke-width: 1.5; stroke-dasharray: 2 2; }

.tm-node--branch .tm-core { fill: #12363b; stroke: var(--map-skill); stroke-width: 1.5; }
.tm-node--leaf .tm-core { fill: var(--map-skill); }
.tm-node--leaf.is-devices .tm-core { fill: var(--kind-professional); }

/* Far bodies are softened; that and size are the whole depth cue. */
.tm-node.is-far .tm-core,
.tm-node.is-far .tm-icon { filter: url(#tm-soft); }

/* States */
.tm-node:hover .tm-aura,
.tm-node.is-hover .tm-aura { stroke-opacity: 0.9; stroke-width: 2; }
.tm-node:hover .tm-core { stroke-width: 2; }
.tm-node:active .tm-aura { stroke-width: 3; }
.tm-node.is-linked .tm-aura { stroke-opacity: 0.8; stroke: var(--kind, var(--map-skill)); }
.tm-node--skill.is-linked .tm-aura { stroke: var(--kind-professional); }
.tm-node.is-focus .tm-aura { stroke-opacity: 0.55; stroke-width: 1; stroke-dasharray: 2 4; }
.tm-node.is-anchor .tm-aura { stroke-opacity: 0.9; }
.tm-node.is-selected .tm-aura { stroke: var(--map-hit); stroke-opacity: 1; stroke-width: 2.5; stroke-dasharray: none; }
.tm-node.is-hit .tm-aura { stroke: var(--map-hit); stroke-opacity: 1; stroke-width: 2; stroke-dasharray: none; }

/* Links */
.tm-link { fill: none; pointer-events: none; }
.tm-link--flow  { stroke: #2e5a5e; stroke-width: 1.5; stroke-dasharray: 3 9; }
/* The web: at rest, every role's threads to the skill areas it drew on.
   Faint on purpose; hovering a role or a skill area lights the same
   threads as beams. */
.tm-link--web   { stroke: var(--kind, var(--map-skill)); stroke-width: 1; stroke-opacity: 0.2; }
.tm-link--beam  { stroke: var(--kind, var(--map-skill)); stroke-width: 1.6; stroke-opacity: 0.9; stroke-dasharray: 5 6; }
.tm-link--child { stroke: var(--map-skill); stroke-opacity: 0.55; stroke-width: 1.2; }
.tm-link--sat   { stroke: var(--map-skill); stroke-opacity: 0.35; stroke-width: 1; }
.tm-link--chain { stroke: var(--map-skill); stroke-opacity: 0.8; stroke-width: 1.5; }
.tm-link.is-new { stroke-dasharray: 1; stroke-dashoffset: 1; animation: tm-draw 620ms var(--ease-out) var(--ld, 0ms) forwards; }

/* Leader lines — the signature. A glow under a hairline, and a port. */
.tm-leader { fill: none; pointer-events: none; }
.tm-leader--glow { stroke: var(--kind, var(--map-skill)); stroke-width: 7; stroke-opacity: 0.14; stroke-linecap: round; }
.tm-leader--pane { stroke: var(--kind, var(--map-skill)); stroke-width: 1.5; stroke-opacity: 0.95; }
.tm-leader--pane.is-drawing,
.tm-leader--glow.is-drawing { stroke-dasharray: 1; stroke-dashoffset: 1; animation: tm-draw 700ms var(--ease-out) 250ms forwards; }
.tm-leader-dot { fill: var(--kind, var(--map-skill)); }
.tm-leader-dot--ring { fill: none; stroke: var(--kind, var(--map-skill)); stroke-width: 1; stroke-opacity: 0.6; }
.tm-leader--tag { stroke: var(--map-muted); stroke-width: 1; }

/* Hover / focus tag: the map's voice. Names live here, never on the canvas. */
.techmap__tag {
  position: absolute;
  top: 0;
  left: 0;
  display: grid;
  gap: 0.15rem;
  max-width: 250px;
  padding: 0.5rem 0.8rem 0.55rem;
  background: rgba(10, 25, 28, 0.96);
  border: 1px solid var(--map-line-strong);
  border-top: 2px solid var(--kind, var(--map-skill));
  border-radius: 8px;
  box-shadow: 0 14px 30px -12px rgba(0, 0, 0, 0.8);
  pointer-events: none;
  will-change: transform;
}
.techmap__tag[hidden] { display: none; }
.techmap__tag-name { font: 600 0.9375rem/1.25 var(--font-sans); color: var(--map-ink); letter-spacing: -0.005em; }
.techmap__tag-meta { font: 400 0.75rem/1.3 var(--font-mono); color: var(--map-muted); }

/* ---- Key: part of the instrument, in the stage's bottom band ---------- */
.techmap__key {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  margin: 0;
  padding: 0.6rem 1rem 0.75rem;
  list-style: none;
  font: 0.75rem/1.3 var(--font-mono);
  letter-spacing: 0.04em;
  color: var(--map-muted);
}
.techmap__key li { display: inline-flex; align-items: center; gap: 0.45rem; }
.techmap__key li::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, var(--kind-ink), var(--kind) 65%);
}
.techmap__key .techmap__key-skill::before { background: #0c2226; border: 1.5px solid var(--map-skill); }

/* ---- Pane: the detail panel, and the list on phones ------------------- */
.techmap__pane {
  grid-area: pane;
  display: grid;
  gap: 1.25rem;
  align-content: start;
  padding: 0 1.25rem 1.5rem;
  background: var(--map-surface);
  border-top: 1px solid var(--map-line);
  min-width: 0;
}
/* The header band: what the leader line lands on. */
.techmap__pane-head {
  position: relative;
  display: grid;
  gap: 0.35rem;
  margin-inline: -1.25rem;
  padding: 1.1rem 1.25rem 1rem;
  border-bottom: 1px solid var(--map-line);
  background: linear-gradient(#132a30, var(--map-surface));
}
.techmap__pane-head::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--kind, var(--map-skill));
  opacity: 0.9;
}
.techmap__pane-trail {
  font: 500 0.75rem/1.4 var(--font-mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--kind-ink, var(--map-skill));
}
.techmap__pane-title {
  position: relative;
  width: fit-content;
  font: 500 1.875rem/1.15 var(--font-serif);
  letter-spacing: -0.012em;
  color: var(--map-ink);
  overflow-wrap: anywhere;
  text-wrap: balance;
}
.techmap__pane-title:focus { outline: none; }
.techmap__pane-title:focus-visible { outline: 2px dotted var(--map-skill); outline-offset: 6px; border-radius: 4px; }
.techmap__pane-meta { font: 400 0.8125rem/1.4 var(--font-mono); color: var(--map-muted); }
.techmap__pane-text { color: var(--map-soft); font-size: 0.9375rem; line-height: 1.6; }
.techmap__details { padding-left: 1.2rem; color: var(--map-soft); font-size: 0.9375rem; line-height: 1.6; }
.techmap__pane-highlight {
  color: var(--map-ink);
  font-size: 0.9375rem;
  line-height: 1.6;
  padding-left: 0.85rem;
  border-left: 2px solid var(--kind, var(--map-skill));
}
.techmap__pane-highlight strong {
  display: block;
  font: 500 0.75rem/1.4 var(--font-mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--kind-ink, var(--map-skill));
}

.techmap__sec { display: grid; gap: 0.6rem; }
.techmap__sec-label {
  margin: 0;
  font: 500 0.75rem/1.3 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--map-muted);
}
.techmap__rows { display: grid; margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--map-line); }
.techmap__row {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  min-height: 52px;
  padding: 0.5rem 0.5rem 0.5rem 0.4rem;
  text-align: left;
  font: inherit;
  color: var(--map-ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--map-line);
  box-shadow: inset 0 0 0 0 var(--kind, var(--map-skill));
  cursor: pointer;
  transition: background-color 160ms ease, box-shadow 160ms ease;
}
.techmap__row:hover { background: var(--map-raised); box-shadow: inset 3px 0 0 0 var(--kind, var(--map-skill)); }
.techmap__row:active { background: #1d4249; }
.techmap__row:focus-visible { outline-offset: -2px; }
.techmap__row[aria-current] { background: var(--map-raised); box-shadow: inset 3px 0 0 0 var(--map-hit); }
.techmap__row-text { display: grid; gap: 0.1rem; min-width: 0; }
.techmap__row-name { font-size: 0.9375rem; font-weight: 500; line-height: 1.35; overflow-wrap: anywhere; }
.techmap__row-name mark {
  color: var(--map-hit);
  background: rgba(69, 195, 174, 0.24);
  border-radius: 2px;
  box-shadow: inset 0 -1px 0 var(--map-skill);
}
.techmap__row-meta { font: 400 0.75rem/1.35 var(--font-mono); color: var(--map-muted); }
.techmap__chev { width: 1rem; height: 1rem; color: var(--map-muted); transition: transform 160ms var(--ease-out), color 160ms ease; }
.techmap__row:hover .techmap__chev { transform: translateX(3px); color: var(--map-ink); }

.techmap__row-mark { display: grid; place-items: center; width: 28px; height: 28px; }
.techmap__row-mark::before { content: ""; display: block; border-radius: 50%; }
.techmap__row-mark--skill::before { display: none; }
.techmap__row-mark--skill svg { width: 22px; height: 22px; fill: none; stroke: var(--map-skill); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.techmap__row-mark--planet::before { width: 18px; height: 18px; background: radial-gradient(circle at 35% 30%, var(--kind-ink), var(--kind) 60%, color-mix(in srgb, var(--kind) 50%, #0b1619)); box-shadow: 2px 3px 6px -2px rgba(0, 0, 0, 0.8); }
.is-dormant .techmap__row-mark--planet::before { opacity: 0.62; }
.techmap__row-mark--moon::before { width: 10px; height: 10px; background: var(--kind); }
.is-placeholder .techmap__row-mark--moon::before { background: transparent; border: 1.5px dashed var(--kind); }
.techmap__row-mark--branch::before { width: 12px; height: 12px; border: 1.5px solid var(--map-skill); background: #12363b; }
.techmap__row-mark--leaf::before { width: 8px; height: 8px; background: var(--map-skill); }

.techmap__chips { display: flex; flex-wrap: wrap; gap: 0.45rem; }
.techmap__chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 40px;
  padding: 0.45rem 0.9rem 0.45rem 0.8rem;
  font: 500 0.875rem/1.2 var(--font-sans);
  color: var(--map-ink);
  background: #142d33;
  border: 1px solid var(--map-line-strong);
  border-radius: 999px;
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease, transform 160ms var(--ease-out);
}
.techmap__chip:hover { border-color: var(--map-skill); background: #1b3f47; transform: translateY(-1px); }
.techmap__chip:active { background: #22505a; transform: none; }
.techmap__chip.tm-kind--professional::before,
.techmap__chip.tm-kind--personal::before,
.techmap__chip.tm-kind--business::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--kind);
}
.techmap__chip--query { font-family: var(--font-mono); font-weight: 400; }

.techmap__empty {
  display: grid;
  gap: 0.5rem;
  justify-items: start;
  padding: 1rem 1.1rem;
  color: var(--map-soft);
  font-size: 0.9375rem;
  line-height: 1.55;
  border: 1px dashed var(--map-line-strong);
  border-radius: 12px;
}
.techmap__empty-title { font: 500 1.125rem/1.3 var(--font-serif); color: var(--map-ink); }
.techmap__empty-line { color: var(--map-muted); font-size: 0.875rem; line-height: 1.5; }

.techmap__devices { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 0.75rem; }
.techmap__device {
  display: grid;
  gap: 0.4rem;
  align-content: start;
  padding: 0.85rem;
  background: #0f2226;
  border: 1px solid #22404a;
  border-radius: 12px;
  animation: tm-rise 480ms var(--ease-out) var(--d, 0ms) both;
}
.techmap__device-art svg { display: block; width: 100%; height: auto; aspect-ratio: 200 / 130; }
.techmap__device h4 { margin: 0; font-size: 1rem; color: var(--map-ink); }
.techmap__device-ver,
.techmap__device-tools { font: 0.75rem/1.35 var(--font-mono); color: var(--map-skill); }
.techmap__device-tools { color: var(--map-muted); }
.techmap__device ul { margin: 0; padding-left: 1.1rem; color: #b5cac7; font-size: 0.875rem; display: grid; gap: 0.2rem; }

/* ---- Desktop: two panes, nothing occluded ----------------------------- */
@media (min-width: 900px) {
  .techmap {
    grid-template-columns: minmax(0, 1fr) clamp(340px, 29vw, 400px);
    grid-template-rows: auto var(--tm-stage-h);
    grid-template-areas: "bar bar" "stage pane";
  }
  .techmap__stage { height: auto; }
  /* The key floats in the stage's empty bottom band; the SVG keeps the
     whole height (map.js measures the SVG, not the stage). */
  .techmap__key { position: absolute; left: 0; bottom: 0; pointer-events: none; }
  /* One bar row at every depth, so the stage never jumps. */
  .techmap__bar { flex-wrap: nowrap; }
  .techmap__crumbs { flex: 1 1 auto; flex-wrap: nowrap; overflow: hidden; }
  .techmap__trail { flex-wrap: nowrap; min-width: 0; }
  .techmap__tools { flex: none; }
  .techmap__pane {
    border-top: 0;
    border-left: 1px solid var(--map-line-strong);
    overflow-y: auto;
    overscroll-behavior: contain;
    min-height: 0;
    scrollbar-width: thin;
    scrollbar-color: var(--map-line-strong) transparent;
  }
  /* The port the map's leader line lands on, sitting on the pane's edge. */
  .techmap.has-leader .techmap__pane-title::before {
    content: "";
    position: absolute;
    top: 50%;
    left: calc(-1.25rem - 6px);
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: var(--kind, var(--map-skill));
    box-shadow: 0 0 0 3px var(--map-surface), 0 0 0 4px var(--kind, var(--map-skill));
    transform: translateY(-50%);
  }
}

/* ---- Phones: the list is the interface; the orbit is a small "you are
   here" picture that is not interactive (it is inert in map.js). ------- */
@media (max-width: 599px) {
  .techmap {
    margin-inline: calc(var(--gutter) * -0.5);
    border-radius: 12px;
  }
  /* Search owns the first row. With a Back button: Back · Pause on the
     second row and the trail on its own full-width line; at home: the
     trail and Pause share the second row. Both wrappers become grid
     items' parents via display: contents. Without :has() support the
     three-row template is used at home too (one near-empty row). */
  .techmap__bar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "search search" "back motion" "trail trail";
    align-items: center;
    gap: 0.5rem 0.6rem;
    padding: 0.75rem;
  }
  .techmap__bar:not(:has(.techmap__back)) { grid-template-areas: "search search" "trail motion"; }
  .techmap__tools,
  .techmap__crumbs { display: contents; }
  .techmap__search { grid-area: search; width: auto; min-width: 0; }
  .techmap__back { grid-area: back; justify-self: start; }
  .techmap__trail { grid-area: trail; min-width: 0; }
  /* The current crumb may use the whole line, so a role's name is not cut
     to 20 characters when there is room for it. */
  .techmap__trail li:last-child { max-width: 100%; min-width: 0; }
  .techmap__trail li:last-child button { max-width: 100%; }
  .techmap__motion { grid-area: motion; justify-self: end; white-space: nowrap; }
  /* The small picture cannot carry 13 threads; keep them as a hint. */
  .techmap.is-mini .tm-link--web { stroke-opacity: 0.12; }
  .techmap__stage { height: 262px; border-bottom: 1px solid var(--map-line); }
  .techmap__key { padding-top: 0; }
  .techmap__pane { border-top: 0; padding: 0 0.85rem 1.25rem; }
  .techmap__pane-head { margin-inline: -0.85rem; padding: 1rem 0.85rem 0.9rem; }
  .techmap__pane-title { font-size: 1.5rem; }
}

/* 44px targets for every map control on phones and on any touch screen
   (a tablet between 600px and 899px gets the interactive orbit, whose
   nodes already have 44px hit circles in map.js, but these controls too). */
@media (max-width: 599px), (pointer: coarse) {
  .techmap__trail button,
  .techmap__back,
  .techmap__motion,
  .techmap__chip,
  .techmap__search-input { min-height: 44px; }
  .techmap__search-clear { right: 0; width: 44px; height: 44px; }
}

/* ---- Ambient motion, only when welcome -------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .tm-link--flow { animation: tm-crawl 3.5s linear infinite; }
  .tm-link--beam { animation: tm-crawl-beam 1.6s linear infinite; }
  .tm-pulse { animation: tm-pulse 3.2s ease-out infinite; }
  .techmap__tag:not([hidden]) { animation: tm-fade 160ms ease-out; }
  .techmap__pane > * { animation: tm-rise 360ms var(--ease-out) both; }
  .techmap__pane > :nth-child(2) { animation-delay: 40ms; }
  .techmap__pane > :nth-child(3) { animation-delay: 80ms; }
  .techmap__pane > :nth-child(n+4) { animation-delay: 120ms; }
}
/* "Pause motion" stops all of it, not just the orbit. */
.techmap.is-paused .tm-link--flow,
.techmap.is-paused .tm-link--beam,
.techmap.is-paused .tm-pulse { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .tm-link.is-new,
  .tm-leader--pane.is-drawing,
  .tm-leader--glow.is-drawing,
  .techmap__device { animation: none; stroke-dasharray: none; stroke-dashoffset: 0; }
  .tm-core, .tm-aura, .techmap__chev, .techmap__chip { transition: none; }
}

@keyframes tm-draw  { to { stroke-dashoffset: 0; } }
@keyframes tm-crawl { to { stroke-dashoffset: -48; } }
@keyframes tm-crawl-beam { to { stroke-dashoffset: -22; } }
@keyframes tm-pulse { from { transform: scale(1); opacity: 0.7; } to { transform: scale(2.6); opacity: 0; } }
@keyframes tm-fade  { from { opacity: 0; } }
@keyframes tm-rise  { from { opacity: 0; transform: translateY(6px); } }
