/**
 * Stage Plot Designer — front-end styles.
 * Theme-aware (light / dark / auto), responsive, print-friendly.
 *
 * @package StagePlotDesigner
 */

/* ---------- Design tokens ---------- */
.spd-app {
	/* Single source of truth for every accent in the app, app chrome
	   included — set from the admin-editable accent_color setting (see
	   spd-app.js build()). #39E6FF (Electric Cyan) is only the out-of-the-box
	   default value, not a floor: --spd-accent-ink is recomputed there too,
	   so an arbitrary admin-picked color still reads correctly as
	   button/badge ink. */
	--spd-accent: #39E6FF;
	--spd-accent-ink: #050608;
	/* Text-weight variant of --spd-accent: a light accent (the cyan default
	   included) is too pale to use as plain text/stroke/outline color, so
	   this darkens it instead — computed in pure CSS, not JS, so it reacts
	   correctly to the in-app theme toggle (which only swaps CSS classes,
	   see SPDApp.prototype.toggleTheme) and not just to a fresh page load.
	   Dark theme re-points it at the full accent below, since bright colors
	   read great on dark surfaces. */
	--spd-accent-text: color-mix(in srgb, var(--spd-accent) 55%, black);
	/* Hover fill for button-like controls: dark slate grey with white text.
	   The old --spd-panel-2 hover was pale-grey-on-white in light mode and a
	   near-invisible navy-on-navy in dark mode; buttons must stay legible
	   under the cursor in both themes. */
	--spd-hover-bg: #4b5563;
	--spd-hover-ink: #ffffff;
	--spd-bg: #ffffff;
	--spd-panel: #f6f8fb;
	--spd-panel-2: #eef1f6;
	--spd-border: #e2e6ec;
	--spd-ink: #1a1d24;
	--spd-muted: #6b7280;
	--spd-tile: #ffffff;
	--spd-floor: #f3f5f9;
	--spd-floor-edge: #d3d8e0;
	--spd-grid: rgba(0, 0, 0, .07);
	--spd-danger: #e23b3b;
	--spd-ok: #159a55;
	--spd-warn: #d98a00;
	--spd-shadow: 0 6px 24px rgba(20, 24, 40, .12);
	--spd-radius: 10px;
	--spd-workspace-h: min(76vh, 780px);

	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	border: 1px solid var(--spd-border);
	border-radius: var(--spd-radius);
	overflow: hidden;
	background: var(--spd-bg);
	color: var(--spd-ink);
	font: 14px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	position: relative;
	max-width: 100%;
}
.spd-app *, .spd-app *::before, .spd-app *::after { box-sizing: border-box; }
/* Every text input in this app (.spd-search, .spd-input, etc.) has its own
   explicit :focus style, but no <button>-based class ever did — toolbar
   buttons, toggles, tabs, category headers, tiles, swatches, template cards.
   Left alone, a clicked button keeps browser/OS focus (Windows retains focus
   on click, unlike macOS) and renders with WHATEVER the browser's native
   default focus indicator looks like on that machine — which can be a solid,
   strongly-colored fill rather than a thin ring depending on OS accent-color
   and accessibility settings, persists until focus moves elsewhere, and is
   invisible to any background-color rule since it's an outline the page
   never declared. This is the "random dark blue box that won't go away"
   bug reported across toolbar buttons, toggles, and panel tabs — fixed here,
   once, for every button in the app, instead of chasing it class by class. */
.spd-app button { outline: none; }
.spd-app button:focus-visible { outline: 2px solid var(--spd-accent-text); outline-offset: 2px; }

.spd-theme-dark {
	--spd-bg: #0f1218;
	--spd-panel: #161a22;
	--spd-panel-2: #1d222c;
	--spd-border: #2a2f3a;
	--spd-ink: #e8ecf4;
	--spd-muted: #8b93a7;
	--spd-tile: #1b2029;
	--spd-floor: #12151c;
	--spd-floor-edge: #2a2f3a;
	--spd-grid: rgba(255, 255, 255, .07);
	--spd-shadow: 0 8px 30px rgba(0, 0, 0, .5);
	--spd-accent-text: var(--spd-accent);
}
@media (prefers-color-scheme: dark) {
	.spd-theme-auto {
		--spd-bg: #0f1218;
		--spd-panel: #161a22;
		--spd-panel-2: #1d222c;
		--spd-border: #2a2f3a;
		--spd-ink: #e8ecf4;
		--spd-muted: #8b93a7;
		--spd-tile: #1b2029;
		--spd-floor: #12151c;
		--spd-floor-edge: #2a2f3a;
		--spd-grid: rgba(255, 255, 255, .07);
		--spd-shadow: 0 8px 30px rgba(0, 0, 0, .5);
		--spd-accent-text: var(--spd-accent);
	}
}

/* ---------- Boot ---------- */
.spd-booting { min-height: 320px; }
.spd-boot { display: flex; gap: 10px; align-items: center; justify-content: center; padding: 60px; color: var(--spd-muted); }
.spd-boot-spinner { width: 18px; height: 18px; border: 2px solid var(--spd-border); border-top-color: var(--spd-accent-text); border-radius: 50%; animation: spd-spin .8s linear infinite; }
@keyframes spd-spin { to { transform: rotate(360deg); } }

/* ---------- Toolbar ---------- */
.spd-toolbar {
	display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
	padding: 8px 10px; background: var(--spd-panel);
	border-bottom: 1px solid var(--spd-border);
}
.spd-brand { display: flex; align-items: center; gap: 6px; font-weight: 700; padding-right: 6px; }
.spd-brand-mark { color: var(--spd-accent-text); font-size: 16px; }
.spd-brand-name { font-size: 13px; letter-spacing: .2px; }
.spd-brand-logo { max-height: 30px; max-width: 160px; display: block; }

/* Branded header / footer */
.spd-brandbar { padding: 14px 16px 4px; }
.spd-brand-heading { margin: 0 0 4px; font-size: 20px; font-weight: 700; color: var(--spd-ink); }
.spd-brand-intro { color: var(--spd-muted); font-size: 14px; }
.spd-brand-intro p { margin: 0 0 6px; }
.spd-brandfoot { padding: 10px 16px 14px; color: var(--spd-muted); font-size: 13px; border-top: 1px solid var(--spd-border); }
.spd-brandfoot p { margin: 0; }
img.spd-tile-ic { object-fit: contain; }
.spd-tgroup { display: flex; align-items: center; gap: 4px; padding: 2px; background: var(--spd-bg); border: 1px solid var(--spd-border); border-radius: 8px; }
.spd-tspacer { flex: 1 1 auto; }
.spd-tgroup-primary { background: transparent; border: none; gap: 6px; }

.spd-btn {
	appearance: none; cursor: pointer; font: inherit; font-size: 13px;
	display: inline-flex; align-items: center; gap: 5px;
	padding: 6px 10px; border-radius: 7px; border: 1px solid transparent;
	background: transparent; color: var(--spd-ink); line-height: 1;
	/* No transition on background/background-color: animating it left an
	   opening for Chromium/Edge to interrupt an in-flight background
	   transition with a second one (e.g. an is-on -> off toggle immediately
	   followed by a hover exit) and occasionally leave the button's paint
	   stuck on an intermediate color instead of resolving to the final one.
	   Color changes are instant instead of a 120ms fade; border/transform
	   still animate since neither showed the stuck-paint symptom. */
	transition: border-color .12s, transform .04s;
}
.spd-btn:hover { background: var(--spd-hover-bg); color: var(--spd-hover-ink); }
.spd-btn:active { transform: translateY(1px); }
.spd-btn:disabled { opacity: .4; cursor: default; }
/* Disabled buttons give no hover feedback (the dark hover fill on a dead
   control reads as clickable). Primary keeps its accent fill so a disabled
   Save/Send doesn't blank out mid-action. */
.spd-btn:disabled:hover { background: transparent; color: var(--spd-ink); }
.spd-tgroup-primary .spd-btn:disabled:hover { background: var(--spd-bg); color: var(--spd-ink); }
.spd-btn.spd-primary:disabled:hover { background: var(--spd-accent); color: var(--spd-accent-ink); filter: none; }
.spd-btn.spd-icon { padding: 6px 9px; font-size: 15px; }
.spd-tgroup-primary .spd-btn { border: 1px solid var(--spd-border); background: var(--spd-bg); }
.spd-tgroup-primary .spd-btn:hover { background: var(--spd-hover-bg); color: var(--spd-hover-ink); }
.spd-btn.spd-primary { background: var(--spd-accent); color: var(--spd-accent-ink); border-color: var(--spd-accent); }
.spd-btn.spd-primary:hover { filter: brightness(1.06); background: var(--spd-accent); color: var(--spd-accent-ink); }
/* Toggles share the dark-grey hover when off; when on they stay on the
   accent fill so hovering never masks the on/off state. (Safe to color the
   off-hover again: the "stuck navy" paint bug came from interrupted
   background *transitions*, and .spd-btn no longer animates background —
   color changes are instant.) */
.spd-toggle:hover { background: var(--spd-hover-bg); color: var(--spd-hover-ink); }
.spd-toggle.is-on { background: var(--spd-accent); color: var(--spd-accent-ink); }
.spd-toggle.is-on:hover { background: var(--spd-accent); color: var(--spd-accent-ink); }
.spd-zoom-label { font-size: 12px; color: var(--spd-muted); min-width: 40px; text-align: center; }

/* ---------- Body layout ----------
   The workspace fills the whole body; the palette and panels float above it
   as movable windows, so the stage canvas is always as large as possible. */
.spd-body { display: flex; position: relative; height: var(--spd-workspace-h); min-height: 420px; overflow: hidden; }
.spd-workspace { flex: 1 1 auto; position: relative; overflow: hidden; background:
		radial-gradient(circle at 1px 1px, var(--spd-grid) 1px, transparent 0) 0 0 / 22px 22px, var(--spd-bg); }
.spd-palette, .spd-inspector, .spd-punchlist { background: var(--spd-panel); display: flex; flex-direction: column; overflow: hidden; min-height: 0; flex: 1 1 auto; }
.spd-punchlist { overflow-y: auto; }
.spd-hidden { display: none !important; }

/* ---------- Floating tool windows ---------- */
.spd-window {
	position: absolute; z-index: 30; display: flex; flex-direction: column; overflow: hidden;
	min-width: 220px; min-height: 44px; max-width: calc(100% - 8px); max-height: calc(100% - 8px);
	background: var(--spd-panel); border: 1px solid var(--spd-border); border-radius: 10px;
	box-shadow: 0 10px 34px rgba(0, 0, 0, .22);
}
.spd-window.is-front { z-index: 40; }
.spd-win-head {
	display: flex; align-items: center; gap: 4px; padding: 6px 6px 6px 12px; flex: 0 0 auto;
	background: var(--spd-panel-2); border-bottom: 1px solid var(--spd-border);
	cursor: grab; user-select: none; touch-action: none;
}
.spd-win-head:active { cursor: grabbing; }
.spd-win-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .6px; color: var(--spd-muted); margin-right: auto; }
.spd-window.is-min { height: auto !important; min-height: 0; }
.spd-window.is-min .spd-win-body, .spd-window.is-min .spd-win-resize { display: none; }
.spd-win-resize {
	position: absolute; right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; touch-action: none;
	background: linear-gradient(135deg, transparent 50%, var(--spd-border) 50%);
	border-bottom-right-radius: 9px;
}

/* ---------- Maximize: fill the whole browser window ---------- */
.spd-app.spd-max {
	position: fixed; inset: 0; z-index: 999990; margin: 0; border-radius: 0; border: none;
	display: flex; flex-direction: column; height: 100vh; height: 100dvh; width: 100%;
}
.spd-app.spd-max .spd-body { flex: 1 1 auto; height: auto; min-height: 0; }
.spd-app.spd-max .spd-brandbar, .spd-app.spd-max .spd-brandfoot { display: none; }
body.spd-noscroll { overflow: hidden !important; }

/* ---------- Input-list drag interactions ---------- */
.spd-cgrip { width: 18px; padding: 0 2px; }
.spd-row-grip { cursor: grab; color: var(--spd-muted); font-size: 13px; touch-action: none; user-select: none; display: inline-block; padding: 2px 3px; }
.spd-row-grip:active { cursor: grabbing; }
tr.spd-row-dragging { opacity: .55; outline: 1.5px dashed var(--spd-accent-text); }
tr.spd-drop-target > td { background: color-mix(in srgb, var(--spd-accent) 18%, transparent); }
tr.spd-drop-target .spd-cell-input { background-color: transparent; }

/* ---------- Palette ---------- */
.spd-palette-head { padding: 10px; border-bottom: 1px solid var(--spd-border); }
.spd-palette-head h3 { margin: 0 0 8px; font-size: 13px; text-transform: uppercase; letter-spacing: .6px; color: var(--spd-muted); }
.spd-search { width: 100%; padding: 8px 10px; border: 1px solid var(--spd-border); border-radius: 8px; background: var(--spd-bg); color: var(--spd-ink); font: inherit; font-size: 13px; }
.spd-search:focus { outline: 2px solid var(--spd-accent-text); outline-offset: -1px; }
.spd-lib-row { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.spd-lib-label { font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--spd-muted); white-space: nowrap; }
.spd-lib-select { flex: 1; min-width: 0; padding: 6px 8px; border: 1px solid var(--spd-border); border-radius: 8px; background: var(--spd-bg); color: var(--spd-ink); font: inherit; font-size: 13px; }
.spd-lib-select:focus { outline: 2px solid var(--spd-accent-text); outline-offset: -1px; }
.spd-cats { overflow-y: auto; padding: 6px; flex: 1; }
.spd-cat { margin-bottom: 4px; }
.spd-cat-head { width: 100%; display: flex; align-items: center; gap: 6px; padding: 8px 8px; background: transparent; border: none; color: var(--spd-ink); font: inherit; font-weight: 600; font-size: 13px; cursor: pointer; border-radius: 6px; }
.spd-cat-head:hover { background: var(--spd-hover-bg); color: var(--spd-hover-ink); }
.spd-cat-head:hover .spd-cat-caret { color: var(--spd-hover-ink); }
.spd-cat-head:hover .spd-cat-count { color: var(--spd-hover-ink); background: rgba(255, 255, 255, .16); }
.spd-cat-caret { transition: transform .15s; color: var(--spd-muted); font-size: 11px; }
.spd-cat.is-open .spd-cat-caret { transform: rotate(90deg); }
.spd-cat-count { margin-left: auto; font-size: 11px; color: var(--spd-muted); background: var(--spd-panel-2); padding: 1px 7px; border-radius: 10px; }
.spd-cat-grid { display: none; grid-template-columns: repeat(2, 1fr); gap: 6px; padding: 4px 2px 8px; }
.spd-cat.is-open .spd-cat-grid { display: grid; }
.spd-tile { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 9px 6px; background: var(--spd-tile); border: 1px solid var(--spd-border); border-radius: 9px; cursor: grab; color: var(--spd-ink); font: inherit; transition: border-color .12s, transform .06s, box-shadow .12s; }
.spd-tile:hover { border-color: var(--spd-accent-text); box-shadow: 0 2px 10px rgba(0, 0, 0, .08); }
.spd-tile:active { cursor: grabbing; transform: scale(.97); }
.spd-tile-ic { width: 40px; height: 34px; color: var(--spd-ink); }
.spd-tile-name { font-size: 11px; text-align: center; line-height: 1.15; color: var(--spd-muted); }

/* ---------- Stage (SVG) ----------
   The SVG fills the workspace edge-to-edge; a camera group inside it handles
   pan/zoom, so the stage is the full width of the app space. */
.spd-stage-wrap { position: absolute; inset: 0; overflow: hidden; }
/* Inline embeds keep vertical page scroll (touch-action: pan-y); two-finger
   pinch is still handled in JS. Maximized takes full gesture control. */
.spd-stage { display: block; width: 100%; height: 100%; touch-action: pan-y; user-select: none; -webkit-touch-callout: none; }
.spd-app.spd-max .spd-stage { touch-action: none; }
.spd-stage-wrap.is-pan { cursor: grab; }
.spd-stage-wrap.is-grabbing { cursor: grabbing; }
.spd-stage-wrap.is-placing { cursor: copy; }
/* A click-drag move in progress: keep the "move" cursor for the whole
   gesture even once the pointer strays past the shape being dragged
   (drag tracking is window-level, not element-hover). */
.spd-stage-wrap.is-moving { cursor: move; }

/* Right-click / long-press context menu */
.spd-ctxmenu {
	z-index: 999995; min-width: 168px; padding: 5px; display: flex; flex-direction: column;
	background: var(--spd-panel); border: 1px solid var(--spd-border); border-radius: 10px;
	box-shadow: 0 12px 34px rgba(0, 0, 0, .26); font: inherit;
}
.spd-ctx-item {
	display: block; width: 100%; text-align: left; padding: 8px 12px; border: none; border-radius: 6px;
	background: transparent; color: var(--spd-ink); font: inherit; font-size: 13px; cursor: pointer; white-space: nowrap;
}
.spd-ctx-item:hover, .spd-ctx-item:focus { background: var(--spd-accent); color: var(--spd-accent-ink); outline: none; }
.spd-ctx-danger { color: #d63638; }
.spd-ctx-danger:hover, .spd-ctx-danger:focus { background: #d63638; color: #fff; }
.spd-floor { fill: var(--spd-floor); stroke: var(--spd-floor-edge); stroke-width: 2; }
.spd-grid-line { stroke: var(--spd-grid); stroke-width: 1; fill: none; }
.spd-edge-label { fill: var(--spd-muted); font: 700 12px system-ui, sans-serif; letter-spacing: 1.5px; }
/* Stage Left / Stage Right run vertically along the side edges (rotated via
   SVG transform in JS, same camera-transformed decor group as the
   downstage/upstage labels above). Same font/color treatment, slightly
   tighter tracking since the "(performer's ..., facing audience)" clarifier
   text is longer than the front/back labels. */
.spd-edge-label-side { letter-spacing: 1px; }
.spd-dim-label { fill: var(--spd-muted); font: 600 12px system-ui, sans-serif; }

.spd-el { color: var(--spd-ink); cursor: move; }
.spd-el.is-locked { cursor: default; opacity: .92; }
/* Ghost feedback while a symbol is being click-dragged. */
.spd-el.is-dragging { opacity: .8; }
/* font-size intentionally omitted: each label sets its own via the SVG
   font-size attribute (see SPDApp.prototype.labelFontSize) so the Stage
   Settings "Label size" dynamic/static control can control it per element;
   a size here would win over that attribute and defeat both modes. */
.spd-el-label { fill: var(--spd-ink); font-weight: 600; font-family: system-ui, sans-serif; paint-order: stroke; stroke: var(--spd-bg); stroke-width: 3px; stroke-linejoin: round; pointer-events: none; }
.spd-el-text { fill: var(--spd-ink); font-weight: 700; font-family: system-ui, sans-serif; }
.spd-el-center { fill: var(--spd-ink); font-weight: 800; font-family: system-ui, sans-serif; pointer-events: none; }
.spd-ch-badge { fill: var(--spd-accent); stroke: var(--spd-bg); stroke-width: 1.5; cursor: move; }
/* font-size intentionally omitted (see .spd-el-label above): each badge sets
   its own via the SVG font-size attribute (SPDApp.prototype.badgeRadius) so
   it scales with the element it's attached to instead of staying fixed. */
.spd-ch-badge-t { fill: var(--spd-accent-ink); font-weight: 700; font-family: system-ui, sans-serif; pointer-events: none; }
.spd-edge-label, .spd-edge-label-side, .spd-dim-label { pointer-events: none; }

/* Icon paint classes (used by symbols) */
.spd-ic-fill { fill: currentColor; }
.spd-ic-stroke { fill: none; stroke: currentColor; stroke-width: 4; stroke-linejoin: round; stroke-linecap: round; }
.spd-ic-line { fill: none; stroke: currentColor; stroke-width: 3; }
.spd-ic-bg { fill: var(--spd-floor); }
.spd-ic-accent { fill: var(--spd-accent-text); }
.spd-ic-hole { fill: var(--spd-floor); }

/* Selection + handles. These sit on --spd-floor, which is light in the
   light/auto theme — raw --spd-accent (bright cyan) is nearly invisible
   there, so these use --spd-accent-text, same as the text-on-light-surface
   cases above (resolves to a darker brand teal in light theme, full accent
   in dark theme). */
.spd-sel { fill: none; stroke: var(--spd-accent-text); stroke-width: 1.5; stroke-dasharray: 5 4; vector-effect: non-scaling-stroke; }
/* Solid (vs. dashed) outline distinguishes "actively being moved" from
   plain selection, using the same theme-aware accent color either way. */
.spd-sel.is-dragging { stroke-dasharray: none; stroke-width: 2; }
.spd-handle { fill: var(--spd-bg); stroke: var(--spd-accent-text); stroke-width: 1.5; cursor: nwse-resize; vector-effect: non-scaling-stroke; }
.spd-rot-handle { fill: var(--spd-accent-text); stroke: var(--spd-bg); stroke-width: 1.5; cursor: grab; }
.spd-rot-line { stroke: var(--spd-accent-text); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.spd-marquee { fill: rgba(57, 230, 255, .12); stroke: var(--spd-accent-text); stroke-width: 1; stroke-dasharray: 4 3; vector-effect: non-scaling-stroke; }

/* ---------- Inspector ---------- */
.spd-tabs { display: flex; border-bottom: 1px solid var(--spd-border); background: var(--spd-panel); overflow-x: auto; }
.spd-tab { flex: 1; padding: 10px 6px; background: transparent; border: none; border-bottom: 2px solid transparent; color: var(--spd-muted); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.spd-tab:hover { color: var(--spd-ink); }
.spd-tab.is-active { color: var(--spd-accent-text); border-bottom-color: var(--spd-accent-text); }
.spd-panels { overflow-y: auto; flex: 1; }
.spd-panel { padding: 12px; }
.spd-panel-wide { padding: 10px; }
.spd-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.spd-panel-head strong { font-size: 13px; }
.spd-muted { color: var(--spd-muted); }

.spd-field { display: block; margin-bottom: 10px; }
.spd-field-label { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--spd-muted); margin-bottom: 4px; }
.spd-input { width: 100%; padding: 7px 9px; border: 1px solid var(--spd-border); border-radius: 7px; background: var(--spd-bg); color: var(--spd-ink); font: inherit; font-size: 13px; }
.spd-input:focus { outline: 2px solid var(--spd-accent-text); outline-offset: -1px; }

/* ---------- Select chevron ----------
   .spd-input / .spd-lib-select / .spd-cell-input are shared with plain
   text/number <input> fields, so a bare <select> using them has no visual
   cue it opens a list. Reset native appearance and draw one small themed
   down-arrow (currentColor -> --spd-ink) so it reads as a dropdown in both
   light and dark themes. One rule covers every <select> in the app. */
select.spd-input, select.spd-lib-select, select.spd-cell-input {
	appearance: none; -webkit-appearance: none; -moz-appearance: none;
	padding-right: 26px;
	background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
	background-position: right 13px top 55%, right 8px top 55%;
	background-size: 5px 5px, 5px 5px;
	background-repeat: no-repeat;
}
.spd-textarea { resize: vertical; min-height: 60px; }
.spd-row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }

.spd-color-row { display: flex; flex-wrap: wrap; gap: 6px; }
.spd-swatch { width: 24px; height: 24px; border-radius: 6px; border: 2px solid var(--spd-border); cursor: pointer; padding: 0; }
.spd-swatch.is-on { border-color: var(--spd-accent-text); box-shadow: 0 0 0 2px var(--spd-accent-text); }
.spd-swatch-auto { background: var(--spd-panel-2); color: var(--spd-muted); font-size: 11px; font-weight: 700; }

.spd-prop-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.spd-mini { padding: 6px 9px; font-size: 12px; border: 1px solid var(--spd-border); border-radius: 6px; background: var(--spd-bg); }
.spd-mini:hover { background: var(--spd-hover-bg); color: var(--spd-hover-ink); }
.spd-mini.is-on { background: var(--spd-accent); color: var(--spd-accent-ink); }
.spd-mini.is-on:hover { background: var(--spd-accent); color: var(--spd-accent-ink); }
.spd-danger { color: var(--spd-danger); border-color: color-mix(in srgb, var(--spd-danger) 40%, var(--spd-border)); }
/* Destructive minis (Delete / Remove) hover red, matching the context menu's
   danger item, instead of the neutral grey. */
.spd-mini.spd-danger:hover { background: var(--spd-danger); color: #fff; border-color: var(--spd-danger); }
.spd-hint { color: var(--spd-muted); font-size: 12.5px; line-height: 1.5; padding: 10px; background: var(--spd-panel-2); border-radius: 8px; }

/* ---------- Tables ---------- */
.spd-itable { width: 100%; border-collapse: collapse; font-size: 12px; }
.spd-itable th { text-align: left; padding: 6px 5px; color: var(--spd-muted); font-weight: 600; border-bottom: 1px solid var(--spd-border); font-size: 11px; text-transform: uppercase; letter-spacing: .4px; position: sticky; top: 0; background: var(--spd-panel); }
.spd-itable td { padding: 2px 3px; border-bottom: 1px solid var(--spd-border); vertical-align: middle; }
.spd-ch { text-align: center; color: var(--spd-muted); font-weight: 700; width: 26px; }
.spd-c48 { text-align: center; width: 34px; }
.spd-crm { width: 26px; }
.spd-cell-input { width: 100%; padding: 5px 6px; border: 1px solid transparent; border-radius: 5px; background: transparent; color: var(--spd-ink); font: inherit; font-size: 12px; }
.spd-cell-input:hover { border-color: var(--spd-border); }
.spd-cell-input:focus { outline: none; border-color: var(--spd-accent-text); background-color: var(--spd-bg); }

/* ---------- Punch List ---------- */
.spd-punch-summary { display: flex; justify-content: space-between; gap: 10px; padding: 8px 10px; margin-bottom: 10px; background: var(--spd-panel-2); border-radius: 8px; font-size: 12.5px; color: var(--spd-muted); font-weight: 600; }
.spd-punch-group { margin-bottom: 14px; }
.spd-punch-group:last-of-type { margin-bottom: 4px; }
.spd-punch-cat { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--spd-muted); padding: 4px 2px; border-bottom: 1px solid var(--spd-border); margin-bottom: 2px; }
.spd-punch-list { list-style: none; margin: 0; padding: 0; }
.spd-punch-list li { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 5px 2px; border-bottom: 1px solid var(--spd-border); font-size: 12.5px; }
.spd-punch-list li:last-child { border-bottom: none; }
.spd-punch-name { color: var(--spd-ink); }
.spd-punch-count { flex: 0 0 auto; min-width: 20px; text-align: center; font-size: 11px; font-weight: 700; color: var(--spd-muted); background: var(--spd-panel-2); padding: 1px 8px; border-radius: 10px; }
.spd-punch-total { display: flex; justify-content: space-between; align-items: center; padding: 10px 8px 4px; margin-top: 4px; border-top: 2px solid var(--spd-border); font-size: 13px; font-weight: 700; color: var(--spd-ink); }

/* ---------- Toast ---------- */
.spd-toast { position: absolute; left: 50%; bottom: 16px; transform: translate(-50%, 20px); opacity: 0; pointer-events: none; padding: 9px 16px; border-radius: 8px; background: var(--spd-ink); color: var(--spd-bg); font-size: 13px; box-shadow: var(--spd-shadow); transition: opacity .2s, transform .2s; z-index: 40; max-width: 80%; }
.spd-toast.is-show { opacity: 1; transform: translate(-50%, 0); }
.spd-toast-ok { background: var(--spd-ok); color: #fff; }
.spd-toast-warn { background: var(--spd-warn); color: #fff; }
.spd-toast-error { background: var(--spd-danger); color: #fff; }

/* ---------- Modal ---------- */
.spd-modal-back { position: absolute; inset: 0; background: rgba(10, 12, 18, .55); display: flex; align-items: center; justify-content: center; z-index: 50; padding: 16px; }
.spd-modal { width: min(560px, 96%); max-height: 88%; overflow: auto; background: var(--spd-bg); border: 1px solid var(--spd-border); border-radius: 12px; box-shadow: var(--spd-shadow); }
.spd-modal-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 1px solid var(--spd-border); }
.spd-modal-body { padding: 16px; }
.spd-modal-actions { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--spd-border); }
.spd-form .spd-field { margin-bottom: 12px; }

.spd-template-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.spd-template-card { display: flex; flex-direction: column; gap: 4px; padding: 14px; border: 1px solid var(--spd-border); border-radius: 10px; background: var(--spd-panel); cursor: pointer; text-align: left; color: var(--spd-ink); font: inherit; }
.spd-template-card:hover { border-color: var(--spd-accent-text); }
.spd-template-card span { font-size: 11px; color: var(--spd-muted); }

.spd-login-gate { padding: 20px; text-align: center; border: 1px dashed var(--spd-border, #ccc); border-radius: 10px; }

.spd-share-row { display: flex; gap: 8px; margin-top: 10px; }
.spd-share-row .spd-input { flex: 1; }
.spd-plot-list { display: flex; flex-direction: column; gap: 6px; }
.spd-plot-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 12px; border: 1px solid var(--spd-border); border-radius: 8px; }
.spd-plot-meta { display: flex; flex-direction: column; }
.spd-plot-meta span { font-size: 11px; color: var(--spd-muted); }
.spd-plot-acts { display: flex; gap: 6px; }

/* ---------- User guide (Help window) ---------- */
.spd-help { display: flex; flex-direction: row; overflow: hidden; min-height: 0; flex: 1 1 auto; background: var(--spd-panel); }
.spd-help-index { flex: 0 0 168px; overflow-y: auto; padding: 8px; background: var(--spd-panel-2); border-right: 1px solid var(--spd-border); }
.spd-help-idx-btn { display: block; width: 100%; text-align: left; padding: 7px 9px; margin-bottom: 2px; border: none; border-radius: 6px; background: transparent; color: var(--spd-ink); font: inherit; font-size: 12px; line-height: 1.3; cursor: pointer; }
.spd-help-idx-btn:hover { background: var(--spd-hover-bg); color: var(--spd-hover-ink); }
.spd-help-idx-btn.is-active { background: var(--spd-accent); color: var(--spd-accent-ink); }
.spd-help-content { flex: 1 1 auto; overflow-y: auto; padding: 14px 18px; position: relative; }
.spd-help-sec { margin-bottom: 22px; }
.spd-help-sec:last-child { margin-bottom: 2px; }
.spd-help-h { margin: 0 0 6px; font-size: 14px; color: var(--spd-ink); }
.spd-help-body { font-size: 12.5px; color: var(--spd-muted); line-height: 1.55; }
.spd-help-body p { margin: 0 0 8px; }
.spd-help-body ul { margin: 0 0 8px; padding-left: 18px; }
.spd-help-body li { margin-bottom: 4px; }
.spd-help-body strong { color: var(--spd-ink); }

/* ---------- Read-only ---------- */
.spd-readonly .spd-palette, .spd-readonly .spd-tgroup-primary .spd-primary { display: none; }

/* ---------- Responsive ---------- */
@media (max-width: 820px) {
	/* Stacked layout: windows stop floating and flow under the stage. */
	.spd-body { flex-direction: column; height: auto; overflow: visible; }
	.spd-workspace { height: 58vh; min-height: 360px; flex: 0 0 auto; order: 0; }
	.spd-window {
		position: relative !important; left: 0 !important; top: 0 !important;
		width: 100% !important; height: auto !important; max-width: none; max-height: none;
		border-radius: 0; border-left: none; border-right: none; box-shadow: none; order: 1;
	}
	.spd-window .spd-win-head { cursor: default; }
	.spd-win-resize { display: none; }
	.spd-window .spd-palette { max-height: 200px; }
	.spd-window .spd-inspector { max-height: 340px; }
	.spd-window .spd-help { max-height: 340px; flex-direction: column; }
	.spd-window .spd-punchlist { max-height: 340px; }
	.spd-help-index { flex: 0 0 auto; max-height: 96px; border-right: none; border-bottom: 1px solid var(--spd-border); display: flex; flex-wrap: wrap; gap: 2px; }
	.spd-help-idx-btn { width: auto; flex: 0 0 auto; }
	.spd-cat-grid { grid-template-columns: repeat(4, 1fr); }
	.spd-app.spd-max .spd-body { overflow: auto; }
	.spd-app.spd-max .spd-workspace { height: 52vh; height: 52dvh; }
}
@media (max-width: 520px) {
	.spd-brand-name { display: none; }
	.spd-cat-grid { grid-template-columns: repeat(3, 1fr); }
	.spd-toolbar { gap: 6px; padding: 6px; }
}

/* ---------- Print ---------- */
@media print {
	.spd-toolbar, .spd-window, .spd-toast, .spd-modal-host { display: none !important; }
	.spd-app { border: none; }
	.spd-body { height: auto; }
}
