/* ─────────────────────────────────────────────────────────────────
   3D Dental Viewer — layout + custom UI bits on top of GDS tokens
   ───────────────────────────────────────────────────────────────── */
* { box-sizing: border-box; }
html, body, #root { height: 100%; margin: 0; }
:root { --ease-panel: cubic-bezier(0.22, 1, 0.36, 1); }
body {
  background: var(--neutral-50);
  color: var(--fg-alt);
  overflow: hidden;
  font: var(--text-body-sm);
}
button { font: inherit; cursor: pointer; border: 0; background: transparent; color: inherit; }
button:disabled { cursor: not-allowed; opacity: 0.45; }
input[type="number"], input[type="text"] {
  font: var(--text-body-sm); color: var(--fg-default);
  border: 1px solid var(--border-default); border-radius: var(--radius-sm);
  padding: 6px 8px; background: var(--neutral-0); outline: none;
  -moz-appearance: textfield;
}
input[type="number"]:focus, input[type="text"]:focus {
  border-color: var(--neutral-800); box-shadow: 0 0 0 3px rgba(38, 38, 38, 0.22);
}
input[type="checkbox"] {
  appearance: none; width: 16px; height: 16px; border: 1.5px solid var(--border-strong);
  border-radius: 3px; background: var(--neutral-0); display: inline-grid; place-content: center;
  cursor: pointer; transition: all 120ms var(--ease-out);
  margin: 0;
}
input[type="checkbox"]::before {
  content: ""; width: 9px; height: 9px; transform: scale(0);
  box-shadow: inset 9px 9px var(--gds-brand-on-bg);
  clip-path: polygon(14% 44%, 0 60%, 40% 100%, 100% 18%, 84% 4%, 38% 70%);
  transition: 100ms transform var(--ease-out);
}
input[type="checkbox"]:checked {
  background: var(--neutral-800); border-color: var(--neutral-800);
}
input[type="checkbox"]:checked::before { transform: scale(1); }
input[type="checkbox"]:focus-visible { box-shadow: 0 0 0 3px rgba(38, 38, 38, 0.22); }

/* ─── App shell ──────────────────────────────────────────────────── */
.app {
  height: 100vh;
  height: 100dvh;
  background: var(--neutral-0);
  position: relative;
}

/* ─── Loading splash (covers canvas + panel until scans arrive) ────── */
.load-overlay {
  position: absolute; top: 56px; left: 0; right: 0; bottom: 0;
  z-index: 30;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 20px;
  opacity: 1;
  transition: opacity 280ms var(--ease-out);
}
.load-overlay-hide { opacity: 0; pointer-events: none; }
.load-overlay-text { margin: 0; font: var(--text-body-lg); color: var(--fg-muted); }
.load-bar-track {
  width: 292px; height: 6px; border-radius: var(--radius-full);
  background: var(--neutral-200); overflow: hidden;
}
.load-bar-fill {
  height: 100%; width: 0%; border-radius: var(--radius-full);
  background: var(--neutral-800);
  transition-property: width; transition-timing-function: ease-in;
}

/* ─── Header ─────────────────────────────────────────────────────── */
.header {
  position: absolute; top: 0; left: 0; right: 0; height: 56px;
  display: flex; align-items: center; gap: 24px;
  padding: 0 24px;
  border-bottom: 1px solid var(--border-default);
  background: var(--neutral-0);
  z-index: 20;
  opacity: 1;
  transition: transform 570ms var(--ease-panel), opacity 530ms var(--ease-panel);
}
.app-zen .header { transform: translateY(-100%); opacity: 0; pointer-events: none; }

/* ─── Toast — e.g. "annotation saved" ────────────────────────────── */
/* Sits just below the header's 56px + a 24px gap. z-index is below the
   header's (20) so it visibly slides out from underneath it rather than
   overlapping it. Re-mounted with a fresh key per trigger (see viewer.jsx)
   so repeated saves always restart the animation cleanly; a JS timeout
   (not just animation-fill-mode) removes it from the DOM afterward so it
   never lingers as an invisible, pointer-events-none-but-still-there node. */
.toast {
  position: fixed;
  top: 80px; left: 50%;
  z-index: 19;
  background: var(--neutral-0);
  border-radius: 16px;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08), var(--shadow-md);
  padding: 16px 24px;
  pointer-events: none;
  transform: translate(-50%, 0);
  opacity: 1;
}
.toast-text { font: 500 16px/24px var(--font-sans); color: #171717; white-space: nowrap; }
@media (prefers-reduced-motion: no-preference) {
  .toast { animation: toast-pop 2.8s var(--ease-out) both; }
}
@keyframes toast-pop {
  0%   { opacity: 0; transform: translate(-50%, -80px); }
  11%  { opacity: 1; transform: translate(-50%, 0); animation-timing-function: linear; }
  82%  { opacity: 1; transform: translate(-50%, 0); animation-timing-function: ease-in; }
  100% { opacity: 0; transform: translate(-50%, 0); }
}

.brand { display: flex; align-items: center; gap: 12px; }
.brand-divider {
  width: 1px; height: 22px; background: var(--border-default);
}
.brand-product {
  font: var(--text-body-med); color: var(--fg-alt);
  font-family: var(--font-display); font-weight: 400;
  letter-spacing: -0.005em;
}

.nav-tabs { display: flex; gap: 4px; margin-left: 8px; }
.nav-tab {
  padding: 18px 16px; font: var(--text-body-sm-med); color: var(--fg-muted);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color 120ms;
}
.nav-tab:hover { color: var(--fg-default); }
.nav-tab.active { color: var(--gds-brand-bg); border-bottom-color: var(--gds-brand-bg); }

.header-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.header-tech {
  font: var(--text-body-sm); color: var(--fg-muted);
  margin-right: 16px;
}
.header-tech strong { color: var(--fg-default); font-weight: 500; }

.icon-btn {
  width: 36px; height: 36px; display: grid; place-content: center;
  border-radius: var(--radius-sm); color: var(--fg-alt);
  transition: background 120ms;
  position: relative;
}
.icon-btn:hover { background: var(--neutral-100); }
.icon-btn.active { color: var(--gds-brand-bg); }
.icon-btn .dot {
  position: absolute; top: 8px; right: 8px;
  width: 7px; height: 7px; border-radius: 50%; background: var(--gds-brand-bg);
}

.menu-btn {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-radius: var(--radius-sm);
  font: var(--text-body-sm-med); color: var(--fg-alt);
  border: 1px solid var(--border-default); background: var(--neutral-0);
  transition: background 120ms;
}
.menu-btn:hover { background: var(--neutral-50); }
.menu-btn svg { width: 14px; height: 14px; color: var(--fg-muted); }

/* ─── Secondary toolbar ──────────────────────────────────────────── */
.toolbar {
  display: flex; align-items: center; gap: 8px;
  padding: 0 16px;
  border-bottom: 1px solid var(--border-default);
  background: var(--neutral-0);
  z-index: 15;
}
.toolbar-divider { width: 1px; height: 24px; background: var(--border-default); margin: 0 4px; }

.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: var(--radius-sm);
  font: var(--text-body-sm-med);
  transition: background 120ms, border-color 120ms, color 120ms;
  border: 1px solid transparent;
}
.btn-primary {
  background: var(--gds-brand-bg); color: var(--gds-brand-on-bg);
}
.btn-primary:hover { background: var(--gds-brand-bg-hover); }
.btn-primary:active { background: var(--gds-brand-bg-active); }
.btn-secondary {
  background: var(--neutral-0); border-color: var(--gds-brand-bg);
  color: var(--gds-brand-bg);
}
.btn-secondary:hover { background: rgba(235, 0, 69, 0.04); }
.btn-ghost {
  color: var(--gds-brand-bg);
}
.btn-ghost:hover { background: var(--neutral-100); }
.btn-neutral {
  background: var(--neutral-0); border-color: var(--border-default); color: var(--fg-alt);
}
.btn-neutral:hover { background: var(--neutral-50); }
.btn-reject {
  background: var(--neutral-0); border-color: var(--border-default); color: var(--fg-alt);
}
.btn-reject:hover { background: var(--neutral-50); border-color: var(--border-strong); color: var(--danger-fg); }
.btn-reject svg { color: #262626; }
.btn-reject:hover svg { color: var(--danger-fg); }
.btn-approve {
  background: #262626; color: white; border-color: #262626;
}
.btn-approve:hover { background: #2b2b2b; border-color: #2b2b2b; }
.btn-approve:active { background: #000; }
.btn-sm { padding: 6px 10px; font: var(--text-body-mini-med); }
.btn-lg { padding: 10px 18px; font: var(--text-body-med); gap: 12px; }

/* ─── Main area ──────────────────────────────────────────────────── */
.main {
  display: grid;
  grid-template-columns: 1fr;
  min-height: 0;
  position: absolute;
  inset: 0;
}

/* ─── Left sidebar ───────────────────────────────────────────────── */
.sidebar {
  background: var(--neutral-0);
  border-right: 1px solid var(--border-default);
  padding: 12px 0;
  display: flex; flex-direction: column; gap: 4px;
  z-index: 10;
}
.sidebar .icon-btn { width: 44px; height: 40px; margin: 0 auto; border-radius: var(--radius-sm); }
.sidebar .icon-btn.active {
  color: var(--gds-brand-bg); background: rgba(235, 0, 69, 0.08);
}
.sidebar .icon-btn .dot {
  top: 6px; right: 6px; width: 6px; height: 6px;
}

/* ─── Canvas area ────────────────────────────────────────────────── */
.canvas-area {
  position: relative;
  min-width: 0;
  overflow: hidden;
  background:
    radial-gradient(ellipse at 50% 35%, #E4E8EE 0%, #CDD3DC 50%, #B9C0CB 100%);
}
.canvas-area canvas { display: block; width: 100% !important; height: 100% !important; outline: none; }
.canvas-area:fullscreen { width: 100vw; height: 100vh; }

.canvas-overlay {
  position: absolute; inset: 0; pointer-events: none;
}
.canvas-overlay > * { pointer-events: auto; }
.canvas-caption {
  position: absolute; left: 16px; top: 70px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  font-family: var(--font-mono);
  color: var(--neutral-800);
  pointer-events: none;
  text-align: left;
  transition: top 570ms var(--ease-panel);
}
.app-zen .canvas-caption { top: 14px; }
.canvas-caption > span:first-child {
  font: var(--text-body-lg-bold);
  color: var(--neutral-900);
}
.canvas-caption > span:last-child {
  font: var(--text-body-sm);
  color: var(--neutral-700);
}
.canvas-actions {
  position: absolute; right: 370px; top: 70px;
  display: flex; align-items: center; gap: 2px;
  transition: right 570ms var(--ease-panel), top 570ms var(--ease-panel);
}
.app-zen .canvas-actions { right: 16px; top: 14px; }
.canvas-actions .icon-btn { background: transparent; color: var(--fg-alt); }
.canvas-actions .icon-btn:hover { background: rgba(0,0,0,0.06); }

/* ─── Right panel ────────────────────────────────────────────────── */
.right-panel {
  width: 340px;
  background: rgba(255,255,255,0.62);
  backdrop-filter: blur(28px) saturate(1.6);
  -webkit-backdrop-filter: blur(28px) saturate(1.6);
  border-radius: 24px;
  box-shadow: var(--shadow-md);
  display: flex; flex-direction: column;
  overflow: hidden;
  position: absolute;
  top: 70px; right: 14px; bottom: 14px;
  z-index: 10;
  height: auto;
  min-height: 0;
  opacity: 1;
  transition: width 240ms var(--ease-out), top 570ms var(--ease-panel), transform 570ms var(--ease-panel), opacity 530ms var(--ease-panel);
}
.app-zen .right-panel { top: 14px; transform: translateX(calc(100% + 28px)); opacity: 0; pointer-events: none; }
.app-intro .right-panel, .app-intro .vpt-wrap { transition-duration: 630ms; transition-timing-function: var(--ease-panel); }
.app-intro-start .right-panel { transform: translateX(120%); opacity: 0; }
.app-intro-start .vpt-wrap { transform: translateX(-50%) translateY(140%); opacity: 0; }
/* Replaying the intro (see replayIntro in viewer.jsx) re-arms .app-intro-start
   from an already-visible panel, which would otherwise itself transition
   closed over 630ms before the reveal even starts — halving the reveal's
   apparent length. This snaps straight to the hidden position with no
   transition for that one frame; .app-intro-snap is removed the instant
   .app-intro-start is, so only the actual reveal animates. */
.app-intro-snap .right-panel, .app-intro-snap .vpt-wrap { transition: none !important; }
.icon-img { display: block; }
.right-panel-inner {
  overflow-y: auto; overflow-x: hidden;
  /* min-height:0 lets this flex child shrink below its content height so it
     scrolls — without it the panel expands and pushes the support CTA off
     screen on short viewports. */
  flex: 1 1 auto; min-height: 0; width: 340px;
  padding-bottom: 179px;
}

/* ─── Glass L2 — shared frosted-glass surface for perspective buttons,
   visibility cards, design review, and approval status ────────────── */
.glass-l2 {
  background: rgba(255,255,255,0.8);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

/* ─── Design Review — fixed to bottom of right panel ─────────────── */
.review-section-fixed {
  position: absolute;
  left: 8px; right: 8px; bottom: 8px;
  border-radius: 16px;
  padding: 20px;
  z-index: 5;
}
/* Distinct pop-in so this section stands out from the panel/menu it rides
   in on, rather than just riding their slide. Position is already correct
   from the start — only scale + opacity animate — timed via animation-delay
   to start once the panel's own entrance (630ms on desktop, see .app-intro
   .right-panel) has finished.
   Gated on ":not(.app-intro-start)" rather than a bare animation-delay: the
   panel stays hidden behind the loading splash for as long as the scans take
   to arrive (see handleScansReady / startChromeAndModelIntro in viewer.jsx),
   which is well past 630ms, so a delay measured from component-mount would
   finish invisibly before the splash ever lifts. Keying off the class that's
   removed at the real reveal moment keeps the two in sync regardless of load
   time. */
@media (prefers-reduced-motion: no-preference) {
  .app:not(.app-intro-start) .review-section-fixed { animation: review-pop-in 220ms var(--ease-out) 630ms both; }
}
@keyframes review-pop-in {
  from { opacity: 0; transform: scale(0.94); }
  to   { opacity: 1; transform: scale(1); }
}
.review-fixed-text {
  margin: 0 0 16px;
  font: 400 16px/24px var(--font-sans); color: var(--fg-default);
  text-wrap: pretty;
}
.review-status-card {
  display: flex; align-items: center; gap: 16px;
  background: rgba(255,255,255,0.8); box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08);
  backdrop-filter: blur(40px); -webkit-backdrop-filter: blur(40px);
  border-radius: 16px; padding: 16px;
}
.review-status-icon {
  width: 40px; height: 40px; flex-shrink: 0; border-radius: var(--radius-full);
  display: grid; place-content: center;
}
.review-status-icon svg { width: 24px; height: 24px; }
.review-status-icon.approve { background: rgb(220,252,231); color: rgb(22,163,74); box-shadow: inset 0 0 0 1px rgb(134,239,172); }
.review-status-icon.reject { background: #FFF7ED; color: #C2410C; box-shadow: inset 0 0 0 1px #FED7AA; }
.review-status-text { font: 400 14px/20px var(--font-sans); color: rgb(10,10,10); }
.review-section-status { background: none; backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; padding: 0; }

/* ─── Support CTA pinned to bottom of right panel ────────────────── */
.support-cta {
  flex-shrink: 0;
  width: 340px;
  padding: 16px 20px;
  border-top: 1px solid rgba(0,0,0,0.08);
  background: rgba(245,245,245,0.6);
  display: flex; flex-direction: column; gap: 6px;
}
.support-cta-title {
  margin: 0;
  font: var(--text-body-sm-bold);
  color: var(--fg-default);
}
.support-cta-text {
  margin: 0;
  font: var(--text-body-sm);
  color: var(--fg-alt);
  text-wrap: pretty;
}
.support-cta-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%;
  height: 36px;
  margin-top: 6px;
  padding: 0 16px;
  background: var(--neutral-0);
  color: var(--secondary-fg);
  font: var(--text-body-sm-med);
  border: 1px solid var(--secondary-border);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}
.support-cta-btn:hover { background: var(--secondary-bg-hover); }
.support-cta-btn:active { background: var(--neutral-100); }
.support-cta-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring);
}

.panel-section {
  padding: 20px;
  border-bottom: 1px solid rgba(0,0,0,0.08);
}
.panel-section:last-child { border-bottom: 0; }
.panel-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 16px;
}
.panel-title {
  font: var(--text-body-med); color: var(--fg-default);
}
.panel-collapse {
  color: var(--fg-muted); padding: 4px; transition: transform 200ms;
}
.panel-collapse.collapsed { transform: rotate(-90deg); }

.checkbox-row {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 0;
  font: var(--text-body-sm); color: var(--fg-alt);
  cursor: pointer; user-select: none;
}
.checkbox-row:hover { color: var(--fg-default); }

/* ─── Viewport toolbar (floating bottom bar) ─────────────────────── */
/* Positioning/animation lives on the wrapper, not the toolbar itself, so a
   "tool unavailable" message can stack above it (column-reverse: the
   toolbar is the first child but pins to the wrapper's bottom edge, so the
   message — appended after it — renders above with a clean 24px gap and
   without needing to know the toolbar's own height). */
.vpt-wrap {
  position: absolute;
  bottom: 14px; left: calc(50% - 177px); transform: translateX(-50%);
  display: flex; flex-direction: column-reverse; align-items: center; gap: 24px;
  z-index: 4;
  opacity: 1;
  transition: left 570ms var(--ease-panel), transform 570ms var(--ease-panel), opacity 530ms var(--ease-panel);
}
.app-zen .vpt-wrap { left: 50%; }
.viewport-toolbar-v2 {
  display: flex; align-items: stretch;
  border-radius: 24px;
  background: rgba(255,255,255,0.62);
  backdrop-filter: blur(28px) saturate(1.6);
  -webkit-backdrop-filter: blur(28px) saturate(1.6);
  box-shadow: var(--shadow-md);
}
.viewport-toolbar-v2.dark {
  background: rgba(20, 28, 40, 0.6);
}
.vpt-unavailable {
  margin: 0;
  font: var(--text-body-sm-med); color: var(--fg-default);
  white-space: nowrap; text-align: center;
}
.vpt-wrap.dark .vpt-unavailable { color: var(--neutral-0); }
.vpt-group {
  display: flex; align-items: stretch; gap: 8px;
  padding: 16px;
}
.vpt-divider {
  width: 1px; align-self: stretch;
  background: rgba(0,0,0,0.08);
  flex-shrink: 0;
}
.viewport-toolbar-v2.dark .vpt-divider { background: rgba(255,255,255,0.14); }

.vpt-btn {
  position: relative;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 8px;
  border: 0; background: transparent;
  color: var(--fg-muted);
  cursor: pointer;
  flex-shrink: 0;
  transition: background 120ms var(--ease-out), border-color 120ms var(--ease-out), color 120ms var(--ease-out);
}
.vpt-btn.boxed {
}
.vpt-btn.boxed.glass-l2 { background: rgba(255,255,255,0.8); }
.viewport-toolbar-v2.dark .vpt-btn.boxed {
  background: rgba(255,255,255,0.06);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.16);
}
.vpt-btn:hover { background: rgb(245,245,245); }
.viewport-toolbar-v2.dark .vpt-btn:hover { background: rgba(255,255,255,0.1); }
.vpt-btn.active { color: #262626; }
.vpt-btn.tool-active { background: #262626; color: rgb(250,250,250); }
.vpt-btn.tool-active:hover { background: #2b2b2b; }

.vpt-tip {
  position: absolute;
  bottom: calc(100% + 10px); left: 50%;
  transform: translateX(-50%) translateY(2px);
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  background: #262626;
  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
  border-radius: 8px;
  font: 500 12px/1.2 "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: #fff;
  white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: opacity 120ms var(--ease-out), transform 120ms var(--ease-out);
  z-index: 20;
}
.vpt-tip::after {
  content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  border: 5px solid transparent; border-top-color: #262626;
}
.vpt-tip .tip-key { color: rgb(163,163,163); font-weight: 500; display: flex; align-items: center; }
.vpt-btn:hover .vpt-tip { opacity: 1; transform: translateX(-50%) translateY(0); }
.canvas-actions .icon-btn { position: relative; }
.canvas-actions .icon-btn .vpt-tip {
  bottom: auto; top: calc(100% + 10px);
  z-index: 30;
}
.canvas-actions .icon-btn .vpt-tip::after {
  top: auto; bottom: 100%;
  border-top-color: transparent; border-bottom-color: #262626;
}
.canvas-actions .icon-btn:hover .vpt-tip { opacity: 1; transform: translateX(-50%) translateY(0); }
.canvas-actions .tip-align-right { left: auto; right: 0; transform: translateY(2px); }
.canvas-actions .tip-align-right::after { left: auto; right: 12px; transform: none; }
.canvas-actions .icon-btn:hover .tip-align-right { transform: translateY(0); }
.header-icon-btn { position: relative; }
.header-icon-btn .vpt-tip {
  bottom: auto; top: calc(100% + 10px);
  z-index: 30;
}
.header-icon-btn .vpt-tip::after { top: auto; bottom: 100%; border-top-color: transparent; border-bottom-color: #262626; }
.header-icon-btn:hover .vpt-tip { opacity: 1; transform: translateX(-50%) translateY(0); }
.header-icon-btn .tip-align-right { left: auto; right: 0; transform: translateY(2px); }
.header-icon-btn .tip-align-right::after { left: auto; right: 12px; transform: none; }
.header-icon-btn:hover .tip-align-right { transform: translateY(0); }

.settings-menu-wrap { position: relative; }
.settings-menu {
  position: absolute; top: calc(100% + 8px); right: 0;
  background: var(--bg-surface); border: 1px solid var(--border-default);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
  padding: 6px; min-width: 190px; z-index: 40;
}
.settings-menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 10px; border-radius: var(--radius-sm);
  font: var(--text-body-sm); color: var(--fg-default); text-align: left;
  background: transparent; border: none; cursor: pointer;
}
.settings-menu-item:hover { background: var(--neutral-100); }
.settings-menu-wrap .icon-btn.active { color: var(--fg-alt); }

/* sliders */
.slider-row {
  display: flex; align-items: center; gap: 10px;
  margin-top: 10px;
}
.slider-row label {
  display: flex; align-items: center; gap: 8px;
  font: var(--text-body-sm); color: var(--fg-alt);
  cursor: pointer;
}
.slider {
  flex: 1; appearance: none; height: 4px;
  background: var(--neutral-200); border-radius: 999px;
  outline: none;
}
.slider::-webkit-slider-thumb {
  appearance: none; width: 14px; height: 14px; border-radius: 50%;
  background: #262626; cursor: pointer;
  box-shadow: 0 1px 3px rgba(0,0,0,0.15);
}
.slider::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%; border: 0;
  background: #262626; cursor: pointer;
}
.slider-filled {
  background: linear-gradient(to right, #262626 var(--fill, 70%), var(--neutral-200) var(--fill, 70%));
}

.subsection-label {
  font: var(--text-body-sm-med); color: var(--fg-default);
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 4px; margin-bottom: 6px;
}
.panel-rule {
  border: 0; border-top: 1px solid rgba(0,0,0,0.08);
  margin: 20px -20px;
}

/* ─── Visibility card (label + eye toggle, full-width slider below) ─ */
.vis-card {
  border-radius: var(--radius);
  margin-top: 12px;
  overflow: hidden;
}
.vis-card-head {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px 0;
}
.vis-eye {
  width: 30px; height: 30px; flex-shrink: 0;
  display: grid; place-content: center;
  border-radius: var(--radius-sm);
  color: var(--fg-alt);
  transition: background 120ms var(--ease-out), color 120ms var(--ease-out);
}
.vis-eye:hover { background: var(--neutral-100); color: var(--fg-default); }
.vis-eye:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.vis-label {
  flex: 1;
  font: var(--text-body-sm-med); color: var(--fg-default);
  line-height: 1.3;
}
.vis-label .mono-id { font-family: var(--font-mono); color: var(--fg-default); }
.vis-card-body {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px 9px 12px;
}
.vis-slider { flex: 1; display: block; }
.vis-slider-wrap { flex: 1; position: relative; display: flex; }
.vis-slider-wrap .vis-slider { flex: 1; }
.vis-slider-wrap:hover .vpt-tip { opacity: 1; transform: translateX(-50%) translateY(0); }
.vis-card + .vis-card { margin-top: 8px; }
.vis-slider:disabled { cursor: not-allowed; }
.vis-card-extra {
  border-top: 1px solid rgba(0,0,0,0.08);
  padding: 6px 14px 10px;
}
/* When the card is hidden, lock its checkboxes: keep their selected /
   not-selected state visible but dimmed and non-interactive. */
.vis-card.is-hidden .vis-card-extra { opacity: 0.5; }
.vis-card-extra input[type="checkbox"]:disabled { cursor: not-allowed; }
.checkbox-row:has(input:disabled) { cursor: not-allowed; color: var(--fg-subtle); }

/* Hidden state — dim the label + slider to signal they're locked,
   but keep the eye toggle interactive so the item can be re-shown. */
.vis-card.is-hidden .vis-eye { color: var(--fg-muted); }
.vis-card.is-hidden .vis-label { color: var(--fg-subtle); }
.vis-card.is-hidden .vis-label .mono-id { color: var(--fg-subtle); }
.vis-card.is-hidden .vis-slider {
  opacity: 0.4;
  background: linear-gradient(to right, var(--neutral-400) var(--fill, 70%), var(--neutral-200) var(--fill, 70%));
}

/* Model color swatches */
.color-swatches {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 14px;
  padding: 4px 0 2px;
}
.color-swatches .swatch {
  position: relative;
  width: 36px; height: 36px;
  border-radius: 50%;
  border: 0;
  background: none;
  padding: 0; cursor: pointer;
  outline: none;
  transition: transform var(--dur-fast) var(--ease-out);
}
.color-swatches .swatch img { width: 100%; height: 100%; display: block; pointer-events: none; border-radius: 50%; }
.color-swatches .swatch:hover { transform: scale(1.08); }
.color-swatches .swatch:focus, .color-swatches .swatch:focus-visible { outline: none; }
.color-swatches .swatch.active::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 2px solid #262626;
  pointer-events: none;
}
.swatch-tip {
  position: absolute;
  bottom: calc(100% + 10px); left: 50%;
  transform: translateX(-50%) translateY(2px);
  padding: 6px 10px;
  background: #262626;
  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
  border-radius: 8px;
  font: 500 12px/1.2 "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: #fff;
  white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: opacity 120ms var(--ease-out), transform 120ms var(--ease-out);
  z-index: 20;
}
.swatch-tip::after {
  content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  border: 5px solid transparent; border-top-color: #262626;
}
.color-swatches .swatch:hover .swatch-tip { opacity: 1; transform: translateX(-50%) translateY(0); }

/* Unit list */
.unit-card {
  border: 1px solid var(--border-default);
  border-radius: var(--radius);
  margin-top: 12px;
  overflow: hidden;
}
.unit-card-head {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border-default);
}
.unit-card-head .label {
  font: var(--text-body-sm-med); color: var(--fg-default); flex: 1;
  display: flex; align-items: center; gap: 8px;
}
.unit-card-head .id {
  font: var(--text-mono); color: var(--fg-default);
}
.unit-card-body { padding: 8px 14px 14px; }

/* ─── Contacts panel (floating) ──────────────────────────────────── */
.contacts {
  position: absolute; top: 20px; left: 20px;
  width: 270px;
  background: var(--neutral-0);
  border: 1px solid var(--border-default);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  z-index: 5;
}
.contacts-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border-default);
}
.contacts-head .title {
  font: var(--text-body-med); color: var(--fg-default);
}
.contacts.collapsed .contacts-head { border-bottom: 0; }

/* Smile-design photo grid: square thumbnails, 3 across. An incomplete
   final row simply leaves the trailing column(s) empty. The scroll area
   is capped just under two full rows, so additional photos peek beneath
   the fold and signal that the grid scrolls. */
.smile-scroll {
  max-height: 144px;
  overflow-y: auto;
  overflow-x: hidden;
}
.smile-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  align-content: start;
}
.smile-thumb {
  aspect-ratio: 1 / 1;
  width: 100%;
  padding: 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--neutral-100);
  cursor: pointer;
  transition: border-color 120ms var(--ease-out), box-shadow 120ms var(--ease-out);
}
.smile-thumb:hover { border-color: var(--neutral-800); }
.smile-thumb:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(38, 38, 38, 0.22); }
.smile-thumb img {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
}

/* ─── Lightbox ───────────────────────────────────────────────────── */
.lightbox-overlay {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(10, 10, 10, 0.5);
  display: grid; place-items: center;
}
.lightbox {
  position: relative;
  width: 880px; height: 600px;
  max-width: 92vw; max-height: 86vh;
  background: #000;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-2xl);
}
.lb-stage {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  overflow: hidden;
}
.lb-stage.zoomable { cursor: grab; }
.lb-stage.dragging { cursor: grabbing; }
.lb-stage img {
  max-width: 100%; max-height: 100%;
  object-fit: contain;
  transform-origin: center;
  transition: transform 160ms var(--ease-out);
  user-select: none; -webkit-user-select: none;
  -webkit-user-drag: none;
}
/* No easing while actively dragging — pan should track the cursor 1:1. */
.lb-stage.dragging img { transition: none; }
.lb-filename {
  position: absolute; left: 12px; top: 12px; z-index: 2;
  font: var(--text-body-sm-med); font-family: var(--font-mono);
  color: rgba(255, 255, 255, 0.95);
  background: rgba(0, 0, 0, 0.5);
  padding: 5px 10px; border-radius: var(--radius-sm);
  pointer-events: none;
}
.lb-close, .lb-arrow, .lb-zoom button {
  display: grid; place-content: center;
  border-radius: var(--radius-full);
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  transition: background 120ms var(--ease-out);
}
.lb-close:hover, .lb-arrow:hover, .lb-zoom button:hover { background: rgba(0, 0, 0, 0.8); }
.lb-close:focus-visible, .lb-arrow:focus-visible, .lb-zoom button:focus-visible {
  outline: 2px solid rgba(255, 255, 255, 0.7); outline-offset: 2px;
}
.lb-close {
  position: absolute; top: 12px; right: 12px; z-index: 3;
  width: 36px; height: 36px;
}
.lb-arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
  width: 44px; height: 44px;
}
.lb-arrow svg { width: 22px; height: 22px; }
.lb-prev { left: 12px; }
.lb-next { right: 12px; }
.lb-zoom {
  position: absolute; right: 12px; bottom: 12px; z-index: 3;
  display: flex; gap: 6px;
}
.lb-zoom button { width: 36px; height: 36px; }
.lb-zoom button:disabled { opacity: 0.4; cursor: not-allowed; }

/* ─── Review modal ───────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(10, 10, 10, 0.5);
  display: grid; place-items: center;
  padding: 24px;
}
.modal {
  width: 480px; max-width: calc(100vw - 48px);
  background: var(--neutral-0);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  overflow: hidden;
}
.modal-lg { width: 660px; }
.modal-head {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 24px 26px 0;
  position: relative;
}
.modal-headtext { flex: 1; padding-right: 28px; }
.modal-title {
  margin: 0;
  font: var(--text-h3); font-family: var(--font-display);
  color: var(--fg-default); line-height: 1.25;
}
.modal-sub {
  margin-top: 12px;
  font: var(--text-body-sm); color: var(--fg-alt);
}
.modal-sub-name { font: var(--text-body-sm-med); color: var(--fg-default); }
.modal-sub-list {
  margin: 4px 0 0; padding-left: 20px;
  color: var(--fg-alt); line-height: 1.6;
}
.modal-sub-list li { padding-left: 2px; }
.modal-sub-list .mono-id { font-family: var(--font-mono); color: var(--fg-default); }
.modal-sub-list.no-bullet { list-style: none; padding-left: 0; }
.modal-x {
  position: absolute; top: 16px; right: 16px;
  width: 32px; height: 32px; color: var(--fg-muted);
}
.modal-body { padding: 22px 26px 4px; }
.field-label {
  display: block;
  font: var(--text-body-sm-med); color: var(--fg-default);
  margin-bottom: 8px;
}
.field-label .req { color: var(--danger-fg); font-weight: 700; }
.field-label .opt { color: var(--fg-muted); font-weight: 400; }
.field-textarea {
  width: 100%; resize: vertical; min-height: 36px;
  font: var(--text-body-sm); color: var(--fg-default);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  padding: 10px 12px; background: var(--neutral-0);
  outline: none;
}
.field-textarea::placeholder { color: var(--fg-subtle); }
.field-textarea:focus {
  border-color: var(--neutral-800); box-shadow: 0 0 0 3px rgba(38, 38, 38, 0.22);
}
.modal-note {
  margin: 16px 0 0;
  font: var(--text-body-sm); color: var(--fg-muted);
  line-height: 1.5;
}
.modal-foot {
  display: flex; justify-content: flex-start; gap: 10px;
  padding: 20px 26px 24px;
}
.btn-danger {
  background: var(--danger-fg); color: #fff; border-color: var(--danger-fg);
}
.btn-danger:hover { filter: brightness(0.92); }
.btn-danger:active { filter: brightness(0.85); }
.btn-danger:disabled { opacity: 0.5; }
.contacts-body { padding: 14px; }

.numfield {
  position: relative;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  padding: 18px 8px 4px;
  background: var(--neutral-0);
  display: flex; align-items: center; gap: 4px;
  cursor: text;
}
.numfield label {
  position: absolute; top: 3px; left: 8px;
  font: var(--text-body-mini); color: var(--fg-muted);
  pointer-events: none;
}
.numfield input {
  border: 0; padding: 0; background: transparent;
  font: var(--text-body-sm); color: var(--fg-default);
  width: 100%; outline: none;
}
.numfield input:focus { box-shadow: none; }
.numfield .spinner {
  display: flex; flex-direction: column; gap: 2px;
  color: var(--fg-muted);
}
.numfield .spinner button {
  padding: 0 2px; line-height: 1; color: var(--fg-muted);
}
.numfield .spinner button:hover { color: var(--gds-brand-bg); }
.numfield:focus-within {
  border-color: var(--gds-brand-bg);
  box-shadow: var(--shadow-focus);
}

.contacts-grid {
  display: grid; grid-template-columns: 1fr 76px 1fr;
  align-items: end; gap: 8px;
}
.tooth-diagram {
  width: 76px; height: 88px;
  margin-top: 4px;
  position: relative;
}
.contacts-divider {
  border: 0; border-top: 1px solid var(--border-default);
  margin: 14px 0;
}
.contacts-actions {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
}
.action-card {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  padding: 6px;
  text-align: center;
  cursor: pointer;
  transition: background 120ms, border-color 120ms;
}
.action-card:hover {
  background: var(--neutral-50);
  border-color: var(--border-strong);
}
.action-card .label {
  font: var(--text-body-mini); color: var(--fg-alt);
  margin-bottom: 4px;
  display: block;
}
.action-card .placeholder {
  height: 36px; background: var(--neutral-100);
  border-radius: 4px;
  display: grid; place-content: center;
  color: var(--fg-subtle);
}

/* ─── Bottom action bar ──────────────────────────────────────────── */
.bottom-bar {
  position: absolute;
  top: 16px; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 14px;
  background: rgba(255,255,255,0.86);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-md);
  padding: 8px 8px 8px 20px;
  z-index: 4;
  width: calc(100% - 24px);
  max-width: 680px;
}
/* Pill-shaped review buttons, fully round to match the toolbar. */
.bottom-bar .btn { border-radius: var(--radius-full); }

/* History nav at the top of the right panel — left aligned. */
.panel-nav {
  display: flex; align-items: center; gap: 4px;
}
.panel-nav .icon-btn { width: 36px; height: 36px; }
.review-section {
  background: transparent;
}
.review-actions {
  display: flex; flex-direction: column; gap: 8px;
}
.review-actions .btn { flex: 1; border-radius: 12px; justify-content: center; text-align: center; padding-top: 14px; padding-bottom: 14px; }
.review-actions .btn-reject {
  background: var(--neutral-200); border-color: transparent; color: var(--fg-default);
}
.review-actions .btn-reject:hover { background: var(--neutral-300); border-color: transparent; color: var(--fg-default); }
.modal-foot .btn { border-radius: 12px; justify-content: center; text-align: center; }
.help-modal { width: 400px; max-height: calc(100vh - 48px); overflow-y: auto; }
.help-modal-body { padding-bottom: 22px; }
.help-rows { display: flex; flex-direction: column; gap: 16px; margin-top: 16px; }
.help-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.help-row-label { font: var(--text-body-med); color: var(--fg-default); }
.help-row-value { font: var(--text-body); color: var(--fg-default); text-align: right; }
.help-divider { border-top: 1px solid var(--border-default); margin: 20px 0 16px; }
.bottom-bar .pt-name {
  font: var(--text-body-sm-med); color: var(--fg-default);
  line-height: 1.15;
}
.bottom-bar .pt-name small {
  display: block; font: var(--text-body-mini); color: var(--fg-muted); font-weight: 400;
}
.tooth-select {
  display: flex; align-items: center; gap: 4px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  padding: 6px 10px;
  background: var(--neutral-0);
  font: var(--text-mono);
  color: var(--fg-default);
  cursor: pointer;
}
.tooth-select:hover { background: var(--neutral-50); }
.bottom-bar .desc {
  flex: 1; min-width: 0;
  font: var(--text-body-sm-med); color: var(--fg-default);
  line-height: 1.2;
}
.bottom-bar .desc .pt-name {
  display: block;
  font-size: 20px; font-weight: 600; color: var(--fg-default);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bottom-bar .desc small {
  display: block; font: var(--text-body-mini); color: var(--fg-muted); font-weight: 400;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* misc */
.kbd {
  display: inline-block;
  padding: 2px 6px;
  background: var(--neutral-100);
  border: 1px solid var(--border-default);
  border-bottom-width: 2px;
  border-radius: 4px;
  font: var(--text-body-mini-med);
  color: var(--fg-alt);
}

.collapse-row {
  display: flex; align-items: center; justify-content: space-between;
}

/* ─── Full-screen confirmation page ──────────────────────────────── */
.confirm-screen {
  position: fixed; inset: 0; z-index: 70;
  background: var(--neutral-50);
  display: flex; flex-direction: column;
}
.confirm-top {
  display: flex; align-items: center; gap: 12px;
  padding: 0 24px; height: 56px; flex-shrink: 0;
  background: var(--neutral-0);
  border-bottom: 1px solid var(--border-default);
}
.confirm-main {
  flex: 1; min-height: 0;
  display: grid; place-items: center;
  padding: 24px;
  overflow-y: auto;
}
.confirm-card {
  width: 100%; max-width: 460px;
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
}
@media (prefers-reduced-motion: no-preference) {
  .confirm-card { animation: confirm-rise 320ms var(--ease-out); }
}
@keyframes confirm-rise {
  from { transform: translateY(10px); }
  to   { transform: translateY(0); }
}
.confirm-badge {
  width: 76px; height: 76px; border-radius: var(--radius-full);
  display: grid; place-content: center;
  margin-bottom: 24px;
}
.confirm-badge-icon svg { width: 34px; height: 34px; }
.confirm-badge.reject .confirm-badge-icon svg { transform: translateY(3px); }
.confirm-badge.approve {
  background: var(--success-bg); color: var(--success-fg);
  border: 1px solid var(--success-border);
}
.confirm-badge.reject {
  background: #FFF7ED; color: #C2410C;
  border: 1px solid #FED7AA;
}
.confirm-title {
  margin: 0;
  font: var(--text-h2); font-family: var(--font-display);
  color: var(--fg-default); line-height: 1.2;
}
.confirm-text {
  margin: 12px 0 0;
  font: var(--text-body); color: var(--fg-muted);
  line-height: 1.6; max-width: 400px;
  text-wrap: pretty;
}
.confirm-ship {
  margin: 12px 0 0;
  font: var(--text-body-bold); color: var(--fg-default);
}
.confirm-ship-tbd { color: var(--warning-fg); }
.confirm-meta {
  width: 100%;
  margin: 28px 0 4px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--neutral-0);
  padding: 6px 18px;
  text-align: left;
}
.confirm-meta-row {
  display: flex; align-items: baseline; gap: 16px;
  padding: 11px 0;
  border-bottom: 1px solid var(--border-subtle);
}
.confirm-meta-row:last-child { border-bottom: 0; }
.confirm-meta-label {
  width: 80px; flex-shrink: 0;
  font: var(--text-body-sm-med); color: var(--fg-muted);
}
.confirm-meta-val {
  flex: 1;
  font: var(--text-body-sm); color: var(--fg-default);
}
.confirm-meta-val .mono-id { font-family: var(--font-mono); }
.confirm-cta {
  margin-top: 28px;
  width: 100%;
  border-radius: 12px;
  justify-content: center;
}
.confirm-bottom {
  flex-shrink: 0;
  display: flex; justify-content: center;
  padding: 0 24px 28px;
}
.confirm-reset {
  font: var(--text-body-sm-med);
  color: var(--fg-subtle);
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  transition: color 120ms var(--ease-out), background 120ms var(--ease-out);
}
.confirm-reset:hover { color: var(--fg-default); background: var(--neutral-100); }
.confirm-reset:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* ─── Annotate tool ──────────────────────────────────────────────── */
.app-annotating .canvas-area, .app-annotating .canvas-area canvas { cursor: crosshair; }
.app-capturing .vpt-wrap, .app-capturing .right-panel, .app-capturing .canvas-caption, .app-capturing .canvas-actions { visibility: hidden; }
.ann-cursor-tip {
  position: fixed; z-index: 80; pointer-events: none;
  transform: translate(16px, 18px);
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; background: #262626; border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
  font: 500 12px/1.2 "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: #fff; white-space: nowrap;
}
.ann-cursor-tip .tip-key { color: rgb(163,163,163); font-weight: 500; }
.ann-marquee {
  position: fixed; z-index: 75; pointer-events: none;
  background: rgba(255,255,255,0.1);
  border: 4px solid #FFFFFF; box-sizing: border-box;
}
.ann-overlay {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(0,0,0,0.4);
  padding: 24px; display: flex; box-sizing: border-box;
}
.ann-modal {
  flex: 1 1 auto; min-width: 0;
  background: #FFFFFF; border-radius: 16px; overflow: hidden;
  padding: 24px; box-sizing: border-box;
  display: flex; flex-direction: column; gap: 16px;
}
.ann-modal-head { display: flex; justify-content: space-between; align-items: flex-start; flex-shrink: 0; }
.ann-modal-title {
  margin: 0; font: 400 24px/32px "Poppins", -apple-system, sans-serif;
  letter-spacing: -0.6px; color: #000;
}
.ann-modal-sub { margin: 2px 0 0; font: 400 14px/20px "Inter", -apple-system, sans-serif; color: rgb(82,82,82); }
.ann-modal-x {
  width: 24px; height: 24px; flex-shrink: 0; padding: 0;
  background: none; border: 0; color: #262626; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.ann-stage {
  flex: 1 1 auto; min-height: 0;
  background: rgb(250,250,250);
  display: flex; align-items: center; justify-content: center; gap: 8px;
  overflow: hidden;
}
.ann-stage img { width: 100%; height: 100%; object-fit: contain; display: block; }
.ann-modal-foot { display: flex; justify-content: flex-start; align-items: center; gap: 16px; height: 48px; flex-shrink: 0; }
.ann-foot-left { display: flex; align-items: center; gap: 16px; }
.ann-btn {
  height: 48px; padding: 12px 24px; box-sizing: border-box;
  border-radius: 12px; border: 1px solid rgb(212,212,212); background: #fff;
  font: 500 16px/24px "Inter", -apple-system, sans-serif; color: rgb(38,38,38);
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  transition: background var(--dur-fast) var(--ease-out);
}
.ann-btn:hover { background: var(--neutral-50); }
.ann-btn-primary { background: rgb(38,38,38); border-color: rgb(38,38,38); color: #fff; }
.ann-btn-primary:hover { background: #2b2b2b; }
.ann-confirm { z-index: 95; }
.vpt-btn:focus, .vpt-btn:focus-visible { outline: none; box-shadow: none; }
.ann-btn-destructive { background: #DC2626; border-color: #DC2626; color: #fff; }
.ann-btn-destructive:hover { background: #C51F1F; border-color: #C51F1F; }
.ann-btn-destructive:active { background: #B01B1B; }

/* ─── Annotate editor ────────────────────────────────────────────── */
.ann-stage { position: relative; }
.ann-canvas { position: relative; flex-shrink: 0; overflow: hidden; touch-action: none; }
.ann-canvas img { width: 100%; height: 100%; display: block; user-select: none; }
.ann-canvas.tool-pencil { cursor: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2226%22%20height%3D%2226%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cg%20transform%3D%22translate(1%2C1)%22%3E%3Cpath%20d%3D%22M15.8%203.1%203.8%2015.1a2%202%200%200%200-.5.9L2.3%2019.1l3.1-.9c.35-.1.67-.3.93-.55L18.9%205.6a2.65%202.65%200%200%200-3.1-2.5z%22%20fill%3D%22%23fff%22%20stroke%3D%22%23171717%22%20stroke-width%3D%221.4%22%20stroke-linejoin%3D%22round%22%2F%3E%3Cpath%20d%3D%22M14.5%204.5l3%203%22%20stroke%3D%22%23171717%22%20stroke-width%3D%221.4%22%20stroke-linecap%3D%22round%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E") 2 23, crosshair; }
.ann-canvas.tool-text { cursor: crosshair; }
.ann-strokes { position: absolute; left: 0; top: 0; pointer-events: none; }
.ann-text {
  position: absolute; margin: 0;
  font: 700 24px/30px "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  max-width: 400px; width: max-content;
  white-space: pre-wrap; overflow-wrap: break-word;
  pointer-events: none; outline: none;
}
.ann-text.draggable { pointer-events: auto; cursor: move; }
.ann-text-edit { pointer-events: auto; min-width: 2px; cursor: text; }
.ann-toolbar {
  position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 72px; border-radius: 24px;
  background: rgba(255,255,255,0.8);
  backdrop-filter: blur(20px) saturate(1.6);
  -webkit-backdrop-filter: blur(20px) saturate(1.6);
  box-shadow: inset 0 0 0 1px rgb(229,229,229), var(--shadow-md);
  display: flex; flex-direction: column; align-items: stretch;
  z-index: 3;
}
.ann-tool-group { display: flex; flex-direction: column; gap: 8px; padding: 16px; }
.ann-tool-divider { height: 1px; background: rgb(229,229,229); }
.ann-tool {
  position: relative;
  width: 40px; height: 40px; padding: 0;
  display: grid; place-items: center;
  border: 0; border-radius: 8px; background: transparent;
  color: var(--fg-muted); cursor: pointer;
  transition: background 120ms var(--ease-out), color 120ms var(--ease-out);
}
.ann-tool:hover { background: rgb(245,245,245); }
.ann-tool.active { background: rgb(43,43,43); color: rgb(250,250,250); }
.ann-tool:focus, .ann-tool:focus-visible { outline: none; }
.ann-dot { width: 18px; height: 18px; border-radius: 50%; box-shadow: 0 0 0 2px #fff; }
.ann-tool.active .ann-dot { box-shadow: 0 0 0 2px #fff; }
.ann-tip {
  position: absolute; left: calc(100% + 10px); top: 50%; transform: translateY(-50%) translateX(-2px);
  padding: 6px 10px; background: #262626; color: #fff; border-radius: 8px;
  font: 500 12px/1.2 "Inter", -apple-system, sans-serif; white-space: nowrap;
  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
  opacity: 0; pointer-events: none;
  transition: opacity 120ms var(--ease-out), transform 120ms var(--ease-out);
}
.ann-tool:hover .ann-tip { opacity: 1; transform: translateY(-50%) translateX(0); }
.ann-head-actions { display: flex; align-items: center; gap: 16px; flex-shrink: 0; }
.ann-modal-x:disabled { opacity: 0.35; cursor: default; }
.ann-text.selected { outline: 1.5px solid rgba(38,38,38,0.7); outline-offset: 4px; }
.ann-text-edit { outline: 1.5px dashed rgba(38,38,38,0.45); outline-offset: 4px; }
.ann-toolbar { left: 14px; }
.ann-hit { pointer-events: stroke; cursor: move; }
.ann-selbox { fill: none; stroke: rgba(38,38,38,0.7); stroke-width: 1.5; stroke-dasharray: 5 4; pointer-events: none; }
.ann-btn:disabled { opacity: 0.4; cursor: default; }
.ann-btn-primary:disabled:hover { background: rgb(38,38,38); }
.lb-zoom .lb-edit {
  width: auto; padding: 0 14px; height: 36px;
  display: inline-flex; align-items: center; gap: 6px;
  font: 500 13px/1 "Inter", -apple-system, sans-serif;
}
.attach-block { margin-top: 16px; }
.attach-label { font: var(--text-body-sm-med); color: var(--fg-default); margin-bottom: 8px; }
.attach-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.attach-item {
  display: flex; align-items: center; gap: 12px;
  padding: 8px; padding-right: 8px;
  border: 1px solid var(--border-default); border-radius: var(--radius);
  background: var(--neutral-0);
}
.attach-thumb {
  width: 40px; height: 40px; flex-shrink: 0;
  border-radius: 6px; object-fit: cover; display: block;
  border: 1px solid var(--border-subtle);
}
.attach-name { flex: 1; min-width: 0; font: var(--text-mono); color: var(--fg-alt); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attach-x {
  width: 28px; height: 28px; flex-shrink: 0;
  display: grid; place-items: center;
  border: 0; border-radius: var(--radius-sm); background: transparent;
  color: var(--fg-muted); cursor: pointer;
  transition: background 120ms var(--ease-out), color 120ms var(--ease-out);
}
.attach-x:hover { background: var(--neutral-100); color: var(--fg-default); }
.attach-block-top { margin-top: 0; margin-bottom: 18px; }
.attach-empty {
  border: 1px dashed var(--border-strong); border-radius: var(--radius);
  background: var(--neutral-50);
  padding: 14px 16px 16px;
}
.attach-empty-text { margin: 0; font: var(--text-body-sm); color: var(--fg-muted); }
.attach-empty-btn { width: auto; margin-top: 12px; }
.attach-empty-title { margin: 0 0 4px; font: var(--text-body-sm-med); color: var(--fg-default); }
.attach-empty-inline { margin-top: 8px; }
.confirm-meta-val .attach-list { width: 100%; }
.confirm-meta-val .attach-item { background: var(--neutral-0); }
.confirm-meta-row:has(.attach-list) { align-items: flex-start; }
.confirm-meta-row:has(.attach-list) .confirm-meta-label { padding-top: 0; }
.lb-confirm { z-index: 80; }
.lb-confirm .attach-item { cursor: default; }
.smile-scroll-auto { max-height: none; overflow: visible; }
/* Grid area must be able to shrink, otherwise the image's max-height:100%
   resolves against its own intrinsic height and overflows the stage. */
.lb-stage { grid-template: minmax(0, 1fr) / minmax(0, 1fr); }
.lb-stage img { margin: auto; }
.attach-link {
  margin-top: 10px; padding: 0;
  border: 0; background: none; cursor: pointer;
  font: var(--text-body-sm-med); color: #262626;
  text-decoration: underline; text-underline-offset: 3px;
}
.attach-link:hover { color: #000; }

.panel-mobile-actions, .header-menu-btn, .ann-touch-hint { display: none; }
.canvas-area canvas { touch-action: none; }
/* Dragging a marquee must not start a text selection or a browser gesture. */
.app-annotating { -webkit-user-select: none; user-select: none; }
.app-annotating .canvas-area { touch-action: none; -webkit-touch-callout: none; }

/* ─── Mobile (<960px) ─────────────────────────────────────────────── */
@media (max-width: 959.98px) {
  /* Header keeps brand + menu button only */
  .header-icon-btn, .header .settings-menu-wrap { display: none; }
  .header-menu-btn {
    display: grid; place-items: center;
    width: 40px; height: 40px; border-radius: 8px; flex-shrink: 0;
  }
  /* Patient name / case # step down for the narrow canvas */
  .canvas-caption > span:first-child { font: 600 20px/28px var(--font-display); color: var(--neutral-600); }
  .canvas-caption > span:last-child { font: 400 14px/20px var(--font-sans); color: var(--neutral-500); }
  /* Zoom/fullscreen controls float relative to the desktop panel's width;
     with the floating panel gone on mobile, they go with it. */
  .canvas-actions { display: none; }

  /* Right panel becomes a full-bleed menu below the header */
  .right-panel {
    top: 56px; right: 0; bottom: 0; left: 0;
    width: auto; border-radius: 0;
    background: var(--neutral-0);
    backdrop-filter: none; -webkit-backdrop-filter: none;
    box-shadow: none;
    transform: translateY(-100%); opacity: 0; pointer-events: none;
    transition: transform 260ms var(--ease-out), opacity 200ms var(--ease-out);
  }
  .app-menu-open .right-panel { transform: translateY(0); opacity: 1; pointer-events: auto; }
  /* Desktop intro / zen transforms must not fight the menu slide */
  .app-intro-start .right-panel, .app-zen .right-panel { transform: translateY(-100%); opacity: 0; }
  .right-panel-inner { width: auto; }
  .panel-mobile-actions {
    display: flex; justify-content: flex-end; align-items: center; gap: 16px;
    padding: 16px 24px;
  }
  .panel-mobile-actions .icon-btn:active { background: var(--neutral-100); }
  /* The panel clips overflow, so the dropdown anchors inside its padding box */
  .panel-settings-wrap { position: relative; }
  .panel-settings-wrap .settings-menu { top: 32px; right: 0; }
  .review-section-fixed { left: 16px; right: 16px; bottom: 16px; }
  /* Mobile menu slides down in 260ms (see .right-panel transition above) —
     pop the review section in right after that instead of desktop's 630ms
     panel-slide delay. Matches the desktop rule's ":not(.app-intro-start)"
     selector so its specificity wins this override rather than losing to
     the desktop animation-delay on narrow viewports. */
  .app:not(.app-intro-start) .review-section-fixed { animation-delay: 260ms; }

  /* Bottom toolbar: annotate + view presets, tighter padding + radius */
  .vpt-wrap { left: 50%; }
  .viewport-toolbar-v2 { border-radius: 16px; }
  .vpt-group { padding: 8px; }
  .vpt-mobile-hide { display: none; }
  /* Once review is locked the annotate tool goes too — drop the now-empty
     group and its divider rather than leaving a stub. */
  .viewport-toolbar-v2.locked .vpt-group:first-child,
  .viewport-toolbar-v2.locked .vpt-divider { display: none; }
  .vpt-tip, .ann-cursor-tip { display: none; }
  /* Touch replacement for the cursor tooltip */
  .ann-touch-hint {
    display: block;
    position: fixed; left: 50%; transform: translateX(-50%);
    bottom: 92px; z-index: 70; pointer-events: none;
    padding: 8px 14px; border-radius: var(--radius-full);
    background: rgba(255,255,255,0.9);
    box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08);
    -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px);
    font: var(--text-body-sm-med); color: var(--fg-default); white-space: nowrap;
  }
  /* Splash scales down for the narrow screen */
  .load-overlay { gap: 16px; padding: 0 24px; }
  .load-overlay-text { font: var(--text-body); text-align: center; text-wrap: pretty; }
  .load-bar-track { width: 200px; height: 5px; }

  /* Confirmation page: one scrolling column, nothing pinned, no h-scroll */
  .confirm-screen { display: block; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; }
  .confirm-top { position: sticky; top: 0; z-index: 1; padding: 0 16px; }
  .confirm-main { display: block; overflow: visible; padding: 24px 16px; }
  .confirm-card { margin: 0 auto; }
  .confirm-bottom { padding: 0 16px 28px; }
  .confirm-meta-val { min-width: 0; overflow-wrap: anywhere; }
  .confirm-meta-val .attach-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* ─── Mobile menu: top-level 4-row list ──────────────────────────── */
  .mobile-menu-list { padding: 0; border-top: 1px solid rgba(0,0,0,0.08); }
  .mobile-menu-row {
    display: flex; align-items: center; justify-content: space-between;
    width: 100%; padding: 24px 20px;
    border-bottom: 1px solid rgba(0,0,0,0.08);
    font: var(--text-body-sm-med); color: var(--fg-default);
  }
  .mobile-menu-row svg { color: var(--fg-muted); flex-shrink: 0; }

  /* ─── Mobile menu: Design Photos / Annotations drill-down ────────── */
  .mobile-subpage-head {
    display: flex; align-items: center; gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid rgba(0,0,0,0.08);
  }
  .mobile-subpage-title { font: var(--text-body-med); color: var(--fg-default); }
  .mobile-subpage-body { padding: 20px; }

  /* ─── Mobile canvas overlay: Visibility Controls / Color Options ──
     Same "hide header, drop caption up" mechanics as zen mode, plus the
     bottom toolbar hides and a floating panel takes its visual slot. ── */
  .app-mobile-tool .header { transform: translateY(-100%); opacity: 0; pointer-events: none; }
  .app-mobile-tool .vpt-wrap { display: none; }
  .app-mobile-tool .canvas-caption { top: 14px; }
  .mobile-tool-wrap {
    position: absolute;
    bottom: 14px; left: 50%; transform: translateX(-50%);
    display: flex; flex-direction: column-reverse; align-items: flex-end; gap: 12px;
    width: calc(100% - 32px); max-width: 400px;
    z-index: 4;
  }
  .mobile-tool-panel {
    width: 100%; border-radius: 24px; padding: 16px;
    background: rgba(255,255,255,0.62);
    backdrop-filter: blur(28px) saturate(1.6);
    -webkit-backdrop-filter: blur(28px) saturate(1.6);
    box-shadow: var(--shadow-md);
  }
  .mobile-tool-panel.dark { background: rgba(20, 28, 40, 0.6); }
  .mobile-tool-done {
    padding: 10px 20px; border-radius: var(--radius-full);
    background: var(--neutral-0); color: var(--fg-default);
    font: var(--text-body-sm-med);
    box-shadow: var(--shadow-md);
  }
  .mobile-color-list { display: flex; flex-direction: column; gap: 4px; }
  .mobile-color-row {
    display: flex; align-items: center; gap: 12px;
    width: 100%; padding: 8px; border-radius: var(--radius);
    transition: background 120ms var(--ease-out);
  }
  .mobile-color-row:hover { background: rgba(0,0,0,0.04); }
  .mobile-color-swatch { position: relative; width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0; }
  .mobile-color-swatch img { width: 100%; height: 100%; display: block; border-radius: 50%; }
  .mobile-color-row.active .mobile-color-swatch::after {
    content: ""; position: absolute; inset: -4px; border-radius: 50%;
    border: 2px solid #262626;
  }
  .mobile-color-label { font: var(--text-body-sm-med); color: var(--fg-default); }
  .mobile-tool-wrap.dark .mobile-color-row:hover { background: rgba(255,255,255,0.08); }
  .mobile-tool-wrap.dark .mobile-color-label { color: var(--neutral-0); }
  .mobile-tool-wrap.dark .mobile-color-row.active .mobile-color-swatch::after { border-color: var(--neutral-0); }
}

/* Phone widths only — stack meta labels above their values */
@media (max-width: 560px) {
  .confirm-meta-row { flex-wrap: wrap; gap: 2px 12px; }
  .confirm-meta-label { width: auto; flex: 1 0 100%; }
  .confirm-meta-val { flex: 1 1 100%; }
}

/* ─── Annotate editor on mobile: full-bleed, toolbar along the bottom ── */
@media (max-width: 959.98px) {
  .ann-overlay { padding: 0; }
  .ann-modal { border-radius: 0; padding: 16px; gap: 12px; }
  .ann-modal-title { font: 400 20px/26px "Poppins", -apple-system, sans-serif; }
  .ann-modal-sub { display: none; }
  /* Vertical rail would eat the narrow canvas — lay it out horizontally
     under the image instead, where it can't clip. */
  .ann-toolbar {
    left: 50%; right: auto; top: auto; bottom: 12px;
    transform: translateX(-50%);
    width: max-content;
    flex-direction: row; align-items: center;
    border-radius: 16px;
  }
  .ann-tool-group { flex-direction: row; padding: 8px; }
  .ann-tool-divider { width: 1px; height: auto; align-self: stretch; }
  .ann-tip { display: none; }
  /* Actions stack full-width instead of overflowing off-screen */
  .ann-modal-foot { height: auto; flex-direction: column; gap: 8px; }
  .ann-btn { height: 44px; padding: 10px 16px; width: 100%; justify-content: center; }
  /* The floating toolbar sits at the bottom edge of the stage — let it spill
     past that edge instead of getting clipped. The screenshot/canvas itself
     stays clipped by .ann-canvas's own overflow, so this is toolbar-only. */
  .ann-stage { padding-bottom: 8px; overflow: visible; }

  /* All modal footers (review, discard-confirm, etc.) stack full-width, primary action on top */
  .modal-foot { flex-direction: column; }
  .modal-foot .btn { width: 100%; }
}
