/**
 * editor.css — floor-plan editor page only. Loaded after the shared
 * files (tokens/base/layout/controls/navigation/floor-plan/status/
 * overlays), so .editor-tool-btn/.editor-btn-inline get their font,
 * padding-shape, and border from controls.css's shared button family —
 * this file only adds what's genuinely editor-specific on top of that.
 */

body.editor-page {
  padding: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* [hidden] override needed here too, same reason as .editor-body[hidden]
   below — .editor-app's own `display: flex` ties with the UA stylesheet's
   `[hidden] { display: none }` at equal specificity, and this is the
   element the passcode gate (see js/editor/passcode-gate.js) hides by
   default until unlocked. */
.editor-app {
  padding: var(--space-4) var(--space-4) var(--space-3);
  flex: 1;
  width: 100%;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.editor-app[hidden] { display: none; }

/* ── Passcode gate ──
   A plain centered card, not a dismissible .overlay popup — there's no
   dimmed content behind it to see through (the real editor is [hidden],
   not just visually covered), so it's laid out as ordinary in-flow content
   filling the space .editor-app would otherwise occupy. */
.editor-lock {
  flex: 1;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
}
.editor-lock[hidden] { display: none; }

.editor-lock-card {
  width: 100%;
  max-width: 360px;
  padding: var(--space-6);
}

.editor-lock-card h1 {
  margin-bottom: var(--space-2);
}

.editor-lock-body {
  color: var(--text-muted);
  font-size: var(--text-body);
  line-height: 1.55;
  margin-bottom: var(--space-4);
}

.editor-lock-card .editor-field {
  margin-bottom: var(--space-3);
}

/* The one field on this card — sized up well past the ordinary
   .editor-field input baseline (13px/8+12px padding, sized for a compact
   sidebar form field) since this is the single, full-width, easy-to-misread
   thing standing between someone and the whole editor. #id-level specificity
   is deliberate here, not just convenience: .editor-field's own
   input[type="password"] rule is declared later in this file, so a class-only
   override at the same specificity would lose that cascade tie depending on
   source order — an ID sidesteps that instead of relying on rule ordering. */
#editor-lock-input {
  font-size: var(--text-section-title);
  padding: var(--space-3) var(--space-4);
  width: 100%;
  letter-spacing: 0.08em;
}

.editor-lock-card .editor-status {
  margin-bottom: var(--space-3);
}
.editor-lock-card .editor-status:empty {
  margin-bottom: 0;
}

.editor-lock-card .btn-primary {
  width: 100%;
  padding: var(--space-2) var(--space-4);
}

.editor-header {
  margin-bottom: var(--space-4);
}

.editor-connect {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-2);
  flex-wrap: wrap;
}

.editor-connect-status {
  font-family: var(--font-mono);
  font-size: var(--text-meta);
  color: var(--text-muted);
}

/* ── Trace Walls from Photo (New Room's "Trace from Photo" option) ──
   The canvas itself is sized to the loaded photo's natural resolution (see
   js/photo-trace.js), same as admin/trace.html — CSS here only scales the
   *displayed* size down to fit the popup, never the coordinate space a
   click is read in. */
.trace-photo-canvas-wrap {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  background: #000;
  overflow: auto;
  max-height: 50vh;
  margin: var(--space-3) 0;
}

#trace-photo-canvas {
  display: block;
  max-width: 100%;
  height: auto;
  cursor: crosshair;
}

#trace-photo-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  margin: 0;
  pointer-events: none;
}

/* ── Body: canvas + sidebar ──
   Reuses room.html's own .workstation/.floor-pane/.inspector-panel classes
   (see workstation.css) so the editor is structurally the same app — canvas
   on the left (majority width), a docked sidebar of labelled
   .sidebar-section groups on the right — rather than a separate one-box-
   per-panel layout of its own.

   [hidden] needs an explicit override here — a same-specificity author
   rule declaring `display` (.workstation's own `display: flex`) beats the
   UA stylesheet's own `[hidden] { display: none }` on a cascade tie, so
   without this the editor body/footer show up before a project folder is
   even connected. Same recurring pattern flagged and fixed repeatedly
   elsewhere in this app (room.js's sidebar sections, menu.js's site-toggle
   target) — this is one more instance of it, on editor.html specifically. */
.editor-body[hidden] { display: none; }

.editor-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-bottom: var(--space-2);
  font-size: var(--text-body);
}

.editor-field > span {
  font-size: var(--text-meta);
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.editor-field input[type="text"],
.editor-field input[type="number"],
.editor-field input[type="password"],
.editor-field select,
.editor-field textarea {
  font-family: var(--font-body);
  font-size: var(--text-body);
  background: var(--surface-muted);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-control);
  color: var(--text);
  padding: var(--space-2) var(--space-3);
}

.editor-field textarea {
  font-family: var(--font-mono);
  font-size: var(--text-meta);
  resize: vertical;
}

.editor-field input:focus,
.editor-field select:focus,
.editor-field textarea:focus {
  outline: none;
  border-color: var(--focus);
  background: var(--bg);
}

.editor-field-inline {
  flex-direction: row;
  align-items: center;
  gap: var(--space-2);
}

.editor-field-inline input[type="number"] {
  width: 72px;
}

.editor-field-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.editor-field-row input {
  width: 80px;
}

.editor-assetid-row {
  display: flex;
  gap: 6px;
}

.editor-assetid-row input {
  flex: 1;
  min-width: 0;
}

/* .editor-btn-inline's font/color/border/radius come from controls.css's
   shared button family — only its compact sizing is specific to it. */
.editor-btn-inline {
  flex: 0 0 auto;
  font-size: var(--text-meta);
  padding: 0 var(--space-2);
}
.editor-btn-inline:hover {
  background: var(--focus);
  border-color: var(--focus);
  color: var(--surface);
}

/* Advisory, non-blocking — reuses the existing "minor issue" status color
   rather than introducing a new accent; nothing here prevents saving. */
.editor-field-warning {
  font-size: var(--text-meta);
  color: var(--status-minor-strong);
  margin-top: var(--space-1);
}

/* ── Room status (draft/final badge only — Mark as Final/Unlock Layout
   themselves now live in the footer, see .editor-footer-status-actions) ── */
.editor-room-status {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
  flex-wrap: wrap;
}

.editor-locked-notice {
  color: var(--status-minor-strong);
  margin-top: 0;
}

.editor-tool-group {
  margin-bottom: var(--space-2);
}

.editor-tool-group-label {
  display: block;
  font-size: var(--text-meta);
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: var(--space-2);
}

/* A fixed 3-column grid rather than flex-wrap: a long label ("network
   gear", "peripheral") no longer forces its button to claim most of a row
   on its own — every cell is the same size regardless of label length. */
.editor-tool-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}

/* .editor-tool-btn's font/color/border/radius come from controls.css's
   shared button family — a compact palette of many small buttons is the
   one deliberate exception sized at the metadata tier, not the body tier.
   Icon-over-label rather than a plain text row, so the same button reads
   at a glance in a third of the width a full-word row needed; the label
   truncates instead of wrapping or overflowing its grid cell. */
.editor-tool-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  font-size: var(--text-meta);
  padding: var(--space-1);
  width: 100%;
  min-width: 0;
}

.editor-tool-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.editor-tool-label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.editor-tool-btn.armed {
  background: var(--focus);
  border-color: var(--focus);
  color: var(--surface);
}

.editor-hint {
  font-size: var(--text-meta);
  color: var(--text-muted);
  line-height: 1.5;
  margin: var(--space-3) 0;
}

.editor-shape-type {
  font-family: var(--font-mono);
  font-size: var(--text-meta);
  color: var(--text);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: var(--space-3);
}

#btn-delete-selected {
  width: 100%;
  margin-top: var(--space-2);
}

/* ── Canvas — an ordinary docked surface, no shadow. .floor-pane (see
   workstation.css, applied alongside this class in editor.html) supplies
   flex:1/min-width:0/position:relative; this is just the visual "dock". ── */
.editor-canvas-wrap {
  background: var(--bg);
  border: var(--border-divider);
  border-radius: var(--radius-panel);
  overflow: hidden;
  display: flex;
}

/* ── Zoom/pan viewport — the editor's own version of room.html's
   .room-viewport: a fixed-height clipped window, panned/zoomed via
   .editor-canvas-frame's transform rather than native scrolling (see
   editor.js's View-section block). Sized the same as .room-viewport so the
   two pages' floor plans read as the same-scale surface. */
.editor-canvas-viewport {
  flex: 1;
  min-width: 0;
  width: 100%;
  height: min(70vh, 640px);
  overflow: hidden;
  cursor: grab;
  /* Same reasoning as .room-viewport in floor-plan.css: pan/zoom is
     JS-driven, nothing here relies on native scroll/pinch, so give
     two-finger gestures to view-controls.js instead of the browser. */
  touch-action: none;
}
.editor-canvas-viewport:active { cursor: grabbing; }

/* Sized in JS (editor.js's syncFrameSize) to the room's own
   canvasWidth/canvasHeight, in px — the transform target for pan/zoom.
   Device coordinates and the SVG's own viewBox never change; only this
   frame's translate+scale does. */
.editor-canvas-frame {
  transform-origin: top left;
}

.editor-canvas {
  display: block;
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-control);
  width: 100%;
  height: 100%;
  cursor: crosshair;
}

.ed-canvas-bg { fill: var(--surface); }
/* Note: no `fill` declared here — the grid rect's fill is the
   `fill="url(#editor-grid-pattern)"` attribute canvas-renderer.js sets
   directly; a CSS rule here would win the cascade over that attribute and
   silently blank the grid out regardless of the Show Grid checkbox. */
/* fill: none is required — the pattern's path is an open L-shape (two
   line segments, no closing Z), and SVG fills an open path as though it
   were closed back to its start point. Without this, each tile's implicit
   closed triangle defaults to fill:black, producing a black/white hazard-
   stripe checkerboard across the whole grid instead of a plain line grid. */
.ed-grid-line { stroke: var(--line); stroke-width: 1; fill: none; }

.ed-rect-body {
  fill: var(--surface-muted);
  stroke: var(--text-secondary);
  stroke-width: 1.5;
}
.ed-outline .ed-rect-body { fill: var(--surface); stroke-width: 2; }
.ed-floor .ed-rect-body { stroke: none; }
.ed-counter .ed-rect-body { fill: var(--surface-muted); stroke: var(--line); }
.ed-wallrect .ed-rect-body { fill: var(--text-secondary); opacity: 0.85; }

.ed-shape-label {
  font-family: var(--font-mono);
  font-size: var(--text-meta);
  font-weight: 500;
  fill: var(--text-muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  pointer-events: none;
}

.ed-wall-line { stroke: var(--text-secondary); stroke-width: 2; stroke-linecap: square; }
.ed-door-leaf { stroke: var(--text-secondary); stroke-width: 1.5; }
.ed-door-arc { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 3; fill: none; }

/* wide invisible stroke so thin lines/doors/outline edges are easy to grab */
.ed-hit-line {
  stroke: transparent;
  stroke-width: 14;
  fill: none;
  cursor: move;
}

.ed-shape[data-kind="shape"] { cursor: move; }
.ed-shape .ed-rect-body { cursor: move; }

.ed-handle {
  fill: var(--bg);
  stroke: var(--focus);
  stroke-width: 1.5;
  cursor: grab;
}
.ed-handle:hover { fill: var(--surface-muted); }

.ed-device { cursor: move; }
.ed-device-body {
  fill: var(--status-unchecked);
  stroke: var(--status-unchecked-strong);
  stroke-width: 1.5;
}
.ed-device-printer .ed-device-body { fill: var(--surface-muted); stroke: var(--line); }
.ed-device-staff .ed-device-body { stroke-width: 2; }

.ed-device-label {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 500;
  fill: var(--surface);
  pointer-events: none;
}
.ed-device-printer .ed-device-label { fill: var(--text-secondary); font-size: var(--text-meta); }

/* ── Device-type Legend swatches — each one is a real renderDevice() output
   (see editor.js's buildDeviceLegend), so it's pixel-identical to what that
   type actually looks like once placed, not a redrawn approximation. ── */
.editor-legend-swatch {
  flex-shrink: 0;
  overflow: visible;
}

.ed-selected .ed-rect-body,
.ed-selected .ed-device-body,
circle.ed-selected {
  stroke: var(--focus) !important;
  stroke-width: 3 !important;
}
.ed-selected .ed-wall-line,
.ed-selected .ed-door-leaf {
  stroke: var(--focus);
}

/* ── Locked layout (room status "final") ──
   Purely a visual cue — tools.js is what actually blocks placement/move/
   resize on these, and editor.js's status line is what gives explicit
   feedback the moment one is attempted (see onLockedAttempt). Devices
   never get this class regardless of room status. */
.ed-locked .ed-rect-body,
.ed-locked .ed-wall-line,
.ed-locked .ed-door-leaf,
.ed-locked .ed-door-arc {
  opacity: 0.55;
}
.ed-locked .ed-hit-line,
.ed-locked .ed-rect-body,
.ed-locked[data-kind="shape"] {
  cursor: not-allowed;
}
.ed-locked .ed-handle {
  display: none;
}

/* ── Footer / status ──
   Two groups: room-level commit actions (Mark as Final/Unlock Layout —
   only one ever shown at a time, and only once a room is loaded) on the
   left, document-save actions on the right — same bar, same "deliberate
   commit action" category, but visually distinct from each other. */
.editor-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding-top: var(--space-4);
  margin-top: var(--space-3);
  border-top: var(--border-divider);
}
.editor-footer[hidden] { display: none; }

.editor-footer-status-actions,
.editor-footer-save {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.editor-footer-status-actions .toolbar-btn {
  width: auto;
  margin-top: 0;
}

.editor-dirty {
  font-size: var(--text-meta);
  color: var(--text-muted);
  font-family: var(--font-mono);
}
.editor-dirty-active { color: var(--status-minor-strong); font-weight: 600; }

.editor-status {
  font-size: var(--text-body);
  color: var(--text-muted);
  min-height: 16px;
  margin-top: var(--space-3);
}
.editor-status-error { color: var(--danger-strong); font-weight: 500; }
.editor-status:empty { margin-top: 0; }
