/* MusicMin — Stage & gear (app-stageplot.v1.0.js).

   The drawing's colours are variables here so the plot follows the dark theme on screen; the SVG
   carries print fallbacks for the same names, which is what the PDF gets. Reuses the checklist's
   row, progress-bar and panel classes for the gear list and the template panels. */

.sp-modal .sp-content,
body.mm-modern #event-stageplot-modal .modal-content { max-width: 1180px; width: min(1180px, calc(100vw - 32px)); }
#sp-save:disabled { opacity: .45; cursor: default; }

.sp-canvas {
  --sp-ink: #1e293b;
  --sp-fill: #ffffff;
  --sp-accent: #dbeafe;
  --sp-stage: #f8fafc;
  --sp-grid: #e2e8f0;
  --sp-audience: #e2e8f0;
  --sp-riser: #f1f5f9;
  --sp-ch: #1d4ed8;
  --sp-owner: #7c3aed;
  --sp-power: #d97706;
  --sp-power-bg: #fffbeb;
  --sp-power-text: #ffffff;
  --sp-dir-in: #16a34a;
  --sp-dir-out: #ea580c;
  --sp-select: #2563eb;
}
body.dark .sp-canvas {
  --sp-ink: #e2e8f0;
  --sp-fill: #1e293b;
  --sp-accent: #1e3a5f;
  --sp-stage: #0f172a;
  --sp-grid: #1e293b;
  --sp-audience: #334155;
  --sp-riser: #172033;
  --sp-ch: #2563eb;
  --sp-owner: #c4b5fd;
  --sp-power: #fbbf24;
  --sp-power-bg: #292524;
  --sp-power-text: #1c1917;
  --sp-dir-in: #4ade80;
  --sp-dir-out: #fb923c;
  --sp-select: #60a5fa;
}

.sp-heading { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; }
.sp-heading h2 { flex: 1 1 240px; margin: 0; }
.sp-head-bar { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; }
.sp-head-save, .sp-head-tools { display: inline-flex; align-items: center; gap: 6px; }
.sp-head-save { gap: 10px; }
#sp-fullscreen { gap: 6px; }
#close-event-stageplot { order: 2; }
.sp-sync { font-size: 12px; opacity: .7; }
.sp-sync[data-state="dirty"] { color: #b45309; opacity: 1; font-weight: 600; }
.sp-sync[data-state="pending"] { color: #92400e; opacity: 1; }

/* A kept draft waiting to be restored. Amber: nothing is lost, but something wants deciding. */
.sp-draft-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  margin: 10px 0 0; padding: 10px 12px; border-radius: 10px; font-size: 13px;
  background: rgba(245, 158, 11, .14); border: 1px solid rgba(245, 158, 11, .45); color: inherit;
}
.sp-draft-banner[hidden] { display: none; }
.sp-draft-banner em { display: block; margin-top: 2px; font-style: normal; color: #b45309; }
.sp-draft-actions { display: flex; gap: 6px; }
.sp-tabs {
  display: flex; gap: 4px; margin: 12px 0; overflow-x: auto;
  border-bottom: 1px solid rgba(100, 116, 139, .2);
}
.sp-tab {
  border: 0; background: transparent; color: inherit; font: inherit; font-size: 14px; cursor: pointer;
  padding: 8px 14px; border-bottom: 2px solid transparent; white-space: nowrap; opacity: .72;
}
.sp-tab:hover { opacity: 1; }
.sp-tab.is-active { border-bottom-color: var(--primary); opacity: 1; font-weight: 650; }
.sp-tab-count { font-size: 12px; opacity: .7; font-weight: 500; }

.sp-loading, .sp-hint { padding: 14px 0; opacity: .7; font-size: 14px; margin: 0; }
.sp-muted { opacity: .68; font-size: 13px; }
.sp-nowrap { white-space: nowrap; }
.sp-danger:hover { color: #b91c1c; }

/* ---------- Stage tab: palette | drawing | properties */
.sp-stage-layout {
  display: grid; grid-template-columns: 190px minmax(0, 1fr) 280px; gap: 14px; align-items: start;
}
.sp-stage-layout.is-readonly { grid-template-columns: minmax(0, 1fr) 260px; }

.sp-adder { min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.sp-palette { max-height: 68vh; overflow-y: auto; padding-right: 4px; }

/* Quick add: type a name, Enter puts it on the stage. */
.sp-quick { position: relative; }
.sp-quick-input {
  width: 100%; box-sizing: border-box; padding: 7px 10px; border-radius: 10px; font: inherit; font-size: 13px;
  border: 1px solid rgba(100, 116, 139, .35); background: var(--card-bg, transparent); color: inherit;
}
.sp-quick-input:focus { outline: 2px solid rgba(59, 130, 246, .55); outline-offset: 1px; border-color: rgba(59, 130, 246, .6); }
.sp-quick-list {
  position: absolute; z-index: 30; top: calc(100% + 4px); left: 0; width: max(100%, 260px); max-height: 320px; overflow-y: auto;
  padding: 4px; border-radius: 12px; border: 1px solid rgba(100, 116, 139, .3);
  background: var(--card-bg, #ffffff); color: inherit; box-shadow: 0 12px 32px rgba(15, 23, 42, .18);
}
.sp-quick-option {
  display: grid; grid-template-columns: 30px minmax(0, 1fr); grid-template-rows: auto auto; column-gap: 8px; align-items: center;
  width: 100%; padding: 5px 8px; border: 0; border-radius: 8px; background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer;
  --sp-ink: currentColor; --sp-fill: transparent; --sp-accent: rgba(59, 130, 246, .2); --sp-riser: transparent;
}
.sp-quick-option svg { grid-row: 1 / 3; width: 28px; height: 24px; }
.sp-quick-name { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-quick-group { font-size: 11px; opacity: .6; }
.sp-quick-option:hover, .sp-quick-option.is-active { background: rgba(59, 130, 246, .12); }
.sp-quick-none { margin: 6px 8px; font-size: 12px; opacity: .7; }
body.dark .sp-quick-list { background: #1e293b; border-color: rgba(148, 163, 184, .3); }
body.dark .sp-quick-input { background: #0f172a; border-color: rgba(148, 163, 184, .35); }
.sp-palette-group h4 {
  margin: 6px 0; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; opacity: .65;
}
.sp-palette-items { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 8px; }
.sp-palette-item {
  display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 6px 4px;
  border: 1px solid rgba(100, 116, 139, .22); border-radius: 10px; background: transparent;
  color: inherit; font: inherit; font-size: 11px; line-height: 1.15; cursor: pointer; text-align: center;
  --sp-ink: currentColor; --sp-fill: transparent; --sp-accent: rgba(59, 130, 246, .2); --sp-riser: transparent;
}
.sp-palette-item:hover { background: rgba(59, 130, 246, .08); border-color: rgba(59, 130, 246, .45); }
.sp-palette-item svg { width: 34px; height: 30px; }

.sp-canvas-wrap { min-width: 0; position: relative; }

/* On-stage controls around the selected item. The frame is only a positioning box — it lets
   presses through to the drawing so the item can still be dragged from anywhere inside it; only
   the round buttons catch the pointer. Size (− +) sits on the bottom edge rather than over the
   middle, because over a vocal mic it would cover the very thing you want to drag. */
.sp-handles { position: absolute; z-index: 3; pointer-events: none; }
.sp-handles[hidden] { display: none; }
.sp-handle {
  position: absolute; width: 30px; height: 30px; padding: 0; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; pointer-events: auto; cursor: pointer;
  background: #ffffff; color: #334155; border: 1px solid rgba(100, 116, 139, .3);
  box-shadow: 0 2px 6px rgba(15, 23, 42, .18);
}
.sp-handle svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.sp-handle:hover { background: #eff6ff; color: #1d4ed8; border-color: rgba(37, 99, 235, .45); }
.sp-handle.is-danger { background: #dc2626; color: #ffffff; border-color: #dc2626; }
.sp-handle.is-danger:hover { background: #b91c1c; color: #ffffff; }
body.dark .sp-handle:not(.is-danger) { background: #1e293b; color: #e2e8f0; border-color: rgba(148, 163, 184, .35); }
.sp-h-tl  { left: -15px; top: -15px; }
.sp-h-tr1 { right: 21px; top: -15px; }
.sp-h-tr2 { right: -15px; top: -15px; }
.sp-h-c1  { left: calc(50% - 33px); bottom: -15px; }
.sp-h-c2  { left: calc(50% + 3px); bottom: -15px; }
.sp-h-bl1 { left: -15px; bottom: 21px; }
.sp-h-bl2 { left: -15px; bottom: -15px; }
.sp-h-r   { right: -15px; bottom: 21px; }
.sp-h-br1 { right: 21px; bottom: -15px; }
.sp-h-br2 { right: -15px; bottom: -15px; }

/* Several selected: the controls act on all of them, so the ones that only make sense for one item
   (rename, one step forward or back) step aside. */
.sp-handles.is-multi .sp-h-tr2, .sp-handles.is-multi .sp-h-bl1, .sp-handles.is-multi .sp-h-bl2 { display: none; }

/* The selection box, and what it will pick up while it is being drawn. */
.sp-marquee { fill: rgba(37, 99, 235, .08); stroke: #2563eb; stroke-width: 1.5px; stroke-dasharray: 5 4; vector-effect: non-scaling-stroke; pointer-events: none; }
.sp-item.is-marked { filter: drop-shadow(0 0 3px rgba(37, 99, 235, .9)); }
.sp-canvas.is-panning .sp-svg, .sp-canvas.is-panning .sp-item, .sp-canvas.is-panning .sp-item-label { cursor: grab !important; }

.sp-align { display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; }
.sp-align-btn {
  height: 32px; display: flex; align-items: center; justify-content: center; cursor: pointer;
  border: 1px solid rgba(100, 116, 139, .3); border-radius: 8px; background: transparent; color: inherit;
}
.sp-align-btn:hover { background: rgba(59, 130, 246, .1); border-color: rgba(37, 99, 235, .45); }
.sp-align-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

/* Zoom: three buttons floating in the drawing's bottom-right corner, beside the audience strip
   where nothing is ever placed. The middle one shows the level and fits the whole stage again. */
.sp-zoom {
  position: absolute; bottom: 8px; right: 8px; z-index: 2; display: flex;
  border-radius: 10px; overflow: hidden; box-shadow: 0 2px 8px rgba(15, 23, 42, .15);
  border: 1px solid rgba(100, 116, 139, .25); background: var(--card-bg, #fff);
}
body.dark .sp-zoom { background: #1e293b; }
.sp-zoom-btn {
  border: 0; background: transparent; color: inherit; font: inherit; cursor: pointer;
  min-width: 34px; height: 32px; padding: 0 8px; font-size: 16px; line-height: 1;
}
.sp-zoom-btn + .sp-zoom-btn { border-left: 1px solid rgba(100, 116, 139, .2); }
.sp-zoom-btn:hover { background: rgba(59, 130, 246, .1); }
.sp-zoom-level { font-size: 12px; font-weight: 650; min-width: 54px; font-variant-numeric: tabular-nums; }
.sp-canvas.is-zoomed .sp-svg { cursor: grab; }
.sp-canvas.is-zoomed .sp-svg:active { cursor: grabbing; }
.sp-canvas {
  border: 1px solid rgba(100, 116, 139, .22); border-radius: 12px; overflow: hidden; background: var(--sp-stage);
}
.sp-svg { display: block; width: 100%; height: auto; max-height: 68vh; touch-action: none; user-select: none; -webkit-user-select: none; }
.sp-item, .sp-item-label { cursor: pointer; }
.is-readonly .sp-item, .is-readonly .sp-item-label { cursor: default; }
.sp-stage-layout:not(.is-readonly) .sp-item, .sp-stage-layout:not(.is-readonly) .sp-item-label { cursor: grab; }
.sp-stage-layout:not(.is-readonly) .sp-item:active { cursor: grabbing; }

.sp-side {
  display: flex; flex-direction: column; gap: 9px; font-size: 13px;
  padding: 12px; border-radius: 12px; background: rgba(100, 116, 139, .07); max-height: 68vh; overflow-y: auto;
}
.sp-side h3 { margin: 0; font-size: 15px; }
.sp-side h4 { margin: 4px 0; font-size: 12px; letter-spacing: .04em; text-transform: uppercase; opacity: .75; }
.sp-side p { margin: 0; }
.sp-side label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; font-weight: 600; }
.sp-side input[type="text"], .sp-side input[type="number"], .sp-side select, .sp-side textarea { font-size: 13px; margin: 0; }
.sp-side-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
/* Who brings it and how many share a row: they answer one question. */
.sp-owner-row { display: grid; grid-template-columns: minmax(0, 1fr) 76px; gap: 6px; align-items: end; }
.sp-field-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 6px; }
.sp-check { flex-direction: row !important; align-items: center; gap: 6px !important; font-weight: 500 !important; }
.sp-check input { width: auto; margin: 0; }
.sp-tools { display: flex; flex-wrap: wrap; gap: 5px; }
.sp-tools .btn { padding: 5px 9px; }
.sp-readlist { margin: 0; padding-left: 18px; }
.sp-readlist li { margin-bottom: 4px; }

.sp-inputs { display: flex; flex-direction: column; gap: 6px; }
.sp-input {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 7px; border-radius: 8px;
  border: 1px solid rgba(100, 116, 139, .18); position: relative;
}
/* The name and its remove button share one row, so the ✕ stays centred on the name field whatever
   height the theme gives inputs. */
.sp-input-head { grid-column: 1 / -1; display: flex; align-items: center; gap: 4px; min-width: 0; }
.sp-input-head input { flex: 1; min-width: 0; }
.sp-input-head .sp-icon { flex: none; }
.sp-input > input, .sp-input > select, .sp-input > label, .sp-side input, .sp-side select, .sp-side textarea { min-width: 0; width: 100%; box-sizing: border-box; }
.sp-side .sp-check input { width: auto; }

.sp-icon {
  border: 0; background: transparent; cursor: pointer; font-size: 13px; line-height: 1;
  padding: 5px 7px; border-radius: 7px; color: inherit; opacity: .65;
}
.sp-icon:hover:not(:disabled) { opacity: 1; background: rgba(100, 116, 139, .16); }
.sp-icon:disabled { opacity: .2; cursor: default; }

/* ---------- Inputs tab */
.sp-table-wrap { overflow-x: auto; }
.sp-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.sp-table th {
  text-align: left; font-size: 11px; letter-spacing: .05em; text-transform: uppercase; opacity: .7;
  padding: 6px; border-bottom: 1px solid rgba(100, 116, 139, .25);
}
.sp-table td { padding: 4px 6px; border-bottom: 1px solid rgba(100, 116, 139, .12); vertical-align: middle; }
.sp-table td input[type="text"], .sp-table td select { margin: 0; font-size: 13px; padding: 5px 7px; min-width: 90px; }
.sp-table td input[type="checkbox"] { width: auto; margin: 0; }
.sp-table .sp-ch { font-weight: 700; color: var(--primary); width: 34px; }
/* Dragging channels. The grip is the only handle, so the inputs and selects in the row keep
   working normally; touch-action:none stops a finger on it from scrolling the page instead. */
.sp-table-hint { margin: 0 0 6px; }
.sp-grip-col { width: 28px; }
.sp-grip {
  width: 28px; text-align: center; cursor: grab; user-select: none; -webkit-user-select: none;
  touch-action: none; color: #94a3b8; font-weight: 700; letter-spacing: -2px; font-size: 15px;
}
.sp-grip:hover { color: var(--primary); }
.sp-table.is-sorting, .sp-table.is-sorting * { cursor: grabbing !important; user-select: none; }
.sp-table tr.is-dragging td {
  background: rgba(59, 130, 246, .12); box-shadow: inset 0 1px 0 rgba(37, 99, 235, .5), inset 0 -1px 0 rgba(37, 99, 235, .5);
}
.sp-table tr.is-dragging .sp-grip { color: var(--primary); }
.sp-visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.sp-needs { font-size: 13px; margin: 14px 0 0; padding: 10px 12px; border-radius: 10px; background: rgba(59, 130, 246, .08); }

/* ---------- Monitors tab */
.sp-mix {
  border: 1px solid rgba(100, 116, 139, .2); border-radius: 12px; padding: 12px; margin-bottom: 10px;
  display: flex; flex-direction: column; gap: 8px;
}
.sp-mix h4 { margin: 0; font-size: 14px; }
.sp-mix p { margin: 0; font-size: 13px; }
.sp-mix-head { display: flex; align-items: center; gap: 8px; }
.sp-mix-head input { flex: 1 1 auto; margin: 0; }
.sp-mix-head select { flex: 0 0 120px; margin: 0; }
.sp-mix > input { margin: 0; font-size: 13px; }
.sp-sends-bar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 2px 0 6px; }
.sp-sends-bar .sp-muted { margin-right: 4px; }
.sp-sends { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 4px 10px; }
.sp-send { display: flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; margin: 0; }
.sp-send input { width: auto; margin: 0; }
.sp-row-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 6px; }

/* ---------- Gear tab */
.sp-gear-head { margin-bottom: 12px; }
.sp-gear-group h4, .sp-gear-extra h4 {
  margin: 14px 0 6px; font-size: 12px; letter-spacing: .06em; text-transform: uppercase; opacity: .75;
}
.sp-gear-row { cursor: pointer; }
.sp-gear-extra { margin-top: 18px; padding-top: 10px; border-top: 1px solid rgba(100, 116, 139, .18); }
.sp-gear-extra > p { margin: 0 0 8px; }
.sp-extra { display: grid; grid-template-columns: minmax(140px, 2fr) 70px minmax(130px, 1.4fr) auto; gap: 6px; align-items: center; margin-bottom: 6px; }
.sp-extra input, .sp-extra select { margin: 0; font-size: 13px; }
.sp-extra input[data-sp-g="ownerText"] { grid-column: 3; }

/* ---------- Notes tab */
.sp-note { display: flex; flex-direction: column; gap: 5px; font-weight: 600; font-size: 13px; margin-bottom: 12px; }
.sp-note textarea { font-weight: 400; margin: 0; }
section.sp-note h4 { margin: 0; font-size: 13px; }
section.sp-note p { margin: 0; font-weight: 400; }

.sp-panel-host .mm-checklist-panel h4 { margin: 12px 0 6px; font-size: 12px; text-transform: uppercase; letter-spacing: .05em; opacity: .7; }
.sp-start-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 0; border-bottom: 1px solid rgba(100, 116, 139, .12); }
.sp-start-row > span:last-child { display: flex; align-items: center; gap: 4px; }
#sp-template-overwrite { display: inline-flex; gap: 6px; align-items: center; }
#sp-template-overwrite select { margin: 0; max-width: 240px; }

.sp-footer { display: flex; gap: 8px; flex-wrap: wrap; padding-top: 12px; margin-top: 14px; border-top: 1px solid rgba(100, 116, 139, .18); }

/* Full screen: the dialog fills the window and the stage takes every pixel the tabs and toolbar
   leave. Mirrors #event-modal.fullscreen in app-ui. When the page is also in browser full screen,
   the modal itself is the fullscreen element, so it needs its own backdrop. */
body.mm-modern #event-stageplot-modal.fullscreen .modal-content,
#event-stageplot-modal.fullscreen .modal-content {
  width: calc(100vw - 24px); max-width: calc(100vw - 24px);
  height: calc(100dvh - 24px); max-height: calc(100dvh - 24px);
  display: flex; flex-direction: column;
}
#event-stageplot-modal:fullscreen { background: rgba(15, 23, 42, .6); }
#event-stageplot-modal.fullscreen .sp-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
#event-stageplot-modal.fullscreen .sp-heading,
#event-stageplot-modal.fullscreen .sp-tabs,
#event-stageplot-modal.fullscreen .sp-draft-banner,
#event-stageplot-modal.fullscreen .sp-panel-host,
#event-stageplot-modal.fullscreen .sp-footer { flex: none; }
#event-stageplot-modal.fullscreen .sp-stage-layout { height: 100%; grid-template-columns: 200px minmax(0, 1fr) 300px; grid-template-rows: minmax(0, 1fr); }
#event-stageplot-modal.fullscreen .sp-stage-layout.is-readonly { grid-template-columns: minmax(0, 1fr) 280px; }
#event-stageplot-modal.fullscreen .sp-canvas-wrap { height: 100%; min-height: 0; display: flex; flex-direction: column; }
/* The drawing is laid over the box rather than inside its flow, so the box's size comes from the
   window and never from the drawing — otherwise a wide stage pushes the row taller than the screen. */
#event-stageplot-modal.fullscreen .sp-canvas { flex: 1 1 auto; min-height: 0; position: relative; }
#event-stageplot-modal.fullscreen .sp-svg { position: absolute; inset: 0; width: 100%; height: 100%; max-height: none; }
#event-stageplot-modal.fullscreen .sp-adder,
#event-stageplot-modal.fullscreen .sp-side { max-height: 100%; height: 100%; box-sizing: border-box; }
#event-stageplot-modal.fullscreen .sp-palette { flex: 1 1 auto; min-height: 0; max-height: none; }
#event-stageplot-modal.fullscreen .sp-footer { margin-top: 10px; padding-top: 10px; }

/* Medium screens: the properties panel drops under the drawing. */
@media (max-width: 1100px) {
  .sp-stage-layout { grid-template-columns: 170px minmax(0, 1fr); }
  .sp-stage-layout.is-readonly { grid-template-columns: minmax(0, 1fr); }
  .sp-side { grid-column: 1 / -1; max-height: none; }
}

/* Phones, portrait and landscape: the same condition the rest of the app uses. The palette becomes
   one scrolling strip above the stage so the drawing keeps the full width. */
@media (max-width: 768px), ((orientation: landscape) and (max-height: 500px) and (pointer: coarse)) {
  .sp-modal .sp-content,
  body.mm-modern #event-stageplot-modal .modal-content { width: 100vw; max-width: 100vw; }
  .sp-stage-layout, .sp-stage-layout.is-readonly { grid-template-columns: minmax(0, 1fr); }
  .sp-palette { max-height: none; overflow-x: auto; overflow-y: hidden; display: flex; gap: 6px; padding-bottom: 4px; }
  .sp-palette-group { display: contents; }
  .sp-palette-group h4 { display: none; }
  .sp-palette-items { display: contents; }
  .sp-palette-item { flex: 0 0 74px; }
  .sp-zoom-btn { min-width: 40px; height: 38px; }
  .sp-handle { width: 34px; height: 34px; }
  .sp-svg { max-height: 60vh; }
  .sp-side { max-height: none; }
  .sp-extra { grid-template-columns: 1fr 64px auto; }
  .sp-extra select, .sp-extra input[data-sp-g="ownerText"] { grid-column: 1 / -1; }
  /* A phone's sheet is already the whole screen; full screen just lets the stage be taller. */
  body.mm-modern #event-stageplot-modal.fullscreen .modal-content,
  #event-stageplot-modal.fullscreen .modal-content { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; border-radius: 0; }
  #event-stageplot-modal.fullscreen .sp-stage-layout,
  #event-stageplot-modal.fullscreen .sp-stage-layout.is-readonly { height: auto; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto; }
  #event-stageplot-modal.fullscreen .sp-canvas-wrap { height: auto; }
  #event-stageplot-modal.fullscreen .sp-canvas { position: static; }
  #event-stageplot-modal.fullscreen .sp-svg { position: static; height: auto; max-height: 72dvh; }
  #event-stageplot-modal.fullscreen .sp-side { height: auto; }
}

/* Preparation controls remain usable on a phone and in both themes. */
.sp-readiness, .sp-resource, .sp-conflict { padding: 14px; margin: 12px 0; border: 1px solid rgba(128,128,128,.3); border-radius: 10px; }
.sp-resource-form { display: flex; gap: 10px; flex-wrap: wrap; align-items: end; margin: 12px 0; }
.sp-resource-form label { flex: 1 1 140px; display: grid; gap: 4px; }
.sp-resource-form input { width: 100%; box-sizing: border-box; }
.sp-resource > span { display: block; }
.sp-gear-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; margin-bottom: 4px; }
.sp-gear-bar .sp-gear-head { margin: 0; flex: 1 1 160px; }
.sp-gear-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; padding: 7px 10px; margin: 4px 0; border: 1px solid rgba(128,128,128,.25); border-radius: 8px; }
.sp-gear-what { flex: 1 1 120px; min-width: 0; }
.sp-gear-what strong { display: block; font-size: 14px; line-height: 1.3; }
.sp-gear-what small { display: block; font-size: 12px; line-height: 1.3; }
.sp-gear-who { display: flex; gap: 6px; }
.sp-gear-row .sp-gear-who select, .sp-gear-row .sp-gear-who input { width: 130px; min-height: 34px; padding: 4px 6px; margin: 0; font-size: 13px; box-sizing: border-box; }
.sp-gear-qty { font-weight: 500; opacity: .65; }
.sp-gear-ctl { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; margin-left: auto; }
.sp-gear-tick { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; white-space: nowrap; }
.sp-gear-tick input { width: 20px; height: 20px; margin: 0; }
.sp-gear-count { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; white-space: nowrap; }
.sp-gear-row .sp-gear-ctl input:not([type=checkbox]) { min-height: 34px; padding: 4px 6px; box-sizing: border-box; }
.sp-gear-row .sp-gear-count input { width: 56px; }
.sp-gear-row .sp-gear-contact { width: 150px; }
.sp-gear-row.is-done { border-color: #16a34a; background: rgba(22,163,74,.08); }
.sp-event-readiness { font-size: 12px; padding: 8px 0; opacity: .85; }
.sp-table-wrap { overflow-x: auto; }
.sp-conflict .sp-tools { flex-wrap: wrap; }
@media(max-width:640px) { .sp-resource-form { flex-direction: column; align-items: stretch; } .sp-resource-form label { flex-basis: auto; } }
.sp-resource-form input, .sp-gear-what input:not([type=checkbox]), .sp-gear-row select { min-height: 40px; padding: 6px 8px; box-sizing: border-box; }
.sp-resource-form input[type=number] { min-width: 0; }

/* Mixer & cables */
.sp-rig-head { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 12px; margin-bottom: 10px; }
.sp-rig-head label { display: flex; flex-direction: column; gap: 3px; font-size: 12px; font-weight: 600; min-width: 0; }
.sp-rig-head input[type="text"] { width: 220px; max-width: 100%; margin: 0; }
.sp-rig-head select { margin: 0; }
.sp-rig-head .sp-tools { margin: 0; }
.sp-rig-title { margin: 0 0 8px; }
.sp-rig-panel {
  overflow-x: auto; border-radius: 12px; margin-bottom: 8px;
  --sp-ink: #1e293b; --sp-fill: #ffffff; --sp-accent: #dbeafe; --sp-stage: #f8fafc; --sp-ch: #1d4ed8;
}
body.dark .sp-rig-panel { --sp-ink: #e2e8f0; --sp-fill: #1e293b; --sp-accent: #1e3a5f; --sp-stage: #0f172a; --sp-ch: #60a5fa; }
.sp-rig-svg { display: block; width: 100%; min-width: 720px; height: auto; }
.sp-rig-warn { border: 1px solid rgba(217, 119, 6, .45); background: rgba(251, 191, 36, .12); border-radius: 8px; padding: 6px 10px; margin-bottom: 8px; font-size: 13px; }
.sp-rig-warn p { margin: 2px 0; }
.sp-wire-table tr.is-warn td { background: rgba(251, 191, 36, .12); }
.sp-wire-table td select { min-width: 120px; }
.sp-length { width: 74px; margin: 0; padding: 5px 7px; font-size: 13px; }
.sp-feeds { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; font-size: 12.5px; }
.sp-feeds label { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.sp-feeds input[type="checkbox"] { width: auto; margin: 0; }
.sp-feeds input[type="text"] { flex: 1 1 140px; min-width: 120px; margin: 0; padding: 4px 7px; font-size: 12.5px; }
.sp-link { border: 0; background: none; padding: 0; color: var(--primary, #2563eb); font: inherit; font-size: 12px; cursor: pointer; text-decoration: underline; }
.sp-sock-editor { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; margin: 8px 0 12px; }
.sp-sock-editor h4 { margin: 0 0 6px; }
.sp-sock { display: grid; grid-template-columns: minmax(0, 1fr) 130px auto; gap: 4px; align-items: center; margin-bottom: 4px; }
.sp-sock input, .sp-sock select { margin: 0; min-width: 0; width: 100%; box-sizing: border-box; }
.sp-cable-summary { margin-top: 12px; }
.sp-cable-summary ul { margin: 4px 0 6px; padding-left: 18px; }
.sp-cable-summary li { margin: 2px 0; }

/* Tapping a socket on the mixer panel */
.sp-socket { cursor: pointer; }
.sp-socket:hover > rect:first-child { fill: rgba(37, 99, 235, .08) !important; }
.sp-rig-wrap { position: relative; }
.sp-rig-hint { margin: -4px 0 8px; font-size: 12px; }
.sp-sock-pop {
  position: absolute; z-index: 5; width: 300px; max-width: calc(100% - 8px); box-sizing: border-box;
  display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; border-radius: 12px;
  background: var(--card-bg, #ffffff); color: inherit; border: 1px solid rgba(100, 116, 139, .3);
  box-shadow: 0 12px 32px rgba(15, 23, 42, .18); font-size: 13px;
}
body.dark .sp-sock-pop { background: #1e293b; border-color: rgba(148, 163, 184, .3); }
.sp-sock-pop-head { display: flex; align-items: center; gap: 8px; }
.sp-sock-pop-head .sp-icon { margin-left: auto; }
.sp-sock-pop label { display: flex; flex-direction: column; gap: 3px; font-weight: 600; font-size: 12px; }
.sp-sock-pop select, .sp-sock-pop input[type="text"] { margin: 0; width: 100%; box-sizing: border-box; font-weight: 400; }
.sp-sock-pop .sp-feeds label { flex-direction: row; font-weight: 400; }
.sp-sock-pop p { margin: 0; font-size: 12px; }
.sp-sock-pop { text-align: left; }
.sp-sock-pop .sp-stereo { flex-direction: row; align-self: flex-start; font-weight: 500; }
.sp-sock-pop .sp-desk-feed { flex-direction: column; align-items: stretch; margin: 0; }
.sp-sock-pop .sp-desk-feed .sp-muted { font-weight: 400; }

/* Stereo pairs */
.sp-stereo { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; white-space: nowrap; margin: 0; }
.sp-stereo input[type="checkbox"] { width: auto; margin: 0; }
.sp-follow { font-size: 12.5px; }
.sp-st { display: inline-block; padding: 0 5px; border-radius: 6px; font-size: 11px; font-weight: 700; color: #fff; background: var(--primary, #2563eb); }
.sp-wire-table tr.is-follower td { background: rgba(37, 99, 235, .05); }
.sp-pop-carries { display: flex; flex-direction: column; gap: 4px; }
.sp-pop-label { font-weight: 600; font-size: 12px; }
td > select + .sp-stereo { margin-top: 4px; }

/* Several desks. Each desk keeps one colour wherever it shows — its chip, its heading in Inputs,
   and (on the stage) its cables — so A and B are told apart at a glance. */
#event-stageplot-modal { --sp-desk-0: #2563eb; --sp-desk-1: #ea580c; --sp-desk-2: #16a34a; --sp-desk-3: #9333ea; }
body.dark #event-stageplot-modal { --sp-desk-0: #60a5fa; --sp-desk-1: #fb923c; --sp-desk-2: #4ade80; --sp-desk-3: #c084fc; }
.sp-desk-0 { --sp-desk: var(--sp-desk-0); }
.sp-desk-1 { --sp-desk: var(--sp-desk-1); }
.sp-desk-2 { --sp-desk: var(--sp-desk-2); }
.sp-desk-3 { --sp-desk: var(--sp-desk-3); }
.sp-desks { display: flex; flex-wrap: wrap; align-items: stretch; gap: 8px; margin: 0 0 12px; }
.sp-desk-chip {
  display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto auto; column-gap: 8px; align-items: center;
  text-align: left; min-width: 0; max-width: 100%; padding: 7px 12px 7px 8px; border-radius: 10px; cursor: pointer;
  border: 1px solid rgba(148, 163, 184, .45); background: transparent; color: inherit; font: inherit;
  transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.sp-desk-chip:hover { border-color: var(--sp-desk); }
.sp-desk-chip:focus-visible { outline: 2px solid var(--sp-desk); outline-offset: 2px; }
.sp-desk-chip.is-active { border-color: var(--sp-desk); box-shadow: inset 0 0 0 1px var(--sp-desk); background: color-mix(in srgb, var(--sp-desk) 9%, transparent); }
.sp-desk-dot {
  display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; flex: none;
  background: var(--sp-desk, #64748b); color: #fff; font-size: 12px; font-weight: 700; line-height: 1;
}
.sp-desk-chip .sp-desk-dot { grid-row: 1 / span 2; }
.sp-desk-name { font-weight: 600; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-desk-meta { grid-column: 2; font-size: 12px; opacity: .7; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sp-desk-add { align-self: center; }
.sp-desk-add-menu { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.sp-desk-feed { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 0 0 6px; font-size: 12px; font-weight: 600; }
.sp-desk-feed select { margin: 0; width: auto; }
.sp-desk-link { margin: 8px 0; padding: 8px 10px; border-radius: 8px; border: 1px dashed rgba(148, 163, 184, .55); }
.sp-desk-link label { margin-bottom: 4px; }
.sp-desk-rows-head th { text-align: left; font-size: 14px; font-weight: 700; text-transform: none; letter-spacing: 0; color: inherit; padding-top: 16px; border-bottom: 2px solid var(--sp-desk); }
.sp-desk-rows-head th .sp-muted { font-weight: 400; }
.sp-desk-rows-head .sp-desk-dot { width: 20px; height: 20px; font-size: 11px; margin-right: 8px; vertical-align: -5px; }
.sp-danger-text { color: #b91c1c; }
body.dark .sp-danger-text { color: #fca5a5; }
@media (max-width: 768px), ((orientation: landscape) and (max-height: 500px) and (pointer: coarse)) {
  .sp-desks { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; }
  .sp-desk-chip { flex: 0 0 auto; max-width: 78vw; }
}

/* Wired / wireless: a two-way switch on a mic, and the receiver it is paired with. */
.sp-seg { display: inline-flex; border: 1px solid rgba(148, 163, 184, .6); border-radius: 999px; padding: 2px; gap: 2px; margin: 4px 0; }
.sp-seg button { border: 0; background: transparent; color: inherit; font: inherit; font-size: 12px; font-weight: 600; padding: 4px 12px; border-radius: 999px; cursor: pointer; }
.sp-seg button.is-on { background: var(--primary, #2563eb); color: #fff; }
.sp-seg button:focus-visible { outline: 2px solid var(--primary, #2563eb); outline-offset: 1px; }
.sp-rx { display: flex; flex-direction: column; gap: 3px; font-size: 12px; font-weight: 600; }
.sp-rx select { margin: 0; font-weight: 400; }
.sp-rx-note { font-size: 12px; margin: 2px 0 4px; }
.sp-receiver { margin: 8px 0; padding: 8px 10px; border-radius: 8px; border: 1px solid rgba(148, 163, 184, .45); }
.sp-receiver h4 { margin: 0 0 6px; }
.sp-slots { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
.sp-slot { display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px 3px 4px; border-radius: 999px; font-size: 12px; border: 1px dashed rgba(148, 163, 184, .7); }
.sp-slot strong { display: inline-grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; background: rgba(148, 163, 184, .35); font-size: 11px; }
.sp-slot.is-used { border-style: solid; border-color: var(--primary, #2563eb); }
.sp-slot.is-used strong { background: var(--primary, #2563eb); color: #fff; }

/* Cables between two things on the stage */
.sp-links { margin-top: 14px; }
.sp-link-add { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px; margin: 8px 0; }
.sp-link-add label { display: flex; flex-direction: column; gap: 3px; font-size: 12px; font-weight: 600; min-width: 0; }
.sp-link-add select { margin: 0; max-width: 100%; }

/* Connecting by dragging. The plug sits on the right edge of the selected item, above Flip; it is
   the one control drawn in the accent colour, and it pulses the first few times it appears. */
.sp-h-port { right: -15px; top: calc(50% - 33px); display: none; }
.sp-handles.has-port .sp-h-port { display: flex; }
.sp-handle.is-port { background: var(--primary, #2563eb); color: #fff; border-color: var(--primary, #2563eb); touch-action: none; -webkit-touch-callout: none; user-select: none; cursor: grab; }
.sp-handle.is-port:hover { background: #1d4ed8; color: #fff; }
body.dark .sp-handle.is-port { background: #3b82f6; color: #fff; border-color: #3b82f6; }
.sp-handles.is-port-new .sp-h-port { animation: sp-port-pulse 1.6s ease-out 3; }
@keyframes sp-port-pulse { 0% { box-shadow: 0 0 0 0 rgba(37, 99, 235, .55); } 80%, 100% { box-shadow: 0 0 0 12px rgba(37, 99, 235, 0); } }
.sp-handles.is-wiring .sp-handle:not(.is-port) { visibility: hidden; }
.sp-handles.is-wiring .sp-h-port { cursor: grabbing; }

/* While a wire is drawn: what it can go into stands out, the rest steps back. */
.sp-canvas.is-wiring .sp-item { transition: opacity .15s ease, filter .15s ease; }
.sp-canvas.is-wiring .sp-item:not(.is-drop-ok):not(.is-wire-from) { opacity: .3; }
.sp-canvas.is-wiring .sp-item-label { opacity: .5; }
.sp-item.is-drop-ok { filter: drop-shadow(0 0 2px rgba(37, 99, 235, .55)); cursor: copy; }
.sp-item.is-drop-hover { filter: drop-shadow(0 0 5px rgba(37, 99, 235, 1)) drop-shadow(0 0 2px rgba(37, 99, 235, 1)); }
.sp-wire-layer { pointer-events: none; }
.sp-wire-band { fill: none; stroke-width: 3px; stroke-linecap: round; vector-effect: non-scaling-stroke; stroke-dasharray: 8 5; animation: sp-wire-flow .6s linear infinite; }
.sp-wire-layer.is-landed .sp-wire-band { stroke-dasharray: none; animation: none; }
.sp-wire-layer.is-retracting { opacity: 0; transition: opacity .15s ease; }
@keyframes sp-wire-flow { to { stroke-dashoffset: -13; } }
.sp-wire-chip {
  position: absolute; z-index: 6; pointer-events: none; padding: 4px 9px; border-radius: 999px; font-size: 12px; font-weight: 600; white-space: nowrap;
  background: #0f172a; color: #fff; box-shadow: 0 4px 12px rgba(15, 23, 42, .25);
}
.sp-item.is-connected { animation: sp-connected .9s ease-out; }
@keyframes sp-connected { 0% { filter: drop-shadow(0 0 0 rgba(22, 163, 74, 0)); } 30% { filter: drop-shadow(0 0 7px rgba(22, 163, 74, 1)); } 100% { filter: drop-shadow(0 0 0 rgba(22, 163, 74, 0)); } }
@media (prefers-reduced-motion: reduce) {
  .sp-wire-band, .sp-handles.is-port-new .sp-h-port, .sp-item.is-connected { animation: none; }
}

/* The connect popover, where the wire landed. */
#sp-wire-pop-host { position: absolute; inset: 0; pointer-events: none; z-index: 7; }
.sp-wire-pop { pointer-events: auto; width: 340px; max-height: min(70vh, 520px); overflow: auto; }
.sp-wire-pop[data-mode="in"] { width: 400px; max-width: calc(100% - 8px); }
.sp-wire-pop[data-mode="in"] .sp-wire-row { grid-template-columns: minmax(0, .8fr) minmax(0, 1.4fr); }
.sp-wire-pop.is-centred { left: 50%; top: 24px; transform: translateX(-50%); }
.sp-wire-rows { display: flex; flex-direction: column; gap: 6px; }
.sp-wire-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); gap: 2px 8px; align-items: center; }
.sp-wire-name { font-weight: 600; font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; }
.sp-wire-row .sp-wire-cable { grid-column: 2; }
.sp-wire-cables { grid-column: 2; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.sp-wire-cables select { font-size: 12px; max-width: 100%; }
.sp-lead-select { display: block; margin-top: 4px; }
.sp-chain-cable { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; font-size: 12px; }
.sp-cable-badge { display: inline-block; font-size: 11px; padding: 1px 7px; border-radius: 6px; background: rgba(148, 163, 184, .18); color: inherit; white-space: nowrap; }
.sp-wire-foot { display: flex; justify-content: flex-end; gap: 6px; margin-top: 4px; }
.sp-wire-group { display: flex; flex-direction: column; gap: 4px; }
.sp-wire-targets { display: flex; flex-wrap: wrap; gap: 6px; }
.sp-wire-target { border: 1px solid rgba(148, 163, 184, .55); background: transparent; color: inherit; font: inherit; font-size: 12.5px; padding: 4px 10px; border-radius: 999px; cursor: pointer; }
.sp-wire-target:hover, .sp-wire-target:focus-visible { border-color: var(--primary, #2563eb); color: var(--primary, #2563eb); outline: none; }
.sp-wire-now { margin: 0; padding-left: 16px; font-size: 12.5px; }
.sp-wire-now li { margin: 2px 0; }
.sp-wire-now .sp-icon { width: 22px; height: 22px; font-size: 11px; vertical-align: middle; }
.sp-wire-tip { font-size: 11.5px; }
.sp-wire-jacks { font-weight: 600; }
.sp-slot-picks { display: flex; flex-wrap: wrap; gap: 6px; }
.sp-slot-pick { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px 4px 4px; border-radius: 999px; font: inherit; font-size: 12px; cursor: pointer;
  border: 1px dashed rgba(148, 163, 184, .7); background: transparent; color: inherit; }
.sp-slot-pick strong { display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: rgba(148, 163, 184, .35); font-size: 11px; }
.sp-slot-pick.is-taken { opacity: .75; }
.sp-slot-pick.is-on { border-style: solid; border-color: var(--primary, #2563eb); }
.sp-slot-pick.is-on strong { background: var(--primary, #2563eb); color: #fff; }

/* What still has no connection, under the stage. */
.sp-connect-status { margin-top: 8px; padding: 6px 10px; border-radius: 8px; font-size: 12.5px; background: rgba(251, 191, 36, .12); border: 1px solid rgba(217, 119, 6, .35); }
.sp-connect-status .sp-link { font-size: inherit; padding: 0; }

@media (max-width: 768px), ((orientation: landscape) and (max-height: 500px) and (pointer: coarse)) {
  .sp-h-port { right: -17px; top: calc(50% - 38px); }
  /* The heading: title and ✕ on one line, then the save state on the left and the tools on the
     right. Full screen shows its icon only. */
  .sp-heading { flex-wrap: wrap; row-gap: 10px; }
  #close-event-stageplot { order: 1; }
  .sp-head-bar { order: 2; flex: 1 1 100%; justify-content: space-between; flex-wrap: nowrap; }
  .sp-head-save { min-width: 0; }
  .sp-head-save .sp-sync { min-width: 0; line-height: 1.25; }
  .sp-head-tools .btn, .sp-head-save .btn { min-height: 36px; padding: 6px 12px; }
  .sp-btn-label { display: none; }
  .sp-heading { margin-bottom: 8px; }
  .sp-tabs { margin-top: 4px; }
  /* Palette tiles: a compact strip — the app's phone button sizing would otherwise make each one
     a 16px-text card over 110px tall. */
  #event-stageplot-modal .sp-palette-item { flex: 0 0 66px; min-height: 0; padding: 6px 3px 5px; font-size: 11px; line-height: 1.15; font-weight: 500; }
  #event-stageplot-modal .sp-palette-item svg { width: 28px; height: 24px; }
  /* The plot tools stay on one line and scroll sideways; Undo and Redo come first. */
  .sp-footer { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-top: 10px; padding: 10px 0 2px; }
  .sp-footer::-webkit-scrollbar { display: none; }
  .sp-footer .btn { flex: none; min-height: 38px; padding: 6px 12px; white-space: nowrap; }
  /* About four matches, so the list stays above the on-screen keyboard; the rest scroll. */
  .sp-quick-list { max-height: min(212px, 40dvh); }
  /* Name, who brings it and the packed tick share one line. */
  .sp-gear-what { flex-basis: 90px; }
  .sp-gear-row .sp-gear-who select, .sp-gear-row .sp-gear-who input { width: 110px; font-size: 12px; }
  .sp-gear-row.is-venue .sp-gear-ctl { flex: 1 1 100%; }
  .sp-gear-row .sp-gear-contact { flex: 1 1 auto; }
  /* On a phone the popover is a sheet along the bottom of the screen. */
  #sp-wire-pop-host .sp-wire-pop { position: fixed; left: 0 !important; right: 0; top: auto !important; bottom: 0; width: 100%; max-width: 100%; max-height: 70dvh; border-radius: 16px 16px 0 0; transform: none; }
}
.sp-wire-pop .sp-sock-pop-head { flex-wrap: wrap; align-items: flex-start; }
.sp-wire-pop .sp-sock-pop-head strong { flex: 1 1 0; min-width: 0; line-height: 1.3; }
.sp-wire-pop .sp-sock-pop-head .sp-muted { order: 3; flex-basis: 100%; font-size: 12px; margin-top: -4px; }

/* Cables on the stage: Lines (straight from each thing to its desk) or a Tidy route. Each desk in
   its colour; outputs dashed; a lead between two things in grey; a wireless mic dotted to its
   receiver. They sit under everything on the stage and are never printed. */
#event-stageplot-modal { --sp-link: #64748b; }
body.dark #event-stageplot-modal { --sp-link: #94a3b8; }
.sp-cables { pointer-events: none; }
.sp-cable { fill: none; stroke-linecap: round; stroke-linejoin: round; opacity: .75; pointer-events: stroke; cursor: pointer; }
.sp-cable:hover { opacity: 1; }
.sp-cable-out { stroke-dasharray: 0.5 0.35; }
.sp-cable-radio { stroke-dasharray: 0.08 0.3; opacity: .9; }
.sp-cables.is-tidy .sp-cable { opacity: .9; }
.sp-cable-trunk { fill: none; stroke-linecap: round; stroke-linejoin: round; opacity: .28; }
/* Thin lines: fine and sharp — square ends and mitred corners, and a little stronger so they still read. */
.sp-cables.is-thin .sp-cable, .sp-cables.is-thin .sp-cable-trunk { stroke-linecap: butt; stroke-linejoin: miter; }
.sp-cables.is-thin .sp-cable { opacity: .95; }
.sp-cables.is-thin .sp-cable-trunk { opacity: .22; }
.sp-cable-count { pointer-events: none; }
.sp-cable-view { position: absolute; left: 10px; bottom: 10px; z-index: 2; display: inline-flex; align-items: center; gap: 2px; padding: 3px; border-radius: 999px;
  background: var(--card-bg, #fff); border: 1px solid rgba(100, 116, 139, .3); box-shadow: 0 2px 8px rgba(15, 23, 42, .12); font-size: 12px; }
body.dark .sp-cable-view { background: #1e293b; border-color: rgba(148, 163, 184, .3); }
.sp-cable-view-label { font-weight: 700; padding: 0 6px 0 8px; opacity: .7; }
.sp-cable-view button { border: 0; background: transparent; color: inherit; font: inherit; font-weight: 600; padding: 5px 10px; border-radius: 999px; cursor: pointer; }
.sp-cable-view button.is-on { background: var(--primary, #2563eb); color: #fff; }
.sp-cable-view-sep { width: 1px; align-self: stretch; margin: 3px 4px; background: currentColor; opacity: .2; }
.sp-tidy { margin-top: 8px; padding: 8px 12px; border-radius: 8px; font-size: 13px; border: 1px solid rgba(22, 163, 74, .35); background: rgba(22, 163, 74, .07); }
.sp-tidy ul { margin: 6px 0; padding-left: 18px; }
.sp-tidy li { margin: 4px 0; }
.sp-tidy li .btn { margin-left: 6px; }
/* Power: what needs a socket, and the strips and extension cords to bring. Amber, like the drop. */
.sp-power-panel { margin-top: 8px; padding: 8px 12px; border-radius: 8px; font-size: 13px; border: 1px solid rgba(217, 119, 6, .4); background: rgba(245, 158, 11, .08); }
.sp-power-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px; }
.sp-power-sizes { display: inline-flex; align-items: center; gap: 2px; font-size: 12px; }
.sp-power-sizes button { border: 1px solid rgba(217, 119, 6, .4); background: transparent; color: inherit; font: inherit; font-weight: 600; min-width: 28px; padding: 2px 8px; border-radius: 999px; cursor: pointer; }
.sp-power-sizes button.is-on { background: #d97706; border-color: #d97706; color: #fff; }
.sp-power-total { margin: 6px 0; }
.sp-power-list { margin: 6px 0; padding-left: 18px; }
.sp-power-list > li { margin: 6px 0; }
.sp-power-list ul { margin: 2px 0; padding-left: 16px; }
.sp-power-panel p { margin: 6px 0; }
.sp-svg.is-power .sp-cables { opacity: .22; }
#event-stageplot-modal.fullscreen .sp-power-panel { flex: none; max-height: 30vh; overflow: auto; }
/* The drawing and everything floating on it share one box; what is said about the stage sits under it. */
.sp-canvas-frame { position: relative; min-width: 0; }
#event-stageplot-modal.fullscreen .sp-canvas-frame { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
#event-stageplot-modal.fullscreen .sp-connect-status, #event-stageplot-modal.fullscreen .sp-tidy { flex: none; max-height: 30vh; overflow: auto; }
.sp-input > .sp-seg, .sp-input > .sp-rx, .sp-input > .sp-rx-note { grid-column: 1 / -1; }
.sp-input > .sp-seg { justify-self: start; }

/* A device's own sockets in its panel: what plugs into it, outputs to other devices, added sockets. */
.sp-sockets { margin: 8px 0; }
.sp-sockets h4 .sp-muted, .sp-inputs h4 .sp-muted { font-weight: 400; font-size: 12px; }
.sp-jacks { list-style: none; margin: 4px 0 8px; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.sp-jack { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; padding: 6px 8px; border-radius: 8px; border: 1px solid rgba(100, 116, 139, .18); font-size: 12.5px; }
.sp-jack-name { font-weight: 600; }
.sp-jack-to { flex: 1 1 100%; order: 3; }
.sp-jack .sp-link { margin-left: auto; font-size: 12px; padding: 0; }
.sp-jack-add { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.sp-jack-add select, .sp-jack-add input { margin: 0; width: auto; flex: 1 1 110px; }
.sp-out-to { grid-column: 1 / -1; margin: 0; font-size: 12px; opacity: .85; }
.sp-out-cables { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 4px 6px; }
.sp-out-cables select { flex: 1 1 160px; min-width: 0; font-size: 12px; }

/* ---------- Socket labels (tape), hover cards, and one device's cables ---------- */
/* Tape on a socket: the leader's own label, as on a real desk. */
.sp-tape {
  display: inline-block; padding: 0 6px; margin-left: 4px; border-radius: 3px; vertical-align: 1px;
  background: #fef3c7; color: #1f2937; border: 1px solid #d6b25e; font-size: 11.5px; font-weight: 700; line-height: 1.5;
}
.sp-sock-note { display: grid; gap: 4px; font-size: 12px; font-weight: 600; margin-bottom: 8px; }
.sp-sock-note input { background: #fffbeb; border-color: #d6b25e; font-weight: 600; }
body.dark .sp-sock-note input { background: rgba(254, 243, 199, .12); color: inherit; }
tr.is-planned td { background: rgba(254, 243, 199, .35); }
body.dark tr.is-planned td { background: rgba(254, 243, 199, .07); }

/* Label sockets: every socket in a list, its label field, and what is plugged in now. */
.sp-label-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px 20px; margin: 12px 0 16px; }
.sp-label-list h4 { margin: 0 0 6px; font-size: 12px; letter-spacing: .06em; text-transform: uppercase; opacity: .7; }
.sp-label-row { display: grid; grid-template-columns: 64px minmax(0, 1fr); align-items: center; gap: 2px 8px; padding: 4px 0; border-top: 1px solid rgba(100, 116, 139, .15); }
.sp-label-socket { font-weight: 700; font-size: 13px; }
.sp-label-row input { margin: 0; min-height: 34px; background: #fffbeb; border-color: #d6b25e; font-weight: 600; }
body.dark .sp-label-row input { background: rgba(254, 243, 199, .12); color: inherit; }
.sp-label-now { grid-column: 2; font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The hover card, for a socket on a desk or a device on the stage. */
.sp-tip {
  position: absolute; z-index: 9; max-width: 300px; min-width: 180px; padding: 9px 11px; pointer-events: none;
  border-radius: 10px; background: #0f172a; color: #f8fafc; font-size: 12.5px; line-height: 1.45;
  box-shadow: 0 10px 28px rgba(15, 23, 42, .3);
}
.sp-tip > div { overflow-wrap: anywhere; }
.sp-tip-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 3px; }
.sp-tip-head strong { font-size: 13.5px; }
.sp-tip-head span { opacity: .65; font-size: 11.5px; }
.sp-tip-tape { display: inline-block; margin: 2px 0 5px; padding: 0 7px; border-radius: 3px; background: #fef3c7; color: #1f2937; font-weight: 700; }
.sp-tip-strong { font-weight: 700; color: #93c5fd; }
.sp-tip-muted { opacity: .7; }
.sp-tip-warn { color: #fcd34d; }
.sp-tip-hint { margin-top: 5px; padding-top: 5px; border-top: 1px solid rgba(248, 250, 252, .15); opacity: .55; font-size: 11.5px; }
body.dark .sp-tip { background: #f8fafc; color: #0f172a; }
body.dark .sp-tip-strong { color: #1d4ed8; }
body.dark .sp-tip-warn { color: #b45309; }
body.dark .sp-tip-hint { border-color: rgba(15, 23, 42, .15); }
.sp-conn-head { margin: 12px 0 4px; font-size: 12px; letter-spacing: .06em; text-transform: uppercase; opacity: .7; }
.sp-conn-list li.sp-tip-warn { color: #b45309; }
.sp-conn-list li.sp-tip-muted { opacity: .7; }

/* One device's cables: its lines bold, everything else faded. */
.sp-cables.has-focus .sp-cable.is-faded, .sp-cable-trunk.is-faded { opacity: .12; }
.sp-cables.has-focus .sp-cable.is-focus { opacity: 1; }
.sp-item.is-dimmed, .sp-item-label.is-dimmed { opacity: .28; transition: opacity .15s ease; }
.sp-focus-chip {
  position: absolute; z-index: 6; left: 50%; top: 10px; transform: translateX(-50%); display: flex; align-items: center; gap: 6px;
  max-width: calc(100% - 24px); padding: 4px 4px 4px 12px; border-radius: 999px; font-size: 12.5px;
  background: var(--card-bg, #fff); color: inherit; border: 1px solid rgba(100, 116, 139, .3); box-shadow: 0 6px 18px rgba(15, 23, 42, .15);
}
.sp-focus-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.dark .sp-focus-chip { background: #1e293b; }
/* Into the device (solid, green) or out of it (dashed, orange): the key on the chip matches the lines. */
.sp-dir-key { flex: none; display: inline-flex; align-items: center; gap: 5px; font-weight: 600; white-space: nowrap; }
.sp-dir-key::before { content: ''; width: 18px; height: 0; border-top: 3px solid var(--sp-dir-in, #16a34a); }
.sp-dir-key.is-out::before { border-top: 3px dashed var(--sp-dir-out, #ea580c); }
.sp-dir-key.is-in { color: var(--sp-dir-in, #16a34a); }
.sp-dir-key.is-out { color: var(--sp-dir-out, #ea580c); }
body.dark .sp-dir-key.is-in { --sp-dir-in: #4ade80; }
body.dark .sp-dir-key.is-out { --sp-dir-out: #fb923c; }
@media (max-width: 768px), ((orientation: landscape) and (max-height: 500px) and (pointer: coarse)) {
  .sp-label-list { grid-template-columns: minmax(0, 1fr); }
  .sp-focus-chip { top: 6px; font-size: 12px; }
}

/* Send into another desk: the desk, then which of its inputs. */
.sp-desk-feed label { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.sp-desk-feed-socket { display: inline-flex; align-items: center; gap: 6px; }
.sp-sock-pop .sp-desk-feed label { justify-content: space-between; }

/* A Mixer's panel on the stage: its desk's own sockets. */
.sp-desk-sockets { margin: 12px 0; }
.sp-desk-sockets h4 { margin: 12px 0 6px; font-size: 12px; letter-spacing: .06em; text-transform: uppercase; opacity: .75; }
.sp-desk-sock-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; max-height: 280px; overflow-y: auto; }
.sp-desk-sock {
  display: flex; align-items: baseline; gap: 6px; width: 100%; padding: 5px 8px; border: 0; border-radius: 8px;
  background: transparent; color: inherit; font: inherit; font-size: 12.5px; text-align: left; cursor: pointer;
}
.sp-desk-sock:hover, .sp-desk-sock:focus-visible { background: rgba(59, 130, 246, .08); outline: none; }
.sp-desk-sock-name { flex: none; min-width: 34px; font-weight: 700; }
.sp-desk-sock-now { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-desk-sock.is-used .sp-desk-sock-now { color: var(--sp-ch, #1d4ed8); }
.sp-desk-out { padding: 7px 8px; border-top: 1px solid rgba(100, 116, 139, .15); font-size: 12.5px; }
.sp-desk-out-head { display: flex; align-items: baseline; gap: 6px; margin-bottom: 4px; }
.sp-desk-out-head .sp-desk-sock-now { opacity: .85; }
.sp-desk-out .sp-desk-feed { margin: 0; }
.sp-desk-out .sp-desk-feed select { max-width: 150px; }
body.dark .sp-desk-sock.is-used .sp-desk-sock-now { color: #93c5fd; }
/* In the Mixer's side panel the send controls stack as label | control rows, so nothing wraps oddly. */
.sp-desk-out .sp-desk-feed { display: grid; gap: 4px; }
.sp-desk-out .sp-desk-feed label { display: grid; grid-template-columns: 74px minmax(0, 1fr); align-items: center; gap: 6px; font-weight: 600; }
.sp-desk-out .sp-desk-feed select { max-width: none; width: 100%; min-width: 0; }
.sp-desk-out .sp-desk-feed > .sp-muted { padding-left: 80px; font-weight: 400; }
.sp-desk-out-head strong { flex: none; white-space: nowrap; }

/* Cable colours by type: one colour per kind of run, chosen to stay apart on a light or dark stage
   (and from each other for the common kinds of colour blindness, together with the line styles:
   outputs dashed, wireless dotted). */
#event-stageplot-modal {
  --sp-c-input: #2563eb; --sp-c-iem: #9333ea; --sp-c-wedge: #ea580c; --sp-c-pa: #dc2626;
  --sp-c-desk: #16a34a; --sp-c-lead: #64748b; --sp-c-radio: #0891b2; --sp-c-trunk: #94a3b8; --sp-c-trunk-dot: #475569;
}
body.dark #event-stageplot-modal {
  --sp-c-input: #60a5fa; --sp-c-iem: #c084fc; --sp-c-wedge: #fb923c; --sp-c-pa: #f87171;
  --sp-c-desk: #4ade80; --sp-c-lead: #94a3b8; --sp-c-radio: #22d3ee; --sp-c-trunk: #64748b; --sp-c-trunk-dot: #94a3b8;
}
.sp-cable-halo { fill: none; stroke-linecap: round; stroke-linejoin: round; opacity: .55; pointer-events: none; }
.sp-cables.has-focus .sp-cable-halo.is-faded { opacity: .1; }

/* The key under the stage. */
.sp-cable-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 8px 0 0; font-size: 12px; }
.sp-cable-legend[hidden] { display: none; }
.sp-legend-by { display: inline-flex; align-items: center; gap: 2px; padding: 2px 2px 2px 8px; border-radius: 999px; background: rgba(100, 116, 139, .12); font-weight: 600; }
.sp-legend-by button { border: 0; background: transparent; color: inherit; font: inherit; font-size: 12px; padding: 3px 10px; border-radius: 999px; cursor: pointer; opacity: .75; }
.sp-legend-by button.is-on { background: var(--card-bg, #fff); opacity: 1; box-shadow: 0 1px 2px rgba(15, 23, 42, .15); }
body.dark .sp-legend-by button.is-on { background: #334155; }
.sp-legend-chip { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.sp-legend-chip i { display: inline-block; width: 18px; height: 4px; border-radius: 2px; }
.sp-legend-subset { font-weight: 600; color: var(--primary, #2563eb); }
body.dark .sp-legend-subset { color: #93c5fd; }
.sp-legend-chip i.is-iem, .sp-legend-chip i.is-wedge, .sp-legend-chip i.is-pa { height: 0; border-top: 3px dashed; background: none !important; }
.sp-legend-chip i.is-iem { border-color: var(--sp-c-iem); }
.sp-legend-chip i.is-wedge { border-color: var(--sp-c-wedge); }
.sp-legend-chip i.is-pa { border-color: var(--sp-c-pa); }
.sp-legend-chip i.is-radio { height: 0; border-top: 3px dotted var(--sp-c-radio); background: none !important; }

/* A cable's own colour: the picker shows the chosen colour as a stripe. */
.sp-color-pick { width: auto; max-width: 140px; margin: 4px 0 0; font-size: 12px; border-left: 6px solid var(--sp-pick, transparent) !important; }
.sp-out-cables .sp-color-pick, .sp-chain-cable .sp-color-pick { margin-top: 4px; }

/* Unplugging: the picked cable, the Unplug button, and inputs that are not plugged in. */
.sp-cables .sp-cable.is-picked { opacity: 1; stroke-dasharray: none; filter: drop-shadow(0 0 2px rgba(37, 99, 235, .9)) drop-shadow(0 0 1px rgba(37, 99, 235, .9)); }
.sp-wire-foot .btn.sp-unplug-btn, body .sp-wire-foot .btn.btn-secondary.sp-unplug-btn { margin-right: auto; color: #b91c1c; background: transparent; border: 1px solid rgba(185, 28, 28, .45); box-shadow: none; }
.sp-wire-foot .btn.sp-unplug-btn:hover, body .sp-wire-foot .btn.btn-secondary.sp-unplug-btn:hover { background: rgba(185, 28, 28, .08); }
body.dark .sp-wire-foot .btn.sp-unplug-btn { color: #fca5a5; border-color: rgba(252, 165, 165, .45); }
.sp-conn-list li { display: flex; align-items: center; gap: 6px; }
.sp-conn-list li > span { flex: 1 1 auto; min-width: 0; }
.sp-conn-list .sp-unplug-x { flex: none; }
.sp-table tr.is-unplugged td { opacity: .75; }
.sp-table tr.is-unplugged td:first-child, .sp-table tr.is-unplugged .sp-ch { font-style: italic; }
.sp-unplugged-head { text-align: left; font-weight: 700; }

/* My gear: the church's own devices — first in the palette, saved from a device's panel, kept in
   Venues & inventory. */
.sp-palette-mine h4::after { content: ' ★'; color: #d97706; }
.sp-gear-hint { font-size: 12px; margin: 2px 4px 8px; }
.sp-gear-open { margin-top: 10px; }
.sp-gear-form { margin-top: 10px; padding: 10px 12px; border-radius: 10px; border: 1px solid rgba(37, 99, 235, .3); background: rgba(37, 99, 235, .05); }
.sp-gear-form h4 { margin: 0 0 4px; }
.sp-gear-form .sp-muted { font-size: 12px; margin: 0 0 8px; }
.sp-gear-from { margin: 2px 0 8px; font-size: 13px; }
.sp-gear-from.is-newer { padding: 6px 10px; border-radius: 8px; border: 1px solid rgba(217, 119, 6, .4); background: rgba(245, 158, 11, .1); }
.sp-gear-row-head { display: flex; align-items: center; gap: 10px; }
.sp-gear-row-head svg { width: 40px; height: 32px; flex: none; }
.sp-gear-row .sp-tools span { align-self: center; font-size: 13px; }
body.dark .sp-gear-form { background: rgba(96, 165, 250, .08); border-color: rgba(96, 165, 250, .3); }
@media (max-width: 768px), ((orientation: landscape) and (max-height: 500px) and (pointer: coarse)) {
  .sp-gear-hint { display: none; }
  .sp-gear-row .sp-resource-form { grid-template-columns: minmax(0, 1fr); }
}

/* Where the tidy routes run: back, front, sides or shortest. */
.sp-route-choice { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 6px 0; font-size: 12px; }
.sp-route-choice > span { font-weight: 700; margin-right: 4px; }
.sp-route-choice button { border: 1px solid rgba(22, 163, 74, .4); background: transparent; color: inherit; font: inherit; font-weight: 600; padding: 3px 10px; border-radius: 999px; cursor: pointer; }
.sp-route-choice button.is-on { background: #16a34a; border-color: #16a34a; color: #fff; }

/* The gear list: a small drawing of each device beside its line, and who brings it on every line. */
.sp-gear-icon { flex: 0 0 34px; width: 34px; height: 28px; display: flex; align-items: center; justify-content: center; }
.sp-gear-icon svg { width: 100%; height: 100%; }
.sp-gear-row .sp-gear-who { flex-wrap: wrap; }
@media (max-width: 768px), ((orientation: landscape) and (max-height: 500px) and (pointer: coarse)) {
  .sp-gear-icon { flex-basis: 26px; width: 26px; height: 22px; }
  .sp-gear-row .sp-gear-who select, .sp-gear-row .sp-gear-who input { width: 118px; }
}

/* Wired or wireless for in-ears, the same switch a vocal has. */
.sp-inear-link { margin: 8px 0; }
.sp-inear-link .sp-pop-label { display: block; }
.sp-inear-link .sp-muted { margin: 2px 0 0; font-size: 12px; }
.sp-inear-link .sp-seg button[disabled] { opacity: .45; cursor: not-allowed; }

/* The stage toolbar wraps onto a second row rather than running under the zoom buttons. */
.sp-cable-view { flex-wrap: wrap; max-width: calc(100% - 150px); border-radius: 18px; }
.sp-cable-view button { white-space: nowrap; }

/* Soundcheck: each channel with what the desk needs to know while checking it. */
.sp-sound-count { margin: 4px 0 8px; }
.sp-sound-what { min-width: 260px; }
.sp-sound-what small { display: block; font-size: 12px; line-height: 1.35; margin-top: 2px; }
.sp-sound-what .sp-ch { font-weight: 700; margin-right: 2px; }
.sp-sound-mixes { color: #7c3aed; }
body.dark .sp-sound-mixes { color: #c4b5fd; }
.sp-sound-table tr.is-ready td { background: rgba(22, 163, 74, .06); }
.sp-sound-desk th { text-align: left; font-size: 12px; letter-spacing: .06em; text-transform: uppercase; opacity: .75; padding-top: 12px; }

/* A stereo pair on one Y cable. */
.sp-y-note { display: block; font-size: 11.5px; font-weight: 600; color: #0f766e; margin-bottom: 3px; }
body.dark .sp-y-note { color: #5eead4; }

/* The view switches and the zoom: a bar of their own under the stage drawing, so nothing covers the
   front of the stage however many switches there are or however shallow the stage is. */
.sp-stage-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; }
.sp-stage-bar .sp-cable-view, .sp-stage-bar .sp-zoom { position: static; left: auto; right: auto; bottom: auto; max-width: none; }
.sp-stage-bar .sp-cable-view { flex: 0 1 auto; border-radius: 18px; }
.sp-stage-bar .sp-zoom { flex: none; margin-left: auto; }
/* Lock, Undo and Redo: the same small button group as the zoom. */
.sp-edit-tools {
  display: flex; flex: none; border-radius: 10px; overflow: hidden; box-shadow: 0 2px 8px rgba(15, 23, 42, .15);
  border: 1px solid rgba(100, 116, 139, .25); background: var(--card-bg, #fff);
}
body.dark .sp-edit-tools { background: #1e293b; }
.sp-edit-tools .sp-zoom-btn:disabled { opacity: .35; cursor: default; background: transparent; }
.sp-edit-tools [data-sp-history] { font-size: 20px; font-weight: 600; min-width: 38px; }
.sp-lock-btn { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; padding: 0 12px 0 10px; }
.sp-lock-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.sp-lock-btn.is-locked { background: #f59e0b; color: #1f1300; }
.sp-lock-btn.is-locked:hover { background: #fbbf24; }
.sp-lock-btn.is-nudge { animation: sp-lock-nudge .5s ease 2; }
@keyframes sp-lock-nudge { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }
@media (prefers-reduced-motion: reduce) { .sp-lock-btn.is-nudge { animation: none; outline: 2px solid #f59e0b; } }
/* Locked: things on the stage are pointed at, not picked up. */
.sp-canvas.is-locked .sp-item { cursor: pointer; }
#event-stageplot-modal.fullscreen .sp-stage-bar { flex: none; }

/* The stage picture on a phone: shown first, then shared or saved with a tap of its own. */
.sp-png-sheet {
  position: fixed; inset: 0; z-index: 10050; display: flex; align-items: flex-end; justify-content: center;
  background: rgba(15, 23, 42, .55); padding: 16px; padding-bottom: max(16px, env(safe-area-inset-bottom));
}
.sp-png-card {
  width: 100%; max-width: 560px; max-height: 100%; display: flex; flex-direction: column; gap: 10px;
  background: var(--card-bg, #fff); color: inherit; border-radius: 16px; padding: 14px; box-shadow: 0 10px 30px rgba(15, 23, 42, .3);
}
body.dark .sp-png-card { background: #1e293b; }
.sp-png-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.sp-png-close { border: 0; background: rgba(100, 116, 139, .14); color: inherit; width: 36px; height: 36px; border-radius: 50%; font-size: 15px; cursor: pointer; }
.sp-png-preview { min-height: 0; overflow: auto; border-radius: 10px; border: 1px solid rgba(100, 116, 139, .25); background: #fff; }
.sp-png-preview img { display: block; width: 100%; height: auto; -webkit-touch-callout: default; user-select: auto; }
.sp-png-hint { margin: 0; font-size: 13px; opacity: .75; }
.sp-png-actions { display: flex; gap: 8px; }
.sp-png-actions .btn { flex: 1 1 0; min-height: 44px; }
