/* ============================================================================
   3D Anatomy Atlas — Practice EHR
   Design system ported from the PracticeEHR body-map prototype.
   ========================================================================= */

/* ── tokens ──────────────────────────────────────────────────────────────── */

:root {
  /* text */
  --fg: #1f2a44;
  --mid: #56607a;
  --dim: #7a8499;
  --body: #374151;
  --muted: #9aa4b2;
  --faint: #aab3c2;
  --white: #ffffff;
  --input-fg: #1f2937;

  /* lines */
  --line: #c6cacf;
  --line-soft: #eef1f6;
  --line-input: #d1d5db;
  --line-panel: #cfd8e6;
  --line-head: #d7deea;
  --line-strong: #cbd5e1;
  --line-hover: #bcd3ff;

  /* blues */
  --blue: #2563eb;
  --blue-solid: #3377ff;
  --blue-hover: #1d4ed8;
  --blue-dark: #1e40af;
  --blue-focus: #3b82f6;
  --blue-ring: rgba(37, 99, 235, 0.12);
  --blue-tint: #cde3ff;
  --blue-soft: #f4f8ff;
  --blue-track: #dbeafe;

  /* surfaces */
  --surface-page: #eef2f6;
  --surface-side: #eaeef5;
  --surface-card: var(--white);
  /* Pre-paint fallback only; the viewport gradient itself is ENGINE.backdrop. */
  --view-edge: var(--white);
  --surface-subtle: #f8fafc;
  --surface-track: #f1f5f9;
  --glass: rgba(255, 255, 255, 0.94); /* no backdrop-filter — plain translucency */
  --veil: rgba(255, 255, 255, 0.86);
  --scrim: rgba(15, 23, 42, 0.32);
  --blackout: rgba(11, 18, 32, 0.96);

  /* semantic */
  --green: #16a34a;
  --green-bg: #dcfce7;
  --amber: #a16207;
  --amber-bg: #fef9c3;
  --red: #dc2626;
  --red-bg: #fee2e2;
  --warn: #b45309;
  --warn-bg: #fffbeb;
  --warn-line: #fde68a;
  --purple: #8b5cf6;
  --purple-hover: #7c3aed;
  --purple-deep: #6d28d9;
  --purple-bg: #f5f3ff;
  --purple-line: #ddd6fe;
  --mark: #fef08a;

  /* type */
  --font: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-icon: 'Material Symbols Rounded';
  --font-mono: ui-monospace, 'Cascadia Code', Consolas, monospace;

  /* layout */
  /* Room the breadcrumb row must leave clear on the right for the findings
     pull-tab. Measured in Chrome rather than derived from padding, because the
     tabs are Material Symbols ligatures and mis-measure wildly until the icon
     font resolves: the widest variant is the labelled `.at-bookmark--open` at
     99px (hovered, three-digit count badge), against 40px for the arrow-only
     `.at-bookmark--collapse`. 100px plus a 16px gap matching the inset. */
  --crumb-reserve: 116px;

  /* radii */
  --r-pill: 9999px;
  --r-dialog: 16px;
  --r-card: 12px;
  --r-tool: 12px;
  --r-tip: 12px;
  --r-field: 8px;
  --r-toast: 2px;

  /* shadows */
  --sh-float: 0 4px 16px rgba(15, 23, 42, 0.08);
  --sh-tip: 0 6px 20px rgba(15, 23, 42, 0.14);
  --sh-pintip: 0 12px 30px rgba(15, 23, 42, 0.16);
  --sh-dialog: 0 24px 60px rgba(15, 23, 42, 0.28);
  --sh-flyout: 0 8px 22px rgba(15, 23, 42, 0.28);
  --sh-panel: -16px 0 36px -24px rgba(15, 23, 42, 0.34);
  --sh-side: 16px 0 36px -24px rgba(15, 23, 42, 0.28);
  --sh-toast: 0 8px 24px rgba(22, 163, 74, 0.35);

  --ease: cubic-bezier(0.32, 0.72, 0, 1);
}

/* ── reset ───────────────────────────────────────────────────────────────── */

* {
  box-sizing: border-box;
  scrollbar-width: thin;
  scrollbar-color: var(--dim);
}

html,
body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--surface-page);
  color: var(--fg);
  font-family: var(--font);
  font-size: 13px;
  -webkit-font-smoothing: antialiased;
}

[hidden] {
  display: none !important;
}
button {
  font-family: inherit;
}

/* Material Symbols render as ligature text; no font-size here so each glyph
   inherits the size of the component it sits in. */
.ms {
  font-family: var(--font-icon);
  font-weight: normal;
  font-style: normal;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  direction: ltr;
  display: inline-block;
  white-space: nowrap;
  word-wrap: normal;
  font-feature-settings: 'liga';
  -webkit-font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased;
  font-variation-settings:
    'FILL' 1,
    'wght' 500,
    'GRAD' 0,
    'opsz' 24;
  user-select: none;
  flex-shrink: 0;
}
.ms.outline {
  font-variation-settings:
    'FILL' 0,
    'wght' 500,
    'GRAD' 0,
    'opsz' 24;
}

/* ── shell ───────────────────────────────────────────────────────────────── */

/* --side-w is the single source of truth for the sidebar width: the sidebar
   reads it, the splitter positions off it, and the drag handler writes it. */
.at-app {
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  --side-w: 300px;
}
.at-body {
  position: relative;
  flex: 1;
  display: flex;
  min-height: 0;
}

/* Sits over the sidebar/viewport boundary rather than between them, so widening
   the grab area doesn't shift the layout. */
.at-splitter {
  position: absolute;
  z-index: 5;
  top: 0;
  bottom: 0;
  left: var(--side-w);
  width: 7px;
  margin-left: -3px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: col-resize;
  transition: background 0.12s ease;
}
.at-splitter:hover,
.at-splitter:focus-visible {
  background: var(--line-hover);
  outline: none;
}

/* Visible grip, so the boundary reads as draggable without having to be
   discovered by hovering. The pill is drawn on the pseudo-element rather than
   the splitter itself because the splitter is a 7px hit target that must stay
   full-height — the affordance only needs to be a short tab at mid-height. */
.at-splitter::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 4px;
  height: 34px;
  transform: translate(-50%, -50%);
  border-radius: var(--r-pill);
  background: var(--line-strong);
  transition:
    background 0.12s ease,
    height 0.12s ease;
}
.at-splitter:hover::after,
.at-splitter:focus-visible::after {
  background: var(--blue);
  height: 52px;
}
/* Keep the grip lit for the whole drag, not just while the pointer is inside
   the 7px strip — a fast drag outruns the handle and would otherwise flicker. */
body.is-resizing .at-splitter::after {
  background: var(--blue);
  height: 52px;
}

/* Held on <body> during a drag so the cursor stays consistent and text in the
   sidebar can't be selected by the moving pointer. */
body.is-resizing {
  cursor: col-resize;
  user-select: none;
}

/* ── app bar ─────────────────────────────────────────────────────────────── */

.at-bar {
  height: 56px;
  flex-shrink: 0;
  padding: 0 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface-card);
  border-bottom: 1px solid var(--line-head);
}

.at-bar__spacer {
  flex: 1;
}
.at-bar__title {
  min-width: 0;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
}
.at-bar__title small {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  font-weight: 400;
  color: var(--dim);
}

.at-brand {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-right: 2px;
  padding-right: 10px;
  margin-left: 2px;
  padding-left: 10px;
  border-right: 1px solid var(--line);
  border-left: 1px solid var(--line);
  font-size: 15px;
  font-weight: 600;
  color: var(--fg);
  white-space: nowrap;
  width: 175px;
  justify-content: center;
}

.at-iconbtn {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: none;
  color: var(--mid);
  font-size: 20px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    background 0.12s ease,
    color 0.12s ease;
}
.at-iconbtn:hover {
  background: var(--surface-track);
  color: var(--fg);
}

/* ── buttons ─────────────────────────────────────────────────────────────── */

.at-btn {
  height: 34px;
  padding: 0 14px;
  border-radius: var(--r-pill);
  border: 1px solid var(--blue-solid);
  background: var(--surface-card);
  color: var(--blue);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  transition:
    background 0.12s ease,
    border-color 0.12s ease,
    color 0.12s ease;
}
.at-btn .ms {
  font-size: 17px;
}
.at-btn:hover {
  background: var(--blue-tint);
}

.at-btn--solid {
  background: var(--blue-solid);
  border-color: var(--blue-solid);
  color: var(--white);
}
.at-btn--solid:hover {
  background: var(--blue-hover);
  border-color: var(--blue-hover);
}
.at-btn--solid:active {
  background: var(--blue-dark);
  border-color: var(--blue-dark);
}

.at-btn--ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--mid);
}
.at-btn--ghost:hover {
  background: var(--blue-soft);
  border-color: var(--line-hover);
  color: var(--fg);
}

.at-btn--purple {
  background: var(--purple);
  border-color: var(--purple);
  color: var(--white);
}
.at-btn--purple:hover {
  background: var(--purple-hover);
  border-color: var(--purple-hover);
}

.at-btn--danger {
  background: transparent;
  border-color: var(--line);
  color: var(--red);
}
.at-btn--danger:hover {
  background: var(--red-bg);
  border-color: var(--red);
  color: var(--red);
}

.at-btn:disabled,
.at-btn.is-disabled {
  opacity: 0.5;
  pointer-events: none;
}

/* compact icon action — section heads, panel head, finding cards */
.at-iact {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: none;
  color: var(--dim);
  font-size: 16px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    background 0.12s ease,
    color 0.12s ease;
}
.at-iact:hover {
  background: var(--blue-tint);
  color: var(--blue);
}
.at-iact--danger:hover {
  background: var(--red-bg);
  color: var(--red);
}

/* ── left sidebar ────────────────────────────────────────────────────────── */

.at-side {
  width: var(--side-w);
  flex-shrink: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  background: var(--surface-side);
  border-right: 1px solid var(--line-panel);
  box-shadow: var(--sh-side);
}

.at-sect {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-bottom: 1px solid var(--line-panel);
}
.at-sect--systems {
  flex: 0 0 auto;
}
.at-sect--parts {
  flex: 1;
  min-height: 0;
  border-bottom: 0;
}

.at-sect__head {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 10px 10px 10px 12px;
  background: var(--surface-card);
  border-bottom: 1px solid var(--line-head);
  font-size: 13px;
  font-weight: 600;
  color: var(--fg);
}
.at-sect__icon {
  font-size: 18px;
  color: var(--blue);
}
.at-sect__head .at-iact {
  margin-left: auto;
}

.at-sect__count {
  min-width: 20px;
  height: 18px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--blue-tint);
  color: var(--blue);
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.at-sect__body {
  overflow-y: auto;
  padding: 6px;
  max-height: 30vh;
  scrollbar-gutter: stable;
}

.at-side__hint {
  padding: 10px 14px 14px;
  text-align: center;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--dim);
}

/* the wrapper carries the border so the focus ring encloses the icons too */
.at-search {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  margin: 8px 10px 6px;
  padding: 0 6px 0 9px;
  border: 1px solid var(--line-input);
  border-radius: var(--r-field);
  background: var(--surface-card);
  transition:
    border-color 0.12s ease,
    box-shadow 0.12s ease;
}
.at-search:focus-within {
  border-color: var(--blue-focus);
  box-shadow: 0 0 0 3px var(--blue-ring);
}
.at-search > .ms {
  font-size: 17px;
  color: var(--dim);
}

.at-search input[type='search'] {
  flex: 1;
  min-width: 0;
  border: 0;
  padding: 0;
  background: transparent;
  font-family: inherit;
  font-size: 12.5px;
  color: var(--fg);
  outline: none;
}
.at-search input[type='search']::placeholder {
  color: var(--muted);
}
.at-search input[type='search']::-webkit-search-cancel-button {
  display: none;
}

.at-search__clear {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: none;
  color: var(--dim);
  font-size: 14px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.at-search__clear:hover {
  background: var(--surface-track);
  color: var(--fg);
}

/* ── system rows (js/systems.js) ─────────────────────────────────────────── */

/* Columns: checkbox · colour dot · label (flexes) · mesh count · spinner.
   The opacity slider then spans the full width on a second row. */
.at-sys {
  display: grid;
  grid-template-columns: auto auto 1fr auto auto;
  align-items: center;
  gap: 8px;
  padding: 6px 0px 6px 8px;
  border-radius: var(--r-field);
  cursor: pointer;
  user-select: none;
  transition: background 0.12s ease;
}
.at-sys:hover {
  background: var(--blue-soft);
}
.at-sys.is-on {
  background: var(--blue-track);
}

.at-sys__box {
  width: 16px;
  height: 16px;
  border-radius: 4px;
  border: 1px solid var(--line-input);
  background: var(--surface-card);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    background 0.12s ease,
    border-color 0.12s ease;
}
/* tick is a Material Symbols ligature, so the checkbox needs no child markup */
.at-sys__box::after {
  content: 'check';
  font-family: var(--font-icon);
  font-size: 13px;
  line-height: 1;
  font-variation-settings:
    'FILL' 1,
    'wght' 700,
    'GRAD' 0,
    'opsz' 20;
  color: var(--white);
  opacity: 0;
}
.at-sys__box.is-on,
.at-sys.is-on .at-sys__box {
  background: var(--blue);
  border-color: var(--blue);
}
.at-sys__box.is-on::after,
.at-sys.is-on .at-sys__box::after {
  opacity: 1;
}

.at-sys__dot {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.15);
}
.at-sys__label {
  text-align: left;
  min-width: 0;
  font-size: 13px;
  color: var(--fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.at-sys__meta {
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.at-sys__spin {
  width: 13px;
  height: 13px;
  border-radius: var(--r-pill);
  border: 2px solid var(--blue-track);
  border-top-color: var(--blue);
  animation: spin 0.8s linear infinite;
}

.at-sys__range {
  grid-column: 1 / -1;
  display: none;
  width: 100%;
  height: 4px;
  margin: 2px 0 0;
  accent-color: var(--blue);
  cursor: pointer;
  padding: 6px;
}
.at-sys.is-on .at-sys__range {
  display: block;
}

/* ── part tree (js/tree.js) ──────────────────────────────────────────────── */

.at-tree {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 4px 2px 12px;
  scrollbar-gutter: stable;
}

/* depth indentation comes from tree.js as an inline padding-left */
.at-tnode {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px 0px 3px 6px;
  border-radius: var(--r-field);
  font-size: 12.5px;
  color: var(--fg);
  cursor: pointer;
  user-select: none;
  transition: background 0.1s ease;
}
.at-tnode:hover {
  background: var(--blue-soft);
}

.at-tnode__twist {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--dim);
  font-size: 16px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.15s ease;
}
.at-tnode__twist.is-open {
  transform: rotate(90deg);
}
/* leaves keep the gutter so labels stay aligned, marked with a dot */
.at-tnode__twist.is-leaf {
  cursor: default;
}
.at-tnode__twist.is-leaf::before {
  content: '';
  width: 3px;
  height: 3px;
  border-radius: var(--r-pill);
  background: var(--line-strong);
}

.at-tnode__label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.at-tnode__badge {
  margin-left: auto;
  padding: 0 5px;
  border-radius: var(--r-pill);
  background: var(--surface-track);
  color: var(--muted);
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.at-tnode.is-selected {
  background: var(--blue-tint);
  box-shadow: inset 0 0 0 1px var(--line-hover);
  font-weight: 600;
}
.at-tnode.is-hovered {
  background: var(--blue-soft);
}
.at-tnode.is-hidden-part {
  opacity: 0.45;
}
.at-tnode.is-hidden-part .at-tnode__label {
  text-decoration: line-through;
}
.at-tnode mark {
  background: var(--mark);
  color: inherit;
  border-radius: 2px;
}

.at-tgroup[hidden] {
  display: none;
}

/* ── viewport ────────────────────────────────────────────────────────────── */

/* Only visible for the instant before the first frame paints — the real backdrop
   gradient is drawn in the render pipeline (ENGINE.backdrop in js/config.js). */
.at-view {
  flex: 1;
  position: relative;
  min-width: 0;
  background: var(--view-edge);
}
.at-view > canvas {
  position: absolute;
  inset: 0;
  display: block;
  touch-action: none;
}

/* ── view options bar ────────────────────────────────────────────────────── */

/* Bottom-right, stacked directly above the attribution pill.
   The border/background/shadow live here and nowhere else, so collapsed this is
   a single rounded square and expanding grows that same surface outwards. */
.at-viewbar {
  position: absolute;
  z-index: 12;
  right: 16px;
  bottom: 44px;
  display: flex;
  align-items: center;
  gap: 0;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--glass);
  box-shadow: var(--sh-float);
}

/* Width, not display, so the bar visibly extends out of the toggle. */
.at-viewbar__items {
  display: flex;
  align-items: center;
  gap: 2px;
  max-width: 240px;
  margin-right: 2px;
  overflow: hidden;
  transition:
    max-width 0.22s var(--ease),
    margin-right 0.22s var(--ease),
    opacity 0.18s ease;
}
.at-viewbar:not(.is-open) .at-viewbar__items {
  max-width: 0;
  margin-right: 0;
  opacity: 0;
}
/* That overflow would clip the flyouts, so release it once the row is settled. */
.at-viewbar.is-open .at-viewbar__items:hover {
  overflow: visible;
}

/* ── cross-section popover (js/app.js) ───────────────────────────────────── */

/* Absolute, so it sits above the bar instead of joining its flex row, and
   anchored to the bar's own box so it travels with it. z-index 13 slots between
   the bar (12) and the hover tooltip (14). */
.at-clip {
  position: absolute;
  z-index: 13;
  right: 0;
  bottom: calc(100% + 8px);
  min-width: 244px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface-card);
  box-shadow: var(--sh-tip);
  user-select: none;
}

.at-clip__head {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 1px 2px 8px;
  color: var(--fg);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.at-clip__head .ms {
  font-size: 16px;
  color: var(--dim);
}
/* Pushes the reset button to the far edge without an extra spacer element. */
.at-clip__head .at-iact {
  margin-left: auto;
}

.at-clip__rows {
  display: grid;
  gap: 3px;
}
/* label · offset · flip. The label column is fixed so the three sliders line up
   under each other however long the anatomical name is. */
.at-clip__row {
  display: grid;
  grid-template-columns: 96px 1fr auto;
  align-items: center;
  gap: 8px;
}

.at-clip__toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 4px 2px;
  border: 0;
  background: none;
  color: var(--mid);
  font-size: 11.5px;
  font-weight: 500;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.12s ease;
}
.at-clip__toggle:hover {
  color: var(--blue);
}
.at-clip__toggle.is-on {
  color: var(--fg);
  font-weight: 600;
}

/* The .at-sys__box idiom: the tick is drawn HERE, so app.js must not also insert
   an icon or the row shows two of them. */
.at-clip__box {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  border: 1px solid var(--line-input);
  border-radius: 4px;
  background: var(--surface-card);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    background 0.12s ease,
    border-color 0.12s ease;
}
.at-clip__box::after {
  content: 'content_cut';
  font-family: var(--font-icon);
  font-size: 11px;
  line-height: 1;
  font-variation-settings:
    'FILL' 1,
    'wght' 600;
  color: var(--white);
  opacity: 0;
  transition: opacity 0.12s ease;
}
.at-clip__toggle.is-on .at-clip__box {
  border-color: var(--blue);
  background: var(--blue);
}
.at-clip__toggle.is-on .at-clip__box::after {
  opacity: 1;
}

/* accent-color rather than a hand-built track and thumb: one line, and it takes
   the design token straight from :root. */
.at-clip__slider {
  width: 100%;
  height: 16px;
  margin: 0;
  accent-color: var(--blue);
  cursor: grab;
}
.at-clip__slider:disabled {
  opacity: 0.4;
  cursor: default;
}

.at-clip__flip {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  border: 0;
  border-radius: var(--r-field);
  background: none;
  color: var(--dim);
  font-size: 17px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    background 0.12s ease,
    color 0.12s ease,
    transform 0.16s var(--ease);
}
.at-clip__flip:hover:not(:disabled) {
  background: var(--blue-soft);
  color: var(--blue);
}
.at-clip__flip:disabled {
  opacity: 0.35;
  cursor: default;
}
/* Mirrors the glyph, so the button shows which side is being kept. */
.at-clip__flip.is-flipped {
  transform: scaleX(-1);
  color: var(--blue);
}

.at-clip__head .at-iact:disabled {
  opacity: 0.35;
  cursor: default;
}

/* Same rounded-square button as the tool rail. */
.at-vtool {
  position: relative;
  width: 38px;
  height: 38px;
  flex: 0 0 auto;
  border: 0;
  border-radius: var(--r-tool);
  background: none;
  color: var(--mid);
  font-size: 21px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    background 0.12s ease,
    color 0.12s ease,
    box-shadow 0.12s ease;
}
.at-vtool:hover {
  background: var(--blue-soft);
  color: var(--blue);
}
.at-vtool:active {
  background: var(--blue-tint);
  color: var(--blue);
}

/* Vertical rule between the options and the toggle. */
.at-viewbar__sep {
  width: 1px;
  height: 22px;
  flex: 0 0 auto;
  margin: 0 4px 0 2px;
  background: var(--line);
}
/* Collapsed, the chevron points back toward what it is hiding. */
.at-viewbar:not(.is-open) .at-viewbar__toggle .ms {
  transform: rotate(180deg);
}

/* Flyout above the button — the rail's opens sideways, which here would run
   straight into the gizmo. */
.at-vtool::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%);
  padding: 6px 10px;
  border-radius: var(--r-field);
  background: var(--fg);
  color: var(--white);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  box-shadow: var(--sh-flyout);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.at-vtool::before {
  content: '';
  position: absolute;
  bottom: calc(100% + 3px);
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--fg);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.at-vtool:hover::after,
.at-vtool:hover::before {
  opacity: 1;
}
/* The cross-section button's flyout occupies exactly the space its own popover
   opens into, so while that is up the label is both redundant and in the way. */
.at-vtool[aria-expanded='true'].at-vtool--panel::after,
.at-vtool[aria-expanded='true'].at-vtool--panel::before {
  opacity: 0;
}

/* ── findings pull-tab ───────────────────────────────────────────────────── */

/* Both tabs occupy the same slot: flush to the viewport's right edge, keeping the
   16px top inset. Nothing on the left aligns with that any more — the breadcrumb
   is seated hard into the corner and the rail starts below it — so this inset is
   now the tab's own, and `--crumb-reserve` is what keeps the trail from growing
   under it. Expanded, that edge butts against the panel so the tab reads as
   attached to it; collapsed, it sits on the window edge. Exactly one is shown at
   a time. */
.at-bookmark {
  position: absolute;
  z-index: 13;
  right: 0;
  top: 16px;
  display: none;
  align-items: center;
  gap: 5px;
  padding: 10px 9px 10px 11px;
  border: 1px solid var(--line);
  border-right: 0;
  border-radius: var(--r-card) 0 0 var(--r-card);
  background: var(--surface-card);
  color: var(--blue);
  box-shadow: var(--sh-float);
  cursor: pointer;
  transition:
    padding-right 0.12s ease,
    background 0.12s ease;
}
.at-app:not(.is-findings-collapsed) .at-bookmark--collapse {
  display: flex;
}
.at-app.is-findings-collapsed .at-bookmark--open {
  display: flex;
}

.at-bookmark:hover {
  background: var(--blue-tint);
  padding-right: 13px;
}
.at-bookmark__arrow {
  font-size: 18px;
  color: var(--dim);
}
.at-bookmark:hover .at-bookmark__arrow {
  color: var(--blue);
}

/* Arrow only, so it needs less breathing room than the labelled tab. */
.at-bookmark--collapse {
  padding: 9px 7px 9px 8px;
}
.at-bookmark__icon {
  font-size: 19px;
}
.at-bookmark__count {
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--r-pill);
  background: var(--blue);
  color: var(--white);
  font-size: 10px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.at-float {
  position: absolute;
  z-index: 12;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--sh-float);
}

/* ── hierarchy breadcrumb ────────────────────────────────────────────────── */

/* The pill sizes to the path it shows, so something else has to own the room it
   may grow into: the bounds box spans from the viewport's own corner to just short
   of the findings pull-tab, and the pill is `max-width: 100%` of it. Bounds stays
   inert so the empty space beside a short trail still orbits the model. */
.at-crumbs-bounds {
  position: absolute;
  top: 0;
  left: 0;
  right: var(--crumb-reserve);
  pointer-events: none;
}

/* 22px is a `.at-tnode` row, so the trail reads as the tree's current row lifted
   onto the viewport. Pinned as a height rather than copied from that row's
   `padding: 3px 6px`, because the arithmetic differs here: `.at-float` adds a 1px
   border the tree row has not got, and past that the tallest child decides — a
   side badge and an icon separator would each land somewhere else again.
   Horizontal padding lives on the crumbs instead, so the left fade below can
   reach all the way to the border. */
.at-crumbs {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  height: 22px;
  font-size: 12.5px;
  line-height: 16px;
  pointer-events: auto;
  overflow-x: auto;
  overflow-y: hidden;
  container-type: scroll-state;
  scrollbar-width: none; /* a scrollbar would eat the 22px — this is chrome, not content */
  /* Seated INTO the viewport's top-left corner rather than floating clear of it,
     so the three edges that meet chrome are square and only the one corner facing
     open viewport is rounded — and softer than `--r-card`, which reads as a pill at
     this height. Same reasoning as `.at-bookmark`, which squares the two corners on
     the edge it is flush against and drops that border. */
  border-top: 0;
  border-left: 0;
  border-radius: 0 var(--r-field) var(--r-field) 0;
}
.at-crumbs::-webkit-scrollbar {
  display: none;
}

/* Fade at the left edge so a scrolled trail reads as continuing past the pill
   rather than being chopped. Gated on real scrollability: drawn unconditionally
   it would smudge the first crumb every time the whole path already fits, and a
   browser without `scroll-state` queries simply never fades, which is the safe
   way to be wrong. Sticky rather than absolute because an absolutely positioned
   pseudo-element inside a scroller scrolls away with the content; the negative
   right margin cancels its width in the flex line so it overlays the first crumb
   instead of pushing it along. */
.at-crumbs::before {
  content: '';
  position: sticky;
  left: 0;
  z-index: 1;
  flex: 0 0 auto;
  align-self: stretch;
  width: 24px;
  margin-right: -24px;
  /* Opaque for the first 6px, then a ramp. A pure ramp over a 12.5px glyph is
     almost invisible — the leading letter has to actually go under the edge for
     the trail to read as continuing rather than as starting there. */
  background: linear-gradient(to right, var(--glass) 0 6px, transparent);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s var(--ease);
}
@container scroll-state(scrollable: left) {
  .at-crumbs::before {
    opacity: 1;
  }
}

/* Ancestors are dim and only the current structure is emphasised, so the trail
   reads as one label with its context behind it rather than a row of peers. */
.at-crumbs__item {
  flex: 0 0 auto;
  padding: 0 5px;
  border: 0;
  border-radius: var(--r-field);
  background: none;
  color: var(--mid);
  font: inherit;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background 0.12s var(--ease),
    color 0.12s var(--ease);
}
.at-crumbs__item.is-current {
  color: var(--fg);
  font-weight: 600;
}
/* Every crumb is a target, the current one included — it has nothing left to
   select, so it frames instead. Hence an unconditional hover; it lands after
   `.is-current` so the tint wins the colour and the weight still carries. */
.at-crumbs__item:hover {
  background: var(--blue-soft);
  color: var(--blue);
}

.at-crumbs__sep {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 14px;
  white-space: nowrap;
  user-select: none;
}

/* ── tool rail ───────────────────────────────────────────────────────────── */

/* Starts below the breadcrumb, which is seated in the corner — its 22px plus an
   8px gap — while keeping the rail's own 16px left inset, so the two read as
   separate pieces of chrome rather than one column. The max-height gives up the
   same 30px plus the bottom inset, so a short viewport cannot push the rail past
   it. */
.at-tools {
  top: 30px;
  left: 16px;
  width: 54px;
  max-height: calc(100% - 46px);
  padding: 8px 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  overflow-y: auto;
  scrollbar-width: none; /* the rail is chrome, not content */
}
.at-tools::-webkit-scrollbar {
  display: none;
}
/* A scroll container clips the flyout labels, so overflow is released while the
   pointer is on the rail — it only scrolls at all on very short viewports. */
.at-tools:hover {
  overflow: visible;
}

.at-tools__ghd {
  width: 100%;
  margin: 2px 0 0;
  text-align: center;
  user-select: none;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
}
.at-tools__sep {
  width: 70%;
  height: 1px;
  flex: 0 0 auto;
  margin: 5px 0 3px;
  background: var(--line);
}

.at-tool {
  position: relative;
  width: 38px;
  height: 38px;
  flex: 0 0 auto;
  border: 0;
  border-radius: var(--r-tool);
  background: none;
  color: var(--mid);
  font-size: 21px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    background 0.12s ease,
    color 0.12s ease,
    box-shadow 0.12s ease;
}
.at-tool:hover {
  background: var(--blue-soft);
  color: var(--blue);
}
.at-tool.is-active {
  background: var(--blue-tint);
  color: var(--blue);
  box-shadow: inset 0 0 0 1px var(--line-hover);
}
.at-tool.is-disabled {
  opacity: 0.4;
  pointer-events: none;
}

/* CSS-only flyout label to the right of the rail (the rail sits on the left edge,
   so a label to its left would be clipped), fed by data-tip + data-key. Both
   pseudo-elements are spoken for (label + arrow), so the shortcut is
   concatenated into the label rather than drawn as a separate <kbd> chip. */
.at-tool::after {
  content: attr(data-tip) ' · ' attr(data-key);
  position: absolute;
  left: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%);
  padding: 6px 10px;
  border-radius: var(--r-field);
  background: var(--fg);
  color: var(--white);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  box-shadow: var(--sh-flyout);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.at-tool::before {
  content: '';
  position: absolute;
  left: calc(100% + 4px);
  top: 50%;
  transform: translateY(-50%);
  border: 5px solid transparent;
  border-right-color: var(--fg);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.at-tool:hover::after,
.at-tool:hover::before {
  opacity: 1;
}

/* ── hover readouts ──────────────────────────────────────────────────────── */

/* ui.js measures offsetWidth/offsetHeight to place these, so they must stay in
   flow when hidden — visibility, never display. */
.at-tip {
  position: absolute;
  z-index: 14;
  top: 0;
  left: 0;
  padding: 6px 9px;
  border: 1px solid var(--line);
  border-radius: var(--r-tip);
  background: var(--surface-card);
  color: var(--fg);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  box-shadow: var(--sh-tip);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.12s ease;
}
.at-tip.is-open {
  opacity: 1;
  visibility: visible;
}
.at-tip small {
  display: block;
  margin-top: 1px;
  font-size: 11px;
  font-weight: 500;
  color: var(--dim);
}

/* The tooltip grown into the context menu (menu.js). It keeps its own header —
   the structure name it is already showing — and unfolds the items beneath it,
   so the same two lines are never drawn twice in the same place.

   Only the box changes here — surface, border and type are already the
   tooltip's, and .at-menu below copies those same values, so growing in place
   is seamless and the two menus are indistinguishable. No max-width (unlike a
   plain menu): capping would SHRINK a long structure name on right-click, the
   opposite of extending it.

   Width and height animate off inline px values menu.js measures before
   collapsing; left/top animate only when the clamp has to move it. */
.at-tip.is-menu {
  z-index: 30;
  min-width: 210px;
  overflow: hidden;
  border-radius: var(--r-card);
  pointer-events: auto;
  user-select: none;
  transition:
    width 0.18s var(--ease),
    left 0.18s var(--ease),
    top 0.18s var(--ease);
}

.at-pintip {
  position: absolute;
  z-index: 15;
  top: 0;
  left: 0;
  width: 240px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface-card);
  box-shadow: var(--sh-pintip);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.12s ease;
}
.at-pintip.is-open {
  opacity: 1;
  visibility: visible;
}

.at-pintip__hd {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 5px;
}
.at-pintip__num {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  border-radius: var(--r-pill);
  color: var(--white);
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.at-pintip__type {
  font-size: 13px;
  font-weight: 600;
  color: var(--fg);
}
.at-pintip__sev {
  margin-left: auto;
}
.at-pintip__region {
  margin-bottom: 3px;
  font-size: 12px;
  color: var(--mid);
}
.at-pintip__note {
  font-size: 12px;
  color: var(--body);
  line-height: 1.45;
  display: -webkit-box;
  line-clamp: 3;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.at-pintip__foot {
  margin-top: 6px;
  font-size: 11px;
  color: var(--muted);
}

/* severity pills — shared by the finding cards and the pin tooltip */
.at-sev,
.at-item__sev,
.at-pintip__sev {
  padding: 1px 7px;
  border-radius: var(--r-pill);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.at-sev--mild {
  background: var(--green-bg);
  color: var(--green);
}
.at-sev--moderate {
  background: var(--amber-bg);
  color: var(--amber);
}
.at-sev--severe {
  background: var(--red-bg);
  color: var(--red);
}

/* ── loading overlay (js/ui.js) ──────────────────────────────────────────── */

.at-loading {
  position: absolute;
  inset: 0;
  z-index: 16;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: var(--veil);
  color: var(--mid);
  font-size: 13px;
  font-weight: 600;
}
.at-loading.is-open {
  display: flex;
}
.at-loading__msg {
  max-width: 70%;
  text-align: center;
}
.at-loading__spin {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 3px solid var(--blue-track);
  border-top-color: var(--blue);
  animation: spin 0.8s linear infinite;
}
.at-loading__bar {
  width: 180px;
  height: 4px;
  border-radius: var(--r-pill);
  background: var(--blue-track);
  overflow: hidden;
}
.at-loading__fill {
  width: 0;
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--blue);
  transition: width 0.2s ease;
}
.at-loading__fill.is-indeterminate {
  width: 40%;
  transition: none;
  animation: slide 1.1s var(--ease) infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
@keyframes slide {
  0% {
    transform: translateX(-105%);
  }
  100% {
    transform: translateX(255%);
  }
}

/* ── viewport footnotes ──────────────────────────────────────────────────── */

.at-credit,
.at-hint {
  position: absolute;
  z-index: 11;
  bottom: 14px;
  padding: 4px 11px;
  border-radius: var(--r-pill);
  background: var(--glass);
  border: 1px solid var(--line);
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}
/* Bottom-right, below the view bar; the gizmo owns the bottom-left corner. */
.at-credit {
  right: 16px;
  bottom: 8px;
}
.at-credit a {
  color: var(--dim);
}
/* Raised clear of the attribution pill, which now runs along the bottom-right
   and is wide enough to reach the centre. */
.at-hint {
  left: 50%;
  bottom: 46px;
  transform: translateX(-50%);
  color: var(--mid);
  box-shadow: var(--sh-float);
}
.at-hint:empty {
  display: none;
}
.at-hint b {
  color: var(--fg);
  font-weight: 600;
}

/* ── right panel ─────────────────────────────────────────────────────────── */

.at-panel {
  position: relative;
  width: 360px;
  flex-shrink: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  background: var(--surface-side);
  border-left: 1px solid var(--line-panel);
  box-shadow: var(--sh-panel);
  transition: width 0.28s var(--ease);
}

/* Collapsing animates width to zero rather than unmounting, so the findings list
   keeps its scroll position and the viewport's ResizeObserver picks up the new
   size on its own. `overflow: hidden` above clips the contents mid-transition. */
.at-app.is-findings-collapsed .at-panel {
  width: 0;
  border-left-width: 0;
}

.at-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 12px 12px 16px;
  background: var(--surface-card);
  border-bottom: 1px solid var(--line-head);
}
.at-panel__title {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 14px;
  font-weight: 600;
}
.at-panel__icon {
  font-size: 18px;
  color: var(--blue);
}
.at-panel__count {
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--blue-tint);
  color: var(--blue);
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.at-panel__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.at-panel__foot {
  display: flex;
  gap: 8px;
  padding: 10px 12px;
  background: var(--surface-card);
  border-top: 1px solid var(--line-head);
}
.at-panel__foot .at-btn {
  flex: 1;
}

/* ── finding cards (js/panel.js) ─────────────────────────────────────────── */

.at-item {
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface-card);
  cursor: pointer;
  transition:
    border-color 0.12s ease,
    box-shadow 0.12s ease;
}
.at-item:hover {
  border-color: var(--line-hover);
}
.at-item.is-active {
  border-color: var(--blue);
  box-shadow: inset 0 0 0 2px var(--blue);
}

.at-item__top {
  display: flex;
  align-items: center;
  gap: 6px;
}
.at-item__num {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  border-radius: var(--r-pill);
  color: var(--white);
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.at-item__type {
  font-size: 13px;
  font-weight: 600;
  color: var(--fg);
}

.at-item__scope {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 7px;
  border-radius: var(--r-pill);
  background: var(--surface-track);
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}
.at-item__scope .ms {
  font-size: 13px;
}

/* The finding's pin is not on screen because its system is toggled off. Amber
   rather than red: nothing is wrong with the record, it just isn't visible. */
.at-item__hidden {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  padding: 1px 5px;
  border-radius: var(--r-pill);
  background: var(--warn-bg);
  color: var(--warn);
}
.at-item__hidden .ms {
  font-size: 14px;
}
/* Both chips are right-aligned by the scope chip's auto margin; a second one
   would split the free space and drift them apart. */
.at-item__scope + .at-item__hidden {
  margin-left: 0;
}

/* Dashed edge reads as "not currently drawn" at a glance down the list, without
   dimming the text — a hidden finding still has to be readable and editable. */
.at-item.is-pin-hidden {
  background: var(--surface-subtle);
  border-style: dashed;
}
.at-item.is-pin-hidden .at-item__num {
  opacity: 0.55;
}
.at-item.is-pin-hidden .at-item__part {
  color: var(--dim);
}
/* Selection outranks it: a solid blue ring must stay unambiguous. */
.at-item.is-pin-hidden.is-active {
  border-style: solid;
}

.at-item__part {
  margin-top: 5px;
  font-size: 12px;
  font-weight: 600;
  color: var(--fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.at-item__region {
  margin-top: 2px;
  font-size: 12px;
  color: var(--mid);
}
.at-item__note {
  margin-top: 4px;
  font-size: 12px;
  color: var(--body);
  line-height: 1.45;
  display: -webkit-box;
  line-clamp: 3;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.at-item__icd {
  margin-top: 6px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 7px;
  border-radius: 6px;
  background: var(--blue-tint);
  color: var(--blue);
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.at-item__icd .ms {
  font-size: 13px;
}

.at-item__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--line-soft);
}
.at-item__time {
  font-size: 11px;
  color: var(--muted);
}
.at-item__acts {
  display: flex;
  gap: 2px;
}

.at-empty {
  padding: 26px 14px;
  text-align: center;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--mid);
}
.at-empty .ms {
  display: block;
  margin-bottom: 6px;
  font-size: 30px;
  color: var(--line-strong);
}

/* ── AI analysis pane ────────────────────────────────────────────────────── */

.at-ai {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--surface-card);
  transform: translateY(100%);
  transition: transform 0.4s var(--ease);
}
.at-ai.is-open {
  transform: none;
}

.at-ai__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 13px 12px 13px 16px;
  background: linear-gradient(135deg, var(--purple), var(--purple-deep));
  color: var(--white);
}
.at-ai__title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
}
.at-ai__title .ms {
  font-size: 19px;
}
.at-ai__head .at-iact {
  color: var(--white);
}
.at-ai__head .at-iact:hover {
  background: rgba(255, 255, 255, 0.18);
  color: var(--white);
}

.at-ai__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.at-ai__stub {
  padding: 14px;
  border: 1px dashed var(--purple-line);
  border-radius: var(--r-card);
  background: var(--purple-bg);
  font-size: 12px;
  line-height: 1.55;
  color: var(--mid);
}
.at-ai__stub b {
  color: var(--purple-deep);
  font-weight: 600;
}

.at-apoint {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 10px 11px;
  border: 1px solid var(--line);
  border-radius: var(--r-tool);
  background: var(--surface-subtle);
}
.at-apoint__dot {
  width: 7px;
  height: 7px;
  flex-shrink: 0;
  margin-top: 6px;
  border-radius: var(--r-pill);
  background: var(--purple);
}
.at-apoint__text {
  flex: 1;
  min-width: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--body);
}
.at-apoint__add {
  flex-shrink: 0;
  align-self: center;
  height: 26px;
  padding: 0 10px;
  border: 1px solid var(--purple-line);
  border-radius: var(--r-pill);
  background: var(--surface-card);
  color: var(--purple-hover);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.at-apoint__add .ms {
  font-size: 14px;
}
.at-apoint__add:hover {
  background: var(--purple-bg);
}
.at-apoint__add.is-added {
  background: var(--green-bg);
  border-color: var(--green-bg);
  color: var(--green);
  cursor: default;
}

/* ── modal + forms ───────────────────────────────────────────────────────── */

.at-scrim {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: none;
  place-items: center;
  padding: 24px;
  background: var(--scrim);
}
.at-scrim.is-open {
  display: grid;
}

.at-dialog {
  width: 420px;
  max-width: calc(100vw - 40px);
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  padding: 16px;
  border-radius: var(--r-dialog);
  background: var(--surface-card);
  box-shadow: var(--sh-dialog);
}
.at-dialog__title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  font-size: 15px;
  font-weight: 600;
  color: var(--fg);
}
.at-dialog__title .ms {
  font-size: 19px;
  color: var(--blue);
}
.at-dialog__foot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
}
.at-dialog__gap {
  flex: 1;
}

.at-field {
  margin-bottom: 11px;
}
.at-field label {
  display: block;
  margin-bottom: 4px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--dim);
}
.at-field__note {
  font-weight: 400;
  color: var(--muted);
}

input[type='text'],
input[type='search'],
select,
textarea {
  width: 100%;
  padding: 7px 9px;
  border: 1px solid var(--line-input);
  border-radius: var(--r-field);
  background: var(--surface-card);
  font-family: inherit;
  font-size: 13px;
  color: var(--input-fg);
  outline: none;
  transition:
    border-color 0.12s ease,
    box-shadow 0.12s ease;
}
input[type='text']:focus,
input[type='search']:focus,
select:focus,
textarea:focus {
  border-color: var(--blue-focus);
  box-shadow: 0 0 0 3px var(--blue-ring);
  outline: none;
}
textarea {
  resize: vertical;
  min-height: 64px;
  line-height: 1.5;
}

.at-readout {
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: var(--r-field);
  background: var(--surface-subtle);
  font-size: 13px;
  font-weight: 600;
  color: var(--fg);
}
.at-readout small {
  display: block;
  margin-top: 2px;
  overflow-wrap: anywhere;
  font-size: 11px;
  font-weight: 400;
  line-height: 1.45;
  color: var(--muted);
}

.at-sevseg {
  display: flex;
  gap: 2px;
  padding: 2px;
  border-radius: var(--r-pill);
  background: var(--surface-track);
}
.at-sevseg button {
  flex: 1;
  height: 28px;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--mid);
  cursor: pointer;
  transition:
    background 0.12s ease,
    color 0.12s ease,
    box-shadow 0.12s ease;
}
.at-sevseg button:hover {
  color: var(--fg);
}
.at-sevseg button.is-active {
  background: var(--surface-card);
  color: var(--blue);
  box-shadow: var(--sh-float);
}

.at-icdchip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: var(--r-field);
  background: var(--blue-tint);
  color: var(--blue);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.at-icdchip small {
  font-weight: 500;
  color: var(--mid);
}

/* ── toast ───────────────────────────────────────────────────────────────── */

.at-toast {
  position: fixed;
  z-index: 60;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%) translateY(8px);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 14px;
  border-radius: var(--r-pill);
  background: var(--green);
  color: var(--white);
  font-size: 13px;
  font-weight: 600;
  box-shadow: var(--sh-toast);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.18s ease,
    transform 0.18s var(--ease),
    visibility 0.18s;
}
.at-toast .ms {
  font-size: 17px;
}
.at-toast.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%);
}
.at-toast[data-kind='ok'] {
  background: var(--green);
}
.at-toast[data-kind='warn'] {
  background: var(--warn);
}
.at-toast[data-kind='error'] {
  background: var(--red);
}

/* ── file:// guard ───────────────────────────────────────────────────────── */

.at-fileguard {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: grid;
  place-items: center;
  padding: 24px;
  background: var(--blackout);
}
.at-fileguard__card {
  max-width: 440px;
  padding: 26px;
  border-radius: var(--r-dialog);
  background: var(--surface-card);
  box-shadow: var(--sh-dialog);
  text-align: center;
}
.at-fileguard__card h1 {
  margin: 12px 0 8px;
  font-size: 18px;
  font-weight: 600;
  color: var(--fg);
}
.at-fileguard__card p {
  margin: 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--mid);
}
.at-fileguard__card code {
  padding: 1px 6px;
  border-radius: 5px;
  background: var(--surface-track);
  color: var(--fg);
  font-family: var(--font-mono);
  font-size: 12px;
}

/* ── tree: system headers, search results ────────────────────────────────── */

/* One row per loaded system, sitting above its structures. */
.at-tnode--sys {
  margin-top: 6px;
  font-size: 12px;
  font-weight: 700;
  color: var(--fg);
  letter-spacing: 0.01em;
}
.at-tnode--sys:first-child {
  margin-top: 0;
}

/* Search hits render flat (no depth), so they stack label over breadcrumb. */
.at-tnode--result {
  align-items: flex-start;
  padding-top: 5px;
  padding-bottom: 5px;
}
.at-tnode--result .at-tnode__label {
  white-space: normal;
}

.at-tnode__crumb {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.4;
}

/* Left/right pair: one row, two buttons, each selecting its own structure.
   The label alternates between the sides, so the whole row stays clickable. */
.at-tnode__lr {
  display: inline-flex;
  gap: 2px;
  flex-shrink: 0;
  margin-left: 4px;
}
.at-lr {
  min-width: 17px;
  height: 17px;
  padding: 0 3px;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  background: var(--surface-card);
  color: var(--dim);
  font-family: var(--font);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    background 0.1s ease,
    color 0.1s ease,
    border-color 0.1s ease;
}
.at-lr:hover {
  background: var(--blue-tint);
  border-color: var(--line-hover);
  color: var(--blue);
}
.at-lr.is-selected {
  background: var(--blue);
  border-color: var(--blue);
  color: var(--white);
}
.at-lr.is-hidden-part {
  opacity: 0.45;
  text-decoration: line-through;
}

/* Laterality tag on a mirrored structure. */
.at-tnode__side {
  margin-left: 4px;
  padding: 0 4px;
  border-radius: 4px;
  background: var(--surface-track);
  color: var(--dim);
  font-size: 10px;
  font-weight: 700;
}

/* Same badge in the viewport hover tooltip (js/picking.js) and in the context
   menu's header (js/menu.js) — hence the neutral name, since the menu grows out
   of the tooltip and the two headers have to be identical. The tree's
   grey-on-grey chip disappears against the white card, so this one takes the
   blue tint for contrast; a pill radius reads better than the tree's 4px at this
   size and is a token rather than a literal. */
.at-sidetag {
  margin-left: 5px;
  padding: 0 3px;
  border-radius: var(--r-toast);
  background: var(--blue-tint);
  color: var(--blue);
  font-size: 10px;
  font-weight: 700;
  vertical-align: 1px;
}

.at-tree__note {
  padding: 8px 10px;
  color: var(--muted);
  font-size: 11.5px;
  text-align: center;
}

.at-tnode mark {
  border-radius: 2px;
  background: var(--mark);
  color: inherit;
}

/* ── viewport context menu (js/menu.js) ──────────────────────────────────── */

/* Every metric below is .at-tip's, deliberately duplicated rather than shared
   through a common class: the two are different elements in different stacking
   contexts (the tooltip is absolute inside the viewport, this is fixed to the
   window so it can flip against the screen edges), but a right-click must look
   the same whether or not the tooltip happened to be up to grow out of. Change
   one, change the other.

   z-index 30 takes the free 20–49 band in the stacking ledger — clear of
   .at-tip (14) and .at-loading (16), still under .at-scrim (50) so the finding
   dialog always covers it. */
.at-menu {
  position: fixed;
  z-index: 30;
  top: 0;
  left: 0;
  min-width: 210px;
  padding: 6px 9px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface-card);
  color: var(--fg);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  box-shadow: var(--sh-tip);
  user-select: none;
  /* menu.js measures it with getBoundingClientRect() before placing it, so like
     .at-tip it must stay laid out while hidden — visibility, never display. */
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.1s ease;
}
.at-menu.is-open {
  opacity: 1;
  visibility: visible;
}

/* Unpadded: the host's own padding positions it, exactly as the tooltip's bare
   text nodes are positioned, so the two headers land on the same pixel. */
.at-menu__head {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.at-menu__head small {
  display: block;
  margin-top: 1px;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 11px;
  font-weight: 500;
  color: var(--dim);
}

/* Pulled back out to the host's padding edge, so an item's icon starts on the
   same x as the header text above it and its highlight runs the full width of
   the card. Used inside both hosts; `height` is animated only by the grown
   tooltip, which sets an inline px value. */
.at-menu__list {
  margin: 6px -9px -6px;
  overflow: hidden;
  font-weight: 400;
  transition: height 0.18s var(--ease);
}
/* That top margin only exists to separate the items from a header. An
   empty-space right-click has none — it offers just Isolate/Show all — so
   without this the menu opens with a band of dead space above its first row.
   Element-only matching is what makes this safe in the grown tooltip: the
   tooltip's `small` sub-line always precedes the list, so it never matches there
   even though the label above it is a bare text node. */
.at-menu__list:first-child {
  margin-top: -6px;
}

/* The .at-tnode row idiom, loosened: a tree row is one line in a dense list to
   be scanned, a menu row is a pointer target that lands under the cursor. Square
   because the rows are full-bleed; the host's overflow clips them to its radius. */
.at-menu__item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 9px;
  font-size: 12.5px;
  color: var(--fg);
  white-space: nowrap;
  cursor: pointer;
  transition:
    background 0.1s ease,
    color 0.1s ease;
}
.at-menu__item .ms {
  font-size: 17px;
  color: var(--dim);
}
/* Pointer hover and keyboard focus are the same affordance, so they look alike. */
.at-menu__item:hover,
.at-menu__item.is-focused {
  background: var(--blue-soft);
  color: var(--blue);
}
.at-menu__item:hover .ms,
.at-menu__item.is-focused .ms {
  color: var(--blue);
}

/* Greyed, never removed: the title says which precondition is missing. */
.at-menu__item.is-disabled {
  opacity: 0.45;
  cursor: default;
}
.at-menu__item.is-disabled:hover {
  background: none;
  color: var(--fg);
}
.at-menu__item.is-disabled:hover .ms {
  color: var(--dim);
}

.at-menu__sep {
  height: 1px;
  margin: 4px 6px;
  background: var(--line);
}

/* ── AI pane extras ──────────────────────────────────────────────────────── */

.at-ai__label {
  color: var(--dim);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.at-ai__json {
  max-height: 190px;
  margin: 0;
  overflow: auto;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-tool);
  background: var(--surface-subtle);
  color: var(--body);
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.5;
  white-space: pre;
  tab-size: 2;
}
.at-ai__empty {
  margin: 0;
  color: var(--muted);
  font-size: 12.5px;
  text-align: center;
}

/* Active severity keeps the segmented look but adopts its semantic colour. */
.at-sevseg button.at-sev--mild.is-active {
  color: var(--green);
}
.at-sevseg button.at-sev--moderate.is-active {
  color: var(--amber);
}
.at-sevseg button.at-sev--severe.is-active {
  color: var(--red);
}

/* WebGL init failure notice (viewer.js positions it inline). */
.at-glfail {
  color: var(--mid);
  font-size: 13.5px;
  line-height: 1.6;
}

/* ── scrollbars ──────────────────────────────────────────────────────────── */

.at-panel__body::-webkit-scrollbar,
.at-tree::-webkit-scrollbar,
.at-sect__body::-webkit-scrollbar,
.at-dialog::-webkit-scrollbar {
  width: 5px;
  height: 5px;
}

.at-panel__body::-webkit-scrollbar-track,
.at-tree::-webkit-scrollbar-track,
.at-sect__body::-webkit-scrollbar-track,
.at-dialog::-webkit-scrollbar-track {
  background: transparent;
}

.at-panel__body::-webkit-scrollbar-thumb,
.at-tree::-webkit-scrollbar-thumb,
.at-sect__body::-webkit-scrollbar-thumb,
.at-dialog::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border-radius: var(--r-pill);
}

.at-panel__body::-webkit-scrollbar-thumb:hover,
.at-tree::-webkit-scrollbar-thumb:hover,
.at-sect__body::-webkit-scrollbar-thumb:hover,
.at-dialog::-webkit-scrollbar-thumb:hover {
  background: var(--dim);
}

/* ── snapshot dialog (js/snapshot.js) ─────────────────────────────────────── */

.at-dialog--snap {
  width: 620px;
}

.at-snap__preview {
  margin-bottom: 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  background: var(--blue-soft);
}
.at-snap__preview img {
  display: block;
  width: 100%;
  height: auto;
}

/* Anchors the section popover to the "Add to Sentence View" button. */
.at-snap__addwrap {
  position: relative;
}

.at-snap__menu {
  position: absolute;
  right: 0;
  bottom: calc(100% + 8px);
  min-width: 248px;
  padding: 6px;
  border-radius: 12px;
  background: var(--surface-card);
  border: 1px solid var(--line);
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.18);
  z-index: 10;
}
.at-snap__menu[hidden] {
  display: none;
}
.at-snap__menuhd {
  padding: 6px 8px 8px;
  font-size: 11px;
  color: var(--mid);
}

.at-snap__section {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--fg);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}
.at-snap__section:hover {
  background: var(--blue-soft);
}
.at-snap__section .ms {
  font-size: 18px;
  color: var(--purple);
}
