/* Unified panel/window component (ui/panels/PanelWindow.js).
   Docked panels stack inside #dock in the side panel; floating panels are
   fixed windows over the canvas. Built on the design tokens from
   themes/default/theme.css. */

#dock {
  position: relative; /* absolute reference for drag-to-reorder */
}

.cv-panel {
  box-sizing: border-box;
  /* Overall UI font scale (Settings ▸ Overall font scale). Window body text
     inherits this base; the explicit-px chrome below multiplies by the same
     var so title bars/headlines/labels scale together. Default 1 = 16px, i.e.
     no visual change until the user moves the slider. */
  font-size: calc(1rem * var(--cv-font-scale, 1));
}

/* Panel buttons don't inherit font-size (form-control UA reset) and are set at
   assorted px sizes across windows — pin them to one scalable size so the font
   scale reaches the Features/Visual/… button texts uniformly. */
.cv-panel-body button {
  font-size: var(--fs-md);
}

/* Feature panels are hidden until a structure loads; the attribute must win
   over .cv-floating's display:flex. */
.cv-panel[hidden] {
  display: none !important;
}

/* Keyboard-shortcut focus confirmation (ui/KeyboardShortcuts.js): a brief
   orange outline so a panel — or a plain button (camera alignment, Add
   Structure/Atoms) that wouldn't otherwise show any reaction — visibly
   confirms a keypress landed. Reuses the app's one existing "draw attention"
   orange (the collision-warning banner color). Not scoped to .cv-panel: any
   element can receive the class. */
@keyframes cv-shortcut-flash {
  from { box-shadow: 0 0 0 2px var(--danger); }
  to { box-shadow: 0 0 0 2px rgb(var(--danger-rgb) / 0); }
}

.cv-shortcut-flash {
  animation: cv-shortcut-flash 0.5s ease-out;
}

/* The .cv-panel container itself is chrome-less: collapsed, a panel is just
   its title bar; expanded, the body hangs below the bar as the window
   surface. */

/* ---- docked: title bars stack with a small gap ---- */
.cv-panel.cv-docked {
  margin: 0 0 var(--sp-3) 0;
}

/* ---- side-docked: the window is a TAB in the wide side dock ----
   Its element lives inside #splitPaneBody (sideDock.css). The tab strip is
   the chrome: the title bar is hidden, the body is always shown (per-window
   collapse doesn't apply here — the whole dock collapses instead), and only
   the front window is visible, filling the pane. */
.cv-panel.cv-side-docked {
  display: none;
  margin: 0;
  min-height: 0;
  flex: 1 1 auto;
  flex-direction: column;
}

.cv-panel.cv-side-docked.cv-front {
  display: flex;
}

.cv-panel.cv-side-docked > .cv-panel-titlebar {
  display: none;
}

/* The pane provides the surface; strip the body's own window box. The
   backdrop-filter:none is load-bearing: a backdrop-filter creates a
   containing block for fixed-position descendants, which would trap the
   ⛶-expanded .split-item inside the body. */
.cv-panel.cv-side-docked > .cv-panel-body,
.cv-panel.cv-side-docked.cv-collapsed > .cv-panel-body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  gap: var(--sp-3-5);
  padding: var(--sp-3-5);
  overflow-y: auto;
  border: none;
  border-radius: 0;
  background: transparent;
  backdrop-filter: none;
}

/* A side-docked panel is a single scroll surface. An open collapsible section
   inside it — e.g. the individual-atom list after a 3x3x3 supercell — otherwise
   keeps its own capped max-height + overflow-y:auto (styles.css / responsive.css)
   and scrolls INSIDE the panel that already scrolls: two nested scrollbars in
   the sheet. Docked, it must flow into the one pane/body scroller instead. */
.cv-panel.cv-side-docked .collapsible-content.open {
  max-height: none;
  overflow: visible;
}

/* Host of a ⛶-expanded (fullscreen) .split-item in ANY window state: lift
   the body's backdrop-filter (fixed-position containing block, see above)
   and raise a floating host above the fullscreen overlay (z-index 1350) —
   !important because raise() sets an inline z-index. */
.cv-panel.cv-has-expanded-item > .cv-panel-body {
  backdrop-filter: none;
}

.cv-panel.cv-floating.cv-has-expanded-item {
  z-index: 1400 !important;
}

/* ---- floating ---- */
.cv-panel.cv-floating {
  position: fixed;
  z-index: var(--z-dock);
  min-width: 220px;
  max-width: min(600px, calc(100vw - 16px));
  max-height: calc(100dvh - 16px);
  display: flex;
  flex-direction: column;
  color: var(--panel-fg);
}

.cv-panel.cv-floating > .cv-panel-body {
  overflow-y: auto;
  min-height: 0;
}

.cv-panel.cv-floating > .cv-panel-titlebar,
.cv-panel.cv-floating > .cv-panel-body {
  box-shadow: var(--shadow-glow);
}

/* ---- title bar ---- */
.cv-panel-titlebar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-3);
  cursor: grab;
  user-select: none;
  touch-action: none;
  border-radius: var(--radius);
  background: var(--bg-color);
  border: 1px solid var(--line-1);
  backdrop-filter: blur(10px);
  color: var(--panel-fg);
}

/* Expanded: the bar sits flush on the body surface below it. */
.cv-panel:not(.cv-collapsed) > .cv-panel-titlebar {
  border-radius: var(--radius) var(--radius) 0 0;
}

/* ---- hidden title bar: the ― button shrinks the bar to a short, centered
   accent strip (a "handle"); double-clicking, a long press, or (on touch) a
   single tap - see PanelWindow.js's _onTitlebarPointerDown - restores the
   bar. ---- */
.cv-panel.cv-bar-collapsed > .cv-panel-titlebar {
  height: 8px;
  min-height: 8px;
  width: 100px;
  max-width: 50%;
  margin: 0 auto 3px auto;
  padding: 0;
  border: none;
  border-radius: 2px;
  background: var(--highlight-color); /* green in the standard mode */
  backdrop-filter: none;
  overflow: hidden;
  opacity: 0.6;
  transition: opacity 0.15s ease;
}

/* Desktop/mouse only (hover-capable + fine pointer): the handle stays
   invisible (but still hittable - opacity, not display/visibility) until the
   pointer is actually over it, so it doesn't clutter the view. Touch devices
   have no hover concept, so they keep the default fixed 0.6 opacity above. */
/* The (hover: hover) and (pointer: fine) override for this handle now
   lives in styles/responsive.css, per Wave 4's single-file @media rule. */

.cv-panel.cv-bar-collapsed > .cv-panel-titlebar > * {
  display: none;
}

/* A press being held on the handle (PanelWindow.js's long-press-to-restore):
   light the strip up so the gesture is visibly registered before it fires.
   Carries .cv-bar-collapsed too, purely to outspecify the desktop hover rule
   in responsive.css (opacity: 0), which loads after this sheet. */
.cv-panel.cv-bar-collapsed.cv-bar-longpress > .cv-panel-titlebar {
  opacity: 1;
  filter: brightness(1.25);
}

/* With only the handle above it, the body is a free-standing box again:
   round all corners and restore its top edge. */
.cv-panel.cv-bar-collapsed > .cv-panel-body {
  border-radius: var(--radius-md);
  border-top: 1px solid var(--line-1);
}

/* "Always show small drag handles" (Settings): reverts the handle to the
   EARLY short-centered strip (the "Improve look of collapsed title bars"
   revision) — thin (2px), 64px, solid accent green, always visible (the
   desktop hover reveal is opted out in responsive.css). Everything else —
   the centered placement, 3px gap, and the free-standing body above — is
   unchanged from the current handle. :not(.cv-compact) because these
   higher-specificity rules would otherwise beat the compact round-icon
   rules below, which normally win their tie by source order alone
   (.cv-bar-collapsed stays set while a panel is compact). */
body.cv-small-drag-handles .cv-panel.cv-bar-collapsed:not(.cv-compact) > .cv-panel-titlebar {
  height: 2px;
  min-height: 0;
  width: 64px;
  opacity: 1;
}

.cv-panel-titlebar:active,
.cv-panel.cv-dragging .cv-panel-titlebar,
.cv-panel.cv-drag-moving .cv-panel-titlebar {
  cursor: grabbing;
}

.cv-panel-grip {
  opacity: 0.45;
  font-size: var(--fs-md);
  line-height: 1;
  /* The grip is the drag handle even where the bar around it gives the
     vertical axis back to the dock scroller (responsive.css, coarse rung). */
  touch-action: none;
}

.cv-panel-fold,
.cv-panel-menu-btn,
.cv-panel-barhide,
.cv-panel-close {
  background: none;
  border: none;
  padding: 2px var(--sp-1);
  color: var(--panel-fg);
  font-size: var(--fs-base);
  line-height: 1;
  cursor: pointer;
  border-radius: var(--radius-sm);
}

.cv-panel-fold:hover,
.cv-panel-menu-btn:hover,
.cv-panel-barhide:hover,
.cv-panel-close:hover {
  background: var(--hover-color);
}

.cv-panel-fold:disabled {
  opacity: 0.4;
  cursor: default;
}

.cv-panel-title {
  flex: 1;
  font-size: var(--fs-md);
  font-weight: 700;
  line-height: 1.3;
  color: var(--fg-85);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cv-panel-menu-btn,
.cv-panel-close {
  font-size: var(--fs-lg);
}

/* ---- ≡ window menu (dropdown, portaled to <body> so #ui's scroll container
   can't clip it — see PanelWindow._openMenu) ---- */
.cv-panel-menu {
  position: fixed;
  z-index: var(--z-context-menu); /* above floating windows and the fullscreen-item overlay */
  min-width: 140px;
  padding: var(--sp-1);
  display: flex;
  flex-direction: column;
  background: var(--popup-bg);
  border: 1px solid var(--panel-border, var(--wash-4));
  border-radius: var(--radius);
  box-shadow: 0 4px 14px var(--overlay);
}

/* Greyish section header ("Position", ...). */
.cv-panel-menu-header {
  padding: var(--sp-1) var(--sp-3) 2px;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted-fg); /* --muted-fg is always defined; the #9aa0a6 fallback was dead code */
}

.cv-panel-menu-item {
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  text-align: left;
  padding: var(--sp-1) var(--sp-3) var(--sp-1) 22px;
  position: relative;
  font-size: var(--fs-md);
  color: var(--panel-fg);
  cursor: pointer;
}

.cv-panel-menu-item:hover {
  background: var(--hover-color);
}

/* Thin separator before an untitled section (e.g. the Close item). */
.cv-panel-menu-sep {
  height: 1px;
  margin: var(--sp-1) var(--sp-2);
  background: var(--panel-border, var(--wash-4));
}

/* Checkmark on the item matching the window's current state. */
.cv-panel-menu-item.checked::before {
  content: "✓";
  position: absolute;
  left: 7px;
  color: var(--accent-fg, var(--info));
}

/* The generic .info-button rule sizes it for a standalone corner badge
   (18px); inside a titlebar it needs to sit flush with the other ~13px
   icon buttons instead of towering over them. */
.cv-panel-titlebar .cv-panel-info {
  width: calc(13px * var(--cv-font-scale, 1));
  height: calc(13px * var(--cv-font-scale, 1));
  font-size: calc(8px * var(--cv-font-scale, 1));
  flex-shrink: 0;
  color: var(--fg-2);
  border-color: var(--popup-border);
}

.cv-panel-titlebar .cv-panel-info:hover {
  box-shadow: none;
  background: var(--hover-color);
}

/* ---- body / collapse ---- */
/* The body is the window surface: it carries the box the old .control-group /
   floating popups had, minus the top edge where the title bar sits. */
.cv-panel-body {
  padding: var(--sp-3-5) var(--sp-3);
  color: var(--fg-1);
  border: 1px solid var(--line-1);
  border-top: none;
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  backdrop-filter: blur(10px);
}

.cv-panel.cv-docked > .cv-panel-body {
  background: var(--group-bg);
}

.cv-panel.cv-floating > .cv-panel-body {
  background: var(--popup-bg);
}

.cv-panel.cv-collapsed > .cv-panel-body {
  display: none;
}

/* ---- states ---- */
.cv-panel.cv-unavailable > .cv-panel-titlebar {
  opacity: 0.45;
}

.cv-dock-placeholder {
  box-sizing: border-box;
  margin: 0 0 var(--sp-3) 0;
  border: 1px dashed var(--accent-color);
  border-radius: var(--radius);
  background: var(--hover-color);
}

.cv-panel.cv-dragging {
  z-index: 10;
  width: 100%;
  opacity: 0.95;
  box-shadow: 0 4px 14px var(--overlay);
}

/* .backend-control-group is authored to fit #ui, the ~380px left sidebar
   (backendPanel.css sizes it to 360px so it clears the sidebar's own
   padding). Adopted into a panel body it can be far wider than that — right
   dock, a floating window, any future adopted panel — so the cap must drop
   for every such element, not just the one the JS appends directly: the
   Atomistic window nests a SECOND .backend-control-group (#BackendCalcPanel,
   the Relax/MD action card) inside the first, and a direct-child selector
   alone leaves that inner one stranded at 360px in an otherwise-empty pane.
   Descendant selector so any depth of nesting is covered uniformly. */
.cv-panel-body .backend-control-group {
  max-width: none;
}

/* The outer wrapper only: the panel body already provides the grey box, so
   strip its own to avoid nesting one box inside another. A nested group
   (e.g. #BackendCalcPanel) is real content chrome and keeps its box. */
.cv-panel-body > .backend-control-group {
  margin: 0;
  padding: 0;
  background: none;
  border: none;
  backdrop-filter: none;
}

/* ---- compact round-icon mode ----
   Ordered AFTER the bar-hide-strip rules above so it wins the equal-specificity
   tie when both .cv-bar-collapsed and .cv-compact are on the same element (they
   co-occur: barCollapsed is not cleared when entering compact mode). */
.cv-panel.cv-compact {
  /* .cv-floating's min-width:220px would otherwise leave the round icon flush-
     left inside a much wider invisible box instead of at its anchored edge. */
  min-width: 0;
  width: max-content;
}

.cv-panel.cv-compact > .cv-panel-titlebar {
  width: 54px;
  height: 54px;
  min-height: 54px;
  max-width: none;
  margin: 0;
  padding: 0;
  justify-content: center;
  border: 1px solid var(--wash-4);
  border-radius: 50%;
  background: var(--chrome-1);
  backdrop-filter: none;
  overflow: hidden;
  box-shadow: 0 2px 10px rgb(var(--shadow-rgb) / 0.4);
}

/* .cv-bar-collapsed is never cleared when a panel enters compact mode (the
   two classes co-occur), and its hover:hover-gated opacity:0 rule above is
   the only rule that touches opacity for this element — .cv-compact's own
   rule above doesn't — so that opacity leaked onto the round icon at any
   width narrow enough to go compact, making it hover-only too. It must
   always be visible; only the full bar's hidden-strip handle is meant to be
   hover-only. Scoped to the exact .cv-compact.cv-bar-collapsed combination
   (not a blanket .cv-compact rule) so it doesn't also override the
   unrelated .cv-unavailable dimming above, which shares the same
   specificity and legitimately wants reduced opacity on a compact panel. */
.cv-panel.cv-compact.cv-bar-collapsed > .cv-panel-titlebar {
  opacity: 1;
}

.cv-panel.cv-compact > .cv-panel-titlebar > *:not(.cv-panel-compact-btn) {
  display: none;
}

.cv-panel-compact-btn { display: none; }

.cv-panel.cv-compact .cv-panel-compact-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 0;
  background: none;
  border: 2px solid var(--line-grey);
  border-radius: 50%;
  cursor: pointer;
}

/* Hover matches the scene control buttons: an accent ring + glow, theme-driven,
   in place of the old flat background wash. */
.cv-panel.cv-compact .cv-panel-compact-btn:hover {
  border-color: var(--accent-fg);
  box-shadow: 0 0 0 1px var(--accent-fg), 0 0 6px 1px rgb(var(--btn-glow-rgb) / 0.35);
}

.cv-panel-compact-btn img {
  width: 26px;
  height: 26px;
  pointer-events: none;
  /* White-filled SVGs on a --chrome-1 chip: invisible once that chip is a 5%
     wash on a light palette, which is what --icon-filter-bright flips. */
  filter: var(--icon-filter-bright);
}

/* Expanded-while-compact: unfold to the icon's LEFT, not below it. The row is
   reversed so the title bar (first in the DOM) lands on the right. align-items:
   flex-start (NOT center) keeps the icon pinned exactly where it renders
   collapsed; only the body recenters against it (via align-self). Centering the
   row instead makes the icon jitter each time the toolbar toggles. */
.cv-panel.cv-compact:not(.cv-collapsed) {
  flex-direction: row-reverse;
  align-items: flex-start;
}

.cv-panel.cv-compact:not(.cv-collapsed) > .cv-panel-body {
  align-self: center;
  margin-right: var(--sp-3-5);
  border-radius: var(--radius-md);
  border-top: 1px solid var(--line-1);
  /* The panel is width:max-content, so on a phone an unfolded toolbar runs off
     the left edge (and a tall one off the bottom). Budget: the 54px icon it
     unfolds beside, this margin, the anchor's 20px right offset, and a left
     margin to match. min-width:0 because a flex item's auto minimum is its
     min-content width, which outranks max-width and would pin it wide. */
  box-sizing: border-box;
  min-width: 0;
  max-width: calc(100vw - 54px - var(--sp-3-5) - 40px);
  max-height: calc(100dvh - 32px);
}

/* ---- mobile ----
   The max-width:1024px override for .cv-panel.cv-floating now lives in
   styles/responsive.css's compact rung, per Wave 4's single-file @media
   rule. */
