  * { box-sizing: border-box; margin: 0; padding: 0; }

  body {
    background: #1a1a1a;
    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    height: 100vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    color: #e0e0e0;
    position: relative;
  }

  /* ── Top bar ── */
  .topbar {
    height: 72px;
    background: #1e1e1e;
    border-bottom: 1px solid #2a2a2a;
    display: flex;
    align-items: center;
    padding: 0 8px 0 4px;
    gap: 0;
    flex-shrink: 0;
  }
  .topbar-left {
    display: flex;
    align-items: center;
    gap: 2px;
  }
  .topbar-icon {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: none;
    background: transparent;
    color: #aaa;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
  }
  .topbar-icon:hover { background: rgba(255,255,255,0.08); }
  .topbar-icon svg { width: 22px; height: 22px; fill: currentColor; }
  .topbar-breadcrumb {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: #bbb;
    margin-left: 4px;
    position: relative; /* anchors .patient-popover, New UI only */
  }
  .topbar-breadcrumb-sep { color: #555; font-size: 16px; font-weight: 300; }
  .topbar-patient-name { color: #4da0ff; font-weight: 500; }
  .topbar-patient-edit { color: #888; font-size: 16px; vertical-align: middle; cursor: pointer; }
  .topbar-patient-edit:hover { color: #e0e0e0; }

  /* ── Patient switcher (New UI only) — merged in from
     explorations/patient-switcher. Old UI's patient name stays plain text
     (the rules above), it's only clickable/hoverable once body.new-ui is
     set, matching the toggle's on/off state (see viewer.js). ── */
  body.new-ui .topbar-patient-name {
    cursor: pointer;
    border-radius: 4px;
    padding: 2px 4px;
    margin: -2px -4px;
    transition: background 0.15s;
  }
  body.new-ui .topbar-patient-name:hover { background: rgba(77,160,255,0.12); }
  /* Old UI: patient search is still the left-toolbar Search tool. New UI:
     that's replaced by the patient-name dropdown above, so it's hidden. */
  body.new-ui #searchToolBtn { display: none; }

  .patient-popover {
    position: absolute;
    top: 100%;
    left: 0;
    margin-top: 6px;
    width: 300px;
    background: #242424;
    border: 1px solid #353535;
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.6);
    z-index: 100;
    display: none;
    overflow: hidden;
  }
  .patient-popover.visible { display: block; }
  .patient-popover-search {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    border-bottom: 1px solid #353535;
  }
  .patient-popover-search .material-icons { color: #9aa1aa; font-size: 18px; flex-shrink: 0; }
  .patient-popover-search input {
    background: transparent;
    border: none;
    outline: none;
    color: #e0e0e0;
    font-size: 13px;
    width: 100%;
    font-family: inherit;
  }
  /* #9aa1aa is this app's one muted-text/placeholder colour (was several
     near-identical failing greys - #444/#555/#666 - consolidated into
     this single value, already used elsewhere in the app, since it
     passes 4.5:1 against every dark panel here (Samantha, 2026-09-29:
     accessibility contrast pass + "rationalise... very similar colour
     shades"). */
  .patient-popover-search input::placeholder { color: #9aa1aa; }
  .patient-popover-section-label {
    font-size: 11px;
    color: #9aa1aa;
    padding: 10px 12px 4px;
    letter-spacing: 0.03em;
  }
  .patient-popover-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    cursor: pointer;
    transition: background 0.15s;
  }
  .patient-popover-item:hover { background: rgba(255,255,255,0.06); }
  .patient-popover-item.active { background: rgba(77,160,255,0.1); }
  .patient-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: #333;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 600;
    color: #aaa;
    flex-shrink: 0;
  }
  .patient-popover-item.active .patient-avatar { background: #1a3a5c; color: #4da0ff; }
  .patient-info { flex: 1; min-width: 0; }
  .patient-info-name { font-size: 13px; color: #e0e0e0; font-weight: 500; }
  .patient-popover-item.active .patient-info-name { color: #4da0ff; }
  .patient-info-meta { font-size: 11px; color: #9aa1aa; margin-top: 1px; }
  .patient-check { color: #4da0ff; font-size: 16px; }
  .patient-popover-footer {
    border-top: 1px solid #353535;
    padding: 8px 12px;
  }
  .patient-popover-footer button {
    background: transparent;
    border: none;
    color: #4da0ff;
    font-size: 12px;
    cursor: pointer;
    padding: 0;
    display: flex;
    align-items: center;
    gap: 4px;
    font-family: inherit;
  }
  .patient-popover-footer button:hover { color: #7cb8ff; }
  .patient-popover-footer button .material-icons { font-size: 14px; }

  /* Experimental (design-flag, off by default): breadcrumb badge shown while
     Advanced Enhance is active. Merged in from imaging-quality. */
  .advanced-study-badge {
    display: none;
    align-items: center;
    gap: 6px;
    margin-left: 4px;
    background: transparent;
    border: 1px solid #2c4770;
    border-radius: 12px;
    padding: 3px 10px 3px 8px;
    font-size: 12px;
    font-weight: 500;
    color: #cfd6e0;
    white-space: nowrap;
  }
  .advanced-study-badge.visible { display: inline-flex; }
  .advanced-study-badge-icon { font-size: 12px; color: #4da0ff; flex-shrink: 0; }

  /* ── Breadcrumb exam picker ── */
  .exam-dropdown-wrap { position: relative; }
  .exam-dropdown-trigger {
    display: flex;
    align-items: center;
    gap: 2px;
    background: transparent;
    border: none;
    color: #e0e0e0;
    font-weight: 500;
    font-size: 13px;
    font-family: inherit;
    padding: 4px 4px 4px 6px;
    border-radius: 4px;
    cursor: pointer;
  }
  .exam-dropdown-trigger:hover { background: rgba(255,255,255,0.08); }
  .exam-dropdown-chevron { font-size: 18px; color: #888; }
  /* New UI only: hidden - now redundant with the sidebar's own series/
     modality filter (Samantha, 2026-10-02). Old UI keeps it. */
  body.new-ui .exam-dropdown-chevron { display: none; }
  body.new-ui .exam-dropdown-trigger { cursor: default; }
  body.new-ui .exam-dropdown-trigger:hover { background: transparent; }
  .exam-dropdown-menu {
    display: none;
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    background: #252525;
    border: 1px solid #3a3a3a;
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.5);
    min-width: 200px;
    z-index: 200;
    overflow: hidden;
  }
  .exam-dropdown-menu.open { display: block; }
  .exam-dropdown-item {
    display: block;
    width: 100%;
    padding: 9px 12px;
    background: transparent;
    border: none;
    color: #ccc;
    font-size: 12px;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
    white-space: nowrap;
  }
  .exam-dropdown-item:hover { background: rgba(255,255,255,0.06); }
  .exam-dropdown-item.active { color: #4da0ff; }

  .topbar-right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 4px;
  }
  .topbar-badge-wrap {
    position: relative;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .topbar-badge {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #2196f3;
    border: 1.5px solid #1e1e1e;
  }
  .topbar-launch-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    background: transparent;
    color: #4da0ff;
    border: 1px solid #1976d2;
    border-radius: 20px;
    padding: 4px 16px;
    font-size: 13px;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s;
  }
  .topbar-launch-btn:hover { background: rgba(25,118,210,0.12); }
  .topbar-launch-btn .material-symbols-outlined { font-size: 18px; }

  /* ── Static canvas toggle — placeholder switch; the new canvas model it
     will drive isn't built yet, this just wires up the on/off UI. ── */
  .static-canvas-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-right: 12px;
    cursor: pointer;
    user-select: none;
  }
  .static-canvas-toggle-label { font-size: 13px; color: #ccc; white-space: nowrap; }
  .toggle-switch { position: relative; display: inline-block; width: 34px; height: 18px; flex-shrink: 0; }
  .toggle-switch input {
    position: absolute;
    top: 0; left: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
  }
  .toggle-switch-track {
    position: absolute;
    top: 0; left: 0;
    width: 34px;
    height: 18px;
    background: #3a3a3a;
    border-radius: 10px;
    transition: background 0.15s;
    pointer-events: none;
  }
  .toggle-switch-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    background: #ccc;
    border-radius: 50%;
    transition: transform 0.15s, background 0.15s;
    pointer-events: none;
  }
  .toggle-switch input:checked ~ .toggle-switch-track { background: #1976d2; }
  .toggle-switch input:checked ~ .toggle-switch-thumb { transform: translateX(16px); background: #fff; }
  .toggle-switch input:focus-visible ~ .toggle-switch-track { outline: 2px solid #4da0ff; outline-offset: 2px; }
  .static-canvas-toggle.active .static-canvas-toggle-label { color: #4da0ff; }

  .topbar-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #f44336;
    margin: 0 4px;
  }
  .topbar-location {
    display: flex;
    align-items: center;
    gap: 6px;
    background: transparent;
    border: 1px solid #3a3a3a;
    border-radius: 4px;
    padding: 4px 8px 4px 12px;
    font-size: 13px;
    color: #ccc;
    cursor: pointer;
    min-width: 160px;
  }
  .topbar-location svg { width: 18px; height: 18px; fill: currentColor; color: #888; margin-left: auto; }
  .topbar-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: #37474f;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 500;
    color: #cfd8dc;
    cursor: pointer;
    margin-left: 4px;
  }

  /* ── Main layout ── */
  .layout {
    display: flex;
    flex: 1;
    overflow: hidden;
  }

  /* ── Study panel (thumbnails) ── */
  .study-panel {
    width: 168px;
    background: #141414;
    border-right: 1px solid #252525;
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    overflow: hidden;
    transition: width 0.2s ease;
  }
  /* Collapsed: panel fully hidden; the expand control lives at the bottom of the tool strip */
  body.panel-collapsed .study-panel { width: 0; border-right: none; }
  .study-search {
    padding: 8px 6px 4px;
    border-bottom: 1px solid #252525;
    flex-shrink: 0;
  }
  /* ── Shared trigger-button look for the study-search dropdowns below
     (series, modality) ── */
  .date-filter-trigger {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    background: #1e1e1e;
    border: 1px solid #2e2e2e;
    border-radius: 4px;
    padding: 6px 8px;
    color: #ccc;
    font-size: 12px;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
  }
  .date-filter-trigger:hover { border-color: #3a3a3a; }
  .date-filter-trigger .material-symbols-outlined { font-size: 15px; color: #9aa1aa; flex-shrink: 0; }
  .date-filter-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #9aa1aa; }
  .date-filter-label.set { color: #4da0ff; }
  .date-filter-chevron { font-size: 16px; color: #9aa1aa; flex-shrink: 0; transition: transform 0.15s; }

  /* ── Series list dropdown — jumps straight to a series' date filter,
     applying immediately. Fixed-position + JS-positioned via
     positionMenuAt(): the 168px sidebar is too narrow for this menu's
     content (same escape-the-container approach as .cbct-dots-menu).
     max-height raised so more series fit before scrolling (Samantha,
     2026-10-01, feedback from Tim: "contain more entries before
     scrolling" — not a bigger trigger button/tabs, just a taller list). ── */
  .series-filter-wrap { position: relative; margin-bottom: 6px; }
  .series-filter-menu {
    display: none;
    position: fixed;
    width: 280px;
    max-height: 420px;
    overflow-y: auto;
    background: #252525;
    border: 1px solid #3a3a3a;
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.5);
    z-index: 60;
  }
  .series-filter-menu.open { display: block; }
  .series-filter-item {
    display: block;
    width: 100%;
    padding: 8px 10px;
    background: transparent;
    border: none;
    color: #ccc;
    font-size: 12px;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
    white-space: nowrap;
  }
  .series-filter-item:hover { background: rgba(255,255,255,0.06); }
  .series-filter-item.active { color: #4da0ff; }

  /* ── Modality tabs — sub-feature of the series dropdown above, not its
     own dropdown any more (Samantha, 2026-10-01: "make modality a sub
     feature of this menu... almost like tabs"). Multi-select — picking one
     toggles it on/off, re-filtering the date list immediately, right below
     it in the same open menu, and the main sidebar list too. IO covers its
     sub-layouts (FMX, BWX) too, so those aren't offered as separate tabs. ── */
  .modality-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 8px;
    border-bottom: 1px solid #3a3a3a;
    position: sticky;
    top: 0;
    background: #252525;
  }
  .modality-tab {
    padding: 4px 10px;
    border-radius: 12px;
    background: transparent;
    border: 1px solid #3a3a3a;
    color: #9aa1aa;
    font-size: 11px;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
  }
  .modality-tab:hover { background: rgba(255,255,255,0.08); color: #ccc; }
  .modality-tab.active { background: #1976d2; border-color: #1976d2; color: #fff; }

  /* ── Tooth search — filters the study list to series whose tooth-number
     labels include the entered tooth. Series without real tooth labels
     (photos, CBCT, placeholder singles) never match, same "only when
     they're there" reasoning as the labels themselves. ── */
  .tooth-search-wrap {
    display: flex;
    align-items: center;
    gap: 6px;
    background: #1e1e1e;
    border: 1px solid #2e2e2e;
    border-radius: 4px;
    padding: 6px 8px;
    margin-bottom: 6px;
  }
  .tooth-search-wrap:focus-within { border-color: #3a3a3a; }
  /* New UI only: hidden per Samantha's request (2026-09-22). Old UI keeps it. */
  body.new-ui .tooth-search-wrap { display: none; }
  .tooth-search-icon { font-size: 15px; color: #9aa1aa; flex-shrink: 0; }
  .tooth-search-input {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: #ccc;
    font-size: 12px;
    font-family: inherit;
    width: 100%;
  }
  .tooth-search-input::placeholder { color: #9aa1aa; }

  .study-no-results {
    padding: 16px 8px;
    font-size: 12px;
    color: #9aa1aa;
    text-align: center;
  }

  .study-list {
    flex: 1;
    overflow-y: auto;
    padding: 6px;
  }
  .study-list::-webkit-scrollbar { width: 4px; }
  .study-list::-webkit-scrollbar-thumb { background: #333; border-radius: 2px; }

  .study-card {
    background: #1e1e1e;
    border-radius: 4px;
    margin-bottom: 6px;
    overflow: hidden;
    cursor: pointer;
    border: 1px solid transparent;
    transition: border-color 0.1s;
    position: relative;
  }
  .study-card:hover { border-color: #3a3a3a; }
  .study-card.active { border-color: #1976d2; }

  .study-thumb {
    width: 100%;
    height: 90px;
    object-fit: cover;
    display: block;
    background: #000;
  }
  .study-meta {
    padding: 4px 8px 6px;
    font-size: 11px;
    color: #888;
    line-height: 1.5;
  }
  .study-meta strong { display: block; color: #aaa; }

  .study-footer {
    height: 36px;
    border-top: 1px solid #252525;
    display: flex;
    align-items: center;
    padding: 0 8px;
    font-size: 11px;
    color: #9aa1aa;
    gap: 6px;
    flex-shrink: 0;
  }
  .study-footer-back {
    width: 24px;
    height: 24px;
    border-radius: 4px;
    border: 1px solid #333;
    background: transparent;
    color: #888;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    margin-left: auto;
  }
  .study-footer-back svg { width: 14px; height: 14px; fill: currentColor; }

  /* ── Left tool strip ── */
  .tool-strip {
    width: 60px;
    background: #313339;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 12px 0 6px;
    gap: 9px;
    flex-shrink: 0;
  }
  .tool-btn {
    width: 36px;
    height: 36px;
    border-radius: 5px;
    border: none;
    background: transparent;
    color: #aaa;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.1s, color 0.1s;
    flex-shrink: 0;
  }
  .tool-btn:hover { background: rgba(255,255,255,0.1); color: #fff; }
  .tool-btn.active { background: #4da0ff; color: #fff; border-radius: 5px; }
  /* Zoom in/out at the scale limit (VIEW_MIN/VIEW_MAX) — same disabled
     convention as .reset-btn/.cbct-canvas-btn elsewhere. Both UI modes,
     since the zoom buttons and the scale they clamp are shared, not a
     New UI-specific control (Samantha, 2026-09-23). */
  .tool-btn:disabled { opacity: 0.4; cursor: default; pointer-events: none; outline: none; box-shadow: none; }

  /* Ghosted lives in the left toolbar (Old UI) or the right toolbar,
     grouped with Compare/Move/Layouts (New UI) — never both at once. */
  body.new-ui #ghostedBtnOld { display: none; }
  #ghostedBtnNew { display: none; }
  body.new-ui #ghostedBtnNew { display: flex; }

  /* BCG lives in the bottom toolbar (Old UI, unaffected) or the left
     toolbar above Label (New UI) — never both at once. The New UI copy
     also needs individual view (.visible, toggled in updateStatus()),
     since it's only meaningful for the single selected image, same as
     the bottom toolbar's own selectedTile-gated visibility already was. */
  #bcgBtnLeft { display: none; }
  body.new-ui #bcgBtnLeft.visible { display: flex; }
  body.new-ui #bcgBtnBottom { display: none; }

  /* Rotate/Flip/View Original: New UI only, no Old UI equivalent at all
     (hidden outright rather than toggled per-mode). Individual view
     only, same .visible gating as #bcgBtnLeft (Samantha, 2026-09-23).
     Reset image removed for now, 2026-09-23 - see imaging.md if it comes
     back. #individualToolsDivider closes out this whole cluster
     (BCG/Spot tools/Rotate/Flip/View Original) - same .visible gating,
     since it has nothing to separate in Old UI or in the overview grid,
     where none of these exist. */
  #rotateBtn, #flipHBtn, #viewOriginalBtnLeft, #individualToolsDivider { display: none; }
  body.new-ui #rotateBtn.visible,
  body.new-ui #flipHBtn.visible,
  body.new-ui #viewOriginalBtnLeft.visible { display: flex; }
  body.new-ui #individualToolsDivider.visible { display: block; }
  body.new-ui #flipBtn { display: none; }
  .tool-btn svg { width: 20px; height: 20px; fill: currentColor; }
  .tool-divider { width: 100%; height: 1px; background: rgba(255,255,255,0.2); margin: 0; }

  /* Expand control shown only when the study panel is collapsed; pinned to the
     bottom of the tool strip */
  .panel-expand {
    display: none;
    margin-top: auto;
    margin-bottom: 9px;
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border: 1px solid #333;
    border-radius: 6px;
    background: transparent;
    color: #888;
    cursor: pointer;
    align-items: center;
    justify-content: center;
  }
  .panel-expand:hover { background: rgba(255,255,255,0.1); color: #fff; }
  .panel-expand svg { width: 14px; height: 14px; fill: currentColor; transform: rotate(180deg); }
  body.panel-collapsed .panel-expand { display: flex; }

  /* ── Canvas area ── */
  .canvas-wrap {
    flex: 1;
    position: relative;
    overflow: hidden;
    background: #121212;
  }
  #mainCanvas { display: block; }

  /* Old UI only: flags that Old UI isn't kept in sync any more (New-UI-only
     default, 2026-09-22) and may show stale/incorrect items. Hidden in New
     UI. pointer-events: none so it never intercepts clicks. */
  .old-ui-watermark { display: none; }
  body:not(.new-ui) .old-ui-watermark {
    display: block;
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 40;
  }

  /* ── Spot panel — floats in canvas, anchored top-left ── */
  .spot-panel {
    position: absolute;
    bottom: 80px;
    left: 260px;
    width: 228px;
    background: #242424;
    border: 1px solid #353535;
    border-radius: 6px;
    overflow: hidden;
    display: none;
    box-shadow: 0 4px 16px rgba(0,0,0,0.5);
    z-index: 20;
  }
  .spot-panel.visible { display: block; }
  .panel-header {
    padding: 10px 14px 8px;
    border-bottom: 1px solid #353535;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .panel-title { font-size: 13px; font-weight: 500; color: #e0e0e0; letter-spacing: 0.01em; }
  .panel-actions { display: flex; align-items: center; gap: 2px; }
  .panel-action-btn {
    background: transparent;
    border: none;
    color: #888;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 4px;
    transition: background 0.15s, color 0.15s;
  }
  .panel-action-btn:hover { background: rgba(255,255,255,0.08); color: #e0e0e0; }
  .panel-action-btn .material-icons { font-size: 16px; }
  .panel-body { padding: 14px 14px 6px; }
  .control-row { margin-bottom: 14px; }
  .control-label {
    font-size: 11px;
    color: #888;
    margin-bottom: 6px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    text-transform: none;
    letter-spacing: 0.04em;
  }
  .control-value {
    font-size: 11px;
    color: #bbb;
    font-variant-numeric: tabular-nums;
    min-width: 28px;
    text-align: right;
    text-transform: none;
    letter-spacing: 0;
  }
  .slider-row { display: flex; align-items: center; gap: 6px; }
  .slider-btn {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    border-radius: 3px;
    border: 1px solid #444;
    background: #2e2e2e;
    color: #bbb;
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    user-select: none;
  }
  .slider-btn:hover { background: #3a3a3a; color: #fff; }
  .slider-btn:active { background: #1976d2; border-color: #1976d2; color: #fff; }

  input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    flex: 1;
    height: 4px;
    border-radius: 2px;
    outline: none;
    cursor: pointer;
    background: linear-gradient(to right, #1976d2 50%, #444 50%);
  }
  input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #1976d2;
    cursor: pointer;
  }
  input[type="range"]::-moz-range-thumb {
    width: 14px; height: 14px;
    border-radius: 50%;
    background: #1976d2;
    cursor: pointer;
    border: none;
  }
  .panel-footer {
    padding: 8px 14px 10px;
    border-top: 1px solid #353535;
  }
  .reset-btn {
    background: transparent;
    color: #90caf9;
    border: 1px solid #1976d2;
    border-radius: 4px;
    padding: 5px 14px;
    font-size: 12px;
    cursor: pointer;
    transition: background 0.15s;
  }
  .reset-btn:hover { background: rgba(25,118,210,0.15); }
  .reset-btn:disabled { opacity: 0.4; cursor: default; pointer-events: none; }

  /* ── Right toolbar ── */
  .right-strip {
    width: 60px;
    background: #313339;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 12px 0 6px;
    gap: 9px;
    flex-shrink: 0;
  }

  /* ── Status bar ── */
  /* ── Bottom toolbar ── */
  .bottombar {
    position: absolute;
    left: 169px;
    right: 0;
    bottom: 0;
    height: 48px;
    background: #313339;
    border-top: 1px solid #d1ccc7;
    display: none;
    align-items: center;
    justify-content: flex-start;
    padding-left: 12px;
    gap: 2px;
  }
  .bottom-btn {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: none;
    background: transparent;
    color: #aaa;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
  }
  .bottom-btn:hover { background: rgba(255,255,255,0.08); color: #fff; }
  .bottom-btn svg { width: 20px; height: 20px; fill: currentColor; }
  .tool-btn .material-icons,
  .bottom-btn .material-icons { font-size: 24px; }
  .tool-btn .material-symbols-outlined,
  .bottom-btn .material-symbols-outlined { font-size: 24px; }
  .bottom-btn.active { background: #1976d2; color: #fff; border-radius: 50%; }

  /* Advanced Enhance flip control, merged in from imaging-quality. A
     labelled pill (icon + text) rather than an icon-only circle, since
     "View Original"/"View Enhance" needs to read clearly on its own. */
  .bottom-btn-labeled {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 34px;
    padding: 0 14px;
    border-radius: 17px;
    border: 1px solid #46484e;
    background: transparent;
    color: #aaa;
    font-family: inherit;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    flex-shrink: 0;
    white-space: nowrap;
    margin-left: 8px;
  }
  .bottom-btn-labeled:hover { background: rgba(255,255,255,0.08); color: #fff; }
  .bottom-btn-labeled .material-symbols-outlined { font-size: 18px; }
  /* View Original and View Enhance intentionally look identical: same
     outline, no colour change between them, so the button reads as one
     consistent control rather than having a "more active" state. */

  /* Vertical divider between the icon row and the flip button */
  .bottombar-divider { width: 1px; height: 24px; background: rgba(255,255,255,0.2); margin: 0 6px; flex-shrink: 0; }

  /* Experimental rocket-icon alternative to the flip pill (design flag) */
  #flipBtn.flip-hidden { display: none; }
  #flipRocketBtn { display: none; margin-left: 8px; }
  #flipRocketBtn.visible { display: flex; }
  #flipRocketBtn.active { background: #1976d2; color: #fff; border-radius: 50%; }

  .cbct-card { position: relative; }
  .cbct-thumb-badge {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 90px; /* matches .study-thumb */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    background: rgba(17,17,17,0.72);
    pointer-events: none;
  }
  .cbct-thumb-badge .material-symbols-outlined { font-size: 24px; color: #9aa1aa; }
  .cbct-thumb-badge-text { font-size: 10px; font-weight: 500; color: #999; }

  /* ── CBCT meta row with three-dot menu (Variant C: pick a specific
     viewer, or click the card itself to launch the default) ── */
  .cbct-meta-row {
    display: flex;
    align-items: center;
    width: 100%;
    position: relative;
  }
  .cbct-meta-row .study-meta { flex: 1; }
  .cbct-dots-wrap { position: relative; flex-shrink: 0; }
  .cbct-dots-btn {
    display: flex;
    width: 22px;
    height: 22px;
    border: none;
    background: transparent;
    color: #888;
    cursor: pointer;
    border-radius: 3px;
    align-items: center;
    justify-content: center;
    padding: 0;
    margin-right: 6px;
  }
  .cbct-dots-btn:hover { background: rgba(255,255,255,0.08); color: #ccc; }
  .cbct-dots-btn .material-icons { font-size: 16px; }
  .cbct-dots-menu {
    display: none;
    position: fixed;
    background: #252525;
    border: 1px solid #3a3a3a;
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.5);
    min-width: 170px;
    z-index: 200;
    overflow: hidden;
  }
  .cbct-dots-menu.open { display: block; }
  .cbct-dots-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 9px 12px;
    background: transparent;
    border: none;
    color: #ccc;
    font-size: 12px;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
    white-space: nowrap;
  }
  .cbct-dots-item:hover { background: rgba(255,255,255,0.06); }
  .cbct-dots-item .material-symbols-outlined { font-size: 14px; opacity: 0.6; }

  /* ── Label tray: flyout from the left tool strip, same look as
     .cbct-dots-menu. display:contents on the wrapper so it doesn't
     become an extra flex item in .tool-strip — the button itself stays
     the item, exactly as before this wrapper existed. ── */
  .label-tool-wrap { display: contents; }
  .flyout-tray-menu {
    display: none;
    position: fixed;
    background: #252525;
    border: 1px solid #3a3a3a;
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.5);
    min-width: 150px;
    z-index: 200;
    overflow: hidden;
  }
  .flyout-tray-menu.open { display: block; }
  .flyout-tray-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 9px 12px;
    background: transparent;
    border: none;
    color: #ccc;
    font-size: 12px;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
    white-space: nowrap;
  }
  .flyout-tray-item:hover { background: rgba(255,255,255,0.06); }
  .flyout-tray-item .material-icons, .flyout-tray-item .material-symbols-outlined { font-size: 16px; opacity: 0.7; }
  .flyout-tray-item.active { color: #4da0ff; }
  .flyout-tray-item.active .material-icons, .flyout-tray-item.active .material-symbols-outlined { opacity: 1; }
  .flyout-tray-divider { height: 1px; background: #3a3a3a; margin: 4px 0; }
  /* Clear is a one-shot destructive action, not a persistent tool
     selection like the four above it — never gets .active, and hovers
     toward a warning colour instead of the usual blue. */
  .flyout-tray-item.danger { color: #d98a8a; }
  .flyout-tray-item.danger .material-icons { opacity: 0.85; }
  .flyout-tray-item.danger:hover { background: rgba(217,83,79,0.12); color: #ff6b6b; }
  .flyout-tray-item.danger:hover .material-icons { opacity: 1; }

  /* Custom filter list (Enhance's "Custom" tray item, 2026-09-23) — wider
     than the default 150px min-width since rows carry two icons plus a
     name, some of them long ("Apteryx IO Filter"). */
  #customFilterMenu { min-width: 190px; max-height: 320px; overflow-y: auto; }
  .custom-filter-item .custom-filter-label { flex: 1; }
  /* Star is its own clickable target within the row (stopPropagation in
     JS keeps it from also selecting the filter) - always full opacity,
     not just on hover like the mode icons, so favourite state stays
     legible at a glance. Gold once starred, same convention as a
     favourite star anywhere else. */
  .custom-filter-star { opacity: 0.7 !important; cursor: pointer; }
  .custom-filter-star:hover { opacity: 1 !important; }
  .custom-filter-star.starred { opacity: 1 !important; color: #f2c94c; }
  /* Camera badge = predefined/built-in filter (Samantha: "predefined") vs
     a user-created one, which has no badge at all. */
  .custom-filter-camera { opacity: 0.5 !important; font-size: 14px !important; }

  /* ── Enhance consolidation, New UI only (Samantha, 2026-09-21): a
     compact split control replacing three always-visible buttons. Old UI
     keeps #rocketBtn/#dynamicEnhanceBtn/#customEnhanceBtn exactly as they
     were; this wrap stays hidden there. Edit Enhance has no Old UI
     button to hide — it only exists as this tray's item. A real flex
     item of its own (not display:contents like .label-tool-wrap) so its
     internal button-to-chevron gap can be tight, independent of
     .tool-strip's own 9px gap between toolbar entries. ── */
  .enhance-tool-wrap, .spot-tool-wrap {
    display: none;
    flex-direction: column;
    align-items: center;
    flex-shrink: 0;
  }
  body.new-ui .enhance-tool-wrap { display: flex; }
  body.new-ui #rocketBtn, body.new-ui #dynamicEnhanceBtn, body.new-ui #customEnhanceBtn { display: none; }

  /* Spot tools consolidation, New UI only, individual view only (same
     .visible gating as #bcgBtnLeft — Samantha, 2026-09-23). Old UI keeps
     the three bottom-toolbar buttons exactly as they were. */
  body.new-ui #spotToolWrap.visible { display: flex; }
  body.new-ui #spotBtnBottom, body.new-ui #colorizeBtnBottom, body.new-ui #magnifyBtnBottom { display: none; }

  /* Transform and AI: unwired Old UI placeholders, removed from New UI's
     bottom bar on request (Samantha, 2026-09-23). Hidden, not deleted -
     Old UI keeps both exactly as they were. */
  body.new-ui #transformBtnBottom, body.new-ui #aiBtnBottom { display: none; }

  /* New UI only: Series AI + Launch AI move up into this section (grouped
     with Enhance) via flex `order` on .tool-strip's children — no DOM
     move, so Old UI's own order (search/select, center/zoom, Enhance,
     Label/Ghosted/Series AI/Launch AI) is untouched (Samantha,
     2026-09-21). Every item from here down needs an explicit order
     (including #labelSeriesBtn and #panelExpand) since flex sorts
     same-order items by document order, and #spotBtn/#launchAiBtn sit
     AFTER #labelSeriesBtn in the DOM — without this they'd stay put. */
  body.new-ui .enhance-tool-wrap { order: 1; }
  body.new-ui #spotBtn { order: 2; }
  body.new-ui #launchAiBtn { order: 3; }
  body.new-ui #enhanceAiDivider { order: 4; }
  body.new-ui #labelSeriesBtn { order: 5; }
  body.new-ui #bcgBtnLeft { order: 6; }
  body.new-ui #spotToolWrap { order: 7; }
  body.new-ui #rotateBtn { order: 8; }
  body.new-ui #flipHBtn { order: 9; }
  body.new-ui #individualToolsDivider { order: 10; }
  body.new-ui #viewOriginalBtnLeft { order: 11; }
  body.new-ui #panelExpand { order: 12; }
  .tray-toggle-chevron {
    width: 36px;
    height: 20px;
    margin-top: -1px;
    border: none;
    border-radius: 0 0 5px 5px;
    /* Visible at rest, not just on hover — a fully transparent resting
       state read as empty space rather than a second clickable zone
       (Samantha, 2026-09-21). */
    background: rgba(255,255,255,0.06);
    color: #aaa;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .tray-toggle-chevron:hover { background: rgba(255,255,255,0.16); color: #fff; }
  .tray-toggle-chevron .material-icons { font-size: 18px; }

  /* ── Edit Enhance side panel — a drawer along the canvas's own right
     edge (not the full app window's), reusing .panel-header/.panel-body
     from the bottom-bar spot-tool panels for a consistent look. ── */
  .edit-enhance-panel {
    display: none;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 280px;
    background: #242424;
    border-left: 1px solid #353535;
    box-shadow: -4px 0 16px rgba(0,0,0,0.5);
    z-index: 25;
    flex-direction: column;
  }
  .edit-enhance-panel.visible { display: flex; }
  .edit-enhance-placeholder {
    padding: 32px 12px;
    color: #777;
    font-size: 13px;
    text-align: center;
  }

  /* ── CBCT canvas state ── */
  .cbct-canvas-state {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    background: #111;
    z-index: 5;
  }
  .cbct-canvas-state.visible { display: flex; }
  .cbct-canvas-icon .material-symbols-outlined {
    font-size: 56px;
    color: #9aa1aa;
    transition: color 0.3s;
  }
  @keyframes spin-cube {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }
  .cbct-canvas-state.loading .cbct-canvas-icon .material-symbols-outlined {
    color: #1976d2;
    animation: spin-cube 1.2s linear infinite;
    display: inline-block;
  }
  .cbct-canvas-title { font-size: 16px; font-weight: 500; color: #888; }
  .cbct-canvas-desc { font-size: 13px; color: #9aa1aa; text-align: center; line-height: 1.6; }
  .cbct-canvas-actions { display: flex; gap: 10px; margin-top: 8px; }
  .cbct-canvas-btn:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
  .cbct-canvas-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    padding: 9px 18px;
    border-radius: 6px;
    border: 1px solid #1976d2;
    background: transparent;
    color: #4da0ff;
    cursor: pointer;
    font-family: inherit;
    transition: background 0.15s;
  }
  .cbct-canvas-btn:hover { background: rgba(25,118,210,0.12); }
  .cbct-canvas-btn.primary { background: #1976d2; color: #fff; }
  .cbct-canvas-btn.primary:hover { background: #1565c0; }
  .cbct-canvas-btn .material-symbols-outlined { font-size: 16px; }

  /* ── Image caption + flag on canvas (tracks pan/zoom) ── */
  .canvas-caption {
    position: absolute;
    display: none;
    justify-content: center;
    padding: 6px 4px 4px;
    pointer-events: none; /* only the flag is interactive */
    z-index: 15;
  }
  .canvas-caption.visible { display: flex; }
  .canvas-caption-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
  }
  /* 16px (was 12px) - same size as .cap-date/.cap-enhanced below it
     (Samantha, 2026-09-23). */
  .cap-teeth { font-size: 16px; color: #ccc; text-align: center; }
  /* 16px (was 11px) and #8a8a8a (was #777, not enough contrast at this
     size) - brought in from the quality model branch's ca6898c ("Grow
     caption text..."), closer to production sizing and clears WCAG AA's
     4.5:1 contrast minimum for small text against the canvas's #121212
     background (Samantha, 2026-09-23). */
  .cap-date { font-size: 16px; color: #8a8a8a; text-align: center; }
  /* Hidden by default (enhanceMode === null) — shown + given text by
     updateEnhanceLabels() only while Advanced or Dynamic Enhance is on. */
  .cap-enhanced { display: none; font-size: 16px; color: #ccc; text-align: center; }
  .cap-enhanced.visible { display: block; }
  /* Flag pins to the caption box's right edge (under the image's right edge),
     out of flow, independent of the centred text's own width — otherwise the
     flag shares row space with the text and shifts it off the image's true
     centre. Same caption style is used in both overview and single-image
     mode, both track the image itself rather than sitting in a fixed card. */
  .canvas-caption .flag-btn {
    position: absolute;
    right: 4px;
    top: 6px;
  }

  .flag-btn {
    pointer-events: auto;
    flex-shrink: 0;
    width: 22px; height: 22px;
    background: none;
    border: none;
    border-radius: 4px;
    color: #9aa1aa;
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: color 0.15s, background 0.15s;
    position: relative;
  }
  .flag-btn:hover { color: #ccc; background: rgba(255,255,255,0.08); }
  .flag-btn.flagged { color: #e05050; }
  .flag-btn.flagged:hover { color: #f06060; }
  .flag-btn .flag-tooltip {
    position: absolute;
    bottom: calc(100% + 7px);
    right: 0;
    background: #2a2a34;
    border: 1px solid #3a3a46;
    color: #ddd;
    font-size: 11px;
    white-space: nowrap;
    padding: 4px 8px;
    border-radius: 4px;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.15s;
    z-index: 100;
  }
  .flag-btn:hover .flag-tooltip { opacity: 1; }

  /* ── B/C/G live-value HUD (shown near cursor while dragging/scrolling) ── */
  .bcg-hud {
    position: absolute;
    display: none;
    background: rgba(20,20,20,0.9);
    border: 1px solid #3a3a3a;
    border-radius: 6px;
    padding: 6px 10px;
    font-size: 11px;
    color: #ddd;
    pointer-events: none;
    white-space: nowrap;
    z-index: 50;
  }
  .bcg-hud.visible { display: block; }

  /* ── Prev/next image navigation (merged in from imaging-quality). left/top
     are set per-frame by positionCaptions() in viewer.js, docked in the
     image's letterbox gutter rather than a fixed offset from the canvas
     edge — a fixed offset would sit on top of a wide/tall image instead of
     beside it. ── */
  /* Old UI (default): unchanged fixed 12px offset from the canvas edge —
     Old UI's pan/zoom predates all of this, so it's left exactly as it
     was. New UI overrides this below. */
  .img-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    display: none;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: none;
    background: rgba(20,20,20,0.6);
    color: #cfd6e0;
    cursor: pointer;
    align-items: center;
    justify-content: center;
    z-index: 17;
    opacity: 0.65;
    transition: opacity 0.15s;
  }
  .img-nav:hover { background: rgba(40,40,40,0.85); color: #fff; opacity: 1; }
  /* 28px (was 22px) - bigger icon, same 36px button footprint (Samantha, 2026-09-23). */
  .img-nav .material-icons { font-size: 28px; }
  .img-nav.visible { display: flex; }
  /* Old UI's plain fixed position — untouched, out of scope for the New
     UI-only overlap-prevention fix below. New UI sets .style.left on both
     via JS every frame (positionCaptions() in viewer.js), which overrides
     this regardless (an explicit left + a definite width already beats a
     right value at the spec level, so .img-nav-next's `right` here is
     moot once JS sets `left` in New UI). */
  .img-nav-prev { left: 12px; }
  .img-nav-next { right: 12px; }

  /* ── Back to series: fixed chrome in the canvas's corner, not tied to
     the image's own rect — same background/hover treatment as .img-nav,
     pill-shaped instead of round to fit the label. ── */
  .back-to-series-btn {
    position: absolute;
    top: 16px;
    left: 16px;
    display: none;
    align-items: center;
    gap: 4px;
    height: 32px;
    padding: 0 12px 0 8px;
    border-radius: 16px;
    border: none;
    background: rgba(20,20,20,0.6);
    color: #cfd6e0;
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
    z-index: 17;
  }
  .back-to-series-btn:hover { background: rgba(40,40,40,0.85); color: #fff; }
  .back-to-series-btn .material-icons { font-size: 20px; }
  .back-to-series-btn.visible { display: flex; }

  /* ── Mini-map: which tile is selected (Static canvas mode only) ── */
  .minimap {
    position: absolute;
    top: 16px;
    right: 16px;
    display: none;
    gap: 3px;
    background: rgba(20,20,20,0.85);
    border: 1px solid #333;
    border-radius: 6px;
    padding: 8px;
    z-index: 20;
    /* Grows on hover instead of being permanently bigger - cells stay
       usably small at rest (14px, cramped for FMX's 18-tile grid) but
       scale up together with their gaps/padding for a closer look and
       bigger click targets, without reflowing anything else on the
       canvas. transform-origin: top right matches this box's own anchor
       (top:16px; right:16px), so it grows down-and-left into open canvas
       space rather than toward the right toolbar (Samantha, 2026-09-29). */
    transform-origin: top right;
    transition: transform 0.15s ease;
  }
  .minimap.visible { display: grid; }
  .minimap.visible:hover { transform: scale(1.8); }
  /* placeholder-only ("Awaiting upload") is the base look; has-image is
     brighter to stand out as real content; empty-slot has no image at all
     and isn't clickable. */
  .minimap-cell { background: #3a3a3a; border-radius: 2px; cursor: pointer; transition: background 0.1s; }
  .minimap-cell.placeholder-only { background: #2a2a2a; border: 1px solid #4a4a4a; }
  .minimap-cell.has-image { background: #7a7a7a; }
  .minimap-cell:not(.empty-slot):not(.selected):hover { background: #5a5a5a; }
  .minimap-cell.empty-slot { background: transparent; border: 1px dashed #4a4a4a; cursor: default; }
  .minimap-cell.selected { background: #1976d2; outline: 1.5px solid #4da0ff; }

  /* ── Toast / snackbar ── */
  .toast {
    position: fixed;
    top: 16px;
    left: 50%;
    transform: translateX(-50%) translateY(-8px);
    display: inline-flex;
    align-items: center;
    gap: 10px;
    background: #17233a;
    border: 1px solid #2c4770;
    color: #d7e2f4;
    font-size: 13px;
    padding: 10px 16px;
    border-radius: 22px;
    max-width: 520px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.35);
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.2s, transform 0.2s;
    z-index: 1000;
  }
  .toast.show {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
  .toast-icon { font-size: 16px; color: #4da0ff; flex-shrink: 0; }

  /* ══ User menu: avatar → Profile → Settings list → Location/Site/Design
     Settings — merged in from imaging-quality ══ */
  .usermenu-overlay {
    position: fixed;
    inset: 0;
    background: transparent;
    display: none;
    z-index: 1100;
  }
  .usermenu-overlay.visible { display: block; }
  .usermenu-panel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 380px;
    max-width: calc(100vw - 24px);
    background: #26282e;
    border-left: 1px solid #3a3a3a;
    box-shadow: -8px 0 28px rgba(0,0,0,0.5);
    overflow-y: auto;
  }
  .usermenu-screen { display: none; padding: 20px 0; }
  .usermenu-screen.active { display: block; }
  .usermenu-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 20px 16px;
  }
  .usermenu-title { font-size: 18px; font-weight: 600; color: #f0f0f0; }
  .usermenu-back, .usermenu-close { color: #ccc; cursor: pointer; font-size: 20px; }
  .usermenu-close { margin-left: auto; }
  .usermenu-back:hover, .usermenu-close:hover { color: #fff; }
  .usermenu-list { display: flex; flex-direction: column; }
  .usermenu-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 13px 20px;
    font-size: 14px;
    font-weight: 600;
    color: #e6e6e6;
    cursor: pointer;
  }
  .usermenu-row:hover { background: rgba(255,255,255,0.06); }
  .usermenu-row .material-symbols-outlined { font-size: 20px; color: #cfd6e0; }
  .usermenu-row-nav .material-symbols-outlined { margin-left: auto; font-size: 18px; }
  .usermenu-divider { height: 1px; background: #3a3a3a; margin: 8px 20px; }

  /* Location Settings form */
  .locsettings-body { padding: 4px 20px 20px; }
  .locsettings-current { font-size: 13px; color: #ddd; margin-bottom: 16px; }
  .locsettings-field { margin-bottom: 18px; }
  .locsettings-label { font-size: 13px; color: #ccc; margin-bottom: 8px; }
  .locsettings-segment {
    display: flex;
    border: 1px solid #1976d2;
    border-radius: 4px;
    overflow: hidden;
  }
  .locsettings-opt {
    flex: 1;
    padding: 8px 0;
    background: transparent;
    border: none;
    border-left: 1px solid #1976d2;
    color: #cfd6e0;
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
  }
  .locsettings-opt:first-child { border-left: none; }
  .locsettings-opt:hover { background: rgba(255,255,255,0.06); }
  .locsettings-opt.active { background: #1976d2; color: #fff; }
  .locsettings-opt:disabled { color: #666; cursor: default; }
  .locsettings-select {
    width: 100%;
    padding: 8px 10px;
    background: transparent;
    border: 1px solid #1976d2;
    border-radius: 4px;
    color: #cfd6e0;
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
  }
  .locsettings-select:hover { background: rgba(255,255,255,0.06); }
  .locsettings-save {
    width: 100%;
    margin-top: 8px;
    padding: 10px 0;
    background: #1976d2;
    border: none;
    border-radius: 4px;
    color: #fff;
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
  }
  .locsettings-save:hover { background: #1565c0; }

  /* Site Settings screen */
  .sitesettings-body { padding: 4px 20px 20px; }
  .sitesettings-field { margin-bottom: 18px; }
  .sitesettings-input-wrap { position: relative; }
  .sitesettings-input {
    width: 100%;
    padding: 8px 30px 8px 10px;
    background: transparent;
    border: 1px solid #555;
    border-radius: 4px;
    color: #e6e6e6;
    font-family: inherit;
    font-size: 13px;
  }
  .sitesettings-input-clear, .sitesettings-input-more {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    color: #aaa;
    font-size: 16px;
    cursor: pointer;
  }
  .sitesettings-input-clear { right: 8px; }
  .sitesettings-input-more { right: 30px; }
  .sitesettings-stepper { display: flex; }
  .sitesettings-stepper-input {
    flex: 1;
    min-width: 0;
    padding: 8px 10px;
    background: transparent;
    border: 1px solid #555;
    border-right: none;
    border-radius: 4px 0 0 4px;
    color: #e6e6e6;
    font-family: inherit;
    font-size: 13px;
  }
  .sitesettings-stepper-btn {
    width: 32px;
    flex-shrink: 0;
    background: #1976d2;
    border: none;
    border-left: 1px solid rgba(255,255,255,0.25);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
  }
  .sitesettings-stepper-btn:hover { background: #1565c0; }
  .sitesettings-stepper-btn:last-child { border-radius: 0 4px 4px 0; }
  .sitesettings-stepper-btn .material-icons { font-size: 18px; }
  .sitesettings-checklist { display: flex; flex-direction: column; gap: 12px; margin-bottom: 20px; }
  .sitesettings-checklist .clin-check { display: inline-flex; flex-direction: row-reverse; justify-content: flex-end; }
  .sitesettings-section-title { font-size: 13px; font-weight: 600; color: #e0e0e0; margin: 16px 0 14px; }

  /* Design Settings screen: experimental, off-by-default feedback flags */
  .designsettings-body { padding: 4px 20px 20px; }
  .designsettings-body .clin-check { display: flex; flex-direction: row-reverse; justify-content: flex-end; margin-bottom: 6px; }
  .design-flag-desc { font-size: 11px; color: #9aa1aa; line-height: 1.5; margin: 0 0 18px 23px; }

  /* Generic checkbox used by the Settings screens above (named for its
     original use in imaging-quality's clinical-acceptability card, which
     was NOT merged in — this component was, since Site/Design Settings
     both need a custom checkbox). */
  .clin-check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    font-weight: 500;
    color: #cfd6e0;
    cursor: pointer;
    user-select: none;
  }
  .clin-check input { position: absolute; opacity: 0; width: 0; height: 0; }
  .clin-box {
    width: 15px;
    height: 15px;
    border: 1.5px solid #666;
    border-radius: 4px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, border-color 0.15s;
    flex-shrink: 0;
  }
  .clin-box::after {
    content: '';
    width: 4px;
    height: 8px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg) translate(-1px, -1px);
    opacity: 0;
    transition: opacity 0.15s;
  }
  .clin-check input:checked + .clin-box { background: #1976d2; border-color: #1976d2; }
  .clin-check input:checked + .clin-box::after { opacity: 1; }
  .clin-check input:focus-visible + .clin-box { outline: 2px solid #4da0ff; outline-offset: 2px; }

  /* ── Upload series panel (right toolbar's Import button) — merged in
     from imaging-quality ── */
  .upload-panel {
    position: absolute;
    top: 64px;
    right: 66px;
    width: 260px;
    background: #242424;
    border: 1px solid #353535;
    border-radius: 6px;
    overflow: hidden;
    display: none;
    box-shadow: 0 4px 16px rgba(0,0,0,0.5);
    z-index: 20;
  }
  .upload-panel.visible { display: block; }
  .upload-panel .control-row:last-child { margin-bottom: 0; }
  .upload-optional { color: #9aa1aa; font-weight: 400; text-transform: none; }
  .upload-file-btn {
    display: inline-flex;
    align-items: center;
    background: #2e2e2e;
    border: 1px solid #3a3a3a;
    border-radius: 4px;
    color: #cfd6e0;
    font-size: 12px;
    padding: 6px 10px;
    cursor: pointer;
  }
  .upload-file-btn:hover { background: #363636; }
  .upload-file-list {
    margin-top: 6px;
    font-size: 11px;
    color: #999;
    line-height: 1.5;
    word-break: break-all;
  }
  .upload-hint { margin-top: 6px; font-size: 10.5px; color: #9aa1aa; line-height: 1.4; }
  .upload-text-input {
    width: 100%;
    background: #1e1e1e;
    border: 1px solid #3a3a3a;
    border-radius: 4px;
    color: #e0e0e0;
    font-size: 12px;
    padding: 6px 8px;
  }
  .upload-text-input::placeholder { color: #9aa1aa; }
  .upload-text-input:focus-visible { outline: 2px solid #4da0ff; outline-offset: 1px; }
