/* Modules Menu Panel — P6.d (2026-05-21)
 *
 * Floating side panel listing every user-facing module with a
 * visibility checkbox.  Cousin of the Theme Editor — same
 * design language (bezel surface, mono labels).
 */

.modules-menu-host {
  position: fixed;
  top: 80px;
  right: 16px;
  z-index: 200;
  width: 380px;
  max-width: 90vw;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
}

.modules-menu-host[hidden] {
  display: none !important;
}

.modules-menu-panel {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  background: var(--role-surface-panel);
  border: 1px solid var(--role-line-strong);
  border-radius: var(--neon-radius-md, 6px);
  box-shadow:
    0 8px 32px var(--role-bezel-shadow-drop),
    inset 0 1px 0 var(--role-bezel-highlight);
  color: var(--role-text-primary);
  overflow: hidden;
}

.modules-menu-header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--role-line);
  background: var(--role-surface-deck);
}

.modules-menu-title {
  flex: 1 1 auto;
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--role-text-bright);
}

.modules-menu-close {
  flex: 0 0 auto;
}

.modules-menu-intro {
  flex: 0 0 auto;
  margin: 0;
  padding: 8px 12px;
  border-bottom: 1px solid var(--role-line);
  font-size: 11px;
  line-height: 1.4;
  color: var(--role-text-muted);
}

/* P6.e — "Only current mode" filter strip. */
.modules-menu-filter-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 12px;
  border-bottom: 1px solid var(--role-line);
  background: var(--role-surface-deck);
}

.modules-menu-filter-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  color: var(--role-text-primary);
}

.modules-menu-filter-cb {
  width: 14px;
  height: 14px;
  cursor: pointer;
}

.modules-menu-current-mode {
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--role-accent-info);
}

/* P6.m — Search strip.  Sits below the "Only current mode" row.
 * Live filter by id + name + custom label + mode chip. */
.modules-menu-search-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-bottom: 1px solid var(--role-line);
  background: var(--role-surface-panel);
}

.modules-menu-search-input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 26px;
  padding: 2px 8px;
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  font-size: 11px;
  background: var(--role-surface-sunken);
  color: var(--role-text-primary);
  border: 1px solid var(--role-line);
  border-radius: 2px;
}

.modules-menu-search-input:focus-visible {
  outline: 1px solid var(--role-accent-info);
  outline-offset: 0;
}

.modules-menu-search-count {
  flex: 0 0 auto;
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--role-text-muted);
  white-space: nowrap;
}

.modules-menu-search-count--filtered {
  color: var(--role-accent-armed);
}

.modules-menu-list {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 6px 0;
}

.modules-menu-group {
  padding: 6px 12px;
  border-bottom: 1px dashed var(--role-line-subtle);
}

.modules-menu-group:last-child {
  border-bottom: 0;
}

.modules-menu-group-head {
  margin: 0 0 4px 0;
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--role-accent-info);
}

.modules-menu-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 2px;
  cursor: pointer;
  user-select: none;
}

.modules-menu-row.is-locked {
  cursor: not-allowed;
  opacity: 0.55;
}

/* P6.o — Drag-and-drop reorder.  The dragged row dims slightly; the
 * hovered drop-target draws a 2px accent rule on its top or bottom
 * edge to show whether the drop will land before or after it. */
.modules-menu-row[draggable="true"] {
  cursor: grab;
}

.modules-menu-row[draggable="true"]:active {
  cursor: grabbing;
}

.modules-menu-row.is-dragging {
  opacity: 0.45;
}

.modules-menu-row.is-drop-before {
  box-shadow: inset 0 2px 0 0 var(--role-accent-info);
}

.modules-menu-row.is-drop-after {
  box-shadow: inset 0 -2px 0 0 var(--role-accent-info);
}

.modules-menu-checkbox {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  cursor: pointer;
}

.modules-menu-row.is-locked .modules-menu-checkbox {
  cursor: not-allowed;
}

.modules-menu-row-label {
  flex: 1 1 auto;
  font-size: 12px;
  font-weight: 600;
  color: var(--role-text-primary);
}

.modules-menu-row-id {
  flex: 0 0 auto;
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  font-size: 9px;
  color: var(--role-text-muted);
  opacity: 0.7;
}

/* P6.e — Mode chip: tiny inline badge with the module's mode list.
 * Active in the current mode → highlighted; otherwise muted.  Helps
 * the user understand why toggling a row "didn't seem to do
 * anything" — it'll take effect when they switch modes. */
.modules-menu-row-mode {
  flex: 0 0 auto;
  padding: 1px 5px;
  border: 1px solid var(--role-line);
  border-radius: 2px;
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  color: var(--role-text-muted);
  background: var(--role-surface-sunken);
}

.modules-menu-row-mode[data-active-mode="true"] {
  color: var(--role-accent-info);
  border-color: var(--role-accent-info);
  background: color-mix(in srgb, var(--role-accent-info) 14%, transparent);
}

.modules-menu-row.is-mode-inactive .modules-menu-row-label {
  opacity: 0.55;
  font-style: italic;
}

.modules-menu-empty {
  margin: 12px;
  font-size: 11px;
  color: var(--role-text-muted);
  text-align: center;
  font-style: italic;
}

/* P6.g — Move buttons (▲ ▼).  Tiny chevrons on the right edge of
 * each row.  Visible always but understated so they don't fight
 * the checkbox for attention.  Hover brightens. */
.modules-menu-row-move {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  padding: 0;
  margin: 0;
  border: 1px solid var(--role-line);
  background: var(--role-surface-sunken);
  color: var(--role-text-muted);
  font-size: 9px;
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  cursor: pointer;
  border-radius: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.modules-menu-row-move:hover {
  color: var(--role-text-bright);
  border-color: var(--role-accent-info);
}

/* P6.l — Rename button.  Same metric as the move buttons but slightly
 * less prominent (label is the main action). */
.modules-menu-row-rename {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  padding: 0;
  margin: 0;
  border: 1px solid var(--role-line);
  background: var(--role-surface-sunken);
  color: var(--role-text-muted);
  font-size: 10px;
  cursor: pointer;
  border-radius: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.modules-menu-row-rename:hover {
  color: var(--role-text-bright);
  border-color: var(--role-accent-armed);
}

.modules-menu-row-label.is-custom {
  /* Italic + armed-amber tint distinguishes a renamed module. */
  font-style: italic;
  color: var(--role-accent-armed);
}

.modules-menu-row-rename-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 1px 4px;
  font-size: 12px;
  font-family: inherit;
  background: var(--role-surface-sunken);
  color: var(--role-text-bright);
  border: 1px solid var(--role-accent-armed);
  border-radius: 2px;
}

.modules-menu-row-rename-input:focus-visible {
  outline: 0;
  border-color: var(--role-accent-info);
}

/* P6.n — Height numeric input.  44px wide, fits the row strip
 * between the id code and the reorder buttons. */
.modules-menu-row-height {
  flex: 0 0 auto;
  width: 50px;
  height: 18px;
  padding: 0 4px;
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  font-size: 10px;
  text-align: right;
  background: var(--role-surface-sunken);
  color: var(--role-text-muted);
  border: 1px solid var(--role-line);
  border-radius: 2px;
}

.modules-menu-row-height.is-custom {
  /* Armed-amber accent identifies non-default heights. */
  color: var(--role-accent-armed);
  border-color: var(--role-accent-armed);
}

.modules-menu-row-height:focus-visible {
  outline: 0;
  color: var(--role-text-bright);
  border-color: var(--role-accent-info);
}

/* P6.n — Hide the spinner on Webkit since we have explicit min/max
 * and the up/down arrows for direction.  Cleaner row look. */
.modules-menu-row-height::-webkit-inner-spin-button,
.modules-menu-row-height::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.modules-menu-row.is-locked .modules-menu-row-move {
  /* Charter-locked modules don't need reorder buttons in the UI;
     they're foundational (pattern grid, transport, status bars). */
  display: none;
}

/* P6.h — Snapshot strip.  Sits above the existing Save/Load/Show-all
 * footer; same bezel surface so it reads as part of the chrome. */
.modules-menu-snap-strip {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border-top: 1px solid var(--role-line);
  background: var(--role-surface-deck);
}

.modules-menu-snap-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 auto;
  min-width: 0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--role-text-muted);
}

.modules-menu-snap-select {
  flex: 1 1 auto;
  min-width: 0;
  padding: 3px 6px;
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  font-size: 11px;
  background: var(--role-surface-sunken);
  color: var(--role-text-primary);
  border: 1px solid var(--role-line);
  border-radius: 2px;
}

.modules-menu-snap-select:focus-visible {
  outline: 1px solid var(--role-accent-info);
  outline-offset: 0;
}

.modules-menu-footer {
  flex: 0 0 auto;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 8px 12px;
  border-top: 1px solid var(--role-line);
  background: var(--role-surface-deck);
}

/* Hidden modules: when a module's primary mount has the
 * data-module-hidden attribute, ensure it really stays out of the
 * flow even if its CSS would otherwise override display.  The
 * visibility runtime also writes `display:none` inline, so this is
 * a belt-and-braces fallback. */
[data-module-hidden] {
  display: none !important;
}

/* P6.r — In-place resize handle.  A 6-px tall strip pinned to the
 * bottom edge of every hidable module's primary mount.  Cursor
 * ns-resize hints the affordance; armed-amber rule on hover; gets
 * brighter while dragging.  Pointer events are wired in the
 * visibility runtime — CSS is purely cosmetic. */
.module-resize-handle {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 6px;
  cursor: ns-resize;
  z-index: 5;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: border-color 80ms ease, background 80ms ease;
  user-select: none;
  touch-action: none;
  /* P6.s — hidden by default; revealed in edit mode. */
  display: none;
}

/* P6.s — Edit mode reveals the in-page editing affordances on
 * the modules.  Without this gate the resize handles + future
 * drag-grips clutter the normal viewing experience. */
html[data-modules-edit-mode="true"] .module-resize-handle {
  display: block;
}

/* P6.t — In-page drag-grip for reordering modules directly on
 * the page (Reason-style).  Top-right corner, info-cyan ⠿ glyph,
 * cursor grab → grabbing.  Visible only in edit mode. */
.module-drag-grip {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 6;
  width: 20px;
  height: 20px;
  display: none;
  align-items: center;
  justify-content: center;
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  color: var(--role-text-bright);
  background: color-mix(in srgb, var(--role-accent-info) 70%, transparent);
  border-bottom-left-radius: 3px;
  cursor: grab;
  user-select: none;
  touch-action: none;
}

html[data-modules-edit-mode="true"] .module-drag-grip {
  display: inline-flex;
}

.module-drag-grip:active {
  cursor: grabbing;
}

[data-module-dragging="true"] {
  opacity: 0.55;
}

/* Drop-target hint: same convention as the menu DnD (P6.o) but
 * styled on the module mount itself.  Box-shadow inset gives us
 * a 3px insertion rule on the top or bottom edge that doesn't
 * displace the module's contents. */
[data-module-mount-id].is-module-drop-before {
  box-shadow: inset 0 3px 0 0 var(--role-accent-armed);
}

[data-module-mount-id].is-module-drop-after {
  box-shadow: inset 0 -3px 0 0 var(--role-accent-armed);
}

/* P6.u — In-page hide (✕) + collapse (▾/▸) buttons.  Sit next to
 * the drag-grip in the top-right corner.  Visible only in edit
 * mode.  Hide is danger-red on hover (intent: this removes the
 * module from view); collapse is armed-amber. */
.module-inpage-hide,
.module-inpage-collapse {
  position: absolute;
  top: 0;
  z-index: 6;
  width: 20px;
  height: 20px;
  padding: 0;
  display: none;
  align-items: center;
  justify-content: center;
  border: 0;
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  color: var(--role-text-bright);
  background: color-mix(in srgb, var(--role-surface-deck) 80%, transparent);
  cursor: pointer;
  user-select: none;
}

.module-inpage-hide {
  right: 20px;
  border-bottom-left-radius: 3px;
}

.module-inpage-collapse {
  right: 40px;
}

html[data-modules-edit-mode="true"] .module-inpage-hide,
html[data-modules-edit-mode="true"] .module-inpage-collapse {
  display: inline-flex;
}

.module-inpage-hide:hover {
  color: var(--role-text-bright);
  background: color-mix(in srgb, var(--role-accent-record) 70%, transparent);
}

.module-inpage-collapse:hover {
  color: var(--role-text-bright);
  background: color-mix(in srgb, var(--role-accent-armed) 70%, transparent);
}

/* P6.x — Edit-Mode banner.  32px-tall strip pinned to the top of
 * the viewport when edit mode is on.  Sits above the modules-menu
 * host (z-index 200) at 300 so it always wins.  No layout
 * displacement — overlays existing content. */
.modules-edit-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 32px;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 12px;
  background: color-mix(in srgb, var(--role-accent-armed) 92%, transparent);
  color: var(--role-text-bright);
  border-bottom: 1px solid var(--role-line-strong);
  box-shadow: 0 2px 12px var(--role-bezel-shadow-drop);
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  user-select: none;
}

.modules-edit-banner[hidden] {
  display: none !important;
}

.modules-edit-banner-text {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.modules-edit-banner-text strong {
  letter-spacing: 0.10em;
  text-transform: uppercase;
}

.modules-edit-banner-hint {
  font-weight: 400;
  opacity: 0.82;
}

.modules-edit-banner-actions {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.modules-edit-banner-reset,
.modules-edit-banner-done {
  height: 24px;
  padding: 0 10px;
  border: 1px solid var(--role-line-strong);
  border-radius: 3px;
  background: var(--role-surface-deck);
  color: var(--role-text-bright);
  font-family: inherit;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
}

.modules-edit-banner-reset:hover {
  background: color-mix(in srgb, var(--role-accent-record) 65%, transparent);
  border-color: var(--role-accent-record);
}

.modules-edit-banner-done:hover {
  background: color-mix(in srgb, var(--role-accent-info) 65%, transparent);
  border-color: var(--role-accent-info);
}

/* P6.s — Edit-mode badge.  A subtle dashed outline + corner label
 * on every hidable module mount when edit mode is on, so the user
 * sees at a glance which DOM elements ARE modules (and therefore
 * editable). */
html[data-modules-edit-mode="true"] [data-module-mount-id] {
  outline: 1px dashed color-mix(in srgb, var(--role-accent-info) 50%, transparent);
  outline-offset: -1px;
}

html[data-modules-edit-mode="true"] [data-module-mount-id]::before {
  content: attr(data-module-mount-id);
  position: absolute;
  top: 0;
  left: 0;
  z-index: 6;
  padding: 1px 6px;
  font-family: var(--neon-font-family-mono, ui-monospace, monospace);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--role-text-bright);
  background: color-mix(in srgb, var(--role-accent-info) 55%, transparent);
  border-bottom-right-radius: 3px;
  pointer-events: none;
}

.module-resize-handle:hover {
  background: color-mix(in srgb, var(--role-accent-armed) 18%, transparent);
  border-bottom-color: var(--role-accent-armed);
}

[data-module-resizing="true"] > .module-resize-handle {
  background: color-mix(in srgb, var(--role-accent-info) 28%, transparent);
  border-bottom-color: var(--role-accent-info);
}

/* While a module is being resized, drop its outline / hover hints
 * so the visual focus stays on the dimension feedback. */
[data-module-resizing="true"] {
  user-select: none;
}

/* P6.q — Collapse-to-header toggle.  Same metric as the move /
 * rename buttons but the active state (collapsed) gets an armed
 * tint so the user can tell at a glance which modules are folded.
 * Sits between the visibility checkbox and the label. */
.modules-menu-row-collapse {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  padding: 0;
  margin: 0;
  border: 1px solid var(--role-line);
  background: var(--role-surface-sunken);
  color: var(--role-text-muted);
  font-size: 10px;
  cursor: pointer;
  border-radius: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.modules-menu-row-collapse:hover {
  color: var(--role-text-bright);
  border-color: var(--role-accent-info);
}

.modules-menu-row-collapse.is-collapsed {
  color: var(--role-accent-armed);
  border-color: var(--role-accent-armed);
}

/* P6.q — Folded module mount.  CSS clips the mount to a header
 * strip while keeping it in the layout (vs hide which removes
 * it).  Inline overflow:hidden + max-height match the runtime's
 * defensive write so the effect works without this stylesheet too. */
[data-module-collapsed="true"] {
  max-height: 32px !important;
  overflow: hidden !important;
  transition: max-height 120ms ease;
}

/* P6.p — Hover preview.  When a menu row is hovered we mark its
 * primary mount with data-module-hover; this rule paints a glowing
 * outline so the user can SEE which slice of UI the row controls.
 * Outline (vs border) keeps the surrounding layout unchanged. */
[data-module-hover="true"] {
  outline: 2px solid var(--role-accent-info);
  outline-offset: -2px;
  box-shadow: 0 0 16px var(--role-accent-info);
  transition: outline-color 80ms ease, box-shadow 80ms ease;
}
