/* ════════════════════════════════════════════════════
   LiteSpec Shared UI Components
   Standardised component classes used across Dashboard,
   Engineering Hub, Framing Hub, and all module pages.
   Loaded globally via base.html.
   ════════════════════════════════════════════════════ */

/* ── Global type scale ──────────────────────────────
   All font-size values in shared components should
   reference these variables for consistency.
   ──────────────────────────────────────────────────── */
:root {
  /* Type scale */
  --fs-2xs:  8px;   /* micro labels, badge text */
  --fs-xs:   9px;   /* tags, codes, monospace ids */
  --fs-sm:  10px;   /* column headings, caps labels */
  --fs-base: 11px;  /* primary body text in dense panels */
  --fs-md:  12px;   /* list row text, general content */
  --fs-lg:  12px;   /* section titles, sidebar heads */
  --fs-xl:  14px;   /* panel headers, card titles */
  --fs-2xl: 16px;   /* modal / page headings */
  --fs-3xl: 20px;   /* hero / display text */

  /* Dashboard theme */
  --brand:         #8e75da;
  --brand-light:   #e8e3f5;
  --brand-mid:     #a78bfa;
  --brand-dark:    #120d2b;
  --bg:            #f5f3ff;
  --surface:       #ffffff;
  --surface-2:     #f8f7ff;
  --border:        rgba(142,117,218,0.12);
  --border-strong: rgba(142,117,218,0.25);
  --text-primary:  #17152e;
  --text-secondary:#6b6886;
  --text-tertiary: #a8a5be;
  --success:       #059669;
  --success-bg:    #d1fae5;
  --success-border:#a7f3d0;
  --warning:       #92400e;
  --warning-bg:    #fef3c7;
  --warning-border:#fcd34d;
  --danger:        #991b1b;
  --danger-bg:     #fee2e2;
  --danger-border: #fca5a5;
  --info:          #1e40af;
  --info-bg:       #dbeafe;
  --info-border:   #93c5fd;
  --neutral:       #6b7280;
  --neutral-bg:    #f3f4f6;
  --neutral-border:#d1d5db;
  --sidebar-w:     280px;
  --topbar-h:      56px;
  --radius:        12px;
  --radius-sm:     8px;
  /* Topbar control tokens */
  --tb-h:          30px;
  --tb-h-sm:       26px;
  --tb-radius:     6px;
  --tb-font:       12px;
  --tb-font-label: 10px;
  --tb-gap:        8px;
  --tb-pad-x:      12px;
  --tb-pad-y:      5px;
}



/* ── Module page header ─────────────────────────────
   Used at top of hub/module pages (Engineering, Framing, etc.)
   ──────────────────────────────────────────────────── */
.ls-module-header {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 28px;
}

.ls-module-header-icon {
  width: 44px;
  height: 44px;
  border-radius: 11px;
  background: linear-gradient(135deg, #7c3aed, #6d28d9);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 19px;
  color: #fff;
}

.ls-module-header h1 {
  font-size: 22px;
  font-weight: 800;
  color: #1f2937;
  margin: 0;
  line-height: 1.2;
}

.ls-module-header p {
  color: #6b7280;
  font-size: 12px;
  margin: 3px 0 0;
}


/* ── Library hub page ───────────────────────────────
   Centred card grid for the Engineering Libraries hub.
   Replaces per-page inline <style>; lives on the app shell.
   ──────────────────────────────────────────────────── */
.lib-hub {
  max-width: 900px;
  margin: 0 auto;
  padding: 24px 24px 40px;
}

.lib-hub-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

.lib-hub-back {
  font-size: 12px;
  color: #9ca3af;
  text-align: center;
  margin: 0;
}

.lib-hub-back a {
  color: #7c5fb3;
  text-decoration: none;
}

@media (max-width: 720px) {
  .lib-hub-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ═══════════════════════════════════════════════════
   UNIVERSAL CARD COMPONENT — app-cardbox
   ═══════════════════════════════════════════════════
   
   Single source of truth for all card implementations
   across LiteSpec. Consolidates all existing card
   patterns into a unified, extensible component system.
   
   Base: light interactive card
   Modifiers:
   - --dark: premium dark variant (login/reg card style)
   - --compact: reduced padding
   - --interactive: hover elevation effects
   - --elevated: strong shadow
   - --flat: no shadow/border
   ═══════════════════════════════════════════════════ */

/* ── Base card style ── */
.app-cardbox {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 14px;
  padding: 18px 12px;
  transition: box-shadow .2s, border-color .2s, transform .18s, background .15s;
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
}

/* ── Dark variant — premium card (login/registration) ── */
.app-cardbox--dark {
  background: #271357;
  border: 1px solid #dedede;
  border-radius: 20px;
  padding: 2.5rem 2rem 2rem;
  color: #fff;
  cursor: pointer;
}

.app-cardbox--dark:hover {
  box-shadow: 0 6px 22px rgba(120, 80, 200, 0.15);
  border-color: #a78bfa;
  transform: translateY(-2px);
}

.app-cardbox--dark h1,
.app-cardbox--dark h2,
.app-cardbox--dark h3,
.app-cardbox--dark h4,
.app-cardbox--dark h5,
.app-cardbox--dark h6 {
  color: #fff;
}

.app-cardbox--dark label,
.app-cardbox--dark .label-text {
  color: rgba(255, 255, 255, 0.9);
}

/* ── Compact variant ── */
.app-cardbox--compact {
  padding: 12px 8px;
}

/* ── Interactive variant — hover effects ── */
.app-cardbox--interactive {
  cursor: pointer;
}

.app-cardbox--interactive:hover {
  box-shadow: 0 6px 22px rgba(120, 80, 200, 0.13);
  border-color: #c4b5fd;
  transform: translateY(-2px);
}

/* ── Elevated variant — strong shadow ── */
.app-cardbox--elevated {
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.12);
}

.app-cardbox--elevated:hover {
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.16);
}

/* ── Flat variant — minimal styling ── */
.app-cardbox--flat {
  border: none;
  box-shadow: none;
  background: transparent;
}

/* ── Disabled state ── */
.app-cardbox.is-disabled,
.app-cardbox--disabled {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
}

/* ── Locked state ── */
.app-cardbox.is-locked,
.app-cardbox--locked {
  background: #f9fafb;
  border-color: #e5e7eb;
  opacity: 0.78;
  cursor: default;
}

/* Dark cards keep a dark background when locked/disabled so white text stays readable */
.app-cardbox--dark.app-cardbox--locked,
.app-cardbox--dark.is-locked,
.app-cardbox--dark.app-cardbox--disabled,
.app-cardbox--dark.is-disabled {
  background: #271357;
  border-color: #3a2465;
  opacity: 0.6;
}

.app-cardbox.is-locked:hover,
.app-cardbox--locked:hover {
  box-shadow: 0 6px 22px rgba(120, 80, 200, 0.08);
  border-color: #c4b5fd;
  transform: translateY(-2px);
}

/* ── Grid container for square cards ── */
.app-cardbox--square {
  aspect-ratio: 1;
  width: 100%;
  text-align: center;
  align-items: center;
  justify-content: center;
  gap: 10px;
  cursor: pointer;
}

.app-cardbox--square:hover {
  box-shadow: 0 6px 22px rgba(120, 80, 200, 0.13);
  border-color: #a78bfa;
  transform: translateY(-2px);
}

/* ── List container for management/admin hubs ── */
.lib-hub-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 24px;
}

/* ── Grouped hub layout (engineering landing) ── */
.eng-hub-group {
  margin-bottom: 28px;
}

.eng-hub-group-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ececf3;
}

.eng-hub-group-icon {
  font-size: 16px;
  color: #8e75da;
  width: 20px;
  text-align: center;
  flex-shrink: 0;
}

/* Custom monoline tool icons (SVG sprite, stroke = currentColor) */
.eng-ico {
  width: 26px;
  height: 26px;
  display: block;
  color: inherit;
}

svg.eng-hub-group-icon {
  width: 22px;
  height: 22px;
}

.eng-hub-group-text {
  flex: 1;
  min-width: 0;
}

.eng-hub-group-title {
  font-size: var(--fs-xl, 15px);
  font-weight: 700;
  color: #1f2937;
  margin: 0;
  line-height: 1.3;
}

.eng-hub-group-desc {
  font-size: var(--fs-sm, 12px);
  color: #6b7280;
  margin: 2px 0 0;
  line-height: 1.3;
}

/* ── Row variant — horizontal list item (management hubs) ── */
.app-cardbox--row {
  flex-direction: row;
  align-items: center;
  gap: 16px;
  padding: 14px 18px;
  width: 100%;
  text-align: left;
  cursor: pointer;
}

.app-cardbox--row:hover {
  box-shadow: 0 4px 16px rgba(120, 80, 200, 0.10);
  border-color: #a78bfa;
  transform: translateY(-1px);
}

.app-cardbox--row .app-cardbox-icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  font-size: 18px;
}

.app-cardbox--row .app-cardbox-row-text {
  flex: 1;
  min-width: 0;
}

.app-cardbox--row .app-cardbox-desc {
  margin-top: 2px;
}

.app-cardbox--row .app-cardbox-row-chevron {
  color: #9ca3af;
  font-size: 14px;
  flex-shrink: 0;
}

/* ── Tile variant — compact dashboard tiles (120x120) ── */
.app-cardbox--tile {
  width: 120px;
  height: 120px;
  flex: 0 0 auto;
  padding: 12px;
  text-align: center;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
}

.app-cardbox--tile:hover {
  box-shadow: 0 4px 16px rgba(120, 80, 200, 0.12);
  border-color: #c4b5fd;
  transform: translateY(-1px);
}

/* ── App variant — dashboard Applications cards ──
   The dashboard used icon-only 120x120 tiles, which assumed you already knew
   what each product did. This variant carries a description, so the grid reads
   as a product menu. Sibling of --eng-tile (which centres 80px hub artwork);
   this one leads with a small left-aligned icon chip. */
.app-appgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 12px;
}

.app-cardbox--app {
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  padding: 18px;
  gap: 0;
  min-height: 136px;
  cursor: pointer;
}

.app-cardbox--app:hover {
  box-shadow: 0 4px 16px rgba(120, 80, 200, 0.12);
  border-color: #c4b5fd;
  transform: translateY(-1px);
}

.app-cardbox--app .app-cardbox-icon {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: var(--brand-light);
  margin-bottom: 12px;
}

.app-cardbox--app .app-cardbox-icon i {
  font-size: 18px;
  color: var(--brand);
}

.app-cardbox--app .app-cardbox-label {
  font-size: 15px;
  font-weight: 600;
}

.app-cardbox--app .app-cardbox-desc {
  margin-top: 5px;
  font-size: 12.5px;
  line-height: 1.45;
  /* Two lines keeps every card the same height whatever the copy length. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Live count under a card — turns the launcher into a status board. */
.app-cardbox-stat {
  margin-top: auto;
  padding-top: 10px;
  font-size: 11px;
  color: var(--text-tertiary);
  letter-spacing: 0.2px;
}

/* Walls & Ceilings is the front door that chains the other four, so it keeps
   the purple hub treatment rather than reading as a fifth peer. */
.app-cardbox--app-hub {
  background: #2e1065;
  border-color: #2e1065;
  color: #fff;
  position: relative;
}

.app-cardbox--app-hub:hover {
  background: #3b0f7a;
  border-color: #6d28d9;
  box-shadow: 0 6px 22px rgba(46, 16, 101, 0.28);
}

.app-cardbox--app-hub .app-cardbox-icon {
  background: rgba(255, 255, 255, 0.12);
}

.app-cardbox--app-hub .app-cardbox-icon i,
.app-cardbox--app-hub .app-cardbox-label {
  color: #fff;
}

.app-cardbox--app-hub .app-cardbox-desc {
  color: rgba(255, 255, 255, 0.72);
}

.app-cardbox--app-hub .app-hub-badge {
  position: absolute;
  top: 10px;
  right: 10px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border-radius: 20px;
  background: #fbbf24;
  color: #422006;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.app-cardbox--app-hub .app-hub-badge i {
  font-size: 8px;
}

/* Staggered entrance, matching the stat row above. */
.app-cardbox--app {
  animation: appFadeUp 0.35s ease both;
}

.app-cardbox--app:nth-child(1) { animation-delay: 0.10s; }
.app-cardbox--app:nth-child(2) { animation-delay: 0.13s; }
.app-cardbox--app:nth-child(3) { animation-delay: 0.16s; }
.app-cardbox--app:nth-child(4) { animation-delay: 0.19s; }
.app-cardbox--app:nth-child(5) { animation-delay: 0.22s; }

/* ── Grid container for the Engineering hub ── */
.eng-hub-tilegrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 14px;
  margin-bottom: 24px;
}

/* ── Eng-tile variant — bigger icon, vertical grid tile ── */
.app-cardbox--eng-tile {
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  padding: 20px 18px;
  gap: 16px;
  cursor: pointer;
  height: 100%;
}

.app-cardbox--eng-tile:hover {
  box-shadow: 0 4px 16px rgba(120, 80, 200, 0.10);
  border-color: #a78bfa;
  transform: translateY(-1px);
}

.app-cardbox--eng-tile .app-cardbox-icon {
  width: 80px;
  height: 80px;
  padding: 6px;
  align-self: center;
}

.app-cardbox--eng-tile .eng-ico {
  width: 100%;
  height: 100%;
  max-width: 68px;
  max-height: 68px;
  object-fit: contain;
}

.app-cardbox--eng-tile .app-cardbox-row-text {
  width: 100%;
}

.app-cardbox--eng-tile .app-cardbox-label {
  font-size: 14px;
}

.app-cardbox--eng-tile .app-cardbox-desc {
  margin-top: 4px;
}

/* ── Diagonal "coming soon" ribbon — corner banner on eng-tile cards ── */
.app-cardbox-ribbon {
  position: absolute;
  top: 16px;
  right: -34px;
  width: 130px;
  padding: 3px 0;
  transform: rotate(45deg);
  background: #f3f4f6;
  color: #9ca3af;
  font-size: 10px;
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: .02em;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
  pointer-events: none;
}

/* ── Hub tile — dashboard app selector (solid dark) ── */
.app-cardbox--hub {
  background: #271357;
  border-color: #dedede;
  color: #fff;
  position: relative;
  overflow: visible;
}

.app-cardbox--hub:hover {
  background: #3a2465;
  border-color: #a78bfa;
  transform: translateY(-2px);
  box-shadow: 0 6px 22px rgba(120, 80, 200, 0.15);
}

/* ────────────────────────────────────────────────
   Content utility classes for card children
   ──────────────────────────────────────────────── */

.app-cardbox-header {
  font-size: 18px;
  font-weight: 700;
  color: #1f2937;
  margin-bottom: 0.5rem;
}

.app-cardbox-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.app-cardbox-footer {
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid #e5e7eb;
  display: flex;
  gap: 8px;
}

.app-cardbox-icon {
  width: 56px;
  height: 56px;
  border-radius: 14px;
  background: linear-gradient(135deg, #ede9fe, #ddd6f4);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  color: #664d9e;
  flex-shrink: 0;
}

.app-cardbox-label {
  font-weight: 700;
  font-size: 14px;
  color: #1f2937;
  line-height: 1.3;
}

.app-cardbox-desc {
  font-size: 12px;
  color: #6b7280;
  line-height: 1.45;
}

/* Dark variant text colors */
.app-cardbox--dark .app-cardbox-label {
  color: #fff;
}

.app-cardbox--dark .app-cardbox-desc {
  color: rgba(255, 255, 255, 0.75);
}

/* Tile icon variant (smaller for 120x120 tiles) */
.app-cardbox--tile .app-cardbox-icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: var(--brand-light);
  font-size: 18px;
}

.app-cardbox--tile .app-cardbox-icon i {
  color: var(--brand);
}

/* Hub tile icon — light background */
.app-cardbox--hub .app-cardbox-icon {
  background: rgba(255, 255, 255, 0.12);
}

.app-cardbox--hub .app-cardbox-icon i {
  color: #fff;
}

/* Tile label variant (smaller font) */
.app-cardbox--tile .app-cardbox-label {
  font-size: 11px;
  color: var(--text-secondary);
  font-weight: 400;
  line-height: 1.2;
}

/* Hub tile label — white text */
.app-cardbox--hub .app-cardbox-label {
  color: #fff;
}

/* Badge on hub tiles */
.app-cardbox--hub .app-hub-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  background: #FFD24D;
  color: #24170a;
  padding: 2px 6px;
  border-radius: 10px;
  font-weight: 700;
  font-size: 11px;
  line-height: 1;
  display: inline-flex;
}

/* ────────────────────────────────────────────────
   Badge system for cards
   ──────────────────────────────────────────────── */

.app-cardbox-badge {
  display: inline-flex;
  align-items: center;
  font-size: 10px;
  font-weight: 600;
  border-radius: 99px;
  padding: 2px 9px;
  border: 1px solid #e5e7eb;
  background: #f3f4f6;
  color: #9ca3af;
  white-space: nowrap;
}

.app-cardbox-badge--purple {
  background: #ede9fe;
  color: #6d28d9;
  border-color: #ddd6f4;
}

.app-cardbox-badge--amber {
  background: #fef3c7;
  color: #b45309;
  border-color: #fde68a;
}

.app-cardbox-badge--green {
  background: #dcfce7;
  color: #15803d;
  border-color: #bbf7d0;
}


/* ── Nav / App card ─────────────────────────────────
   DEPRECATED: Use app-cardbox instead.
   Kept for backwards compatibility during migration.
   ──────────────────────────────────────────────────── */
.ls-nav-card {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 14px;
  /* make card size responsive to grid like dashboard cards */
  width: 100%;
  aspect-ratio: 1;
  padding: 18px 12px;
  text-align: center;
  text-decoration: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  position: relative;
  overflow: hidden;
  cursor: pointer;
  transition: box-shadow .2s, transform .18s, border-color .2s;
}

.ls-nav-card:hover {
  box-shadow: 0 6px 22px rgba(120, 80, 200, .13);
  border-color: #c4b5fd;
  transform: translateY(-2px);
}

.ls-nav-card.coming-soon {
  opacity: .55;
  cursor: default;
  pointer-events: none;
}

.ls-nav-card.locked {
  background: #f9fafb;
  border-color: #e5e7eb;
  opacity: .78;
}

.ls-nav-card.locked:hover {
  box-shadow: 0 6px 22px rgba(120, 80, 200, .08);
  border-color: #c4b5fd;
  transform: translateY(-2px);
}

/* Icon box inside a nav card */
.ls-nav-icon {
  width: 56px;
  height: 56px;
  border-radius: 14px;
  background: linear-gradient(135deg, #ede9fe, #ddd6f4);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  color: #7c3aed;
  flex-shrink: 0;
}

.ls-nav-label {
  font-weight: 700;
  font-size: 14px;
  color: #1f2937;
  line-height: 1.3;
}

.ls-nav-desc {
  font-size: 12px;
  color: #6b7280;
  line-height: 1.45;
}

/* Pill badge — "Coming soon", "Pro", plan name */
.ls-badge {
  display: inline-flex;
  align-items: center;
  font-size: 10px;
  font-weight: 600;
  border-radius: 99px;
  padding: 2px 9px;
  border: 1px solid #e5e7eb;
  background: #f3f4f6;
  color: #9ca3af;
  white-space: nowrap;
}

.ls-badge-purple {
  background: #ede9fe;
  color: #6d28d9;
  border-color: #ddd6f4;
}

.ls-badge-amber {
  background: #fef3c7;
  color: #b45309;
  border-color: #fde68a;
}

/* Lock badge — top-right corner of a locked card */
.ls-nav-lock {
  position: absolute;
  top: 10px;
  right: 11px;
  font-size: 10px;
  color: #9ca3af;
  background: #f3f4f6;
  border: 1px solid #e5e7eb;
  border-radius: 99px;
  padding: 2px 7px;
  display: flex;
  align-items: center;
  gap: 4px;
}

/* Category tag — diagonal corner ribbon, e.g. "Wall" / "Ceiling" */
.ls-cat-tag {
  position: absolute;
  top: 14px;
  right: -22px;
  width: 80px;
  text-align: center;
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  padding: 3px 0;
  transform: rotate(45deg);
  transform-origin: center center;
  pointer-events: none;
  z-index: 2;
}

.ls-cat-tag.wall    { background: #ede9fe; color: #6d28d9; }
.ls-cat-tag.ceiling { background: #e0f2fe; color: #0369a1; }


/* ── Status tags (Soon / Upgrade) — diagonal corner ribbon ── */
.ls-card-tag {
  position: absolute;
  top: 14px;
  right: -22px;
  width: 80px;
  text-align: center;
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  padding: 3px 0;
  transform: rotate(45deg);
  transform-origin: center center;
  pointer-events: none;
  z-index: 2;
  overflow: hidden;
}
.ls-card-tag.soon    { background: #e5e7eb; color: #6b7280; }
.ls-card-tag.upgrade { background: #ede9fe; color: #7c3aed; }


/* ── Featured nav card (Workspace) — updated animation ─ */
.ls-nav-card-featured {
  background: linear-gradient(135deg, #6d28d9 0%, #4f46e5 50%, #7c3aed 100%);
  background-size: 300% 300%;
  border: none;
  box-shadow: 0 6px 20px rgba(109, 40, 217, .35);
  animation: ls-ws-grad-new 6s ease infinite;
  overflow: hidden;
}

/* Enhanced shimmer overlay */
.ls-nav-card-featured::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(120deg, transparent 30%, rgba(255,255,255,.15) 50%, transparent 70%);
  background-size: 250% 100%;
  animation: ls-ws-shine-new 4s ease-in-out infinite;
  border-radius: inherit;
  pointer-events: none;
}

@keyframes ls-ws-grad-new {
  0%   { background-position: 0% 0%; }
  50%  { background-position: 100% 100%; }
  100% { background-position: 0% 0%; }
}

@keyframes ls-ws-shine-new {
  0%   { background-position: -150% 0; }
  50%  { background-position: 150% 0; }
  100% { background-position: -150% 0; }
}

.ls-nav-card-featured:hover {
  animation: ls-ws-grad-new 6s ease infinite;
  box-shadow: 0 10px 30px rgba(109, 40, 217, .45);
  transform: translateY(-3px) scale(1.02);
}

.ls-nav-card-featured .ls-nav-icon {
  background: rgba(255,255,255,.18);
  color: #fff;
  backdrop-filter: blur(4px);
}

.ls-nav-card-featured .ls-nav-label {
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  text-shadow: 0 1px 3px rgba(0,0,0,.15);
}

.ls-nav-card-featured .ls-nav-desc {
  color: rgba(255,255,255,.75);
}


/* ── Stat tile ──────────────────────────────────────
   Used in Dashboard Account Overview section.
   ──────────────────────────────────────────────────── */
.ls-stat-tile {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 14px;
  padding: 20px 22px;
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.ls-stat-icon {
  width: 44px;
  height: 44px;
  border-radius: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  flex-shrink: 0;
}

.ls-stat-icon-purple { background: linear-gradient(135deg, #ede9fe, #ddd6f4); color: #7c3aed; }
.ls-stat-icon-blue   { background: linear-gradient(135deg, #dbeafe, #bfdbfe); color: #1d4ed8; }
.ls-stat-icon-green  { background: linear-gradient(135deg, #d1fae5, #a7f3d0); color: #065f46; }

.ls-stat-body { flex: 1; min-width: 0; }

.ls-stat-label {
  font-size: 12px;
  font-weight: 600;
  color: #6b7280;
  margin: 0 0 4px;
  text-transform: uppercase;
  letter-spacing: .04em;
}

.ls-stat-value {
  font-size: 26px;
  font-weight: 800;
  color: #111827;
  line-height: 1;
  margin: 0 0 10px;
}

.ls-stat-value span {
  font-size: 14px;
  font-weight: 400;
  color: #9ca3af;
}

.ls-stat-bar-track {
  height: 5px;
  background: #f3f4f6;
  border-radius: 99px;
  overflow: hidden;
  margin-bottom: 6px;
}

.ls-stat-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, #7c3aed, #a78bfa);
  border-radius: 99px;
  transition: width .7s cubic-bezier(.4,0,.2,1);
}

.ls-stat-remaining {
  font-size: 11px;
  color: #9ca3af;
  margin: 0;
}

.ls-stat-limit {
  color: #f59e0b;
  font-weight: 600;
}


/* ── Dashboard hero banner ──────────────────────────
   Full-width gradient banner at top of dashboard.
   ──────────────────────────────────────────────────── */
.ls-dash-hero {
  position: relative;
  overflow: hidden;
  background: #f5f3ff;
  border: 1px solid #ddd6fe;
  border-radius: 16px;
  padding: 28px 32px;
  margin-bottom: 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.ls-dash-hero-text { position: relative; z-index: 2; }

.ls-dash-hero-plan {
  display: inline-flex;
  align-items: center;
  background: #ede9fe;
  color: #6d28d9;
  font-size: 11px;
  font-weight: 600;
  border-radius: 99px;
  padding: 3px 11px;
  margin-bottom: 10px;
  border: 1px solid #ddd6fe;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.ls-dash-hero h2 {
  font-size: 24px;
  font-weight: 800;
  color: #1f2937;
  margin: 0 0 5px;
  line-height: 1.2;
}

.ls-dash-hero p {
  color: #6b7280;
  font-size: 12px;
  margin: 0 0 18px;
}

.ls-dash-hero-actions { display: flex; gap: 10px; flex-wrap: wrap; }

.ls-dash-hero-btn-outline {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: #fff;
  color: #374151;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  padding: 7px 16px;
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  transition: border-color .15s, background .15s;
}

.ls-dash-hero-btn-outline:hover {
  background: #f9fafb;
  border-color: #9ca3af;
  color: #1f2937;
}



/* Decorative icon cluster — right side of hero */
.ls-dash-hero-icons {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0;
  flex-shrink: 0;
  pointer-events: none;
  user-select: none;
}

.ls-dash-hero-icons i {
  color: rgba(109, 40, 217, .08);
  position: absolute;
}


/* ── Recent work row ────────────────────────────────
   Compact card row for Recent Work section on dashboard.
   ──────────────────────────────────────────────────── */
.ls-recent-row {
  display: flex;
  align-items: center;
  gap: 14px;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: 12px 16px;
  transition: border-color .12s, box-shadow .12s;
}

.ls-recent-row:hover {
  border-color: #c4b5fd;
  box-shadow: 0 2px 10px rgba(120,80,200,.08);
}

.ls-recent-icon {
  width: 36px;
  height: 36px;
  border-radius: 9px;
  background: linear-gradient(135deg, #ede9fe, #ddd6f4);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: #7c3aed;
  flex-shrink: 0;
}

.ls-recent-name {
  font-size: 12px;
  font-weight: 600;
  color: #1f2937;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ls-recent-sub {
  font-size: 11px;
  color: #9ca3af;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ls-recent-date {
  font-size: 11px;
  color: #6b7280;
  background: #f3f4f6;
  border-radius: 6px;
  padding: 2px 8px;
  white-space: nowrap;
  flex-shrink: 0;
}

.ls-recent-action {
  color: #7c3aed;
  font-size: 14px;
  flex-shrink: 0;
  text-decoration: none;
  opacity: .7;
  transition: opacity .12s;
}

.ls-recent-action:hover { opacity: 1; }


/* ── Section heading row ────────────────────────────
   Used above cards/recent work grids.
   ──────────────────────────────────────────────────── */
.ls-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}

.ls-section-head h3 {
  font-size: 14px;
  font-weight: 700;
  color: #374151;
  margin: 0;
  text-transform: uppercase;
  letter-spacing: .05em;
}

.ls-section-head a {
  font-size: 12px;
  font-weight: 600;
  color: #7c3aed;
  text-decoration: none;
}

.ls-section-head a:hover { text-decoration: underline; }


/* ── Quick Actions bar ──────────────────────────────
   Horizontal strip of shortcut buttons below the hero.
   ──────────────────────────────────────────────────── */
.ls-quick-bar {
  display: flex;
  gap: 10px;
  margin-bottom: 24px;
  flex-wrap: wrap;
}

.ls-quick-action {
  display: flex;
  align-items: center;
  gap: 9px;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: 9px 16px 9px 10px;
  text-decoration: none;
  font-size: 12px;
  font-weight: 600;
  color: #374151;
  transition: border-color .13s, box-shadow .13s, transform .13s;
  white-space: nowrap;
}

.ls-quick-action:hover {
  border-color: #c4b5fd;
  box-shadow: 0 3px 12px rgba(120,80,200,.10);
  transform: translateY(-1px);
  color: #6d28d9;
}

.ls-quick-icon {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: linear-gradient(135deg, #ede9fe, #ddd6f4);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: #7c3aed;
  flex-shrink: 0;
}


/* ════════════════════════════════════════════════════
   Dashboard — Figma node 200:470
   ════════════════════════════════════════════════════ */

.ls-db-wrap {
  max-width: 1280px;
  margin: 0 auto;
  padding: 28px 32px 48px;
  background: #f9fafb;
  min-height: 100%;
}

.ls-db-greeting {
  margin: 0 0 20px;
  font-family: 'Inter';
  font-weight: 600;
  font-size: 24px;
  line-height: 29px;
  color: #2a1f5e;
  text-shadow: 2px 4px 4px rgba(0, 0, 0, 0.25);
}

/* ── Stats strip ── */
.ls-db-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin-bottom: 24px;
}

.ls-stat-tile {
  background: #fff;
  border: 0.5px solid #d2d2d2;
  border-radius: 20px;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 16px;
  padding: 16px 20px;
  min-height: 107px;
  overflow: hidden;
}

.ls-stat-icon {
  width: 50px;
  height: 50px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  color: #7354af;
  border-radius: 10px;
  background: rgba(115, 84, 175, 0.20);
  border: 0.2px solid #7354af;
}

.ls-stat-icon-report {
  background: rgba(115, 84, 175, 0.20);
  border: 0.1px solid #7354af;
}

.ls-stat-body { flex: 1; min-width: 0; }

.ls-stat-label {
  font-size: 12px;
  font-weight: 700;
  color: #6d6d6d;
  text-transform: uppercase;
  letter-spacing: .05em;
  margin: 0 0 4px;
}

.ls-stat-value {
  font-size: 20px;
  color: #111827;
  margin: 0 0 8px;
  font-weight: 700;
  line-height: 1;
}

.ls-stat-count { font-size: 20px; font-weight: 700; color: #111827; }
.ls-stat-denom { font-size: 12px; color: #6d6d6d; font-weight: 400; }

.ls-stat-bar-track {
  height: 5px;
  background: #d9d9d9;
  border-radius: 100px;
  overflow: hidden;
  margin-bottom: 6px;
}

.ls-stat-bar-fill {
  height: 100%;
  background: #7354af;
  border-radius: 100px;
  transition: width 0.6s ease;
}

.ls-stat-remaining {
  font-size: 10px;
  color: #6d6d6d;
  margin: 0;
}

.ls-stat-limit { color: #dc2626; font-weight: 700; }

/* ── Body grid ── */
.ls-db-body {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 24px;
  align-items: start;
}

/* ── Left: Recent sections ── */
.ls-db-recents { display: flex; flex-direction: column; gap: 20px; }

.ls-db-recent-section { }

.ls-db-recent-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.ls-db-recent-label {
  font-size: 12px;
  font-weight: 700;
  color: #6d6d6d;
  text-transform: uppercase;
  letter-spacing: .05em;
}

.ls-db-view-all {
  font-size: 12px;
  font-weight: 700;
  color: #7354af;
  text-decoration: none;
}

.ls-db-view-all:hover { text-decoration: underline; }

.ls-db-cardbox {
  background: #fff;
  border: 0.5px solid #d2d2d2;
  border-radius: 20px;
  overflow: hidden;
}

.ls-recent-row {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 59px;
  padding: 0 17px;
  border-bottom: 0.1px solid #ffffff;
  border-radius: 0;
  text-decoration: none;
  color: inherit;
  transition: background .15s;
}

.ls-recent-row:last-child { border-bottom: none; }
.ls-recent-row:hover { background: #f5f3ff; }

.ls-recent-icon {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #eee8f9;
  border-radius: 8px;
  color: #7354af;
  font-size: 16px;
}

.ls-recent-info { flex: 1; min-width: 0; }

.ls-recent-name {
  font-size: 12px;
  font-weight: 700;
  color: #6d6d6d;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ls-recent-sub {
  font-size: 12px;
  color: #6d6d6d;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ls-date-pill {
  background: #D9D9D9;
  color: #7354AF;
  font-size: 10px;
  font-weight: 500;
  font-family: 'Inter';
  border-radius: 6px;
  padding: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  flex-shrink: 0;
  line-height: normal;
}

/* Empty state */
.ls-db-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px 20px;
  gap: 8px;
  text-align: center;
}

.ls-db-empty i { font-size: 22px; color: #d1d5db; }
.ls-db-empty p { font-size: 12px; color: #9ca3af; margin: 0; }

/* ── Right: Applications ── */
.ls-db-apps { }

.ls-db-apps-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.ls-db-app-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
}

.ls-db-app-grid .ls-nav-card {
  width: 100%;
  aspect-ratio: 1;
  min-height: 148px;
  background: #fff;
  border: 0.5px solid #d2d2d2;
  border-radius: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-decoration: none;
  cursor: pointer;
  padding: 14px;
  transition: box-shadow .15s, transform .1s;
}

.ls-db-app-grid .ls-nav-card:hover {
  box-shadow: 0 4px 16px rgba(115, 84, 175, 0.18);
  transform: translateY(-2px);
}

.ls-db-app-grid .ls-nav-card-featured {
  background: linear-gradient(135deg, #687ae4, #7354af);
  border-color: #7354af;
}

.ls-db-app-grid .ls-nav-card-active {
  background: #687ae4;
  border-color: #687ae4;
}

/* Dashboard app grid: icon is bare <i> with this class */
.ls-db-app-grid .ls-nav-icon {
  width: auto;
  height: auto;
  background: none;
  font-size: 24px;
  color: #7354af;
  border-radius: 0;
}

.ls-db-app-grid .ls-nav-card-featured .ls-nav-icon,
.ls-db-app-grid .ls-nav-card-active .ls-nav-icon { color: #fff; }

.ls-db-app-grid .ls-nav-label {
  font-size: 15px;
  font-weight: 700;
  color: #7354af;
  text-align: center;
  line-height: 1.2;
}

.ls-db-app-grid .ls-nav-card-featured .ls-nav-label,
.ls-db-app-grid .ls-nav-card-active .ls-nav-label { color: #fff; }

.ls-db-app-grid .ls-nav-desc {
  font-size: 10px;
  color: #1f2937;
  text-align: center;
  line-height: 1.4;
}

.ls-db-app-grid .ls-nav-card-featured .ls-nav-desc,
.ls-db-app-grid .ls-nav-card-active .ls-nav-desc { color: rgba(255,255,255,0.85); }

/* ── Responsive ── */
@media (max-width: 1100px) {
  .ls-db-app-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 900px) {
  .ls-db-body { grid-template-columns: 1fr; }
  .ls-db-app-grid { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 640px) {
  .ls-db-wrap { padding: 16px 16px 32px; }
  .ls-db-stats { grid-template-columns: 1fr; }
  .ls-db-app-grid { grid-template-columns: repeat(2, 1fr); }
}



/* ── Builder Panel Drag Dividers ────────────────────────────────────────
   Shared resizable dividers used in SmartSpec System Builder,
   Section Builder, and any future builder module.

   Usage:
     Vertical (col-resize):  <div class="ls-divider-col" title="Drag to resize"></div>
     Horizontal (row-resize): <div class="ls-divider-row" title="Drag to resize"></div>
   ────────────────────────────────────────────────────────────────────── */

/* Shared base */
.ls-divider-col,
.ls-divider-row {
  flex-shrink: 0;
  background: #e5e7eb;
  display: flex; align-items: center; justify-content: center;
  transition: background .1s;
  position: relative; z-index: 5;
}
.ls-divider-col:hover, .ls-divider-col.dragging,
.ls-divider-row:hover, .ls-divider-row.dragging { background: #7c3aed; }

/* Vertical divider (col-resize — splits left/right panels) */
.ls-divider-col {
  width: 6px;
  cursor: col-resize;
}
.ls-divider-col::after {
  content: '';
  display: block; width: 2px; height: 28px;
  border-radius: 2px;
  background: rgba(0,0,0,.15);
}

/* Horizontal divider (row-resize — splits top/bottom panels) */
.ls-divider-row {
  height: 6px;
  cursor: row-resize;
}
.ls-divider-row::after {
  content: '';
  display: block; height: 2px; width: 28px;
  border-radius: 2px;
  background: rgba(0,0,0,.15);
}


/* ════════════════════════════════════════════════════
   Primary Button — Figma node 237:1872
   bg #687ae4 | border 0.5px rgba(78,78,78,0.2) | r-8px | shadow 0 4px 2px rgba(0,0,0,0.25)
   ════════════════════════════════════════════════════ */
.btn-primary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: #7354af;
  color: white;
  border: none;
  border-radius: 6px;
  padding: 8px 16px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: 0 3px 2px rgba(0,0,0,0.25);
}
.btn-primary:hover {
  background: #271357;
  box-shadow: 0px 6px 4px rgba(0,0,0,0.22);
  color: #fff;
  text-decoration: none;
}
.btn-primary:active {
  background: #4f61bc;
  box-shadow: 0px 2px 1px rgba(0,0,0,0.2);
}
.btn-primary:disabled,
.btn-primary[disabled] {
  opacity: 0.5;
  pointer-events: none;
}

.btn-secondary {
    background: #f8f9fa;
    color: #495057;
    border: 1px solid #e2e8f0;
    padding: 8px 16px;
    font-size: 12px;
    border-radius: 6px;
    transition: all 0.3s ease;
    font-weight: 500;
    box-shadow: 0 3px 2px rgba(0,0,0,0.25);
}
.btn-secondary:hover {
    background: #e9ecef;
    color: #212529;
    text-decoration: none;
}

/* Ghost — transparent with brand tint on hover */
.btn-ghost {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: rgba(142,117,218,0.10);
    color: var(--brand, #8e75da);
    border: none;
    border-radius: 6px;
    padding: 7px 14px;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: background .15s;
    text-decoration: none;
}
.btn-ghost:hover {
    background: rgba(142,117,218,0.20);
    color: var(--brand, #8e75da);
    text-decoration: none;
}

/* Success — green */
.btn-success {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: #059669;
    color: #fff;
    border: none;
    border-radius: 6px;
    padding: 8px 16px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s;
    text-decoration: none;
}
.btn-success:hover { background: #047857; color: #fff; text-decoration: none; }

/* Danger ghost — red text, transparent */
.btn-danger-ghost {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: transparent;
    color: #9ca3af;
    border: none;
    border-radius: 6px;
    padding: 7px 12px;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: background .12s, color .12s;
}
.btn-danger-ghost:hover { background: #fee2e2; color: #dc2626; }


/* ════════════════════════════════════════════════════
   List Card — Normal  (Figma node 200:407)
   59px tall | border #e8e8e8 0.2px | icon 40×40px
   ════════════════════════════════════════════════════ */
.pl-list-card {
  display: flex;
  align-items: center;
  width: 100%;
  height: 59px;
  padding: 0 17px;
  border: 0.2px solid #e8e8e8;
  border-bottom: none;
  box-sizing: border-box;
  cursor: pointer;
  transition: background .12s;
  position: relative;
  background: #fff;
}
.pl-list-card:first-child { border-top: 0.2px solid #e8e8e8; }
.pl-list-card + .pl-list-card { border-top: 0.2px solid #e8e8e8; }
.pl-list-card:last-child { border-bottom: 0.2px solid #e8e8e8; }
.pl-list-card:hover { background: rgba(115, 84, 175, 0.2); }
.pl-list-card.active  { background: rgba(115, 84, 175, 0.12); }

/* Icon — 40×40px lavender rounded square */
.pl-list-icon {
  width: 40px; height: 40px; flex-shrink: 0;
  margin-right: 12px;
  display: flex; align-items: center; justify-content: center;
  background: #eee8f9; border-radius: 8px;
  color: #7354af; font-size: 16px;
}

/* Body */
.pl-list-card-body  { flex: 1; min-width: 0; }

/* Name row: name text + active badge + date pill all inline on one line */
.pl-list-card-name-row {
  display: flex; align-items: center; gap: 6px;
  white-space: nowrap; overflow: hidden;
}
.pl-list-card-name  {
  font-size: 12px; font-weight: 700; color: #6d6d6d;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  flex-shrink: 1; min-width: 0;
}
.pl-list-card-desc  {
  font-size: 12px; font-weight: 400; color: #6d6d6d;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-top: 2px;
}

/* Date pill pushed to far right of the card */
.pl-list-card-date-right {
  flex-shrink: 0; margin-left: auto;
}

/* Date pill — bg #6d6d6d, rounded 2px, 8px white text */
.pl-list-date {
  display: inline-flex; align-items: center; justify-content: center;
  background: #6d6d6d; color: #fff;
  font-size: 8px; font-weight: 400;
  border-radius: 2px; padding: 0 6px; height: 15px;
  white-space: nowrap;
}

/* Active pill — Figma: green #00b140, bold 10px */
.pl-list-active-badge {
  display: inline-flex; align-items: center; justify-content: center;
  color: #00b140;
  font-size: 10px; font-weight: 700;
  white-space: nowrap;
}

/* Supplier/tag pill — coloured bg, 8px white text */
.pl-list-tag {
  display: inline-flex; align-items: center; justify-content: center;
  background: #b3007e; color: #fff;
  font-size: 8px; font-weight: 400;
  border-radius: 2px; padding: 0 6px; height: 15px;
  white-space: nowrap;
}


/* ════════════════════════════════════════════════════
   List Card — Compact  (Figma node 237:1838)
   ~30px tall | border #d2d2d2 0.2px | icon 16×16px
   ════════════════════════════════════════════════════ */
.pl-list-card--compact {
  height: 30px;
  padding: 0 12px;
  border-color: #d2d2d2;
}
.pl-list-card--compact .pl-list-icon {
  width: 16px; height: 16px;
  margin-right: 8px;
  background: transparent; border-radius: 0;
  font-size: 12px;
}
.pl-list-card--compact .pl-list-card-name {
  font-size: 12px; font-weight: 500;
}
.pl-list-card--compact .pl-list-card-desc { display: none; }
.pl-list-card--compact .pl-list-badges { margin-top: 0; }


/* ════════════════════════════════════════════════════
   Delete icon button — ss-wt-del-btn
   18x18px | rounded 4px | red icon | reveal on parent hover
   ════════════════════════════════════════════════════ */
.ss-wt-del-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 4px;
  color: #f87171;
  cursor: pointer;
  font-size: 10px;
  background: transparent;
  border: none;
  transition: background .12s, color .12s, transform .1s;
}
.ss-wt-del-btn:hover {
  background: #fee2e2;
  color: #dc2626;
  transform: scale(1.15);
}
.ss-wt-del-btn i { pointer-events: none; }


/* ════════════════════════════════════════════════════
   Universal data table — ls-tbl-wrap / ls-tbl
   Neon-inspired: clean header, minimal borders.
   Use anywhere a data grid is needed.
   ════════════════════════════════════════════════════ */
.ls-tbl-wrap {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  overflow: hidden;
  overflow-x: auto;
  box-shadow: 0 1px 3px rgba(0,0,0,.06);
}
.ls-tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

/* ── Title/banner row ── */
.ls-tbl thead tr.ls-tbl-title th {
  padding: 8px 14px;
  font-size: 12.5px;
  font-weight: 700;
  text-align: left;
  color: #fff;
  background: #6344a0;
  border: none;
}
.ls-tbl thead tr.ls-tbl-title.int th      { background: #6344a0; }
.ls-tbl thead tr.ls-tbl-title.ext th      { background: #059669; }
.ls-tbl thead tr.ls-tbl-title.party th    { background: #d97706; }
.ls-tbl thead tr.ls-tbl-title.fire-ext th,
.ls-tbl thead tr.ls-tbl-title.fire-int th { background: #dc2626; }

/* ── Column header row ── */
.ls-tbl thead tr.ls-tbl-cols th {
  background: #f8f9fb;
  color: #6b7280;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  padding: 7px 12px;
  border-bottom: 1px solid #e5e7eb;
  border-right: 1px solid #f1f3f5;
  vertical-align: bottom;
  white-space: nowrap;
  user-select: none;
}
.ls-tbl thead tr.ls-tbl-cols th:last-child { border-right: none; }

/* ── Body rows ── */
.ls-tbl tbody tr { border-bottom: 1px solid #f1f3f5; transition: background .1s; }
.ls-tbl tbody tr:last-child { border-bottom: none; }
.ls-tbl tbody tr:hover > td { background: #f8f6ff; }
/* Data cells — zero padding so selects/content fill edge-to-edge */
.ls-tbl td {
  padding: 0;
  vertical-align: middle;
  border-right: 1px solid #f1f3f5;
  font-size: 13px;
  color: #374151;
}
.ls-tbl td:last-child { border-right: none; }
/* Floor + height fixed columns keep small padding */
.ls-tbl td.sq-td-floor   { padding: 0 10px; text-align: center; font-size: 12px; font-weight: 600; color: #374151; white-space: nowrap; }
.ls-tbl td.sq-td-height  { padding: 0 10px; text-align: right;  font-size: 12px; color: #374151; white-space: nowrap; }
.ls-tbl td.ls-td-center  { text-align: center; }
.ls-tbl td.ls-td-right   { text-align: right;  }

/* ── Component-type label (column header) — neutral, no colour variants ── */
.ls-tbl .ls-comp-badge {
  display: inline-block;
  margin-top: 3px;
  font-size: 10px;
  padding: 1px 6px;
  border-radius: 3px;
  font-weight: 600;
  text-transform: capitalize;
  background: transparent;
  color: #9ca3af;
  border: 1px solid #e5e7eb;
}
/* All ct-* variants share the same neutral style */
.ls-tbl .ls-comp-badge[class*="ct-"] { background: transparent; color: #9ca3af; border-color: #e5e7eb; }

/* ── Cell select — fills the full cell, borderless ── */
.ls-tbl .ls-tbl-select {
  display: block;
  width: 100%;
  min-width: 120px;
  font-size: 11.5px;
  border: none;
  border-radius: 0;
  padding: 9px 10px;
  background: transparent;
  color: #374151;
  cursor: pointer;
  transition: background .12s;
  appearance: auto;
}
.ls-tbl .ls-tbl-select:hover  { background: #f5f3ff; }
.ls-tbl .ls-tbl-select:focus  { outline: none; background: #fff; box-shadow: inset 0 0 0 2px #7c3aed20; }
.ls-tbl .ls-tbl-cell-row { display: flex; align-items: stretch; gap: 0; margin: 0; }
.ls-tbl .ls-tbl-badge {
  flex-shrink: 0;
  align-self: center;
  font-size: 9px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 4px;
  border: 1px solid;
  white-space: nowrap;
  margin-right: 6px;
}
.ls-tbl .ls-tbl-badge--auto      { color: #2563eb; background: #eff6ff; border-color: #bfdbfe; }
.ls-tbl .ls-tbl-badge--confirmed { color: #059669; background: #ecfdf5; border-color: #a7f3d0; }
.ls-tbl .ls-tbl-nosku { font-size: 10px; color: #d1d5db; font-style: italic; padding: 8px 10px; }

/* ── Column number / name header block ── */
.ls-tbl .ls-th-comp-num  { font-size: 10px; font-weight: 700; color: #9ca3af; text-transform: uppercase; letter-spacing: .05em; }
.ls-tbl .ls-th-comp-name { font-size: 12px; font-weight: 700; color: #1f2937; margin-top: 2px; line-height: 1.3; white-space: normal; text-transform: none; letter-spacing: 0; }
/* Floor / Height fixed-column headers */
.ls-tbl thead tr.ls-tbl-cols th.sq-th-floor,
.ls-tbl thead tr.ls-tbl-cols th.sq-th-height { width: 60px; text-align: center; white-space: nowrap; }
/* Component column headers — allow wrapping, normal case */
.ls-tbl thead tr.ls-tbl-cols th.sq-th-comp { white-space: normal; min-width: 140px; }


/* ════════════════════════════════════════════════════
   Primary data table — primary-table-wrap / primary-table
   Universal table component. Visual reference: inspection panel line-list.
   Used site-wide: Projects, Catalogue, Engineering libraries.
   ════════════════════════════════════════════════════ */
/* ── Shared table design tokens — single source of truth for ALL tables.
   primary-table and every legacy table class (ft-, insp-, flr-, cap-,
   litespec-, ai-matches-, #systemTable …) consume these so the whole
   app shares one consistent table look. ── */
:root {
  --tbl-font:          13px;   /* body cell text */
  --tbl-head-font:     13px;   /* header text */
  --tbl-head-bg:       #f5f3ff;
  --tbl-head-color:    #1f2937;
  --tbl-head-border:   #ddd6fe;
  --tbl-head-pad:      10px 14px;
  --tbl-cell-pad:      8px 14px;
  --tbl-cell-color:    #374151;
  --tbl-border:        #f3f4f6;
  --tbl-row-hover:     #f5f3ff;
  --tbl-row-selected:  #ede9fe;
  --tbl-head-hover-bg: #ede9fe;
}
.primary-table-wrap {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  overflow-x: auto;
  overflow-y: hidden;
}
/* Auto-width variant — table shrinks to content rather than stretching full width */
.primary-table-wrap--auto {
  width: fit-content;
  max-width: 100%;
}
.primary-table {
  width: 100%;
  table-layout: auto;
  border-collapse: collapse;
  font-size: var(--tbl-font);
  font-family: inherit;
}
.primary-table thead th {
  position: sticky;
  top: 0;
  background: var(--tbl-head-bg);
  padding: var(--tbl-head-pad);
  text-align: left;
  font-size: var(--tbl-head-font);
  font-weight: 600;
  color: var(--tbl-head-color);
  border-bottom: 1px solid var(--tbl-head-border);
  border-right: none;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.primary-table thead th:last-child { cursor: default; }
.primary-table thead th:hover:not(:last-child) {
  background: var(--tbl-head-hover-bg);
  color: var(--tbl-head-color);
}
.primary-table tbody tr {
  border-bottom: 1px solid var(--tbl-border);
  cursor: pointer;
  transition: background .1s;
}
.primary-table tbody tr:last-child { border-bottom: none; }
.primary-table tbody tr:hover { background: var(--tbl-row-hover); }
.primary-table tbody tr.selected { background: var(--tbl-row-selected); }
.primary-table td {
  padding: var(--tbl-cell-pad);
  vertical-align: middle;
  border-right: 1px solid var(--tbl-border);
  color: var(--tbl-cell-color);
  font-size: var(--tbl-font);
}
.primary-table td:last-child { border-right: none; }
/* Alignment helpers */
.primary-table td.td-num,
.primary-table th.th-num { text-align: right; }
.primary-table td.td-center,
.primary-table th.th-center { text-align: center; }
/* Shrink-to-fit: action buttons, numeric IDs, short codes — column hugs its content */
.primary-table th.th-shrink,
.primary-table td.td-shrink {
  white-space: nowrap;
}
/* Descriptive columns (name/description) — also content-sized, never forced to stretch.
   Class kept for semantic intent; widths are content-driven under table-layout: auto. */
.primary-table th.th-grow,
.primary-table td.td-grow {
  width: auto;
}

/* Column resize handle — injected by ws-table-utils.js */
.ws-col-resizer {
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  width: 5px;
  cursor: col-resize;
  z-index: 1;
  background: transparent;
  transition: background .1s;
}
.ws-col-resizer:hover,
.ws-col-resizer:active {
  background: #a78bfa;
  opacity: 0.5;
}

/* Library workspace content wrapper */
.lib-workspace-wrap {
  padding: 1.75rem 1.5rem;
}

/* ════════════════════════════════════════════════════
   Shared library detail panel classes
   Used by Engineering side panels (Material, Section, Fixing, Connector, Load Case).
   ════════════════════════════════════════════════════ */
.detail-row { display: flex; justify-content: space-between; padding: 5px 0; border-bottom: 1px solid #f3f4f6; font-size: 12px; }
.detail-label { color: #6b7280; }
.detail-val { font-weight: 600; color: #1f2937; }
.detail-group { margin-bottom: 16px; }
.detail-group h4 { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: #7c5fb3; margin: 0 0 6px; }

/* Shared type badge — library tables (Material, Fixing, Connector) */
.lib-type-badge { font-size: 10px; padding: 2px 8px; border-radius: 99px; background: #ede9fc; color: #5b21b6; font-weight: 600; }

/* Shared capacity / component sub-table — Fixing, Connector, Load Case detail panels */
.cap-table { width: 100%; border-collapse: collapse; font-size: 11px; margin-top: 6px; }
.cap-table th { background: var(--tbl-head-bg); padding: 5px 8px; text-align: left; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--tbl-head-color); border-bottom: 1px solid var(--tbl-head-border); }
.cap-table td { padding: 5px 8px; border-bottom: 1px solid var(--tbl-border); color: var(--tbl-cell-color); }


/* ΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉ
   Generic icon button ΓÇö pl-icon-btn
   20├ù20px | rounded 4px | gray bg | state variants
   ΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉ */
.pl-icon-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 4px;
  border: none;
  cursor: pointer;
  font-size: 10px;
  background: transparent;
  color: #4e4e4e;
  transition: background .12s, color .12s, transform .1s;
}
.pl-icon-btn:hover { background: #d4d4d4; transform: scale(1.1); }
.pl-icon-btn:disabled { opacity: .4; cursor: default; pointer-events: none; }
.pl-icon-btn.dirty { border-color: #764ba2; background: #ede9fe; color: #764ba2; }
.pl-icon-btn.saved { border-color: #10b981; background: #dcfce7; color: #10b981; }
.pl-icon-btn i { pointer-events: none; }


/* ΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉ
   Project select dropdown ΓÇö ls-select-wrap / ls-select
   Sidebar project picker with FA folder icon.
   Usage:
     <div class="ls-select-wrap">
       <i class="fas fa-folder ls-select-icon"></i>
       <select class="ls-select" onchange="...">...</select>
     </div>
   ΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉ */
.ls-select-wrap {
  position: relative;
  display: flex;
  align-items: center;
  padding: 10px 17px;
  flex-shrink: 0;
}
.ls-select-icon {
  position: absolute;
  left: 26px;
  font-size: 12px;
  color: #7354af;
  pointer-events: none;
  z-index: 1;
}
.ls-select {
  width: 100%;
  height: 37px;
  padding: 0 28px 0 28px;
  border: 0.2px solid #dedede;
  border-radius: 6px;
  font-size: 12px;
  color: #6d6d6d;
  background: #fff;
  outline: none;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'><path fill='%236d6d6d' d='M0 0l5 6 5-6z'/></svg>");
  background-repeat: no-repeat;
  background-position: calc(100% - 10px) 50%;
  background-size: 8px 5px;
  box-sizing: border-box;
  transition: border-color .15s;
}
.ls-select:focus { border-color: #7354af; }
input.ls-select, textarea.ls-select { background-image: none; cursor: text; }

/* ΓöÇΓöÇ Shared search bar (catalogue + projects) ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ
   Exact same styles as catalog/product_library_content.html inline CSS.
   Loaded globally so projects page can reuse without duplicating.
   ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ */
.pl-search-bar {
  background: #f5f5f5;
  border: 0.5px solid #d2d2d2;
  border-radius: 10px;
  box-shadow: 0px 4px 4px 0px rgba(0,0,0,0.25);
  overflow: hidden;
  margin-bottom: 0;
}
.pl-search-bar-hdr {
  background: #dddddd;
  height: 40px;
  display: flex;
  align-items: center;
  padding: 0 21px;
}
.pl-search-bar-hdr-title {
  color: #4E4E4E; font-weight: 700; font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em;
}
.pl-search-bar-hdr-end { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.pl-search-bar-body {
  padding: 8px 20px 14px;
  display: flex;
  align-items: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}
.pl-sb-field { display: flex; flex-direction: column; gap: 4px; }
.pl-sb-field-label { font-size: 12px; font-weight: 700; color: #4e4e4e; white-space: nowrap; }
.pl-search-input-wrap { position: relative; display: inline-block; width: 251px; }
.pl-search-input-wrap i {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  color: #f5f3ff; font-size: 12px; pointer-events: none; z-index: 1;
}
.pl-search-input-wrap input {
  width: 100%; height: 32px;
  border: 0.5px solid #6d6d6d; border-radius: 6px;
  padding: 0 10px 0 32px;
  font-size: 12px; color: #4e4e4e; background: #fff;
  outline: none; box-sizing: border-box;
}
.pl-search-input-wrap input:focus { border-color: #a78bfa; }
.pl-sb-select-wrap { position: relative; }
.pl-sb-select-wrap i {
  position: absolute; right: 9px; top: 50%; transform: translateY(-50%);
  color: #4e4e4e; font-size: 10px; pointer-events: none;
}
.pl-filter-select {
  width: 149px; height: 32px;
  border: 0.5px solid #6d6d6d; border-radius: 6px;
  padding: 0 26px 0 10px;
  font-size: 12px; color: #4e4e4e; background: #fff;
  outline: none; cursor: pointer;
  appearance: none; -webkit-appearance: none;
  box-sizing: border-box;
}
.pl-filter-select:focus { border-color: #a78bfa; }
.pl-count-badge {
  font-size: 12px; color: #4e4e4e; padding: 0 10px;
  background: #fff; border-radius: 6px; height: 25px;
  display: inline-flex; align-items: center; white-space: nowrap;
}
.pl-add-btn {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 0 14px; border: none; border-radius: 7px;
  background: #764ba2; color: #fff; font-size: 12px; font-weight: 600;
  cursor: pointer; transition: background .15s; white-space: nowrap;
  height: 32px; text-decoration: none;
}
.pl-add-btn:hover { background: #5b4282; color: #fff; }

/* ════════════════════════════════════════════════════
   Framing Table (ft-)
   Shared by Stud Wall Framing and all future framing modules.
   ════════════════════════════════════════════════════ */

/* ── Page shell ──────────────────────────────────── */
#ftMatrixWrap { flex:1; overflow:auto; padding:16px 20px 24px; }

/* ════════════════════════════════════════════════════
   Split-workspace shell — universal, module-agnostic.
   Use for any module that pairs a slide-out side panel
   (e.g. .detail-panel "Design Assumptions") with a
   results canvas, inside .app-workspace's content block:

     <div class="ws-split">
       <div class="detail-panel" id="...">...</div>   <!-- optional side panel -->
       <div class="ws-split-main">
         <div class="ws-canvas">...results...</div>
       </div>
     </div>

   .ws-split       — flex row, fills the workspace, clips overflow
   .ws-split-main  — the non-panel column; owns its own scroll
   .ws-canvas      — padded, tinted content pane (was ftMain+ftContent)
   Skip .ws-split/.ws-split-main entirely for single-pane pages —
   just drop .ws-canvas straight into the content block (see
   ceiling_stud.html).
   ════════════════════════════════════════════════════ */
.ws-split      { display:flex; flex-direction:row; flex:1; overflow:hidden; }
.ws-split-main { flex:1; min-width:0; min-height:0; display:flex; flex-direction:column; overflow:auto; }
.ws-canvas     { flex:1; background:#fafafa; padding:16px; display:flex; flex-direction:column; gap:12px; }

/* ── Input panel topbar ──────────────────────────────
   Sits as a sibling element directly after .app-topbar-bar
   inside {% block dbs_topbar %}. Follows sq-stats-bar
   visual language: flat, white, border-bottom.
   ─────────────────────────────────────────────────── */
.app-topbar-panel {
  display:flex;
  align-items:stretch;
  flex-shrink:0;
  min-height:48px;
  background:var(--surface,#fff);
  border-bottom:1px solid var(--border,rgba(142,117,218,.12));
  padding:0 0.5rem;
}
.ft-filter-inner {
  display:flex;
  align-items:stretch;
  flex:1;
}
.ft-filter-section {
  display:flex;
  flex-direction:column;
  justify-content:center;
  gap:5px;
  padding:8px 16px;
  min-width:0;
  flex:1;
}
.ft-filter-section--grow { flex:1; }
.ft-filter-section-header {
  display:flex;
  flex-direction:column;
  gap:1px;
  line-height:1;
}
.ft-filter-section-title {
  font-size: var(--tbl-head-font, 12px);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--tbl-head-color, #6b7280);
}
.ft-filter-section-desc {
  font-size: var(--tbl-head-font, 12px);
  color: var(--tbl-head-color, #6b7280);
  font-weight: 400;
  opacity: .7;
}
.ft-filter-tags {
  display:flex;
  align-items:center;
  gap:6px;
  flex-wrap:wrap;
}
.ft-filter-divider {
  width:1px;
  background:var(--border,rgba(142,117,218,.12));
  flex-shrink:0;
  align-self:stretch;
  margin:8px 0;
}

/* ── Topbar zones (scope · filters · actions) ─────────
   The panel is three semantic zones, not a flat rail:
   scope is a connected context cluster on the left,
   filters grows to fill the middle, actions anchors
   hard right via margin-left:auto (robust even when the
   filters zone is empty). Replaces the old "only the
   grow section pushes actions right" mechanism.
   ─────────────────────────────────────────────────── */
.tb-zone { display:flex; align-items:stretch; min-width:0; }
.tb-zone--filters { flex:1 1 auto; min-width:0; }
.tb-zone--actions {
  margin-left:auto;
  align-items:center;
}
/* No rules between fields. Every divider the panel drew — full-height at
   first, then the thinner internal ones — fenced each control into its own
   cell, which is what made the bar read as a spreadsheet header row rather
   than a toolbar. The zones are already separated by whitespace (actions is
   pushed right by margin-left:auto), so the ink bought nothing. Spacing does
   the grouping instead: .app-field-group's 18px of side padding against its
   own 8px internal gap, so a label always sits nearer its own control than
   the neighbouring one. */

/* ── Settings cluster ─────────────────────────────────
   Module tools (Design Assumptions, Add custom system) immediately left of
   the primary Run cluster. Tighter than the zone's field spacing so the two
   read as one right-hand group rather than two unrelated islands.
   ─────────────────────────────────────────────────── */
.tb-settings { display:flex; align-items:center; gap:6px; }

/* ── Labelled field group ─────────────────────────────
   One bordered capsule: a muted label prefix + a bare control.
     .tb-field
       .tb-field__label   (icon + word, tinted, hairline to the right)
       .app-select--bare  (the control, border/background stripped)

   Exists because the Project and Loading pickers are two visually identical
   selects sitting side by side — both filled with project-ish names, told
   apart only by a cryptic 12px icon. An in-capsule label names each one
   without resurrecting the shouting standalone labels: the word is part of
   the control, lowercase-quiet, and cannot drift away from it.
   ─────────────────────────────────────────────────── */
.tb-field {
  display: inline-flex;
  align-items: stretch;
  height: var(--tb-h, 30px);
  border: 1px solid var(--neutral-border, #d1d5db);
  border-radius: var(--tb-radius, 6px);
  background: var(--surface, #fff);
  overflow: hidden;
  transition: border-color .12s, box-shadow .12s;
}
.tb-field:hover        { border-color: var(--brand-mid, #a78bfa); }
.tb-field:focus-within {
  border-color: var(--brand, #8e75da);
  box-shadow: 0 0 0 2px rgba(142,117,218,.18);
}
/* The wrapper carries the disabled look — the select inside is bare, so its
   own :disabled dimming would only fade the text, not the capsule. */
.tb-field:has(> select:disabled) { opacity: .55; }
.tb-field__label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 9px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-secondary, #6b7280);
  background: var(--neutral-bg, #f3f4f6);
  border-right: 1px solid var(--border, rgba(142,117,218,.12));
  white-space: nowrap;
  user-select: none;
}
.tb-field__label i { font-size: 11px; color: var(--brand, #8e75da); }
/* Bare select for use inside .tb-field: the capsule owns border, focus ring
   and disabled look; the select keeps only its text and caret. Declared
   after .app-select so the modifier wins at equal specificity. */
.app-select--bare,
.app-select.app-select--bare {
  height: 100%;
  border: none;
  border-radius: 0;
  background-color: transparent;
  outline: none;
  box-shadow: none;
}
.app-select--bare:focus-visible { outline: none; }
[data-theme="dark"] .tb-field { background:#1e293b; border-color:#334155; }
[data-theme="dark"] .tb-field__label { background:#0f172a; border-right-color:#334155; color:#94a3b8; }

/* ── Stacked (two-row) topbar ─────────────────────────
   Opt-in via `stacked` on the include. The panel wraps so
   the filter inputs (scope + filters zones) sit on the top
   row and the actions zone drops to its own full-width row
   below, becoming a dedicated buttons rail. Keeps the same
   sections/config — only the flow changes.
   ─────────────────────────────────────────────────── */
.app-topbar-panel--stacked { flex-wrap:wrap; }
.app-topbar-panel--stacked .tb-zone--actions {
  flex-basis:100%;
  margin-left:0;
  border-left:none;
  border-top:1px solid var(--border,rgba(142,117,218,.12));
  justify-content:flex-start;
}
/* Cap topbar select width so a long option list (e.g. many category or
   supplier names) can't blow the control out to its widest option. */
.app-topbar-panel .tb-zone .app-select { max-width:200px; }

/* ── Topbar control tokens ───────────────────────────
   Shared by all module topbar partials. Replaces
   inline styles so all modules render identically.
   ─────────────────────────────────────────────────── */

/* Generic action button — backward-compat alias for app-btn.
   New code should use app-btn / app-btn-secondary directly. */
.ft-ctrl-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--tb-gap, 6px);
  height: var(--tb-h, 30px);
  padding: 0 var(--tb-pad-x, 12px);
  border: 1px solid var(--border-strong, rgba(142,117,218,.25));
  border-radius: var(--tb-radius, 6px);
  background: var(--surface, #fff);
  color: var(--text-secondary, #6b6886);
  font-size: var(--tb-font, 12px);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background .12s, border-color .12s, color .12s;
  box-sizing: border-box;
  flex-shrink: 0;
}
.ft-ctrl-btn:hover { background: var(--brand-light, #e8e3f5); border-color: var(--brand-mid, #a78bfa); color: var(--brand, #8e75da); }
.ft-ctrl-btn:focus-visible { outline: 2px solid var(--brand-mid, #a78bfa); outline-offset: 2px; }

/* Primary — use app-btn-primary instead */
.ft-ctrl-btn--primary {
  background:   var(--brand, #8e75da);
  border-color: var(--brand, #8e75da);
  color: #fff;
}
.ft-ctrl-btn--primary:hover { background: #7c3aed; border-color: #7c3aed; color: #fff; }

/* Icon button — use app-btn-icon instead */
.ft-ctrl-btn--icon {
  padding: 0;
  width:  var(--tb-h, 30px);
  height: var(--tb-h, 30px);
  justify-content: center;
  flex-shrink: 0;
  color: var(--brand, #8e75da);
}
.ft-ctrl-btn--icon:hover { background: var(--brand-light, #e8e3f5); border-color: var(--brand-mid, #a78bfa); }

/* Auto-saved draft badge — use app-badge--info instead */
.ft-badge--draft {
  display: none;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: var(--tb-radius, 6px);
  border: 1px solid var(--info-border, #93c5fd);
  background: var(--info-bg, #dbeafe);
  color: var(--info, #1e40af);
  font-size: var(--tb-font, 12px);
  font-weight: 600;
}

/* Mode button group (Manual / Design / Run / Optimise) */
.ft-mode-group {
  display:inline-flex;
  align-self:flex-start;   /* don't stretch to full width in the column flex section */
  border:1px solid var(--border-strong,rgba(142,117,218,.25));
  border-radius:6px;
  overflow:hidden;
}
.ft-mode-btn {
  padding:4px 12px;
  border:none;
  border-left:1px solid var(--border-strong,rgba(142,117,218,.25));
  background:var(--surface,#fff);
  color:var(--text-secondary,#6b6886);
  font-size:12px;
  font-weight:600;
  cursor:pointer;
  white-space:nowrap;
  transition:background .12s, color .12s;
}
.ft-mode-btn:first-child { border-left:none; }
.ft-mode-btn--active { background:#6366f1; color:#fff; font-weight:700; }
.ft-mode-btn:hover:not(.ft-mode-btn--active) { background:var(--brand-light,#e8e3f5); color:var(--brand,#8e75da); }
.ft-products-badge {
  background:#3d1a6e;
  color:#fff;
  font-size:12px;
  font-weight:600;
  padding:4px 14px;
  border-radius:6px;
  letter-spacing:.01em;
}
/* ── Calculation status pill ─────────────────────────────────────────
   Reports calc lifecycle only — it is NOT an action. Saving belongs to the
   Save button in the same cluster; a pill that morphed into a second Save
   was the source of the duplicate-Save bug, so there is deliberately no
   --save state here. Universal — usable by any precompute module.
   States: --progress (calculating) · --warn (blocked) · --busy (saving)
   · --saved / --ok (success flash) · --error.
   Height is pinned to the shared control height so the pill lines up with
   the Run/Save buttons beside it instead of floating mid-cluster. */
.calc-status {
  display:inline-flex;
  align-items:center;
  gap:6px;
  height:var(--tb-h, 30px);
  font-size:12px;
  font-weight:600;
  line-height:1;
  border:1px solid transparent;
  border-radius:var(--tb-radius, 6px);
  padding:0 12px;
  white-space:nowrap;
  box-sizing:border-box;   /* borders inside --tb-h, matching .app-btn */
}
.calc-status--progress { color:#6d28d9; background:#ede9fe; border-color:#c4b5fd; }
.calc-status--warn     { color:#92400e; background:#fef3c7; border-color:#fcd34d; }
.calc-status--busy {
  color:#fff;
  background:var(--brand,#8e75da);
  border-color:var(--brand,#8e75da);
  cursor:default;
  opacity:.75;
}
.calc-status--error { color:#b91c1c; background:#fee2e2; border-color:#fca5a5; }
.calc-status--ok    { color:#fff; background:#16a34a; border-color:#16a34a; cursor:default; }
/* ── Status strip variant ─────────────────────────────
   The component renders the calc status as a full-width row directly under
   the rail (see input_panel_topbar.html) instead of a pill inside the
   button cluster. Layout keys on the attribute, not a class: _statusBase
   rewrites className on every state change ('calc-status calc-status--warn'),
   and an attribute is the only hook that survives that. Colours still come
   from the calc-status--* state classes above; these rules only flatten the
   pill geometry into a strip. Declared after the variants so the tie on
   specificity goes to the strip. */
[data-ta-statusbar] {
  width: 100%;
  height: auto;
  align-items: center;
  border: none;
  border-radius: 0;
  padding: 6px 17px;   /* text aligns with the scope zone's first capsule */
}
/* Determinate progress bar inside the pill ("12 / 42" + filling track).
   Driven by TopbarActions.setProgress(done, total). */
.calc-progress {
  display:inline-block;
  width:56px;
  height:4px;
  border-radius:2px;
  background:#ddd6fe;
  overflow:hidden;
  vertical-align:middle;
  margin-left:4px;
}
.calc-progress-fill {
  display:block;
  height:100%;
  width:0;
  border-radius:2px;
  background:#6d28d9;
  transition:width .3s ease;
}
/* legacy helpers kept for other uses */
.ft-filter-top { display:flex; justify-content:space-between; align-items:center; margin-bottom:10px; }
.ft-filter-label { font-size:11px; font-weight:800; text-transform:uppercase; letter-spacing:.08em; color:#374151; }
.ft-filter-section-lbl { font-size:10px; font-weight:800; text-transform:uppercase; letter-spacing:.08em; color:#9ca3af; flex-shrink:0; }
.ft-filter-row { display:flex; align-items:center; gap:8px; }
.ft-filter-row label { font-size:11px; font-weight:600; color:#374151; flex-shrink:0; }
/* Backward-compat: ft-filter-select now mirrors app-select tokens.
   New code should use app-select directly. */
.ft-filter-select {
  font-size: var(--tb-font, 12px);
  border: 1px solid var(--neutral-border, #d1d5db);
  border-radius: var(--tb-radius, 6px);
  height: var(--tb-h, 30px);
  padding: 0 28px 0 10px;
  appearance: none;
  background: var(--surface, #fff)
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'><path fill='%238e75da' d='M0 0l5 6 5-6z'/></svg>")
    no-repeat right 10px center / 8px 5px;
  min-width: 160px;
  color: var(--text-primary, #374151);
  outline: none;
  cursor: pointer;
  box-sizing: border-box;
  transition: border-color .12s;
}
.ft-filter-select:hover { border-color: var(--brand-mid, #a78bfa); }
.ft-filter-select:focus { border-color: var(--brand, #8e75da); }

/* ── Wall type filter tags ───────────────────────── */
.ft-type-tag {
  display:inline-flex; align-items:center; gap:5px;
  font-size:12px; font-weight:600; padding:5px 12px; border-radius:20px; cursor:pointer;
  border:1px solid #e5e7eb; background:#f9fafb; color:#6b7280;
  transition:background .15s, color .15s, border-color .15s;
  white-space:nowrap;
}
.ft-type-tag:hover { background:#f3f0ff; border-color:#c4b5fd; color:#6d28d9; }
.ft-type-tag.active { background:#ede9fe; border-color:#a78bfa; color:#6d28d9; font-weight:700; }
.ft-type-tag-count {
  font-size:10px; font-weight:700;
  background:rgba(0,0,0,.07);
  border-radius:10px; padding:1px 6px;
}
/* Per-type accent colours when active */
.ft-type-tag--ext.active    { background:#d1fae5; border-color:#6ee7b7; color:#065f46; }
.ft-type-tag--int.active    { background:#ede9fe; border-color:#a78bfa; color:#5b21b6; }
.ft-type-tag--party.active  { background:#fef3c7; border-color:#fcd34d; color:#92400e; }
.ft-type-tag--fire-ext.active,
.ft-type-tag--fire-int.active { background:#fee2e2; border-color:#fca5a5; color:#991b1b; }
.ft-type-tag--frw.active    { background:#ede9fe; border-color:#a78bfa; color:#5b21b6; }

/* ── View mode toggle ────────────────────────────── */
.ft-view-toggle { display:flex; border:1px solid #e5e7eb; border-radius:8px; overflow:hidden; width:fit-content; }
.ft-view-btn {
  background:#fff; border:none; cursor:pointer; font-size:12px; font-weight:600;
  color:#6b7280; padding:6px 14px; display:flex; align-items:center; gap:6px;
  transition:background .15s, color .15s; white-space:nowrap;
}
.ft-view-btn + .ft-view-btn { border-left:1px solid #e5e7eb; }
.ft-view-btn.active { background:#ede9fe; color:#7c3aed; }
.ft-view-btn:hover:not(.active) { background:#f5f0ff; color:#7c3aed; }

/* ════════════════════════════════════════════════════════════════
   UNIVERSAL APP-TOPBAR-PANEL DESIGN SYSTEM
   ════════════════════════════════════════════════════════════════
   Canonical UI classes for every control inside .app-topbar-panel
   across all LiteSpec modules (Catalog, Engineering, Libraries,
   Projects, SmartSpec, SmartQuote, Reviews, Admin).

   Naming:  app-{component}  /  app-{component}--{variant}
   Source:  this block in static/css/components.css

   Deprecated class → Universal replacement mapping:
     ft-ctrl-btn             → app-btn
     ft-ctrl-btn--primary    → app-btn-primary
     ft-ctrl-btn--icon       → app-btn-icon
     ft-filter-select        → app-select
     tb-btn                  → app-btn
     tb-btn.primary          → app-btn-primary
     tb-select / tb-input    → app-select / app-input
     status-pill--on/--off   → app-badge--success / app-badge--danger
     status-badge .pass/fail → app-badge--success / app-badge--danger
     lib-badge-archived      → app-badge--warning
     pass-pill / fail-pill   → app-badge--success / app-badge--danger
     ls-badge-uls / ls-badge-sls → app-badge--danger / app-badge--info
     ft-filter-section-title → app-label
     ft-filter-section-desc  → app-caption
     ft-filter-section       → app-field-group
   ════════════════════════════════════════════════════════════════ */

/* ── app-badge ────────────────────────────────────────────────────
   Universal status/tag badge. Replaces all pill/badge variants.
   ─────────────────────────────────────────────────────────────── */
.app-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--tb-font-label, 10px);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 99px;
  white-space: nowrap;
  line-height: 1.4;
  border: 1px solid var(--neutral-border, #d1d5db);
  background: var(--neutral-bg, #f3f4f6);
  color: var(--neutral, #6b7280);
}
.app-badge--success {
  background:   var(--success-bg,      #d1fae5);
  color:        var(--success,         #065f46);
  border-color: var(--success-border,  #a7f3d0);
}
.app-badge--warning {
  background:   var(--warning-bg,      #fef3c7);
  color:        var(--warning,         #92400e);
  border-color: var(--warning-border,  #fcd34d);
}
.app-badge--danger {
  background:   var(--danger-bg,       #fee2e2);
  color:        var(--danger,          #991b1b);
  border-color: var(--danger-border,   #fca5a5);
}
.app-badge--info {
  background:   var(--info-bg,         #dbeafe);
  color:        var(--info,            #1e40af);
  border-color: var(--info-border,     #93c5fd);
}
.app-badge--neutral {
  background:   var(--neutral-bg,      #f3f4f6);
  color:        var(--neutral,         #6b7280);
  border-color: var(--neutral-border,  #d1d5db);
}
.app-badge--primary {
  background:   var(--brand-light,     #e8e3f5);
  color:        #5b21b6;
  border-color: var(--brand-mid,       #a78bfa);
}

/* ── app-topbar-dd ────────────────────────────────────────────────
   Dropdown anchored inside .app-topbar-panel sections.
   Structure:
     .app-topbar-dd
       button.app-topbar-dd__trigger  (app-btn variant)
       .app-topbar-dd__menu
         .app-topbar-dd__item
           .app-topbar-dd__item-main  (click = primary action)
           .app-topbar-dd__actions
             button.app-topbar-dd__act-btn
             button.app-topbar-dd__act-btn--danger
   ─────────────────────────────────────────────────────────────── */
.app-topbar-dd { position: relative; }

.app-topbar-dd__menu {
  position:   absolute;
  top:        calc(100% + 4px);
  left:       0;
  min-width:  260px;
  max-height: 320px;
  overflow-y: auto;
  background: var(--surface, #fff);
  border:     1px solid var(--border, #e5e7eb);
  border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0,0,0,.12);
  z-index:    9999;
  display:    none;
}
.app-topbar-dd__menu.is-open { display: block; }
/* .tb-zone--actions is pinned to the far right edge of the page
   (margin-left:auto). A menu that grows rightward from its trigger's left
   edge (the base rule above) runs off the viewport there — the Saved dropdown
   on every module topbar had this bug. Anchor to the trigger's right edge
   instead, so the menu grows back into the toolbar. Matches the existing
   .ta-mode-menu treatment; covers Load, Columns and pricelist dropdowns alike
   since all three live in the actions zone. */
.tb-zone--actions .app-topbar-dd__menu { left: auto; right: 0; }
[data-theme="dark"] .app-topbar-dd__menu {
  background:   #1e293b;
  border-color: #334155;
}

.app-topbar-dd__empty {
  padding:    14px 12px;
  font-size:  12px;
  color:      var(--text-muted, #9ca3af);
  text-align: center;
}

.app-topbar-dd__item {
  display:       flex;
  align-items:   center;
  border-bottom: 1px solid var(--border-subtle, #f3f4f6);
}
[data-theme="dark"] .app-topbar-dd__item { border-bottom-color: #334155; }
.app-topbar-dd__item:last-child { border-bottom: none; }

.app-topbar-dd__item-main {
  flex:           1;
  min-width:      0;
  padding:        8px 10px;
  cursor:         pointer;
  display:        flex;
  flex-direction: column;
  gap:            2px;
  background:     none;
  border:         none;
  text-align:     left;
}
.app-topbar-dd__item-main:hover { background: rgba(0,0,0,.04); }
[data-theme="dark"] .app-topbar-dd__item-main:hover { background: rgba(255,255,255,.06); }

.app-topbar-dd__item-name {
  font-size:     12px;
  font-weight:   600;
  color:         var(--text, #111827);
  white-space:   nowrap;
  overflow:      hidden;
  text-overflow: ellipsis;
}
[data-theme="dark"] .app-topbar-dd__item-name { color: #f1f5f9; }

.app-topbar-dd__item-meta {
  font-size: 10px;
  color:     var(--text-muted, #9ca3af);
}

.app-topbar-dd__actions {
  display:     flex;
  align-items: stretch;
  flex-shrink: 0;
  border-left: 1px solid var(--border-subtle, #f3f4f6);
}
[data-theme="dark"] .app-topbar-dd__actions { border-left-color: #334155; }

.app-topbar-dd__act-btn {
  display:         flex;
  align-items:     center;
  justify-content: center;
  width:           30px;
  background:      none;
  border:          none;
  border-right:    1px solid var(--border-subtle, #f3f4f6);
  cursor:          pointer;
  color:           var(--text-muted, #6b7280);
  font-size:       11px;
  transition:      background .15s, color .15s;
}
[data-theme="dark"] .app-topbar-dd__act-btn { border-right-color: #334155; color: #94a3b8; }
.app-topbar-dd__act-btn:last-child { border-right: none; }
.app-topbar-dd__act-btn:hover { background: rgba(0,0,0,.06); color: var(--text, #111827); }
[data-theme="dark"] .app-topbar-dd__act-btn:hover { background: rgba(255,255,255,.08); color: #f1f5f9; }

.app-topbar-dd__act-btn--danger:hover { background: #fef2f2; color: #ef4444; }
[data-theme="dark"] .app-topbar-dd__act-btn--danger:hover { background: rgba(239,68,68,.15); color: #f87171; }

/* Load action — labelled (not icon-only) and accented so it reads as the primary action */
.app-topbar-dd__act-btn--load {
  width: auto; gap: 5px; padding: 0 10px; font-weight: 600;
  color: #7c3aed; white-space: nowrap;
}
.app-topbar-dd__act-btn--load:hover { background: #f3effb; color: #6d28d9; }
[data-theme="dark"] .app-topbar-dd__act-btn--load { color: #c4b5fd; }
[data-theme="dark"] .app-topbar-dd__act-btn--load:hover { background: rgba(124,58,237,.18); color: #ddd6fe; }

/* ── Topbar Actions (TopbarActions) ───────────────────────────────
   Universal Run / Save / Load cluster rendered by
   components/input_panel_topbar/_actions.html.
   ─────────────────────────────────────────────────────────────── */
.ta-cluster { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Run is the hero of the actions zone: bolder, wider, unmistakably primary,
   so it never reads as a peer of Save. Save/Saved stay app-btn-secondary.
   Hero-ness comes from colour, weight and width — NOT height: every control
   in the cluster shares --tb-h so the row has one baseline. */
.ta-cluster .ta-run--hero { padding: 0 18px; font-size: 13px; font-weight: 700; }

/* Live count on the always-visible Saved dropdown. */
.ta-load-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; margin-left: 2px;
  border-radius: 9px; font-size: 11px; font-weight: 700; line-height: 1;
  background: var(--brand-light, #e8e3f5); color: var(--brand, #8e75da);
}
[data-theme="dark"] .ta-load-count { background: rgba(124,58,237,.28); color: #ddd6fe; }

/* Split Run button: main action + caret, fused into one pill. */
.ta-split { display: inline-flex; align-items: stretch; }
/* Square the joint only when a caret actually follows — a modeless module
   renders Run alone inside the split, and unconditional squaring left it
   half-rounded, visibly different from every sibling module's Run. */
.ta-split .ta-run:not(:last-child) { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.ta-mode { position: relative; display: inline-flex; }
.ta-split .ta-caret {
  border-top-left-radius: 0; border-bottom-left-radius: 0;
  border-left: 1px solid rgba(255,255,255,.35);
  padding: 0 8px;
}

/* Mode menu reuses .app-topbar-dd__menu positioning; just narrower. */
.ta-mode-menu { min-width: 160px; right: 0; left: auto; padding: 4px; }
.ta-mode-item {
  display: flex; align-items: center; width: 100%;
  padding: 7px 10px; border: none; background: none; cursor: pointer;
  font-size: 12px; font-weight: 600; color: var(--text, #111827);
  border-radius: 5px; text-align: left;
}
.ta-mode-item:hover { background: rgba(0,0,0,.05); }
.ta-mode-item.is-active { background: rgba(124,58,237,.12); color: #6d28d9; }
[data-theme="dark"] .ta-mode-item { color: #f1f5f9; }
[data-theme="dark"] .ta-mode-item:hover { background: rgba(255,255,255,.07); }
[data-theme="dark"] .ta-mode-item.is-active { background: rgba(124,58,237,.28); color: #ddd6fe; }

/* ── app-btn ──────────────────────────────────────────────────────
   Universal action button. Replaces: ft-ctrl-btn, tb-btn,
   libws-btn, lib-restore-btn.
   ─────────────────────────────────────────────────────────────── */
.app-btn[hidden] { display: none; }
.app-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--tb-gap, 6px);
  height: var(--tb-h, 30px);
  padding: 0 var(--tb-pad-x, 12px);
  border: 1px solid var(--border-strong, rgba(142,117,218,.25));
  border-radius: var(--tb-radius, 6px);
  background: var(--surface, #fff);
  color: var(--text-secondary, #6b6886);
  font-size: var(--tb-font, 12px);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: background .12s, border-color .12s, color .12s;
  box-sizing: border-box;
  flex-shrink: 0;
}
.app-btn:hover {
  background:   var(--brand-light, #e8e3f5);
  border-color: var(--brand-mid,   #a78bfa);
  color:        var(--brand,       #8e75da);
}
.app-btn:focus-visible {
  outline: 2px solid var(--brand-mid, #a78bfa);
  outline-offset: 2px;
}
.app-btn:disabled,
.app-btn[disabled] { opacity: .5; cursor: not-allowed; pointer-events: none; }

/* Primary — filled brand colour */
.app-btn-primary {
  background:   var(--brand, #8e75da);
  border-color: var(--brand, #8e75da);
  color: #fff;
}
.app-btn-primary:hover  { background: #7c3aed; border-color: #7c3aed; color: #fff; }
.app-btn-primary:active { background: #6d28d9; border-color: #6d28d9; }

/* Secondary — default; kept as alias for clarity */
.app-btn-secondary {
  background:   var(--surface, #fff);
  border-color: var(--border-strong, rgba(142,117,218,.25));
  color:        var(--text-secondary, #6b6886);
}
.app-btn-secondary:hover {
  background:   var(--brand-light, #e8e3f5);
  border-color: var(--brand-mid,   #a78bfa);
  color:        var(--brand,       #8e75da);
}

/* Ghost — borderless at rest */
.app-btn-ghost {
  border-color: transparent;
  background: transparent;
  color: var(--text-secondary, #6b6886);
}
.app-btn-ghost:hover {
  background:   var(--brand-light, #e8e3f5);
  border-color: var(--brand-mid,   #a78bfa);
  color:        var(--brand,       #8e75da);
}

/* Icon button — square, icon only */
.app-btn-icon {
  width: var(--tb-h, 30px);
  height: var(--tb-h, 30px);
  padding: 0;
  justify-content: center;
  flex-shrink: 0;
}
/* Brand-tinted glyph — for icon buttons that are an accent rather than a
   neutral control (e.g. the topbar Design Assumptions button). Carries the
   colour the retired .ft-ctrl-btn--icon alias used to supply. */
.app-btn-icon--brand { color: var(--brand, #8e75da); }
/* Destructive glyph — stays neutral until hovered, so a row of icon buttons
   does not read as a wall of red, but the intent is unmistakable on approach.
   Pairs with .app-btn-icon, not with the filled .app-btn-danger. */
.app-btn-icon--danger:hover {
  color: #dc2626;
  border-color: #fecaca;
  background: #fef2f2;
}

/* ── Semantic filled variants — pair with .app-btn ────────────────
   Use for the affirmative action in a modal / toolbar:
     app-btn-danger   → delete / destructive
     app-btn-warning  → caution / proceed-with-care
     app-btn-success  → update / save / confirm-positive
   (primary = brand default; secondary = neutral cancel.)
   ─────────────────────────────────────────────────────────────── */
.app-btn-danger {
  background: #dc2626; border-color: #dc2626; color: #fff;
}
.app-btn-danger:hover  { background: #ef4444; border-color: #ef4444; color: #fff; }
.app-btn-danger:active { background: #b91c1c; border-color: #b91c1c; }

.app-btn-warning {
  background: #d97706; border-color: #d97706; color: #fff;
}
.app-btn-warning:hover  { background: #f59e0b; border-color: #f59e0b; color: #fff; }
.app-btn-warning:active { background: #b45309; border-color: #b45309; }

.app-btn-success {
  background: #059669; border-color: #059669; color: #fff;
}
.app-btn-success:hover  { background: #10b981; border-color: #10b981; color: #fff; }
.app-btn-success:active { background: #047857; border-color: #047857; }

/* ════════════════════════════════════════════════════════════════
   app-modal — UNIVERSAL modal / dialog system
   One shell, two layouts:
     • Panel   (.app-modal)           header + scrolling body + footer
     • Confirm (.app-modal-confirm)   icon + title + message + centred actions
   Tones colour the confirm icon: primary / danger / warning / success / info.
   Dark canvases (SmartQuote etc.): add .app-modal-dark on the overlay.
   JS helper:  AppModal.confirm() / .prompt() / .alert()  (defined in base.html)
   Footer buttons use .app-btn + a semantic variant (app-btn-danger…).
   ════════════════════════════════════════════════════════════════ */
.app-modal-overlay {
  position: fixed; inset: 0; z-index: 10050;
  display: none; align-items: center; justify-content: center;
  padding: 16px;
  background: rgba(17, 24, 39, .55);
}
.app-modal-overlay.open { display: flex; }

.app-modal {
  background: var(--surface, #fff);
  border: 1px solid var(--neutral-border, #e5e7eb);
  border-radius: 14px;
  width: 100%; max-width: 460px;
  max-height: 88vh;
  display: flex; flex-direction: column;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .30);
  overflow: hidden;
}
.app-modal-sm { max-width: 380px; }
.app-modal-lg { max-width: 680px; }

/* Header */
.app-modal-head {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px;
  background: var(--tbl-head-bg, #f5f3ff);
  border-bottom: 1px solid var(--tbl-head-border, #ddd6fe);
  flex-shrink: 0;
}
.app-modal-title {
  margin: 0; flex: 1;
  font-size: 15px; font-weight: 700; color: var(--text-primary, #1f2937);
  display: flex; align-items: center; gap: 8px;
}
.app-modal-title i { color: var(--brand, #7c3aed); }
.app-modal-close {
  background: none; border: none; cursor: pointer; line-height: 1;
  font-size: 16px; color: var(--text-tertiary, #9ca3af);
  padding: 4px; border-radius: 6px;
}
.app-modal-close:hover { color: #ef4444; background: rgba(239, 68, 68, .08); }

/* Body / footer */
.app-modal-body { padding: 16px 18px; overflow-y: auto; }
.app-modal-foot {
  display: flex; gap: 8px; justify-content: flex-end;
  padding: 12px 18px;
  border-top: 1px solid var(--neutral-border, #e5e7eb);
  flex-shrink: 0;
}
.app-modal-foot-center { justify-content: center; }

/* ── Confirm layout ── */
.app-modal-confirm { max-width: 380px; text-align: center; }
.app-modal-confirm .app-modal-body { padding: 24px 22px 4px; }
.app-modal-icon {
  width: 52px; height: 52px; margin: 0 auto 14px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 20px;
  background: var(--brand-light, #ede9fe); color: var(--brand, #7c3aed);
}
.app-modal-ctitle { font-size: 17px; font-weight: 700; color: var(--text-primary, #1f2937); }
.app-modal-cmsg { font-size: 13px; color: var(--text-secondary, #6b7280); margin-top: 8px; line-height: 1.5; }
.app-modal-cmsg:empty { display: none; }
.app-modal-confirm .app-modal-foot { border-top: none; justify-content: center; padding: 18px 22px 20px; }
.app-modal-confirm .app-modal-foot .app-btn { min-width: 120px; justify-content: center; height: 38px; }
/* Three-action confirm (Cancel / alt / OK): widen so buttons don't squeeze. */
.app-modal-confirm.app-modal-3btn { max-width: 460px; }
.app-modal-confirm.app-modal-3btn .app-modal-foot { gap: 10px; padding-left: 18px; padding-right: 18px; }
.app-modal-confirm.app-modal-3btn .app-modal-foot .app-btn { min-width: 0; flex: 1; padding-left: 8px; padding-right: 8px; white-space: nowrap; }

/* Tone → confirm-icon colours */
.app-modal-tone-danger  .app-modal-icon { background: #fee2e2; color: #dc2626; }
.app-modal-tone-warning .app-modal-icon { background: #fef3c7; color: #d97706; }
.app-modal-tone-success .app-modal-icon { background: #d1fae5; color: #059669; }
.app-modal-tone-info    .app-modal-icon { background: #dbeafe; color: #2563eb; }

/* Inline prompt() field + validation error */
.app-modal-field { text-align: left; margin-top: 16px; }
.app-modal-field label {
  display: block; margin-bottom: 6px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-secondary, #6b7280);
}
.app-modal-field .app-input { width: 100%; height: 34px; }
.app-modal-error { margin-top: 10px; font-size: 12px; color: #b91c1c; text-align: left; }
.app-modal-error:empty { display: none; }

/* ── Dark canvas variant (SmartQuote etc.) ── */
.app-modal-dark .app-modal { background: #1e293b; border-color: #334155; color: #e2e8f0; }
.app-modal-dark .app-modal-head { background: #1e293b; border-color: #334155; }
.app-modal-dark .app-modal-foot { border-color: #334155; }
.app-modal-dark .app-modal-title,
.app-modal-dark .app-modal-ctitle { color: #e2e8f0; }
.app-modal-dark .app-modal-cmsg { color: #94a3b8; }
.app-modal-dark .app-modal-close { color: #94a3b8; }
.app-modal-dark .app-modal-field label { color: #94a3b8; }
.app-modal-dark .app-modal-field .app-input {
  background: #0f172a; border-color: #334155; color: #e2e8f0;
}
.app-modal-dark .app-btn-secondary {
  background: #273549; border-color: #334155; color: #e2e8f0;
}
.app-modal-dark .app-btn-secondary:hover {
  background: #334155; border-color: #475569; color: #fff;
}

/* ── AIDetect (ai-detect-ui.js) ───────────────────────────────────
   Shared chrome for every AI Detect surface: toast, model pills,
   dialog scaffold. Replaces the per-template pill/toast/dialog CSS
   in project_systems.html, system_builder.html and _ai_detect.html. */
#aid-toasts { position: fixed; top: 18px; right: 18px; z-index: 100001;
  display: flex; flex-direction: column; gap: 8px; pointer-events: none; }
.aid-toast { padding: 10px 16px; border-radius: 8px; color: #fff;
  font-size: 13px; box-shadow: 0 6px 20px rgba(0,0,0,.18);
  background: #2563eb; opacity: 1; transition: opacity .3s, transform .3s; }
.aid-toast--success { background: #059669; }
.aid-toast--error   { background: #dc2626; }
.aid-toast--warning { background: #b45309; }
.aid-toast--out { opacity: 0; transform: translateY(-6px); }

.aid-model-pill { display: inline-flex; flex-direction: column; align-items: flex-start;
  gap: 1px; padding: 7px 12px; margin: 0 6px 6px 0; border: 1px solid #ddd;
  border-radius: 8px; background: #fafafa; cursor: pointer; text-align: left; }
.aid-model-pill--on { border-color: #0a66c2; background: #e8f1fb; }
.aid-mp-name { font-size: 12.5px; font-weight: 700; color: #1f2937; }
.aid-mp-note { font-size: 10.5px; color: #6b7280; }
.aid-mp-cost { font-size: 10.5px; font-weight: 700; color: #0a7d28; margin-top: 2px; }
.aid-model-pill--on .aid-mp-name { color: #0a66c2; }

.aid-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.45);
  z-index: 99999; display: flex; align-items: center; justify-content: center; }
.aid-card { background: #fff; border-radius: 10px; max-width: 520px; width: 92%;
  max-height: 84vh; display: flex; flex-direction: column;
  box-shadow: 0 12px 40px rgba(0,0,0,.3); color: #222; }
.aid-card--wide { max-width: 760px; }
.aid-card-head { display: flex; align-items: center; gap: 8px;
  padding: 14px 18px 10px; font-size: 16px; font-weight: 700; }
.aid-card-head i { color: #0a66c2; }
.aid-card-head span { flex: 1; }
.aid-card-x { border: none; background: none; font-size: 22px; line-height: 1;
  color: #9ca3af; cursor: pointer; padding: 0 2px; }
.aid-card-x:hover { color: #374151; }
.aid-card-body { padding: 4px 18px 18px; overflow-y: auto; }

/* ── AI Detect dialog content ─────────────────────────────────────
   Shared by every AI dialog body (project AI Scan, and any surface
   that renders rows inside AIDetect.dialog). These were 30+ inline
   styles in ai-scan-plan.js, which is why the same "note", "row" and
   "chip" looked slightly different here than in the canvas dialog.
   Buttons and badges are NOT redefined — use .app-btn / .app-badge.
   ─────────────────────────────────────────────────────────────── */
.aid-lede { margin: 0 0 10px; font-size: 12.5px; color: #555; }
.aid-note { margin: 0 0 12px; font-size: 13px; color: #555; }
.aid-note--warn  { color: #b35900; }
.aid-note--error { color: #b00020; }

.aid-field { margin-bottom: 10px; }
.aid-field-label { font-size: 11px; font-weight: 700; text-transform: uppercase;
  color: #6b7280; margin-bottom: 4px; }

.aid-row { display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 0; border-top: 1px solid #eee; cursor: pointer; }
.aid-row--off { opacity: .65; cursor: default; }
.aid-row-icon { width: 22px; text-align: center; color: #6d28d9; flex-shrink: 0; }
.aid-row-main { flex: 1; min-width: 0; }
.aid-row-title { font-size: 13px; font-weight: 600; color: #1f2937; }
.aid-row-sub { font-size: 11.5px; color: #6b7280;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aid-row-chips { margin-top: 3px; }
.aid-row-state { font-size: 11px; margin-top: 3px; }
.aid-row-cost { text-align: right; flex-shrink: 0;
  font-size: 11.5px; color: #0a7d28; font-weight: 700; }
.aid-cb { margin-top: 3px; flex-shrink: 0; }

.aid-chip { display: inline-block; padding: 1px 6px; margin-right: 4px;
  border-radius: 99px; background: #eef2ff; color: #4338ca; font-size: 10.5px; }

.aid-link { font-size: 11px; color: #0a66c2; }

/* Run state of one row — the four colours were a JS lookup table. */
.aid-state--ok      { color: #059669; }
.aid-state--fail    { color: #b91c1c; }
.aid-state--running { color: #0a66c2; }
.aid-state--queued,
.aid-state--idle    { color: #9ca3af; }
.aid-state--done    { color: #059669; }

.aid-foot { margin-top: 14px; display: flex; align-items: center; gap: 12px; }
.aid-foot-total { flex: 1; font-size: 12.5px; color: #374151; }
.aid-foot-total b { color: inherit; }
.aid-money { color: #0a7d28; }

/* Running state — AIDetect.running(). */
.aid-progress { display: flex; align-items: center; gap: 12px;
  padding: 6px 0 12px; }
.aid-progress-icon { font-size: 20px; color: #6d28d9; flex-shrink: 0; }
.aid-progress-main { flex: 1; min-width: 0; }
.aid-progress-title { font-size: 13.5px; font-weight: 600; color: #1f2937; }
.aid-progress-sub { font-size: 11.5px; color: #6b7280; margin-top: 2px; }
.aid-progress-time { font-size: 12px; color: #9ca3af;
  font-variant-numeric: tabular-nums; flex-shrink: 0; }

/* Post-run review panel (schedule rows before they are saved). */
.aid-review { margin-top: 16px; border-top: 2px solid #ede9fe; padding-top: 12px; }
.aid-review-title { font-size: 13px; font-weight: 700; color: #6d28d9; margin-bottom: 6px; }
.aid-review-sub { font-size: 11.5px; color: #6b7280; margin-bottom: 8px; }
.aid-review-list { max-height: 190px; overflow-y: auto; font-size: 12px; }
.aid-review-row { display: flex; gap: 8px; padding: 3px 0; border-bottom: 1px solid #f3f4f6; }
.aid-rr-tag  { width: 46px; }
.aid-rr-kind { width: 64px; color: #6b7280; }
.aid-rr-name { flex: 1; color: #374151; }
.aid-rr-size { color: #6b7280; }
.aid-review-foot { margin-top: 10px; text-align: right; }

/* ── app-input ────────────────────────────────────────────────────
   Universal text / number input. Replaces: tb-input.
   ─────────────────────────────────────────────────────────────── */
.app-input {
  height: var(--tb-h, 30px);
  padding: 0 var(--tb-pad-x, 12px);
  border: 1px solid var(--neutral-border, #d1d5db);
  border-radius: var(--tb-radius, 6px);
  background: var(--surface, #fff);
  color: var(--text-primary, #374151);
  font-size: var(--tb-font, 12px);
  outline: none;
  transition: border-color .12s;
  box-sizing: border-box;
  min-width: 0;
}
.app-input::placeholder { color: var(--text-tertiary, #9ca3af); }
.app-input:hover  { border-color: var(--brand-mid, #a78bfa); }
.app-input:focus  { border-color: var(--brand,     #8e75da); }
.app-input:disabled { opacity: .5; cursor: not-allowed; background: var(--neutral-bg, #f3f4f6); }

/* ── app-input[type=file] ─────────────────────────────────────────
   The container's border/radius/height come from .app-input above;
   this reskins the "choose file" button and filename text the browser
   draws itself, since neither inherits page CSS by default. ─────── */
.app-input[type="file"] {
  display: inline-flex;
  align-items: center;
  padding: 0 12px 0 4px;
  color: var(--text-secondary, #6b6886);
  cursor: pointer;
}
.app-input[type="file"]::file-selector-button,
.app-input[type="file"]::-webkit-file-upload-button {
  height: 22px;
  margin-right: 10px;
  padding: 0 10px;
  border: 1px solid var(--border-strong, rgba(142,117,218,.25));
  border-radius: 4px;
  background: var(--brand-light, #e8e3f5);
  color: var(--brand, #8e75da);
  font-size: var(--tb-font, 12px);
  font-weight: 600;
  cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.app-input[type="file"]:hover::file-selector-button,
.app-input[type="file"]:hover::-webkit-file-upload-button {
  background: var(--brand, #8e75da);
  border-color: var(--brand, #8e75da);
  color: #fff;
}
.app-input[type="file"]:disabled::file-selector-button,
.app-input[type="file"]:disabled::-webkit-file-upload-button { cursor: not-allowed; }

/* ── app-select ───────────────────────────────────────────────────
   Universal <select>. Replaces: ft-filter-select, tb-select.
   ─────────────────────────────────────────────────────────────── */
.app-select {
  height: var(--tb-h, 30px);
  padding: 0 28px 0 10px;
  border: 1px solid var(--neutral-border, #d1d5db);
  border-radius: var(--tb-radius, 6px);
  background: var(--surface, #fff)
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'><path fill='%238e75da' d='M0 0l5 6 5-6z'/></svg>")
    no-repeat right 10px center / 8px 5px;
  appearance: none;
  color: var(--text-primary, #374151);
  font-size: var(--tb-font, 12px);
  outline: none;
  transition: border-color .12s;
  box-sizing: border-box;
  cursor: pointer;
  min-width: 120px;
}
.app-select:hover { border-color: var(--brand-mid, #a78bfa); }
.app-select:focus { border-color: var(--brand,     #8e75da); }
.app-select:disabled { opacity: .5; cursor: not-allowed; }
/* `outline:none` above also removes the keyboard focus ring, which a border
   tint alone does not replace — it is invisible against a hover. Put a real
   ring back for keyboard users only, so mouse focus stays quiet. */
.app-select:focus-visible {
  outline: 2px solid var(--brand, #8e75da);
  outline-offset: 1px;
}

/* ── Dropdown picker — the open list ──────────────────────────────
   Universal: applies to every <select> in the app, whatever class it
   carries (.app-select, .param-select, .flr-tbl-sel, select.app-input,
   or none at all). They all open the same list, so the list is defined
   once, here.

   The closed control has always been themed; the list it opened was not,
   because the popup is drawn by the OS and CSS cannot reach it — hence
   the system font, square corners and blue highlight.

   Two layers, in order of what a browser supports:

   1. `option` colours. Honoured by Chromium's native popup and ignored
      elsewhere, so the list at least stops being white-on-blue. The dark
      theme's `color-scheme: dark` (tokens.css) already flips the popup
      chrome to match.
   2. `appearance: base-select`. Moves the picker into the page where it
      can be styled properly, matching .app-topbar-dd__menu so the app has
      one menu language. Chrome 135+ today; browsers without it keep the
      native popup and layer 1. Progressive enhancement — nothing here is
      required for a select to work.
   ─────────────────────────────────────────────────────────────── */
/* Baseline for every <select>, so a dropdown looks like a LiteSpec dropdown
   whether or not someone remembered to add .app-select. Deliberately low
   specificity (one element selector): .app-select, .param-select and the rest
   still win on the properties they set, so this only fills gaps — it does not
   re-style controls that already made a choice. Sizing is left out for the
   same reason; dense table selects set their own. */
select {
  appearance: none;
  padding: 0 28px 0 10px;
  border: 1px solid var(--neutral-border, #d1d5db);
  border-radius: var(--tb-radius, 6px);
  background: var(--surface, #fff)
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'><path fill='%238e75da' d='M0 0l5 6 5-6z'/></svg>")
    no-repeat right 10px center / 8px 5px;
  color: var(--text-primary, #374151);
  font-family: inherit;
  font-size: var(--tb-font, 12px);
  cursor: pointer;
  transition: border-color .12s;
}
select:hover { border-color: var(--brand-mid, #a78bfa); }
select:focus-visible { outline: 2px solid var(--brand, #8e75da); outline-offset: 1px; }
select:disabled { opacity: .5; cursor: not-allowed; }

select option {
  background-color: var(--surface, #fff);
  color: var(--text-primary, #374151);
}
[data-theme="dark"] select option {
  background-color: #1e293b;
  color: #f1f5f9;
}

@supports (appearance: base-select) {
  /* Every class here already sets `appearance`, so naming them is not
     redundant — a bare `select` rule loses to them on specificity and the
     picker silently stays native. That is exactly the bug this block exists
     to fix, so the list must cover every select-styling class in the app. */
  select,
  .app-select,
  select.app-input,
  .param-select,
  .flr-tbl-sel { appearance: base-select; }

  /* We paint our own caret as a background image; drop the one base-select
     supplies so the two don't stack. */
  select::picker-icon,
  .app-select::picker-icon,
  select.app-input::picker-icon,
  .param-select::picker-icon,
  .flr-tbl-sel::picker-icon { display: none; }

  /* base-select renders the closed control as a real button, so a long value
     wrapped to a second line and spilled past the fixed height — the native
     control clipped it. `nowrap` puts the clipping back.

     Clipped, not ellipsised, and that is as far as CSS goes here: Chrome
     forces overflow:visible on a base-select <select> (the picker has to
     escape the button box) and text-overflow needs a clipping box, so it
     can never fire on the select itself. `::selectedcontent` is not a
     selectable pseudo-element either. The only route to a real ellipsis is
     authoring <button><selectedcontent></selectedcontent></button> inside
     every select, which browsers without the customizable-select parser
     hoist back out as a stray button next to the control. Clipped beats
     broken. */
  select { white-space: nowrap; }
  /* Honoured only by selects that do author the button/selectedcontent
     pattern; harmless for the rest. */
  select selectedcontent {
    display: block;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }

  select::picker(select) {
    font-family: inherit;
    appearance: base-select;
    background: var(--surface, #fff);
    border: 1px solid var(--border, #e5e7eb);
    border-radius: 8px;
    box-shadow: 0 6px 20px rgba(0,0,0,.12);
    padding: 4px;
    /* At least as wide as the control, free to grow past it. The closed
       control truncates; the list is where you actually read the value, so
       it should not truncate too. */
    min-width: anchor-size(width);
    width: max-content;
    max-width: min(520px, 90vw);
    max-height: 320px;
    overflow: auto;
    /* No entrance transition here on purpose. Animating in would mean
       defaulting the picker to opacity:0 and relying on :popover-open to
       raise it — and if that selector ever fails to match, every dropdown in
       the app opens invisible. Not worth 120ms of polish. */
  }

  select option {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 10px;
    border-radius: 6px;
    font-size: var(--tb-font, 12px);
    line-height: 1.4;
    color: var(--text-primary, #374151);
    background: transparent;
    cursor: pointer;
    white-space: nowrap;
  }
  select option:hover,
  select option:focus {
    background: var(--brand-light, #e8e3f5);
    color: #5b21b6;
    outline: none;
  }
  select option:checked {
    background: var(--brand-light, #e8e3f5);
    color: #5b21b6;
    font-weight: 600;
  }
  /* The tick marks the current value; push it to the trailing edge so the
     labels stay left-aligned whether or not a row carries one. */
  select option::checkmark {
    order: 1;
    margin-left: auto;
    color: var(--brand, #8e75da);
  }
  select option:disabled { opacity: .5; cursor: not-allowed; }

  [data-theme="dark"] select::picker(select) {
    background: #1e293b;
    border-color: #334155;
    box-shadow: 0 6px 20px rgba(0,0,0,.4);
  }
  [data-theme="dark"] select option { color: #f1f5f9; background: transparent; }
  [data-theme="dark"] select option:hover,
  [data-theme="dark"] select option:focus,
  [data-theme="dark"] select option:checked {
    background: rgba(124,58,237,.22);
    color: #ddd6fe;
  }
}

/* ── app-search ───────────────────────────────────────────────────
   Search input with leading icon. Replaces: _search.html inline.
   ─────────────────────────────────────────────────────────────── */
.app-search {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 100%;
}
.app-search__icon {
  position: absolute;
  left: 9px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-tertiary, #9ca3af);
  font-size: 12px;
  pointer-events: none;
}
.app-search__input {
  height: var(--tb-h, 30px);
  padding: 0 10px 0 30px;
  border: 1px solid var(--neutral-border, #d1d5db);
  border-radius: var(--tb-radius, 6px);
  background: var(--surface, #fff);
  color: var(--text-primary, #374151);
  font-size: var(--tb-font, 12px);
  outline: none;
  transition: border-color .12s;
  box-sizing: border-box;
  width: 100%;
}
.app-search__input::placeholder { color: var(--text-tertiary, #9ca3af); }
.app-search__input:hover  { border-color: var(--brand-mid, #a78bfa); }
.app-search__input:focus  { border-color: var(--brand,     #8e75da); }

/* ── app-checkbox / app-radio ────────────────────────────────────
   Universal checkbox/radio label. Replaces: _checkbox inline.
   ─────────────────────────────────────────────────────────────── */
.app-checkbox,
.app-radio {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--tb-font, 12px);
  font-weight: 600;
  color: var(--text-primary, #374151);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  line-height: 1.3;
}
.app-checkbox input[type="checkbox"],
.app-radio    input[type="radio"] {
  width: 14px;
  height: 14px;
  accent-color: var(--brand, #8e75da);
  cursor: pointer;
  flex-shrink: 0;
}

/* ── app-toggle ───────────────────────────────────────────────────
   CSS-only toggle switch (pill). Mark up:
   <label class="app-toggle">
     <input type="checkbox" hidden>
     <span class="app-toggle__track"><span class="app-toggle__thumb"></span></span>
     <span>Label text</span>
   </label>
   ─────────────────────────────────────────────────────────────── */
.app-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: var(--tb-font, 12px);
  font-weight: 600;
  color: var(--text-secondary, #6b6886);
  user-select: none;
}
.app-toggle input[type="checkbox"] { position: absolute; opacity: 0; width: 0; height: 0; }
.app-toggle__track {
  position: relative;
  width: 36px;
  height: 20px;
  border-radius: 10px;
  background: var(--neutral-border, #d1d5db);
  transition: background .15s;
  flex-shrink: 0;
}
.app-toggle__thumb {
  position: absolute;
  top: 3px; left: 3px;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,.2);
  transition: left .15s;
}
.app-toggle input:checked + .app-toggle__track { background: var(--brand, #8e75da); }
.app-toggle input:checked + .app-toggle__track .app-toggle__thumb { left: 19px; }

/* ── app-label / app-caption / app-field-group ───────────────────
   Typography and layout for topbar control groups.
   Replaces: ft-filter-section, ft-filter-section-title,
             ft-filter-section-desc, tb-label.
   ─────────────────────────────────────────────────────────────── */
.app-label {
  font-size: var(--tbl-head-font, 12px);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--tbl-head-color, #6b7280);
  white-space: nowrap;
  line-height: 1;
}
.app-caption {
  font-size: var(--tbl-head-font, 12px);
  color: var(--tbl-head-color, #6b7280);
  font-weight: 400;
  opacity: .7;
  line-height: 1;
}
/* Single-row toolbar field: icon/label + control, vertically centred within
   the fixed-height .app-topbar-panel — replaces the old two-line
   title-over-description stack (each field used to carry its own header
   block, which is what made the bar read as a stack of form fields rather
   than one toolbar). The dropped description text moves to a `title=`
   tooltip on the control itself in each partial, so nothing is lost, just
   deferred to hover. */
.app-field-group {
  display: flex;
  align-items: center;
  gap: 8px;
  /* Must stay wider than the 8px internal gap above, or a label sits as
     close to the previous field's control as to its own — the dividers
     used to mask that, and nothing masks it now. */
  padding: 0 9px;
  min-width: 0;
  flex: 1;
}
.app-field-group--shrink { flex: 0 0 auto; }
.app-field-group--grow   { flex: 1; }
/* Kept only for the two hand-rolled panels that never adopted this
   component (connection_engine, loading_sidebar) and still render the old
   stacked title+description header. Not used by any input_panel_topbar
   partial any more. */
.app-field-group__header {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.app-field-group__icon { font-size: 14px; color: var(--brand, #8e75da); flex-shrink: 0; }

/* ── Backward-compatibility aliases ──────────────────────────────
   Old class names kept working but pointing at the same visual
   system. Templates should migrate to app-* over time.
   ft-ctrl-btn retains its own definition below.
   ft-filter-select retains its own updated definition above (line ~2249).
   ft-filter-section retains its own definition below.
   ─────────────────────────────────────────────────────────────── */

/* ════════════════════════════════════════════════════════════════ */

/* ── Grouped framing table wrap ──────────────────── */
.ft-framing-wrap { background:#fff; border:1px solid #c8bcee; border-radius:0; overflow-x:auto; overflow-y:visible; display:flex; flex-direction:column; gap:0; }

/* ── Matrix / pivot table ────────────────────────── */
.ft-wrap { background:#fff; border:1px solid #e0d9f5; border-radius:10px; overflow:hidden; box-shadow:0 1px 4px rgba(61,36,96,.06); }
.ft-table { width:100%; border-collapse:collapse; font-size:12px; }
.ft-table thead th {
  background:#5a52a2; padding:12px 14px; font-size:11px; font-weight:700;
  text-transform:uppercase; letter-spacing:.06em; color:#fff;
  border-bottom:2px solid #4a4388; white-space:nowrap; text-align:left;
}
.ft-table th.col-sticky,
.ft-table td.col-sticky { position:sticky; left:0; z-index:4; background:#fff; }
.ft-table thead th.col-sticky { background:#5a52a2; z-index:6; min-width:220px; }
.ft-table tbody td.col-sticky { border-right:2px solid #e0d9f5; min-width:220px; max-width:280px; }
.ft-table tbody tr { border-bottom:1px solid #eee9f7; }
.ft-table tbody tr:last-child { border-bottom:none; }
.ft-table tbody tr:nth-child(even) td { background:#faf8ff; }
.ft-table tbody tr:hover td { background:#ede9fe !important; }
.ft-table td { padding:10px 14px; vertical-align:middle; font-size:12px; color:#374151; }
.ft-table tbody tr:nth-child(even) td.col-sticky { background:#faf8ff; }
.ft-table tbody tr:hover td.col-sticky { background:#ede9fe !important; }
.ft-table tbody tr:hover .sys-diagram-tooltip { display:block; }

/* ── Floor column header ─────────────────────────── */
.floor-col-th { text-align:center; min-width:130px; border-left:1px solid rgba(255,255,255,.15); transition:background .2s; }
.floor-col-th.calculating { background:#6d63c2 !important; animation:floor-pulse .9s ease-in-out infinite alternate; }

/* ────────────────────────────────────────────────────
   UNIFIED SIDEBAR COMPONENT SYSTEM
   All sidebars (SmartSpec, WSF, Catalog, etc.) use
   these base styles for consistency: typography,
   spacing, colors, and interactive states.
   ──────────────────────────────────────────────────── */

/* Base sidebar section header — consistent across all modules */
.sidebar-section-header {
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 10px 12px 6px;
  margin-top: 12px;
  margin-bottom: 0;
  flex-shrink: 0;
  border-bottom: 1px solid var(--secondary-sidebar-border);
  color: rgba(0, 0, 0, 0.55);
}

[data-theme="dark"] .sidebar-section-header {
  color: rgba(255, 255, 255, 0.55);
}

.sidebar-section-header:first-child {
  margin-top: 0;
}

/* Base sidebar list item — consistent spacing and typography */
.sidebar-list-item {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 12px;
  font-size: var(--fs-md);
  font-weight: 500;
  color: var(--secondary-sidebar-text);
  cursor: pointer;
  border-bottom: 1px solid var(--secondary-sidebar-border);
  transition: background 0.12s;
}

.sidebar-list-item:last-child {
  border-bottom: none;
}

.sidebar-list-item:hover {
  background: rgba(0, 0, 0, 0.04);
}

[data-theme="dark"] .sidebar-list-item:hover {
  background: rgba(255, 255, 255, 0.06);
}

.sidebar-list-item.active {
  background: rgba(0, 0, 0, 0.08);
  color: var(--secondary-sidebar-text);
  font-weight: 600;
}

[data-theme="dark"] .sidebar-list-item.active {
  background: rgba(255, 255, 255, 0.1);
}

/* Empty state in sidebar list */
.sidebar-list-empty {
  font-size: var(--fs-md);
  color: rgba(0, 0, 0, 0.4);
  text-align: center;
  padding: 12px 10px;
}

[data-theme="dark"] .sidebar-list-empty {
  color: rgba(255, 255, 255, 0.4);
}

/* ── Shared sidebar list primitives (used by SmartSpec, WSF, etc.) ── */
.ss-sec-head {
  padding: 10px 12px 6px;
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  gap: 5px;
  flex-shrink: 0;
  margin-top: 12px;
  border-bottom: 1px solid var(--secondary-sidebar-border);
}

[data-theme="dark"] .ss-sec-head {
  color: rgba(255, 255, 255, 0.55);
}

.ss-sec-head:first-child { margin-top: 0; }
.ss-sec-head-notop { margin-top: 0 !important; }
.ss-sec-badge { font-size: var(--fs-sm); color: rgba(0, 0, 0, 0.55); font-weight: 400; }
[data-theme="dark"] .ss-sec-badge { color: rgba(255, 255, 255, 0.55); }
.ss-viewall { margin-left: auto; font-size: var(--fs-md); font-weight: 600; color: rgba(0, 0, 0, 0.55); text-decoration: none; cursor: pointer; }
[data-theme="dark"] .ss-viewall { color: rgba(255, 255, 255, 0.55); }
.ss-viewall:hover { text-decoration: underline; }

.ss-list-item {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 12px;
  font-size: var(--fs-md);
  font-weight: 500;
  color: var(--secondary-sidebar-text);
  cursor: pointer;
  transition: background 0.12s;
  border-bottom: 1px solid var(--secondary-sidebar-border);
}
.ss-list-item:last-child { border-bottom: none; }
.ss-list-item:hover { background: rgba(0, 0, 0, 0.04); }
[data-theme="dark"] .ss-list-item:hover { background: rgba(255, 255, 255, 0.06); }
.ss-list-item.active { background: rgba(0, 0, 0, 0.08); font-weight: 600; }
[data-theme="dark"] .ss-list-item.active { background: rgba(255, 255, 255, 0.1); }
.ss-list-empty { font-size: var(--fs-md); color: rgba(0, 0, 0, 0.4); text-align: center; padding: 12px 10px; }
[data-theme="dark"] .ss-list-empty { color: rgba(255, 255, 255, 0.4); }

/* Dark sidebar variant (WSF) */
.ss-list-item--dark {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 12px;
  font-size: var(--fs-md);
  font-weight: 500;
  color: var(--secondary-sidebar-text);
  cursor: pointer;
  background: transparent;
  border-bottom: 1px solid var(--secondary-sidebar-border);
  transition: background 0.12s;
}
.ss-list-item--dark:hover { background: rgba(0, 0, 0, 0.04); }
[data-theme="dark"] .ss-list-item--dark:hover { background: rgba(255, 255, 255, 0.06); }
.ss-list-item--dark.is-active { background: rgba(0, 0, 0, 0.08); font-weight: 600; }
[data-theme="dark"] .ss-list-item--dark.is-active { background: rgba(255, 255, 255, 0.1); }
.ss-list-item--dark .ss-wt-del-btn { opacity: 0; transition: opacity .15s; }
.ss-list-item--dark:hover .ss-wt-del-btn { opacity: 1; }
.ss-list-item--dark .ss-wt-edit-btn { opacity: 0; }
.ss-list-item--dark:hover .ss-wt-edit-btn,
.ss-list-item--dark.is-active .ss-wt-edit-btn,
.ss-list-item--dark.is-active .ss-wt-del-btn { opacity: 1; }

/* Apply dark styling to calc-row items */
.ss-list-item.calc-row {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 10px; font-size: 12px; font-weight: 500; 
  color: rgba(0, 0, 0, 0.5);
  cursor: pointer;
  background: rgba(0, 0, 0, 0.02);
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  transition: background .12s, color .12s;
  height: auto;
  border: none;
}
.ss-list-item.calc-row:hover { background: rgba(0, 0, 0, 0.04); color: rgba(0, 0, 0, 0.7); }
[data-theme="dark"] .ss-list-item.calc-row {
  color: #9098b8;
  background: rgba(255, 255, 255, 0.03);
  border-bottom-color: rgba(255, 255, 255, 0.04);
}
[data-theme="dark"] .ss-list-item.calc-row:hover { background: rgba(255, 255, 255, 0.06); color: #d0d6ee; }

/* Spinning load icon */
.calc-row-load-icon {
  animation: spin 1s linear infinite;
  display: inline-block;
  flex-shrink: 0;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.ss-wt-del-btn { opacity: 0; transition: opacity .15s; }
.ss-list-item:hover .ss-wt-del-btn { opacity: 1; }
.ss-wt-del-btn:hover { background: rgba(220, 38, 38, 0.08); }
[data-theme="dark"] .ss-wt-del-btn:hover { background: rgba(220, 38, 38, 0.15); }

/* ════════════════════════════════════════════════════
   Dark sidebar — SmartSpec utility classes
   Matches the WSF dark sidebar design system (ms-*)
   ════════════════════════════════════════════════════ */

/* Scrollable list container inside dark sidebar */
.ms-list-scroll {
  overflow-y: auto;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  flex-shrink: 0;
}
.ms-list-scroll--sm  { max-height: 140px; }
.ms-list-scroll--md  { max-height: 200px; }
.ms-list-scroll--lg  { max-height: 280px; }
#sq-drawing-list { max-height: 550px; overflow: hidden; border-bottom: 1px solid var(--secondary-sidebar-border); }

/* Item name — truncating span */
.ms-item-name {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Icon colour variants inside ss-list-item--dark */
.ss-li-ico { font-size: 9px; flex-shrink: 0; }
.ss-li-ico--muted  { color: rgba(0, 0, 0, 0.5); }
[data-theme="dark"] .ss-li-ico--muted { color: #94a3b8; }
.ss-li-ico--blue   { color: #2563eb; }
[data-theme="dark"] .ss-li-ico--blue { color: #60a5fa; }
.ss-li-ico--purple { color: #7c3aed; font-size: 5px; }
[data-theme="dark"] .ss-li-ico--purple { color: #a78bfa; }
.ss-li-ico--lilac  { color: #a78bfa; font-size: 6px; }
[data-theme="dark"] .ss-li-ico--lilac { color: #c4b5fd; }

/* Count badge inside ms-section-header */
.ms-sec-count {
  font-size: 9px;
  font-weight: 500;
  color: #4a5070;
  margin-left: 4px;
}

/* Mini add button inside ms-section-header */
.ms-add-btn {
  margin-left: auto;
  background: rgba(108,92,231,0.15);
  border: 1px solid rgba(108,92,231,0.3);
  color: #a78bfa;
  border-radius: 4px;
  width: 18px;
  height: 18px;
  font-size: 9px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background .12s, border-color .12s, color .12s;
}
.ms-add-btn:hover { background: #6c5ce7; color: #fff; border-color: #6c5ce7; }

/* "View all" link — bottom of a dark list section */
.ms-viewall {
  display: block;
  text-align: center;
  font-size: 9px;
  font-weight: 500;
  color: #6c5ce7;
  padding: 5px 8px 6px;
  text-decoration: none;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  background: rgba(108,92,231,0.05);
  flex-shrink: 0;
  transition: background .12s, color .12s;
}
.ms-viewall:hover { background: rgba(108,92,231,0.12); color: #a78bfa; text-decoration: none; }

/* Smartspec sidebar: slightly larger, more readable "View all" link */
.ms-sidebar .ms-viewall {
  font-size: 12px;
  padding: 8px 10px;
  color: #6c5ce7;
  background: transparent;
  border-bottom: 1px solid rgba(255,255,255,0.02);
}

/* Empty state inside dark list */
.ms-list-empty {
  font-size: 10px;
  color: #4a5070;
  text-align: center;
  padding: 8px 10px;
  margin: 0;
}

/* Gray system badge variant */
.ss-sys-badge--gray { background: #6d6d6d; }

/* Drawings section — hidden until project selected */
.ms-drawings-wrap { display: none; flex-shrink: 0; }
.ms-drawings-list {
  padding: 0 8px 6px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Project AI systems section — hidden until project selected */
.ms-project-section { display: none; flex-shrink: 0; }

/* Edit + delete action buttons group inside ss-list-item */
.ss-wt-action-btns {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}
.ss-wt-edit-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 4px;
  color: #7c3aed;
  cursor: pointer;
  font-size: 10px;
  background: transparent;
  border: none;
  opacity: 0;
  transition: background .12s, opacity .15s;
}
.ss-wt-edit-btn:hover { background: #ede9fe; }
/* Show both buttons only on hover OR when item is active */
.ss-list-item:hover .ss-wt-edit-btn,
.ss-list-item.active .ss-wt-edit-btn { opacity: 1; }
.ss-list-item.active .ss-wt-del-btn { opacity: 1; }
.ss-sys-badge {
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  height: 15px; padding: 0 6px; border-radius: 2px;
  font-size: var(--fs-2xs); font-weight: 400; color: #fff; white-space: nowrap;
  max-width: 110px; overflow: hidden; text-overflow: ellipsis;
}
.ss-cardbox {
  margin: 0 17px 8px; background: #fff;
  border: 0.5px solid #d2d2d2; border-radius: 6px; overflow: hidden; flex-shrink: 0;
}

@keyframes floor-pulse { from { background:#6d63c2; } to { background:#7c72cc; } }
.floor-name-lbl { font-size:12px; font-weight:800; margin-bottom:2px; }
.floor-h-label { display:block; font-size:9px; color:rgba(255,255,255,.65); text-transform:uppercase; letter-spacing:.06em; margin-bottom:3px; }
.floor-h-wrap { display:flex; align-items:center; justify-content:center; gap:4px; }
.floor-h-input { width:62px; padding:3px 6px; font-size:11px; border:1px solid rgba(255,255,255,.3); border-radius:5px; background:rgba(255,255,255,.15); color:#fff; text-align:right; transition:border-color .15s, background .15s; }
.floor-h-input:focus { outline:none; border-color:#fff; background:rgba(255,255,255,.25); }
.floor-h-input.dirty { border-color:#fbbf24; background:rgba(251,191,36,.2); }
.floor-h-unit { font-size:9px; color:rgba(255,255,255,.6); }

/* ── Type separator rows ─────────────────────────── */
.type-sep-row td { background:#f3f0fb !important; padding:4px 14px; border-bottom:1px solid #e0d9f5; }
.type-sep-label { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.06em; color:#6d4fa8; display:inline-flex; align-items:center; gap:6px; }

/* ── Wall system cell ────────────────────────────── */
.sys-cell-inner { position:relative; padding-left:12px; }
.sys-type-accent { position:absolute; left:0; top:6px; bottom:6px; width:3px; border-radius:2px; }
.sys-type-accent.ext      { background:#3b82f6; }
.sys-type-accent.int      { background:#9ca3af; }
.sys-type-accent.pty      { background:#f59e0b; }

/* ── SmartSpec System Builder — shared panel components ── */

/* Secondary sidebar panel: compact inputs column with lavender accent */
.sidebar-secondary {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 8px 12px;
  gap: 6px;
  border-right: 1px solid #c4b5fd;
}
.sidebar-secondary input::placeholder,
.sidebar-secondary textarea::placeholder {
  color: #c4b5fd;
  font-weight: 300;
  font-style: italic;
  opacity: 1;
}

/* ── Slide-out panel (collapses to width:0, expands on .open) ── */
.detail-panel {
  width: 0; flex-shrink: 0; overflow: hidden;
  transition: width .22s cubic-bezier(.4,0,.2,1);
  background: #fff;
  box-shadow: 4px 0 12px rgba(0,0,0,.10);
  display: flex; flex-direction: column; position: relative; z-index: 10;
}
.detail-panel.open { width: var(--detail-panel-width, 300px); }
.detail-panel-inner {
  width: 100%;
  display: flex; flex-direction: column; height: 100%;
}
.detail-panel-header {
  padding: 9px 12px 8px; background: #f2f4f8; border-bottom: 1px solid #e5e7eb;
  flex-shrink: 0; font-size: var(--fs-md); font-weight: 600;
  letter-spacing: .06em; color: #7354af; display: flex; align-items: center; gap: 6px;
}
.detail-panel-body {
  flex: 1; overflow-y: auto; padding: 2px 0;
}
.detail-panel-footer {
  padding: 6px 10px; border-top: 1px solid #f3f4f6;
  display: flex; gap: 4px; flex-wrap: wrap; align-items: center; flex-shrink: 0;
}

/* System library pagination background */
#sb-lib-pagination {
  background: #f2f4f8;
}

/* Centralized SmartSpec detail-panel overrides moved from smartspec.css */
/* Apply 500px width and header styling for SmartSpec panels */
#sb-lib-list,
.detail-panel-body.system-library {
  width: 100%;
  box-sizing: border-box;
}

/* Make slide panel headers consistent across app */
.detail-panel-header {
  height: 50px;
  min-height: 50px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  color: #271354;
  font-weight: 700;
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  box-sizing: border-box;
}

/* Ensure header action icons match header color (override inline styles) */
.detail-panel-header button i.fas.fa-times,
.detail-panel-header button i.fas.fa-arrow-left {
  color: #271354 !important;
}

/* Normalize header title font-size across specific SmartSpec panels */
.detail-panel-header .panel-title,
.detail-panel-header #sb-new-title,
.detail-panel-header #sb-clg-header-title {
  font-size: 14px !important;
  font-weight: 700 !important;
  line-height: 1.2 !important;
}

/* Choice cards used by the New System panel (moved from smartspec.css) */
.sb-new-choice-card {
  flex: 0 0 160px;
  width: 160px;
  padding: 12px 10px;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  background: #fafafa;
  cursor: pointer;
  text-align: center;
  transition: border-color .15s, background .15s;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  box-sizing: border-box;
  gap: 8px;
}
.sb-new-choice-card:hover { border-color: #a78bfa; background: #f5f3ff; }
.sb-new-card-icon { font-size: 18px; color: #7c3aed; }
.sb-new-card-label { font-size: 12px; font-weight: 700; color: #1e1b4b; margin-top: 0; }
.sb-new-card-desc { font-size: 10px; color: #9ca3af; line-height: 1.25; }

/* Row-style choice cards — New System panel */
.sb-new-row-card {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border: 1.5px solid #e9e9f0; border-radius: 10px;
  background: #fff; cursor: pointer; text-align: left; width: 100%;
  box-sizing: border-box; transition: border-color .15s, background .15s, box-shadow .15s;
}
.sb-new-row-card:hover { border-color: #a78bfa; background: #faf9ff; box-shadow: 0 2px 8px rgba(124,58,237,.08); }
.sb-row-card-icon {
  width: 38px; height: 38px; border-radius: 10px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 16px;
}
.sb-row-card-icon--lib { background: #eff6ff; color: #2563eb; }
.sb-row-card-icon--tpl { background: #ede9fe; color: #7c3aed; }
.sb-row-card-body { flex: 1; min-width: 0; }
.sb-row-card-title { font-size: 12.5px; font-weight: 700; color: #1a1b2e; }
.sb-row-card-desc { font-size: 10.5px; color: #9ca3af; margin-top: 1px; line-height: 1.35; }
.sb-row-card-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 7px; }
.sb-row-card-chip { font-size: 9px; font-weight: 600; padding: 2px 7px; border-radius: 99px; background: #f3f4f6; color: #6b7280; border: 1px solid #e5e7eb; }
.sb-row-card-arrow { font-size: 10px; color: #d1d5db; flex-shrink: 0; transition: color .15s, transform .15s; }
.sb-new-row-card:hover .sb-row-card-arrow { color: #7c3aed; transform: translateX(2px); }

/* Column heading (used in sb-info-right-bar, sb-info-col-right) */
.sb-info-col-heading {
  font-size: var(--fs-md); font-weight: 700; color: #4e4e4e;
  padding: 6px 10px 5px; border-bottom: 1px solid #e2e8f0;
  display: flex; align-items: center; gap: 4px; flex-shrink: 0;
}

/* System info rows — 2-column grid */
.sb-sysinfo-rows { display: flex; flex-direction: column; padding: 4px 0; overflow-y: auto; flex: 1; }
.sb-sysinfo-grid  { display: grid; grid-template-columns: 1fr 1fr; gap: 0; padding: 0; border: 1px solid #e5e7eb; border-radius: 0; overflow: hidden; }
.sb-sysinfo-col   { display: contents; }
.sb-sysinfo-col-perf { border-left: none; }
.sb-sysinfo-lbl { font-size: 11px; font-weight: 500; color: #6b7280; width: 60px; flex-shrink: 0; }
.sb-sysinfo-val,
.sb-perf-val    { font-size: 11px; font-weight: 600; color: #4e4e4e; }
.sb-sysinfo-val strong,
.sb-perf-val strong { font-weight: 700; }
/* supplier brand colour applied via inline style */
.sb-sysinfo-thermal strong { background: #53a24f; color: #fff; padding: 1px 7px; border-radius: 2px; font-size: 11px; font-weight: 700; }

/* System info grid rows — compact with border separators */
.sb-sysinfo-grid .ss-list-item {
  height: auto; min-height: 28px; padding: 4px 10px; cursor: default; gap: 4px;
  border-bottom: 1px solid #e5e7eb; border-right: 1px solid #e5e7eb; background: none;
  font-size: 11px;
}
.sb-sysinfo-grid .ss-list-item:nth-child(2n) { border-right: none; }
.sb-sysinfo-grid .ss-list-item:last-child { border-bottom: none; }
.sb-sysinfo-grid .ss-list-item:nth-last-child(2):nth-child(odd) { border-bottom: none; }
.sb-sysinfo-grid .ss-list-item:hover { background: none; }

/* Perf value colours */
.sb-perf-val.frl   { color: #dc2626; }
.sb-perf-val.rw    { color: #2563eb; }
.sb-perf-val.width { color: #0891b2; }
.sb-perf-val.stud  { color: #6d6d6d; }
.sb-perf-empty { color: #9ca3af; font-weight: 400; font-size: 11px; }

/* Column action buttons */
.sb-col-btn {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 14px; border-radius: 6px; border: none;
  font-size: var(--fs-base); font-weight: 600; cursor: pointer;
  transition: opacity .15s; white-space: nowrap;
}
.sb-col-btn-primary { background: #7354af; color: #fff; box-shadow: 0 4px 2px rgba(0,0,0,0.25); }
.sb-col-btn-primary:hover { opacity: .88; }
.sb-col-btn-primary:disabled { background: #c4b5fd; color: #fff; cursor: default; opacity: .65; }
.sb-col-btn-danger { background: #ef4444; color: #fff; text-decoration: none; }
.sb-col-btn-danger:hover { opacity: .88; color: #fff; }

/* Info cell — labelled input field with lavender styling */
.sb-info-cell {
  display: flex; flex-direction: column;
  background: rgba(255,255,255,0.65); border: 1px solid rgba(255,255,255,0.9);
  border-radius: 6px; padding: 4px 10px; min-width: 0; cursor: text;
  transition: border-color .15s, background .15s, box-shadow .15s;
}
.sb-info-cell:hover { border-color: #a78bfa; background: rgba(255,255,255,0.85); }
.sb-info-cell:focus-within { border-color: #7c3aed; background: #fff; box-shadow: 0 0 0 2px #ede9fe66; }
.sb-info-cell.sb-cell-error { border-color: #ef4444 !important; background: #fef2f2 !important; box-shadow: 0 0 0 2px rgba(239,68,68,.25) !important; animation: sb-input-shake .35s ease; }
@keyframes sb-input-shake {
  0%,100% { transform: translateX(0); }
  25%      { transform: translateX(-4px); }
  75%      { transform: translateX(4px); }
}
.sb-info-cell.notes-cell { flex: 1; }
.sb-info-cell label {
  font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase;
  letter-spacing: .07em; color: #6d28d9; white-space: nowrap;
  margin-bottom: 1px; cursor: text; user-select: none;
}
.sb-info-cell input, .sb-info-cell textarea {
  border: none; padding: 0; font-size: var(--fs-md); color: #1f2937;
  background: transparent; outline: none; min-width: 0; resize: none; font-weight: 600;
}
.sb-info-cell textarea { height: 100%; min-height: 28px; line-height: 1.4; }
.sys-type-accent.fire-ext { background:#ef4444; }
.sys-type-accent.fire-int { background:#f97316; }
.sys-type-accent.frw      { background:#ec4899; }
.sys-title-row { display:flex; align-items:center; gap:5px; flex-wrap:wrap; margin-bottom:2px; }
.sys-sub-row { font-size: var(--fs-sm); color:#9ca3af; display:flex; align-items:center; gap:4px; flex-wrap:wrap; }
.sys-sub-row i { color:#c4b5fd; font-size: var(--fs-xs); }
.sys-name { font-size: var(--fs-md); font-weight:700; color:#1f2937; }
.sys-frl  { font-size:9px; font-weight:700; color:#dc2626; background:#fee2e2; border-radius:3px; padding:1px 5px; }
.sys-src  { font-size:9px; color:#a78bda; }
.sys-diagram-tooltip { display:none; position:absolute; left:105%; top:50%; transform:translateY(-50%); z-index:50; background:#fff; border:1px solid #e5e7eb; border-radius:8px; box-shadow:0 4px 20px rgba(0,0,0,.12); padding:8px; pointer-events:none; white-space:nowrap; }
.sys-count-badge { display:inline-flex; align-items:center; background:rgba(255,255,255,.25); color:#fff; font-size:9px; font-weight:800; border-radius:99px; padding:1px 7px; }

/* ── Type badges ─────────────────────────────────── */
.type-badge { display:inline-block; padding:2px 7px; border-radius:99px; font-size:10px; font-weight:700; white-space:nowrap; }
.type-badge.ext      { background:#dbeafe; color:#1d4ed8; }
.type-badge.int      { background:#f3f4f6; color:#6b7280; }
.type-badge.pty      { background:#fef3c7; color:#92400e; }
.type-badge.fire-ext { background:#fee2e2; color:#991b1b; }
.type-badge.fire-int { background:#fff7ed; color:#9a3412; }
.type-badge.frw      { background:#fce7f3; color:#9d174d; }

/* ── Result cells ────────────────────────────────── */
.result-cell { text-align:center; cursor:pointer; min-width:120px; border-left:1px solid #eee9f7; }
.result-cell:hover { background:#ede9fe !important; }
.result-cell.sel { background:#e9e3f7 !important; outline:2px solid #a78bdb; outline-offset:-2px; }
.cell-empty { color:#d1d5db; font-size:18px; }
.cell-loading { display:inline-flex; align-items:center; gap:5px; color:#a78bdb; font-size:10px; }
.cell-util { display:inline-block; padding:2px 8px; border-radius:99px; font-size:12px; font-weight:800; }
.cell-util.pass { background:#d1fae5; color:#065f46; }
.cell-util.warn { background:#fef3c7; color:#92400e; }
.cell-util.fail { background:#fee2e2; color:#991b1b; }
.cell-st { font-size:10px; font-weight:700; }
.cell-st.pass { color:#059669; }
.cell-st.warn { color:#d97706; }
.cell-st.fail { color:#ef4444; }
.cell-err { color:#ef4444; font-size:10px; font-weight:700; }

/* ── Add custom / delete rows ────────────────────── */
.add-custom-row td { padding:8px 14px; background:#fafafa; border-top:2px dashed #e5e7eb; }
.ft-add-custom-btn { padding:5px 12px; font-size:11px; font-weight:600; border:1.5px dashed #a78bdb; border-radius:7px; background:transparent; color:#7c3aed; cursor:pointer; display:inline-flex; align-items:center; gap:6px; transition:background .12s; }
.ft-add-custom-btn:hover { background:#f5f3ff; }
.row-del-td { width:24px; padding:0 4px !important; text-align:center; }
.row-del { visibility:hidden; background:none; border:none; color:#f87171; cursor:pointer; padding:3px 5px; font-size:11px; border-radius:4px; }
tr:hover .row-del { visibility:visible; }

/* ── Grouped framing rows ────────────────────────── */
.ft-empty { display:flex; flex-direction:column; align-items:center; justify-content:center; padding:64px 20px; color:#9ca3af; text-align:center; }
.ft-empty i { font-size:30px; margin-bottom:12px; color:#d1d5db; }
.ft-empty p { font-size:12px; margin:0; }
.ft-col-header {
  display:flex; align-items:center; background:#f9f6fe;
  border-bottom:0.2px solid #c2c2c2; font-size:12px; font-weight:500; color:#4e4e4e;
}
.ft-col-header .ft-group-strip-hdr { width:28px; min-width:28px; flex-shrink:0; display:flex; align-items:center; justify-content:center; padding:0; }
.ft-col-header .ft-cell { color:#4e4e4e; }
.ft-group { border-bottom:1px solid #c8bcee; border:none; border-bottom:1px solid #c8bcee; border-radius:0; overflow:hidden; background:#fff; box-shadow:none; }
.ft-group:last-of-type { border-bottom:none; }
.ft-group-header { display:flex; flex-direction:column; border-bottom:1px solid #c8bcee; background:#f9f6ff; border-radius:0; color:#7154aa; padding:0; position:relative; }
.ft-group-nametag { padding:10px 14px; display:flex; align-items:center; justify-content:flex-start; width:100%; box-sizing:border-box; gap:8px; min-height:44px; }
.ft-group-nametag-badge { background:#ede9fe; color:#6d28d9; font-size:12px; font-weight:700; padding:3px 10px; border-radius:20px; border:1px solid #c4b5fd; letter-spacing:0.02em; }
.ft-group-nametag-spacer { flex:1; }
.ft-group-nametag-supplier { font-weight:600; color:#059669; }
.ft-group-body { display:grid; grid-template-columns: 140px 200px 200px 1fr 1fr; align-items:flex-start; background:#fff; gap:12px; padding:6px 14px 14px 14px; position:relative; }
.ft-group-left { display:flex; flex-direction:column; }
.ft-group-thumbarea { flex:1; display:flex; align-items:center; justify-content:center; }
.ft-group-thumb { width:100%; background:#f9f6ff; display:flex; align-items:center; justify-content:center; overflow:hidden; border-radius:4px; min-height:80px; border:1px solid #e5d9ff; }
.ft-group-right { display:contents; }
.ft-group-meta { font-size:12px; color:#374151; display:contents; }
.meta-box { background:transparent; padding:0 12px; border-radius:0; border:none; border-right:1px solid #e5d9ff; }
.meta-box:last-child { border-right:none; grid-column: span 2; }
.meta-box-title { font-weight:700; color:#7154aa; font-size:11px; text-transform:uppercase; letter-spacing:.08em; margin-bottom:10px; display:block; }
.meta-box-field { display:flex; flex-direction:row; justify-content:space-between; align-items:center; gap:16px; margin-bottom:6px; font-size:11px; }
.meta-box-field:last-child { margin-bottom:0; }
.meta-box-col { display:flex; flex-direction:column; flex:1; }
.meta-box-col:not(:last-child) { border-right:1px solid #e5d9ff; padding-right:12px; }
.meta-box-col .meta-box-field { margin-bottom:10px; }
.meta-box-col .meta-box-field:last-child { margin-bottom:0; }
.meta-box-label { font-weight:700; color:#5b5b7f; font-size:11px; white-space:nowrap; text-transform:capitalize; text-align:left; }
.meta-box-value { color:#374151; font-size:11px; font-weight:500; text-align:right; flex-shrink:0; }
.meta-box-icon { margin-right:4px; color:#7154aa; }
.ft-group-actions { position:absolute; bottom:12px; right:14px; display:flex; gap:6px; }
.ft-btn-icon { width:28px; height:28px; border-radius:5px; border:1px solid #e5e7eb; background:#fff; cursor:pointer; display:flex; align-items:center; justify-content:center; font-size:12px; color:#6b7280; transition:background .15s, color .15s, border-color .15s; }
.ft-btn-icon:hover { background:#ede9fe; color:#7c3aed; border-color:#c4b5fd; }
.ft-btn-icon.remove-system { color:#ef4444; }
.ft-btn-icon.remove-system:hover { background:#fef2f2; border-color:#fca5a5; }
.ft-btn-icon.collapse-toggle { min-width:28px; }
.ft-floor-rows { display:table; border-collapse:collapse; width:auto; }
.ft-floor-rows.collapsed { display:none; }
.ft-col-header { display:table-row; background:#f9f6fe; border-bottom:1px solid #e5d9ff; font-size:11px; font-weight:600; color:#6d28d9; position:sticky; top:0; z-index:3; }
.ft-floor-row { display:table-row; border-bottom:1px solid #f3e8ff; cursor:pointer; transition:background .12s; }
.ft-floor-row:last-child { border-bottom:none; }
.ft-floor-row:hover .ft-cell,
.ft-floor-row:hover .ft-group-strip,
.ft-col-header:hover .ft-cell { background:#faf8ff; }
.ft-floor-row:hover .ft-group-strip { filter:brightness(1.05); }
.ft-floor-row.selected .ft-cell { background:#ede9fe; }
.ft-group.ft-group-alt .ft-floor-row .ft-cell { background:#fff; }
.ft-group.ft-group-alt .ft-floor-row:hover .ft-cell { background:#faf8ff; }
.ft-group.ft-group-alt .ft-floor-row.selected .ft-cell { background:#ede9fe; }
.ft-group-strip { display:table-cell; width:28px; vertical-align:middle; text-align:center; background:#7c3aed; padding:0; }
.ft-group-strip span { writing-mode:vertical-rl; transform:rotate(180deg); font-size:8px; font-weight:700; text-transform:uppercase; letter-spacing:.06em; color:#fff; }
.ft-group-strip.ext      { background:#059669; }
.ft-group-strip.party    { background:#d97706; }
.ft-group-strip.fire-ext,
.ft-group-strip.fire-int { background:#dc2626; }
.ft-group-strip.frw      { background:#7c3aed; }
.ft-col-header .ft-group-strip-hdr { display:table-cell; width:28px; vertical-align:middle; text-align:center; padding:0; }
.ft-level-circle { width:26px; height:26px; border-radius:50%; background:#fbbf24; color:#fff; font-size:12px; font-weight:700; display:inline-flex; align-items:center; justify-content:center; box-shadow:0 1px 3px rgba(251,191,36,0.3); font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans"; }
.ft-level-circle.ext      { background:#059669; }
.ft-level-circle.party    { background:#d97706; }
.ft-level-circle.fire-ext,
.ft-level-circle.fire-int { background:#dc2626; }
.ft-cell         { display:table-cell; padding:8px 10px; font-size:12px; color:#4e4e4e; font-weight:500; white-space:nowrap; vertical-align:middle; background:#fff; border-right:1px solid #e5d9ff; font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans"; }
.ft-cell:last-child { border-right:none; }
.ft-col-header .ft-cell { border-right:1px solid #c2b8e8; }
.ft-col-header .ft-cell:last-child { border-right:none; }
.ft-cell-level   { text-align:center; }
.ft-cell-ratio   { text-align:center; }
.ft-cell-actions { text-align:center; width:100%; }
.ft-dbg-btn {
  background: none; border: 1px solid #d1d5db; border-radius: 5px;
  color: #6b7280; cursor: pointer; font-size: 11px; padding: 3px 7px;
  opacity: 0.6; transition: opacity .15s, color .15s, border-color .15s;
}
.ft-dbg-btn:hover { opacity: 1; color: #7c3aed; border-color: #7c3aed; }
.ft-cell-connection { display:inline-block; padding:3px 8px; border-radius:12px; font-size:10px; font-weight:600; }
.ft-cell-connection.fixed { background:#dbeafe; color:#0369a1; border:1px solid #bae6fd; }
.ft-cell-connection.friction { background:#f3f4f6; color:#6b7280; border:1px solid #e5e7eb; }
.ft-cell-config { display:table-cell; padding:8px 10px; font-size:12px; color:#4e4e4e; font-weight:500; white-space:nowrap; background:#fff; border-right:1px solid #e5d9ff; font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans"; }
.ft-h-input { width:71px; height:28px; padding:4px 8px; border:1px solid #e5d9ff; border-radius:6px; font-size:11px; text-align:center; color:#4e4e4e; outline:none; background:#f9f6ff; font-weight:500; transition:background .15s, border-color .15s; }
.ft-h-input:focus { border-color:#7c3aed; background:#fff; box-shadow:0 0 0 3px rgba(124,58,237,0.1); }
.ft-h-input.dirty { border-color:#7c3aed; }
.ft-track-block     { font-size:12px; }
.ft-track-primary   { color:#4e4e4e; font-weight:500; white-space:nowrap; }
.ft-track-secondary { color:#4e4e4e; font-size:12px; font-weight:500; }
.ft-add-system-row { padding:10px 16px; border-top:1px dashed #e9d5ff; display:block; }
.ft-add-system-btn { background:none; border:1px dashed #c4b5fd; border-radius:6px; cursor:pointer; font-size:12px; color:#7c3aed; padding:6px 14px; display:inline-flex; align-items:center; gap:6px; transition:background .15s, border-color .15s; justify-content:center; }
.ft-add-system-btn:hover { background:#ede9fe; border-color:#7c3aed; }

/* ── Framing Table per-system card ───────────────────────────────
   Shared by Stud Wall Framing and the ceiling framing tools. ── */
.ft-system-card { margin-bottom:12px; }
.ft-system-hdr {
  display:flex; align-items:center; gap:10px; padding:7px 12px;
  background:var(--tbl-head-bg,#f5f3ff);
  border:1px solid var(--tbl-head-border,#e0d4f7);
  border-radius:8px 8px 0 0; border-bottom:none;
}
.ft-system-name {
  font-size:13px; font-weight:700; color:var(--tbl-head-color,#3b1f6f);
  flex:1; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.ft-type-lbl {
  font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.06em;
  padding:2px 7px; border-radius:4px; flex-shrink:0;
  background:#ede9fe; color:#6d28d9; border:1px solid #c4b5fd;
}
.ft-type-lbl.ext      { background:#d1fae5; color:#065f46; border-color:#6ee7b7; }
.ft-type-lbl.party    { background:#fef3c7; color:#92400e; border-color:#fcd34d; }
.ft-type-lbl.fire-ext,.ft-type-lbl.fire-int { background:#fee2e2; color:#991b1b; border-color:#fca5a5; }
.ft-system-hdr-meta { display:flex; align-items:center; gap:8px; font-size:11px; color:var(--text-muted,#6b7280); flex-shrink:0; }
.ft-hdr-badge { font-size:10px; font-weight:600; padding:1px 6px; border-radius:4px; background:#f3f4f6; color:#6b7280; border:1px solid #e5e7eb; }
.ft-hdr-sep { color:#d1d5db; }
.ft-sku { font-size:10px; color:#9ca3af; font-weight:400; margin-top:1px; }
.ft-level { font-size:12px; font-weight:600; color:#374151; white-space:nowrap; }
.ft-subrow td { background:#f9fafb !important; }
.ft-table-collapsed { display:none; }
.ft-system-card .primary-table-wrap { border-radius:0 0 8px 8px; border-top:none; border-color:var(--tbl-head-border,#ddd6fe); }
/* Collapsed card — the table wrap (which normally supplies the bottom edge) is
   hidden, so the header has to close off the card itself. */
.ft-system-card:has(.ft-table-collapsed) .ft-system-hdr {
  border-radius:8px;
  border-bottom:1px solid var(--tbl-head-border,#ddd6fe);
}

/* ── Detail modal ────────────────────────────────── */
#ftDetailPanel { position:fixed; inset:0; background:rgba(18,13,43,.5); z-index:800; display:none; align-items:center; justify-content:center; }
#ftDetailPanel.open { display:flex; }
.dp-modal { background:#fff; border-radius:12px; width:1100px; max-width:96vw; max-height:88vh; overflow:hidden; display:flex; flex-direction:column; box-shadow:0 24px 60px rgba(0,0,0,.25); }
.dp-head { display:flex; align-items:center; justify-content:space-between; padding:12px 16px; background:#eee8f9; border-bottom:1px solid #d8ccee; flex-shrink:0; }
.dp-head span { font-weight:700; font-size:12px; color:#5b4282; }
.dp-close { background:none; border:none; cursor:pointer; color:#9ca3af; font-size:14px; padding:0; }
.dp-body { overflow-y:auto; flex:1; display:grid; grid-template-columns:1fr 2fr; }
.dp-col { padding:14px 16px; }
.dp-col + .dp-col { border-left:1px solid #f3f4f6; }
.dp-group { margin-bottom:14px; }
.dp-group h4 { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.07em; color:#7c5fb3; margin:0 0 6px; }
.dp-row { display:flex; justify-content:space-between; padding:4px 0; border-bottom:1px solid #f3f4f6; font-size:12px; }
.dp-lbl { color:#6b7280; }
.dp-val { font-weight:600; color:#1f2937; }
.dp-check { display:flex; justify-content:space-between; align-items:center; padding:5px 0; border-bottom:1px solid #f3f4f6; font-size:12px; }

/* ── Universal detail-modal building blocks (WSF + any analysis modal) ──
   Use these classes instead of inline styles so every mode renders identically. */
/* Overview banner — full-width, spans both columns */
.dp-overview { grid-column:1/-1; display:flex; gap:14px; padding:14px 16px; background:#faf8ff; border-bottom:1px solid #ede9fe; align-items:flex-start; }
.dp-overview-svg { flex-shrink:0; width:110px; border:1px solid #e0d4f7; border-radius:8px; overflow:hidden; background:#fff; }
.dp-overview-main { flex:1; min-width:0; }
.dp-overview-title { font-size:13px; font-weight:700; color:#3b1f6f; margin-bottom:6px; }
.dp-badges { display:flex; flex-wrap:wrap; gap:5px; margin-bottom:8px; }
.dp-meta { font-size:11px; color:#6b7280; margin-bottom:2px; }
.dp-meta b { font-weight:600; color:#374151; }
/* Full-width section (e.g. Components) + ONE unified section heading style */
.dp-section { grid-column:1/-1; padding:12px 16px; border-bottom:1px solid #ede9fe; }
.dp-section-title,
.dp-group h4 { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.07em; color:#7354af; margin:0 0 6px; }
.dp-comp-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(170px,1fr)); gap:0; }
/* Sub-block inside a column (e.g. "Selected by design") */
.dp-subgroup { margin-top:8px; padding-top:8px; border-top:1px dashed #e9d5ff; }
/* Twin-frame side-by-side layout */
.dp-frames { display:flex; gap:20px; align-items:flex-start; }
.dp-frame { flex:1; min-width:0; }
.dp-frame-title { margin:0 0 6px; font-size:11px; font-weight:700; color:#5b4282; text-transform:uppercase; letter-spacing:.04em; }
/* Value variants */
.dp-val--right { text-align:right; max-width:55%; word-break:break-word; }
.dp-sel { color:#5b4282; font-weight:700; }              /* a design-selected / changed value */
.dp-was { color:#9ca3af; font-size:10px; font-weight:400; } /* the "(was …)" original hint */
/* Status text */
.dp-status { font-weight:700; }
.dp-status.pass { color:#059669; }
.dp-status.warn { color:#d97706; }
.dp-status.fail { color:#ef4444; }
.dp-status.err  { color:#f97316; }
/* Placeholders */
.dp-empty { color:#9ca3af; font-size:12px; margin:0; }
.dp-empty.error { color:#ef4444; }
.dp-placeholder { grid-column:1/-1; padding:14px 16px; color:#9ca3af; font-size:12px; }
.dp-loading { text-align:center; padding:20px 0; color:#9ca3af; }
.dp-loading .ft-spinner { display:block; margin:0 auto 8px; }
.dp-loading p { font-size:12px; margin:0; }
.dp-note { font-size:11px; color:#9ca3af; font-style:italic; padding:6px 0; }
/* Footer action buttons */
.dp-actions { margin-top:14px; display:flex; flex-direction:column; gap:8px; }
.dp-action { width:100%; padding:8px 12px; border-radius:7px; font-weight:600; font-size:12px; cursor:pointer; display:flex; align-items:center; justify-content:center; gap:6px; border:1px solid transparent; }
.dp-action:hover { filter:brightness(.97); }
.dp-action--fem    { background:#ede9fe; border-color:#c4b5fd; color:#5b4282; }
.dp-action--trials { background:#eef2ff; border-color:#c7d2fe; color:#3730a3; }

/* ── Detail modal tabs (matrix cell modal — Input / Output / Diagrams) ──
   Shared by every framing module (wall stud, ceilings, battens, soffit) so
   the cell modal looks identical across the suite. */
.dp-tabs { display:flex; gap:2px; padding:0 16px; background:#f7f4fd; border-bottom:1px solid #e6ddf6; flex-shrink:0; }
.dp-tab { border:none; background:none; cursor:pointer; padding:10px 14px 8px; font-size:12px; font-weight:600; color:#8b7fa8; border-bottom:2px solid transparent; margin-bottom:-1px; }
.dp-tab:hover { color:#5b4282; }
.dp-tab.active { color:#5b4282; border-bottom-color:#7c3aed; }
.dp-tabpane { display:none; }
.dp-tabpane.active { display:block; overflow-y:auto; flex:1; min-height:0; }
/* Input tab — editable framing fields */
.dp-input-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(230px,1fr)); gap:12px 18px; padding:16px 20px; align-content:start; }
.dp-field { display:flex; flex-direction:column; gap:4px; min-width:0; }
.dp-field label { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.06em; color:#7c5fb3; }
.dp-field select, .dp-field input { height:30px; padding:0 8px; border:1px solid #d1d5db; border-radius:6px; font-size:12px; color:#1f2937; background:#fff; min-width:0; }
.dp-field select:focus, .dp-field input:focus { outline:none; border-color:#a78bfa; }
.dp-field-sub { font-size:10px; color:#9ca3af; }
.dp-field-ro { height:30px; display:flex; align-items:center; padding:0 8px; border:1px solid #eef0f4; border-radius:6px; font-size:12px; font-weight:600; color:#374151; background:#f8faff; }
.dp-input-note { grid-column:1/-1; font-size:11px; color:#6b7280; background:#f5f3ff; border:1px solid #ede9fe; border-radius:8px; padding:8px 12px; line-height:1.5; }
.dp-input-section { grid-column:1/-1; font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.07em; color:#7c5fb3; border-bottom:1px solid #ede9fe; padding-bottom:4px; margin-top:4px; }
/* Diagrams tab — chart cards need a fixed height inside the scrollable pane */
.dp-diag-wrap { padding:16px 18px; display:flex; flex-direction:column; gap:14px; }
.dp-diag-top { display:flex; gap:14px; flex-wrap:wrap; }
.dp-diag-model { background:#f8faff; border:1px solid #e5e7eb; border-radius:8px; padding:14px 14px 10px; display:flex; flex-direction:column; align-items:center; min-width:170px; }
.dp-diag-model-title { font-size:10px; font-weight:700; color:#5b4282; text-transform:uppercase; letter-spacing:.07em; margin-bottom:10px; }
.dp-diag-grid { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.dp-diag-card { background:#fff; border:1px solid #e5e7eb; border-radius:8px; padding:10px 14px; display:flex; flex-direction:column; height:240px; }
.dp-diag-card-title { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.07em; margin-bottom:6px; }
.dp-diag-card-body { flex:1; position:relative; min-height:0; }

/* ── Standard "Computations" tab layout (universal across analysis modals) ──
   Every engineering module renders the same ordered set of section CARDS —
   Framing, Loading, Load Cases, Design Actions & Checks, Diagram — so the
   detailed-calculation modal reads identically suite-wide. Sections are full
   width; .dp-comp-2 pairs the two compact cards (Framing | Loading) on wide
   screens. Cards reuse the shared .dp-group / .dp-row / .dp-check primitives. */
.dp-comp { grid-column:1/-1; padding:14px 16px; display:flex; flex-direction:column; gap:12px; }
.dp-comp-2 { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.dp-card { border:1px solid #ece6f7; border-radius:10px; background:#fff; padding:12px 14px; }
.dp-card > h4 { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.07em; color:#7354af; margin:0 0 8px; display:flex; align-items:center; gap:7px; }
.dp-card > h4 i { opacity:.65; font-size:11px; }
.dp-card .dp-group:last-child { margin-bottom:0; }
/* Two-column split inside a wide card (actions | checks) */
.dp-ac-split { display:grid; grid-template-columns:1fr 1fr; gap:8px 24px; }
.dp-ac-split .dp-group:last-child { margin-bottom:0; }
/* Load-case combination table */
.dp-lc-table { width:100%; border-collapse:collapse; font-size:11px; }
.dp-lc-table th { text-align:right; font-weight:600; color:#8b7fa8; padding:4px 6px; border-bottom:1px solid #ede9fe; white-space:nowrap; }
.dp-lc-table th:first-child { text-align:left; }
.dp-lc-table td { text-align:right; padding:4px 6px; border-bottom:1px solid #f5f3ff; color:#374151; white-space:nowrap; }
.dp-lc-table td:first-child { text-align:left; font-weight:600; color:#1f2937; }
.dp-lc-table tr.dp-lc-gov td { background:#f6f2ff; }
/* Limit-state group header + not-applicable combination rows */
.dp-lc-table tr.dp-lc-grp td { background:#f3eefc; color:#5b4282; font-weight:700; text-transform:uppercase; font-size:9px; letter-spacing:.06em; text-align:left; padding:5px 6px; }
.dp-lc-table tr.dp-lc-na td { color:#9ca3af; }
.dp-lc-wrap { overflow-x:auto; }
@media (max-width:760px){
  .dp-comp-2 { grid-template-columns:1fr; }
  .dp-ac-split { grid-template-columns:1fr; }
}

/* ── Ceiling Picker Modal ───────────────────────── */
.cp-modal-overlay { display:none; position:fixed; inset:0; background:rgba(18,13,43,.55); z-index:9000; align-items:center; justify-content:center; }
.cp-modal-overlay.open { display:flex; }
/* Right-aligned footer for .dp-modal dialogs (Cancel / primary action). */
.dp-foot { display:flex; justify-content:flex-end; align-items:center; gap:8px; padding:12px 16px; border-top:1px solid #ece8f5; flex-shrink:0; }
.cp-modal { background:#fff; border-radius:6px; width:520px; max-width:95vw; box-shadow:0 20px 60px rgba(0,0,0,.25); overflow:hidden; }
.cp-modal-head { background:linear-gradient(135deg,#271357,#a78bfa); padding:18px 20px; display:flex; align-items:center; gap:12px; }
.cp-modal-icon { width:36px; height:36px; background:rgba(255,255,255,.2); border-radius:10px; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.cp-modal-icon i { color:#fff; font-size:15px; }
.cp-modal-title-wrap { flex:1; min-width:0; }
.cp-modal-title { font-size:15px; font-weight:700; color:#fff; }
.cp-modal-subtitle { font-size:11px; color:rgba(255,255,255,.8); }
.cp-modal-close { background:rgba(255,255,255,.15); border:none; color:#fff; width:28px; height:28px; border-radius:8px; cursor:pointer; font-size:14px; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.cp-modal-close:hover { background:rgba(255,255,255,.3); }
.cp-modal-grid { padding:20px; display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.cp-modal-foot { padding:0 20px 16px; display:flex; justify-content:flex-end; }
.cp-modal-cancel { padding:6px 14px; font-size:12px; border:1px solid #e5e7eb; border-radius:8px; background:#fff; color:#6b7280; cursor:pointer; }
.cp-modal-cancel:hover { background:#f9fafb; }
.ceiling-tpl-card { display:flex; flex-direction:column; align-items:center; justify-content:center; padding:16px 12px; border:1.5px solid #e5e7eb; border-radius:12px; background:#fafafa; cursor:pointer; transition:border-color .15s, background .15s; text-align:center; }
.ceiling-tpl-card:hover { border-color:#a78bfa; background:#f5f3ff; }
.ceiling-tpl-icon { font-size:20px; color:#7c3aed; margin-bottom:8px; }
.ceiling-tpl-label { font-size:12px; font-weight:700; color:#1e1b4b; }
.ceiling-tpl-desc { font-size:10px; color:#9ca3af; margin-top:4px; }

/* ── Modal ───────────────────────────────────────── */
.ft-modal-overlay { display:none; position:fixed; inset:0; background:rgba(0,0,0,.4); z-index:500; align-items:center; justify-content:center; }
.ft-modal-overlay.open { display:flex; }
.ft-modal { background:#fff; border-radius:12px; width:520px; max-width:95vw; max-height:90vh; overflow:hidden; display:flex; flex-direction:column; box-shadow:0 20px 60px rgba(0,0,0,.2); }
.ft-modal-head { display:flex; align-items:center; justify-content:space-between; padding:14px 18px; background:#eee8f9; border-bottom:1px solid #d8ccee; flex-shrink:0; }
.ft-modal-head span { font-weight:700; font-size:14px; color:#5b4282; }
.ft-modal-head button { background:none; border:none; cursor:pointer; color:#9ca3af; font-size:16px; }
.ft-modal-body { flex:1; overflow-y:auto; padding:16px 18px; display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.ft-modal-body .modal-field-full { grid-column:1/-1; }
.modal-section-heading { grid-column:1/-1; font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.06em; color:#7c5fb3; padding:6px 0 2px; border-top:1px solid #ede8f7; margin-top:4px; }
.modal-section-heading:first-child { border-top:none; margin-top:0; }
.modal-field label { display:block; font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:#7c5fb3; margin-bottom:4px; }
.modal-field input, .modal-field select { width:100%; padding:6px 8px; font-size:12px; border:1px solid #ddd6f0; border-radius:6px; background:#fff; color:#374151; box-sizing:border-box; }
.modal-field input:focus, .modal-field select:focus { outline:none; border-color:#a78bdb; }
.ft-modal-foot { display:flex; justify-content:flex-end; gap:10px; padding:12px 18px; border-top:1px solid #f3f4f6; flex-shrink:0; }
.ft-modal-foot button { padding:7px 16px; font-size:12px; font-weight:600; border-radius:7px; cursor:pointer; border:1px solid #ddd6f0; background:#fff; color:#374151; transition:background .12s; }
.ft-modal-foot button.primary { background:#7c3aed; color:#fff; border-color:#7c3aed; }
.ft-modal-foot button.primary:hover { background:#6d28d9; }
.ft-modal-foot button.danger  { background:#dc2626; color:#fff; border-color:#dc2626; }
.ft-modal-foot button.danger:hover  { background:#b91c1c; }

/* ── Wall diagram ────────────────────────────────── */
.ft-diagram-clip { width:72px; overflow:hidden; flex-shrink:0; border-radius:5px; border:1px solid #ede9fe; background:#faf8ff; }
.ft-diagram-inner { zoom:0.46; width:156px; line-height:0; }
#cmPreviewBox { width:80px; height:120px; overflow:hidden; position:relative; flex-shrink:0; border:1px solid #e5e7eb; border-radius:6px; background:#f9f7ff; display:flex; align-items:center; justify-content:center; }

/* ── Spinner ─────────────────────────────────────── */
.ft-spinner { display:inline-block; width:14px; height:14px; border:2px solid rgba(124,58,237,.3); border-top-color:#7c3aed; border-radius:50%; animation:ft-spin .6s linear infinite; vertical-align:middle; }
@keyframes ft-spin { to { transform:rotate(360deg); } }

/* ══════════════════════════════════════════════════════════════
   Workspace Selector Sidebar — light theme  (.ms-*)
   Mirrors the dark .ws-sb-* system in workspace_selector.html
   but uses light colours for in-module secondary sidebars.
   Usage: wrap content in .ms-sidebar and use child classes below.
   ══════════════════════════════════════════════════════════════ */

/* Outer container — fills the secondary sidebar shell */
.ms-sidebar {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  background: var(--secondary-sidebar-bg);
  color: var(--secondary-sidebar-text);
}

/* ── Header ── */
.ms-hd {
  padding: 4px 12px;
  flex-shrink: 0;
  background: linear-gradient(135deg, #f5f3ff 0%, #ede9fe 100%);
  border-bottom: 1px solid #ddd6f9;
}
.ms-logo {
  font-size: 15px;
  font-weight: 800;
  letter-spacing: -.02em;
  color: #271354;
  margin: 0;
}
.ms-logo span { color: #7c3aed; }
.ms-hub-lbl {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #9ca3af;
}
.ms-back {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 11px;
  padding: 6px 10px;
  width: 100%;
  box-sizing: border-box;
  border-radius: 7px;
  border: 1px solid #ddd6f4;
  font-size: 11px;
  font-weight: 600;
  color: #64748b;
  background: rgba(255,255,255,.8);
  cursor: pointer;
  text-decoration: none;
  transition: background .14s, color .14s, border-color .14s;
}
.ms-back:hover { background: #fff; color: #6d28d9; border-color: #a78bfa; }

/* -- Unified Header with Back Button -- */
.ms-unified-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 16px;
  flex-shrink: 0;
  background: var(--secondary-sidebar-bg);
  border-bottom: 1px solid var(--secondary-sidebar-border);
}

/* -- Section header bar -- */
.ms-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: rgba(0, 0, 0, 0.55);
  padding: 10px 12px 6px;
  flex-shrink: 0;
  border-bottom: 1px solid var(--secondary-sidebar-border);
}
[data-theme="dark"] .ms-section-header {
  color: rgba(255, 255, 255, 0.55);
}

/* -- Dark form helpers -- */
.ms-sidebar .ls-select { background: var(--secondary-sidebar-bg); color: var(--secondary-sidebar-text); border-color: var(--secondary-sidebar-border); }
.ms-sidebar .ls-select-icon { color: rgba(0, 0, 0, 0.5); }
[data-theme="dark"] .ms-sidebar .ls-select-icon { color: rgba(255, 255, 255, 0.5); }
.ms-field-label { font-size: var(--fs-sm); font-weight: 600; color: var(--secondary-sidebar-text); display: block; margin-bottom: 6px; }


.ms-back-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 7px;
  border: 1px solid var(--secondary-sidebar-border);
  background: transparent;
  color: var(--secondary-sidebar-text);
  text-decoration: none;
  font-size: 12px;
  font-weight: 600;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  white-space: nowrap;
  opacity: 0.7;
}

.ms-back-link:hover {
  opacity: 1;
  background: rgba(108, 92, 231, 0.08);
  border-color: #a78bfa;
  color: #7c3aed;
}

[data-theme="dark"] .ms-back-link {
  color: rgba(229, 231, 235, 0.7);
}

[data-theme="dark"] .ms-back-link:hover {
  color: #a78bfa;
  background: rgba(167, 139, 250, 0.1);
  border-color: rgba(167, 139, 250, 0.4);
  opacity: 1;
}

.ms-back-icon {
  font-size: 12px;
}

.ms-title-center {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ms-title-text {
  margin: 0;
  color: var(--secondary-sidebar-text);
  font-size: 14px;
  font-weight: 500;
}

.ms-collapse-btn {
  background: transparent;
  border: 1px solid var(--secondary-sidebar-border);
  border-radius: 6px;
  padding: 6px 10px;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.15s;
  color: rgba(0, 0, 0, 0.6);
}

.ms-collapse-btn:hover {
  background: rgba(0, 0, 0, 0.05);
  color: rgba(0, 0, 0, 0.8);
}

[data-theme="dark"] .ms-collapse-btn {
  color: rgba(229, 231, 235, 0.6);
}

[data-theme="dark"] .ms-collapse-btn:hover {
  background: rgba(255, 255, 255, 0.05);
  color: rgba(229, 231, 235, 0.8);
}
}

.ms-collapse-icon {
  font-size: 14px;
}

/* ── Project mini card ── */
.ms-proj {
  padding: 12px 14px;
  flex-shrink: 0;
  background: #141720;
  border-bottom: 1px solid #334155;
}
.ms-proj-row { display: flex; align-items: center; gap: 9px; min-width: 0; }
.ms-proj-ico {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 8px;
  background: linear-gradient(135deg, #7c3aed, #5b21b6);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 12px;
}
.ms-proj-name {
  font-size: 12px;
  font-weight: 700;
  color: #e2e8f0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ms-proj-addr {
  font-size: 10px;
  color: #94a3b8;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-top: 1px;
}
.ms-proj-st { margin-top: 8px; }

/* Status badges */
.ms-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 99px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
}
.ms-badge-planning      { background: #ede9fe; color: #6d28d9; }
.ms-badge-design        { background: #e0f2fe; color: #0369a1; }
.ms-badge-documentation { background: #e0f2fe; color: #0369a1; }
.ms-badge-approval      { background: #fef9c3; color: #854d0e; }
.ms-badge-tender        { background: #fef9c3; color: #854d0e; }
.ms-badge-construction  { background: #dcfce7; color: #15803d; }
.ms-badge-completed     { background: #dbeafe; color: #1d4ed8; }
.ms-badge-on_hold       { background: #f3f4f6; color: #6b7280; }
.ms-badge-active        { background: #dcfce7; color: #15803d; }
.ms-badge-default       { background: #f3f4f6; color: #6b7280; }

/* ── Modules section label ── */
.ms-lbl {
  padding: 11px 14px 5px;
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(0,0,0,0.5);
}
[data-theme="dark"] .ms-lbl {
  color: #9ca3af;
}

/* ── Module nav list ── */
.ms-nav {
  flex: 1;
  overflow-y: auto;
  padding: 3px 7px 10px;
  scrollbar-width: thin;
  scrollbar-color: rgba(0,0,0,0.2) transparent;
}
.ms-nav::-webkit-scrollbar { width: 4px; }
.ms-nav::-webkit-scrollbar-track { background: transparent; }
.ms-nav::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.2); border-radius: 99px; }
[data-theme="dark"] .ms-nav {
  scrollbar-color: #475569 transparent;
}
[data-theme="dark"] .ms-nav::-webkit-scrollbar-thumb { background: #475569; }

.ms-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 9px;
  border-radius: 9px;
  cursor: pointer;
  margin-bottom: 2px;
  border: 1px solid transparent;
  text-decoration: none;
  transition: background .13s, border-color .13s;
}
.ms-item:hover { background: rgba(0,0,0,0.04); border-color: rgba(108,92,231,0.2); }
.ms-item.active { background: rgba(108,92,231,0.1); border: 1px solid rgba(108,92,231,0.3); box-shadow: none; }
[data-theme="dark"] .ms-item:hover { background: rgba(255,255,255,0.04); }
[data-theme="dark"] .ms-item.active { background: #3a2557; border-color: rgba(108,92,231,0.4); }

.ms-ico {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border-radius: 8px;
  background: #6c5ce7;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 12px;
  transition: background .13s, color .13s;
}
.ms-item.active .ms-ico {
  background: #6c5ce7;
  color: #fff;
  border-color: transparent;
  box-shadow: none;
}
.ms-txt { flex: 1; min-width: 0; }
.ms-name { font-size: 12px; font-weight: 500; color: var(--secondary-sidebar-text); }
.ms-item.active .ms-name { color: #6c5ce7; }
[data-theme="dark"] .ms-item.active .ms-name { color: #f0f2f8; }
.ms-sub  { font-size: 10px; color: rgba(0,0,0,0.45); margin-top: 1px; }
[data-theme="dark"] .ms-sub { color: #4a5070; }
.ms-item.active .ms-sub { color: #8b8fc8; opacity: 0.8; }
[data-theme="dark"] .ms-item.active .ms-sub { color: #8b8fc8; opacity: 1; }
.ms-arr  { font-size: 10px; color: rgba(0,0,0,0.35); flex-shrink: 0; }
[data-theme="dark"] .ms-arr { color: #4a5070; }
.ms-item.active .ms-arr,
.ms-item:hover  .ms-arr { color: #6c5ce7; }
[data-theme="dark"] .ms-item.active .ms-arr,
[data-theme="dark"] .ms-item:hover  .ms-arr { color: #9098b8; }

/* ── Pricing sidebar template strip ── */
.ss-collapsed-strip {
  height: 100%;
  width: 100%;
  background: var(--secondary-sidebar-bg);
  border: none;
  cursor: pointer;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 16px;
}
.ss-collapsed-icon {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.5);
}
[data-theme="dark"] .ss-collapsed-icon {
  color: #94a3b8;
}

/* ── Pricing sidebar template strip ── */
.pl-active-template-strip {
  padding: 7px 12px;
  background: rgba(16, 185, 129, 0.08);
  border-top: 1px solid var(--secondary-sidebar-border);
  border-bottom: 1px solid var(--secondary-sidebar-border);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 6px;
}
[data-theme="dark"] .pl-active-template-strip {
  background: rgba(16, 185, 129, 0.12);
}
.pl-active-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #10b981;
  flex-shrink: 0;
}
.pl-active-name {
  font-size: 12px;
  font-weight: 600;
  color: #065f46;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}
[data-theme="dark"] .pl-active-name {
  color: #86efac;
}
.pl-active-badge {
  font-size: 9px;
  color: rgba(0, 0, 0, 0.5);
  flex-shrink: 0;
}
[data-theme="dark"] .pl-active-badge {
  color: rgba(255, 255, 255, 0.5);
}

/* Pricing sidebar icon buttons */
.pl-icon-btn-load {
  font-size: 10px;
  color: #5b3fa6;
}
[data-theme="dark"] .pl-icon-btn-load {
  color: #a78bfa;
}
.pl-icon-btn-edit {
  font-size: 10px;
  color: #9a3412;
}
[data-theme="dark"] .pl-icon-btn-edit {
  color: #fed7aa;
}
.pl-icon-btn-delete {
  color: #dc2626;
}
[data-theme="dark"] .pl-icon-btn-delete {
  color: #fca5a5;
}

/* Pricing sidebar empty message */
.pl-empty-message {
  padding: 20px;
  text-align: center;
  color: rgba(0, 0, 0, 0.5);
  font-size: 12px;
}
[data-theme="dark"] .pl-empty-message {
  color: rgba(255, 255, 255, 0.5);
}
.pl-empty-icon {
  font-size: 20px;
  color: #7c3aed;
  display: block;
  margin-bottom: 8px;
}
[data-theme="dark"] .pl-empty-icon {
  color: #a78bfa;
}

/* ── Analysis / module-specific section ── */
.ms-section {
  border-top: 1px solid #334155;
  flex-shrink: 0;
  padding: 10px 12px;
}
.ms-section-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px 5px;
  flex-shrink: 0;
}
.ms-section-lbl {
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: rgba(0, 0, 0, 0.55);
  margin-bottom: 0;
  display: flex;
  align-items: center;
  gap: 4px;
}
[data-theme="dark"] .ms-section-lbl {
  color: rgba(255, 255, 255, 0.55);
}

.ms-new-btn {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: rgba(0, 0, 0, 0.55);
  cursor: pointer;
  transition: color 0.12s;
  display: flex;
  align-items: center;
  gap: 4px;
  text-decoration: none;
}
.ms-new-btn i {
  font-size: 10px;
}
.ms-new-btn:hover {
  color: rgba(0, 0, 0, 0.75);
}
[data-theme="dark"] .ms-new-btn {
  color: rgba(255, 255, 255, 0.55);
}
[data-theme="dark"] .ms-new-btn:hover {
  color: rgba(255, 255, 255, 0.8);
}

/* ── Project list container ── */
.ms-proj-list {
  max-height: 140px;
  overflow-y: auto;
  border-bottom: 1px solid var(--secondary-sidebar-border);
  flex-shrink: 0;
}

.ms-proj-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background 0.12s;
}
.ms-proj-item:hover {
  background: rgba(0, 0, 0, 0.04);
}
[data-theme="dark"] .ms-proj-item:hover {
  background: rgba(255, 255, 255, 0.04);
}
.ms-proj-item.is-active {
  background: rgba(108, 92, 231, 0.1);
  border-color: rgba(108, 92, 231, 0.3);
}

.ms-proj-item-icon {
  color: #60a5fa;
  font-size: 11px;
  flex-shrink: 0;
}

.ms-proj-item-name {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 12px;
}

/* ── Calculations/Saved list container ── */
.ms-calcs-wrap {
  display: flex;
  flex-direction: column;
  flex: 1;
  overflow: hidden;
  min-height: 0;
  padding: 0 12px 10px;
}
.ms-calcs-list {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

.ms-calcs-empty {
  color: var(--secondary-sidebar-text);
  opacity: 0.6;
  font-size: 12px;
  padding: 8px;
  margin: 0;
}

/* ── Tools section ── */
.ms-tools-wrap {
  flex: none;
  padding: 8px 12px;
}

/* ── Save button container ── */
.ms-btn-wrap {
  flex-shrink: 0;
  padding: 12px 12px;
}

/* ── Structural Actions: Floors panel (.flr-*) ── */
#floor-panel {
  --detail-panel-width: 420px;
  box-shadow: 4px 0 12px rgba(0,0,0,.10);
}

.flr-panel-header {
  background: linear-gradient(135deg, #eee8f9, #f5f3ff) !important;
}

.flr-panel-icon {
  color: #6366f1;
  font-size: 12px;
}

.flr-panel-title {
  flex: 1;
}

.flr-panel-close {
  background: rgba(108,99,233,.15);
  border: none;
  color: #7c3aed;
  width: 22px;
  height: 22px;
  border-radius: 5px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  flex-shrink: 0;
}

.flr-panel-scroll {
  background: #fff;
  padding: 12px 16px;
}

#floor-list-viewer {
  flex: 1;
  overflow-y: auto;
  padding: 0;
  display: block;
  margin-top: 32px;
}

.flr-empty {
  color: #6b7280;
  font-size: 12px;
  margin: 0;
  padding: 12px;
}


/* ════════════════════════════════════════════════════
   App Layout — CSS Grid shell
   app-layout > app-sidebar | app-topbar
                            | app-workspace
   ════════════════════════════════════════════════════ */

.app-layout {
  display: grid;
  height: 100vh;
  overflow: hidden;
  grid-template-columns: var(--sidebar-w) 1fr;
  grid-template-rows: auto 1fr;
  transition: grid-template-columns 0.2s ease;
}

/* Sidebar collapsed — grid column shrinks, sidebar content clips */
.app-layout:has(.app-sidebar--collapsed) {
  grid-template-columns: 56px 1fr;
}

/* Embedded mode (workspace iframes): no global nav column at all. The topbar +
   workspace default to grid-column 2 (column 1 is normally the nav); with the
   nav gone they must move to column 1 or a phantom gutter appears. */
.app-layout--embedded { grid-template-columns: 1fr; }
.app-layout--embedded .app-topbar,
.app-layout--embedded .app-workspace { grid-column: 1; }
/* When a module still ships a secondary slide-panel (e.g. stud ceiling), keep
   it as the left column and push the content right. */
.app-layout--embedded:has(> .slide-panel) {
  grid-template-columns: var(--secondary-sidebar-width) 1fr;
}
.app-layout--embedded:has(> .slide-panel) .app-topbar,
.app-layout--embedded:has(> .slide-panel) .app-workspace { grid-column: 2; }
.app-layout--embedded .slide-panel { grid-column: 1; }

/* Slide panel present — add a centre column */
.app-layout:has(> .slide-panel) {
  grid-template-columns: var(--sidebar-w) var(--secondary-sidebar-width) 1fr;
}
.app-layout:has(> .slide-panel) .app-topbar { grid-column: 3; }
.app-layout:has(> .slide-panel) .app-workspace { grid-column: 3; }
.slide-panel { grid-column: 2; grid-row: 1 / -1; }

/* Collapsed sidebar + slide panel */
.app-layout:has(.app-sidebar--collapsed):has(> .slide-panel) {
  grid-template-columns: 56px var(--secondary-sidebar-width) 1fr;
}

/* App sidebar — spans full height in column 1 */
.app-sidebar {
  grid-column: 1;
  grid-row: 1 / -1;
  background: #f8f7f7;
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  padding: 0 0 1rem;
  position: relative;
  z-index: 10;
  overflow: hidden;
}

/* App topbar — header row in column 2, wraps app-topbar-bar + optional app-topbar-panel */
.app-topbar {
  grid-column: 2;
  grid-row: 1;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
}

/* App workspace — scrollable content area in column 2 row 2 */
.app-workspace {
  grid-column: 2;
  grid-row: 2;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Right-rail variant — place as last child of .app-layout, fill with .ms-sidebar */
.app-sidebar--right {
  border-right: none;
  border-left: 1px solid var(--border);
  padding: 0;
  z-index: 9;
}

/* ── Collapsed state — grid-template-columns handles the width ── */
.app-sidebar--collapsed {
  /* width controlled by .app-layout:has(.app-sidebar--collapsed) */
}

.app-sidebar--collapsed .app-sidebar-logo {
  padding: 0.75rem 0;
  cursor: pointer;
}

.app-sidebar--collapsed .app-sidebar-logo img {
  width: 32px;
}

.app-sidebar-logo-text {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.app-sidebar--collapsed .app-sidebar-logo-text,
.app-sidebar--collapsed .app-sidebar-collapse-btn,
.app-sidebar--collapsed .app-nav-sec,
.app-sidebar--collapsed .app-nav-lbl,
.app-sidebar--collapsed .app-nav-badge {
  display: none;
}

.app-sidebar--collapsed .app-nav {
  padding: 0.5rem 6px;
}

.app-sidebar--collapsed .app-nav-item {
  padding: 9px;
  justify-content: center;
  gap: 0;
}

.app-sidebar--collapsed .app-nav-item i {
  width: auto;
}

.app-sidebar--collapsed .app-sidebar-footer {
  padding: 0.4rem;
}

.app-sidebar--collapsed .app-user {
  padding: 6px;
  justify-content: center;
  gap: 0;
}

/* ── Collapse toggle button ── */
.app-sidebar-collapse-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 14px;
  color: rgba(0, 0, 0, 0.6);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, color 0.15s;
  z-index: 1;
}

.app-sidebar-collapse-btn:hover {
  background: var(--brand-light);
  color: var(--brand);
  border-color: var(--brand);
}

/* ════════════════════════════════════════════════════
   Sliding secondary panel (slide-panel)
   Used in dbs layouts where the ms-sidebar slides in
   alongside the main dbs-side nav.
   ════════════════════════════════════════════════════ */
.slide-panel {
  width: var(--sidebar-w);
  flex-shrink: 0;
  overflow: hidden;
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  transition: width 0.22s ease, opacity 0.22s ease;
  opacity: 1;
  background: var(--secondary-sidebar-bg, #f8f7fa);
}

.slide-panel--closed {
  width: 0;
  opacity: 0;
  border-right: none;
}

/* ── Slide panel inner shell (secondary_sidebar.html) ── */
.sp-toggle-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 49px;
  padding: 0 16px;
  background: #d0c5ff;
  border: none;
  border-bottom: 0.5px solid rgba(104, 122, 228, 0.4);
  box-shadow: 2px 0px 4px 0px rgba(0, 0, 0, 0.25);
  cursor: pointer;
  flex-shrink: 0;
}
.sp-toggle-title {
  font-size: 16px;
  font-weight: 700;
  color: #7354af;
  white-space: nowrap;
  overflow: hidden;
}
.sp-toggle-icon {
  font-size: 14px;
  color: #7354af;
  flex-shrink: 0;
}
.sp-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.app-sidebar-logo {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1.25rem 1rem 1rem;
  border-bottom: 1px solid var(--border);
}

.app-sidebar-logo img {
  width: 80px;
  height: auto;
  display: block;
  filter: drop-shadow(0 8px 16px rgba(18, 13, 41, 0.18));
}

.topbar-title {
  display: block;
  font-family: 'Inter', sans-serif;
  font-size: 29px;
  font-weight: 500;
  color: #17152e;
  margin-top: 10px;
  text-align: center;
  letter-spacing: 0.12em;
  text-shadow: 0px 3px 4px rgba(0, 0, 0, 0.1);
}

.topbar-lite {
  color: #8b7dba;
  text-shadow: 0px 3px 4px rgba(0, 0, 0, 0.1);
}

.topbar-spec {
  color: #17152e;
  margin-left: 0px;
  text-shadow: 0px 3px 4px rgba(0, 0, 0, 0.1);
}

.topbar-subtitle {
  font-size: 9px;
  font-family: 'Inter', sans-serif;
  color: #2e1860;
  opacity: 1;
  letter-spacing: 0.05em;
  margin-top: 6px;
  text-transform: uppercase;
  font-weight: 400;
  text-shadow: 0px 3px 4px rgba(0, 0, 0, 0.1);
}

.app-nav {
  flex: 1;
  padding: 1rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
}

.app-nav-sec {
  font-size: 10px;
  color: var(--text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.7px;
  padding: 0.5rem 0.5rem 0.25rem;
  margin-top: 0.5rem;
}

.app-nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 13.5px;
  font-weight: 400;
  transition: background 0.12s, color 0.12s;
  text-decoration: none;
  position: relative;
}

.app-nav-item:hover {
  background: var(--brand-light);
  color: var(--brand);
}

.app-nav-item.active {
  background: var(--brand-light);
  color: var(--brand);
  font-weight: 500;
}

.app-nav-item i {
  font-size: 16px;
  flex-shrink: 0;
  width: 18px;
  text-align: center;
}

.app-nav-badge {
  margin-left: auto;
  background: var(--brand);
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 20px;
}

/* DBS Topbar */
.app-topbar-bar {
  height: var(--topbar-h);
  background: #f8f7f7;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  padding: 0 1.75rem;
  gap: 12px;
  flex-shrink: 0;
}

.app-topbar-title {
  font-size: 15px;
  font-weight: 500;
  color: var(--text-primary);
  flex: 1;
}

.app-topbar-sub {
  font-size: 12px;
  color: var(--text-tertiary);
  margin-left: 6px;
  font-weight: 400;
}

.app-topbar-kbd {
  margin-left: auto;
  font-size: 10px;
  color: var(--text-tertiary);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  padding: 1px 5px;
  border-radius: 4px;
}

.app-icon-btn {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--text-secondary);
  transition: background 0.12s, border-color 0.12s;
  position: relative;
}

.app-icon-btn:hover {
  background: var(--bg);
  border-color: var(--border-strong);
}

.app-icon-btn i {
  font-size: 16px;
}

/* Live unread badge for the app-shell notification bell. Hidden when the
   reviews:notification_count endpoint returns an empty string (zero unread). */
.app-notif-badge {
  position: absolute;
  top: -3px;
  right: -3px;
  min-width: 16px;
  height: 16px;
  padding: 0 3px;
  border-radius: 999px;
  background: #ef4444;
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  line-height: 1;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--surface);
}

.app-notif-badge:empty { display: none; }
.app-notif-badge:not(:empty) { display: flex; }

.app-btn-new {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--brand);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 0 14px;
  height: 34px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s;
  font-family: inherit;
  text-decoration: none;
  letter-spacing: -0.1px;
}

.app-btn-new:hover {
  background: var(--brand-dark);
  color: #fff;
}

.app-btn-new i {
  font-size: 14px;
}

/* ── Sidebar Footer & User trigger ── */
.app-sidebar-footer {
  padding: 0.6rem 0.75rem 0.9rem;
  border-top: 1px solid var(--border);
  position: relative; /* anchor for .app-user-menu */
}

.app-user {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.12s;
  text-decoration: none;
  /* button resets */
  background: none;
  border: none;
  width: 100%;
  font-family: inherit;
  text-align: left;
}

.app-user:hover {
  background: var(--surface-2);
}

.app-user-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.app-user-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-primary);
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-user-company {
  font-size: 11px;
  font-weight: 500;
  color: var(--text-secondary);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-user-role {
  font-size: 10px;
  color: var(--text-tertiary);
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.app-user i {
  margin-left: auto;
  color: var(--text-tertiary);
  font-size: 15px;
}

/* ── Sidebar user popup menu ── */
.app-user-menu {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  right: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, .10), 0 2px 8px rgba(0, 0, 0, .06);
  overflow: hidden;
  z-index: 200;
}

/* Hide popup when sidebar is collapsed */
.app-sidebar--collapsed .app-user-menu {
  display: none !important;
}

.app-user-menu-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 14px 12px;
  background: var(--surface-2);
}

.app-user-menu-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  letter-spacing: 0.04em;
}

.app-user-menu-info {
  flex: 1;
  min-width: 0;
}

.app-user-menu-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-user-menu-company {
  font-size: 11px;
  font-weight: 500;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 1px;
}

.app-user-menu-email {
  font-size: 11px;
  color: var(--text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 1px;
}

.app-user-menu-badge {
  display: inline-block;
  margin-top: 5px;
  padding: 2px 7px;
  border-radius: 20px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.03em;
}

.app-user-menu-badge--admin {
  background: #fef3c7;
  color: #92400e;
}

.app-user-menu-badge--staff {
  background: #ede9fe;
  color: #5b21b6;
}

.app-user-menu-badge--user {
  background: var(--surface-2);
  color: var(--text-secondary);
  border: 1px solid var(--border);
}

.app-user-menu-divider {
  height: 1px;
  background: var(--border);
}

.app-user-menu-items {
  padding: 6px;
}

.app-user-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: 8px;
  font-size: 13px;
  color: var(--text-secondary);
  text-decoration: none;
  transition: background 0.12s, color 0.12s;
  cursor: pointer;
  width: 100%;
  border: none;
  background: transparent;
  font-family: inherit;
  text-align: left;
}

.app-user-menu-item i {
  width: 16px;
  text-align: center;
  font-size: 13px;
  color: var(--text-tertiary);
  flex-shrink: 0;
  transition: color 0.12s;
}

.app-user-menu-item:hover {
  background: var(--surface-2);
  color: var(--text-primary);
}

.app-user-menu-item:hover i {
  color: var(--brand);
}

.app-user-menu-item--danger {
  color: #dc2626;
}

.app-user-menu-item--danger i {
  color: #dc2626;
}

.app-user-menu-item--danger:hover {
  background: #fef2f2;
  color: #b91c1c;
}

.app-user-menu-item--danger:hover i {
  color: #b91c1c;
}

/* Scrollable inner content area (used by pages that need padding + scroll) */
.app-workspace-inner {
  flex: 1;
  overflow-y: auto;
  padding: 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.app-workspace-inner::-webkit-scrollbar {
  width: 5px;
}

.app-workspace-inner::-webkit-scrollbar-track {
  background: transparent;
}

.app-workspace-inner::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 10px;
}

/* DBS Greeting */
.app-greeting {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
}

.app-greeting h1 {
  font-size: 22px;
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: -0.5px;
}

.app-greeting p {
  font-size: 13px;
  color: var(--text-secondary);
  margin-top: 3px;
}

.app-date-pill {
  font-size: 11px;
  color: var(--text-tertiary);
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 4px 10px;
  border-radius: 20px;
  white-space: nowrap;
}

/* DBS Stats */
.app-stats {
  display: grid;
  /* auto-fit, not repeat(5, 1fr): five quota cards fit across a desktop and
     reflow to 3+2 then 2+2+1 without a media query per breakpoint. */
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px;
}

.app-stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem 1rem;
  position: relative;
  overflow: hidden;
  transition: border-color 0.15s;
}

.app-stat:hover {
  border-color: var(--border-strong);
}

.app-stat::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--brand-light);
}

.app-stat-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--brand-light);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 0.75rem;
}

.app-stat-icon i {
  color: var(--brand);
  font-size: 15px;
}

.app-stat-lbl {
  font-size: 11px;
  color: var(--text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 4px;
}

.app-stat-val {
  font-size: 26px;
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: -0.8px;
  line-height: 1;
}

.app-stat-val span {
  font-size: 14px;
  color: var(--text-tertiary);
  font-weight: 400;
}

.app-stat-sub {
  font-size: 11px;
  color: var(--text-tertiary);
  margin-top: 4px;
}

.app-stat-bar {
  height: 3px;
  background: var(--bg);
  border-radius: 2px;
  margin-top: 12px;
}

.app-stat-fill {
  height: 100%;
  border-radius: 2px;
  background: var(--brand);
  transition: width 0.6s ease;
}

/* A spent allowance should be readable at a glance, not just a full bar. */
.app-stat--maxed {
  border-color: var(--danger-border, #fecaca);
}

.app-stat--maxed::after {
  background: var(--danger, #ef4444);
}

.app-stat--maxed .app-stat-fill {
  background: var(--danger, #ef4444);
}

.app-stat--maxed .app-stat-sub {
  color: var(--danger, #ef4444);
}

/* DBS Section Header */
.app-sec-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.app-sec-hd h2 {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-primary);
}

.app-viewall {
  font-size: 12px;
  color: var(--brand);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 3px;
}

.app-viewall:hover {
  opacity: 0.75;
}

/* DBS App Tiles */
.app-apps {
  display: grid;
  grid-template-columns: repeat(auto-fit, 120px);
  gap: 12px;
  justify-content: start;
}

.app-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  box-sizing: border-box;
  width: 120px;
  height: 120px;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
  text-decoration: none;
  text-align: center;
  transition: border-color 0.15s, background 0.15s, transform 0.12s;
}

.app-tile:hover {
  border-color: var(--brand-mid);
  background: var(--brand-light);
  transform: translateY(-1px);
}

.app-tile.hub {
  border-color: var(--brand);
  background: linear-gradient(180deg, var(--brand) 0%, var(--brand-dark) 100%);
  color: #fff;
  position: relative;
  overflow: visible;
}

.app-tile.hub .app-tile-icon {
  background: rgba(255, 255, 255, 0.12);
}

.app-tile.hub .app-tile-icon i {
  color: #fff;
}

.app-tile.hub .app-tile-name {
  color: #fff;
}

.app-tile.hub:hover {
  background: linear-gradient(180deg, var(--brand-mid) 0%, var(--brand-dark) 100%);
  border-color: var(--brand-dark);
  transform: translateY(-2px);
}

.app-tile.hub .app-hub-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  background: #FFD24D;
  color: #24170a;
  padding: 2px 6px;
  border-radius: 10px;
  font-weight: 700;
  font-size: 11px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  box-shadow: 0 4px 10px rgba(18, 13, 41, 0.1);
}

.app-tile.hub .app-hub-badge i {
  font-size: 10px;
  display: inline-block;
}

.app-tile-icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: var(--brand-light);
  display: flex;
  align-items: center;
  justify-content: center;
}

.app-tile-icon i {
  color: var(--brand);
  font-size: 18px;
}

.app-tile-name {
  font-size: 11px;
  color: var(--text-secondary);
  font-weight: 400;
  line-height: 1.2;
}

/* DBS Bottom Panels */
.app-panels {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr;
  gap: 14px;
}

.app-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.app-panel-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px 13px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.app-panel-hd h3 {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-primary);
}

/* DBS Project Row */
.app-proj-row {
  display: flex;
  align-items: center;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.1s;
  gap: 10px;
  text-decoration: none;
}

.app-proj-row:last-child {
  border-bottom: none;
}

.app-proj-row:hover {
  background: var(--surface-2);
}

.app-proj-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--brand);
  flex-shrink: 0;
  margin-top: 1px;
}

.app-proj-info {
  flex: 1;
  min-width: 0;
}

.app-proj-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-proj-loc {
  font-size: 11px;
  color: var(--text-tertiary);
  margin-top: 1px;
}

.app-proj-meta {
  text-align: right;
  flex-shrink: 0;
}

.app-proj-date {
  font-size: 11px;
  color: var(--text-tertiary);
}

.app-proj-state {
  display: inline-flex;
  align-items: center;
  font-size: 10px;
  font-weight: 500;
  padding: 2px 7px;
  border-radius: 20px;
  margin-top: 3px;
}

.app-proj-state.active {
  background: var(--success-bg);
  color: var(--success);
}

/* Completed / on-hold projects read differently from live ones — the row used
   to say "Active" for every status regardless. */
.app-proj-state.done {
  background: var(--brand-light);
  color: var(--brand);
}

.app-proj-state.held {
  background: #f3f4f6;
  color: #6b7280;
}

.app-panel-cta {
  padding: 12px 16px;
  border-top: 1px solid var(--border);
}

.app-btn-inline {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--brand);
  border: 1px solid var(--border-strong);
  padding: 5px 12px;
  border-radius: 7px;
  cursor: pointer;
  background: transparent;
  font-family: inherit;
  transition: background 0.12s;
  font-weight: 500;
  text-decoration: none;
}

.app-btn-inline:hover {
  background: var(--brand-light);
  color: var(--brand);
}

.app-btn-inline i {
  font-size: 13px;
}

/* DBS Empty State */
.app-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.5rem;
  text-align: center;
  gap: 8px;
}

.app-empty-icon {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 4px;
}

.app-empty-icon i {
  font-size: 20px;
  color: var(--text-tertiary);
}

.app-empty p {
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.5;
}

/* DBS Inbox Row */
.app-inbox-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.1s;
}

.app-inbox-row:last-child {
  border-bottom: none;
}

.app-inbox-row:hover {
  background: var(--surface-2);
}

/* ═══════════════════════════════════════════════════════════
   SmartQuote — Session Setup Modal  (.sq-sm-*)
   ═══════════════════════════════════════════════════════════ */

/* Backdrop */
.sq-sm-backdrop {
  position: fixed; inset: 0; z-index: 1200;
  background: rgba(22, 10, 50, 0.55);
  display: flex; align-items: center; justify-content: center;
  padding: 8px;
  opacity: 0; pointer-events: none;
  transition: opacity 0.22s ease;
}
.sq-sm-backdrop.sq-sm-open {
  opacity: 1; pointer-events: all;
}

/* Dialog */
.sq-sm-dialog {
  background: #fff;
  border-radius: 18px;
  width: 96vw; max-width: 1400px;
  height: 88vh; max-height: 88vh;
  display: flex; flex-direction: column;
  box-shadow: 0 32px 96px rgba(22,10,50,0.28), 0 0 0 1px rgba(115,84,175,0.1);
  transform: translateY(36px) scale(0.97);
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  overflow: hidden;
}
.sq-sm-backdrop.sq-sm-open .sq-sm-dialog {
  transform: translateY(0) scale(1);
}

/* Header */
.sq-sm-hd {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 22px 16px;
  border-bottom: 1px solid #ede9fe;
  flex-shrink: 0;
}
.sq-sm-hd-left { display: flex; align-items: center; gap: 12px; }
.sq-sm-hd-icon {
  width: 40px; height: 40px; border-radius: 10px;
  background: linear-gradient(135deg, #7354af, #a78bfa);
  color: #fff; font-size: 17px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.sq-sm-hd-title { font-size: 16px; font-weight: 700; color: #2d1b69; line-height: 1.2; }
.sq-sm-hd-sub   { font-size: 12px; color: #7c6aaa; margin-top: 2px; }
.sq-sm-close-btn {
  width: 34px; height: 34px; border-radius: 8px; border: none;
  background: #f5f3ff; color: #7c6aaa; font-size: 18px; line-height: 1;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  transition: background 0.15s, color 0.15s;
}
.sq-sm-close-btn:hover { background: #ede9fe; color: #5b21b6; }

/* Step progress bar */
.sq-sm-progress {
  display: flex; align-items: center; padding: 12px 24px 10px;
  gap: 0; border-bottom: 1px solid #f3effe; flex-shrink: 0;
}
.sq-sm-prog-step {
  display: flex; align-items: center; gap: 7px; flex: 1;
}
.sq-sm-prog-dot {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  background: #f3effe; border: 2px solid #d4c9f0; color: #9c87cc;
  font-size: 11px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.25s, border-color 0.25s, color 0.25s;
}
.sq-sm-prog-step.active  .sq-sm-prog-dot { background: #7354af; border-color: #7354af; color: #fff; }
.sq-sm-prog-step.done    .sq-sm-prog-dot { background: #10b981; border-color: #10b981; color: #fff; }
.sq-sm-prog-label {
  font-size: 11px; font-weight: 600; color: #b0a0d9;
  transition: color 0.25s;
}
.sq-sm-prog-step.active .sq-sm-prog-label { color: #5b21b6; }
.sq-sm-prog-step.done   .sq-sm-prog-label { color: #059669; }
.sq-sm-prog-line {
  flex: 1; height: 2px; background: #ede9fe;
  margin: 0 8px; border-radius: 2px;
  transition: background 0.3s;
}
.sq-sm-prog-line.done { background: #10b981; }

/* Scrollable body area */
.sq-sm-body {
  flex: 1; overflow-y: auto; position: relative;
}
.sq-sm-loading {
  padding: 72px 24px; text-align: center; color: #7354af;
}
.sq-sm-loading i { font-size: 26px; }
.sq-sm-loading p { margin-top: 12px; font-size: 14px; color: #9c87cc; }
.sq-sm-error-state {
  padding: 40px 24px; text-align: center; color: #dc2626;
}

/* Step panels inside the modal body — animated show/hide */
.sq-step-hidden { display: none !important; }

@keyframes sqSmStepIn {
  from { opacity: 0; transform: translateX(28px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes sqSmStepInBack {
  from { opacity: 0; transform: translateX(-28px); }
  to   { opacity: 1; transform: translateX(0); }
}
.sq-sm-step-enter       { animation: sqSmStepIn     0.26s cubic-bezier(0.4,0,0.2,1) forwards; }
.sq-sm-step-enter-back  { animation: sqSmStepInBack 0.26s cubic-bezier(0.4,0,0.2,1) forwards; }

/* ─── end SmartQuote Session Setup Modal ─── */


/* ════════════════════════════════════════════════════
   SmartQuote Landing — Floor-anchored workflow
   Floors & Sessions table, Final BOQ List, compact picker
   dialogs. Reuses primary-table, insp-icon-btn, app-btn,
   app-badge, and the .sq-sm-backdrop overlay.
   ════════════════════════════════════════════════════ */
.sq-l-wrap { padding: 1.5rem 1.5rem 3rem; display: flex; flex-direction: column; gap: 1.5rem; }
.sq-l-section-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 10px;
}
.sq-l-section-title {
  font-size: 14px; font-weight: 700; color: #2d1b69;
  display: flex; align-items: center; gap: 8px;
}
.sq-l-section-title i { color: #8e75da; font-size: 13px; }

/* Floor → session expand caret (floor rows are primary-table rows) */
.sq-l-caret {
  background: none; border: none; cursor: pointer; color: #7c3aed;
  width: 22px; height: 22px; border-radius: 5px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; transition: background .12s, transform .15s;
}
.sq-l-caret:hover { background: #ede9fe; }
.sq-l-caret.open { transform: rotate(90deg); }

/* ── Floors & Sessions: collapsible cards ────────────────────────────────
   Replaces the old table. A floor and a session share no columns, so the
   session row had to span the whole grid and lay itself out with flexbox
   anyway. As cards, a session can carry its own detail without negotiating
   with the floor's columns. (The BOQ stays a real table.) */
.sq-fc-list { display: flex; flex-direction: column; gap: 8px; }
.sq-fc {
  background: #fff; border: 1px solid #ece8f5; border-radius: 12px;
  overflow: hidden; transition: border-color .12s, box-shadow .12s;
}
.sq-fc:hover { border-color: #ddd4f3; }
.sq-fc.open { border-color: #d6cbef; box-shadow: 0 1px 3px rgba(76, 46, 138, .06); }
.sq-fc-head {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; cursor: pointer; user-select: none;
}
.sq-fc-head:hover { background: #faf9ff; }
.sq-fc-title { font-size: 13.5px; font-weight: 600; color: #1f2937; flex-shrink: 0; }
.sq-fc-meta { font-size: 12px; color: #9189a8; flex-shrink: 0; }
/* Chips take the slack so the count and action stay right-aligned. */
.sq-fc-chips { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; gap: 5px; }
.sq-fc-act { flex-shrink: 0; }
.sq-fc-body { display: none; border-top: 1px solid #f1edfa; }
.sq-fc.open .sq-fc-body { display: block; }
.sq-fc-empty {
  padding: 10px 14px 10px 40px; font-size: 12px; color: #9ca3af; font-style: italic;
}

/* Session card inside a floor */
.sq-sc {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px 8px 40px; background: #faf9ff;
  border-bottom: 1px solid #f1edfa;
}
.sq-sc:last-child { border-bottom: none; }
.sq-sc:hover { background: #f5f2ff; }
.sq-sc-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sq-sc-meta { font-size: 11px; color: #9189a8; white-space: nowrap; }

/* Session actions. The primary action carries a word — a row of five bare
   glyphs gives no clue which one opens the drawing. The rest stay icons,
   grouped by consequence: edit-ish in the middle, destructive past a rule. */
.sq-sc-open { height: 26px; padding: 0 10px; font-size: 12px; }
.sq-sc-sep {
  width: 1px; height: 16px; background: #e5e0f2; flex-shrink: 0; margin: 0 2px;
}
/* Already done / already in the BOQ: state shown on the control itself, so the
   row says what has happened rather than only what you may do. */
.sq-l-actions .app-btn-icon.is-done { color: #10b981; opacity: 1; }
.sq-l-actions .app-btn-icon.is-done:disabled { pointer-events: none; }
.sq-l-actions .app-btn-icon.is-on { color: #7c3aed; }

.sq-l-session-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; }
.sq-l-session-name {
  font-size: 12.5px; font-weight: 600; color: #4338ca;
  text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sq-l-session-name:hover { text-decoration: underline; }
/* Referenceable short session id (monospace) — replaces the verbose name/badge */
.sq-l-session-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px; font-weight: 700; letter-spacing: .03em;
  color: #4338ca; text-decoration: none; white-space: nowrap;
}
.sq-l-session-id:hover { text-decoration: underline; }
.sq-l-session-meta { font-size: 11px; color: #9189a8; white-space: nowrap; }
.sq-l-mod-ico { color: #8e75da; font-size: 11px; }
.sq-l-ico-pdf { color: #dc2626; }
.sq-l-ico-floor { color: #8e75da; }
.sq-l-actions { display: flex; align-items: center; gap: 5px; flex-shrink: 0; }
/* Sub-section label inside an expanded floor — visually separates the Sessions
   list from the Components panel so they're no longer mistaken for each other. */
.sq-l-subhead-row {
  display: flex; align-items: center; gap: 6px;
  padding: 10px 14px 2px 40px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: #9189a8;
}
.sq-l-subhead-row i { color: #8e75da; font-size: 11px; }
.sq-l-subhead-row .sq-l-subhead-count { color: #b8b0cc; font-weight: 600; }

/* Floor component-confirmation zone — a clearly bounded panel, set apart from the
   sessions above it by a divider, inset margin and a faint tint. */
.sq-l-floorcomp-wrap {
  margin: 8px 14px 12px;
  padding: 12px 14px 14px;
  border: 1px solid #e7e0f5;
  border-top: 2px solid #d9cff0;
  border-radius: 10px;
  background: #faf8fe;
}
.sq-floor-comp { display: flex; flex-direction: column; gap: 14px; }
.sq-fc-title {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: #6b7280; display: flex; align-items: center; gap: 6px;
}
.sq-fc-title i { color: #8e75da; }
.sq-fc-module {
  border: 1px solid #ece8f5; border-radius: 10px; padding: 10px 12px; background: #fff;
}
.sq-fc-module-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 10px; flex-wrap: wrap;
}
.sq-fc-module-name { font-size: 13px; font-weight: 700; color: #2d1b69; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.sq-fc-module-name > i { color: #8e75da; font-size: 12px; }
.sq-fc-calc { font-size: 12px; font-weight: 500; color: #7c6aaa; }

/* Staged lock controls: framing → components → session */
.sq-fc-locksteps { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sq-fc-step-sep { color: #c9bce8; font-size: 11px; }
.sq-fc-stage {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 700; padding: 4px 9px; border-radius: 6px;
}
.sq-fc-stage i { font-size: 10px; }
.sq-fc-stage--done { background: #ecfdf5; color: #047857; border: 1px solid #a7f3d0; }
.sq-fc-unlock { font-size: 11px; }
/* Locked stages render read-only. Framing-only lock freezes just the framing
   inputs; a components lock (which implies framing locked) freezes the whole table. */
.sq-fc-flocked .wsf-manual,
.sq-fc-flocked .wsf-fdetails { opacity: .6; pointer-events: none; }
.sq-fc-clocked .wsf-list { opacity: .65; pointer-events: none; }
/* ── Landing polish: Floors & Sessions table ─────────────────────────────── */
/* Floor name stays neutral; readiness is shown with a subtle left accent + row
   hover rather than recolouring the whole label green. */
/* Framing chips: softer fill, comfortable inline rhythm. */
.sq-floor-fr { background: #f1eefb; color: #5b4596; font-weight: 600; }
.sq-floor-fr i { opacity: .8; }

/* Row actions inherit the universal .app-btn-icon; only the hover tint is
   landing-specific, so the canvas inspector buttons are untouched. */
.sq-l-actions .app-btn-icon:hover { background: #f1eefb; color: #5b4596; }

/* Modules with no saved framing collapse to a single compact line (dashed, muted)
   instead of a tall empty panel. */
.sq-fc-module--empty { padding: 8px 12px; background: #fbfafd; border-style: dashed; }
.sq-fc-module--empty .sq-fc-module-head { margin-bottom: 0; }
.sq-fc-nocalc-tag { font-size: 11px; font-weight: 600; color: #ada4c2; display: inline-flex; align-items: center; gap: 5px; }
.sq-fc-nocalc-tag i { font-size: 10px; opacity: .7; }

/* Compact picker dialog (drops into .sq-sm-backdrop instead of .sq-sm-dialog) */
.sq-l-dialog {
  background: #fff; border-radius: 14px;
  width: 96vw; max-width: 540px; max-height: 86vh;
  display: flex; flex-direction: column;
  box-shadow: 0 24px 70px rgba(22,10,50,.28);
  overflow: hidden;
  transform: translateY(24px) scale(.97);
  transition: transform .28s cubic-bezier(.34,1.56,.64,1);
}
.sq-sm-backdrop.sq-sm-open .sq-l-dialog { transform: translateY(0) scale(1); }
.sq-l-dialog--wide { max-width: 760px; }
.sq-l-dialog-body { padding: 16px 20px; overflow-y: auto; }
.sq-l-field .app-select { width: 100%; }
.sq-l-dialog-foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 12px 20px; border-top: 1px solid #ede9fe; flex-shrink: 0;
}
.sq-l-field { margin-bottom: 14px; }
.sq-l-field > label {
  display: block; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: #6b7280; margin-bottom: 5px;
}

/* Option list (PDF / floor / calc pickers) */
.sq-l-opt {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border: 1px solid #e5e7eb; border-radius: 8px;
  cursor: pointer; margin-bottom: 6px; transition: border-color .12s, background .12s;
}
.sq-l-opt:hover { border-color: #a78bfa; background: #f5f3ff; }
.sq-l-opt.selected { border-color: #7c3aed; background: #ede9fe; }
.sq-l-opt.checked  { border-color: #7c3aed; background: #ede9fe; }
.sq-l-opt-name { font-size: 13px; font-weight: 600; color: #1f2937; }
.sq-l-opt-sub  { font-size: 11px; color: #9ca3af; margin-top: 1px; }
/* PDF group heading */
.sq-l-pdf-group { margin-bottom: 4px; }
.sq-l-pdf-group-head {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: #6b7280; padding: 6px 2px 4px;
}
/* Selected PDF chips (multi-select summary row) */
.sq-pdf-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; min-height: 0; }
.sq-pdf-chips:empty { display: none; margin: 0; }
.sq-pdf-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 600; padding: 3px 8px;
  background: #ede9fe; color: #5b21b6; border-radius: 12px;
  border: 1px solid #c4b5fd;
}
.sq-pdf-chip i { font-size: 10px; opacity: .7; }
/* Footer hint in dialogs */
.sq-l-foot-hint { flex: 1; font-size: 12px; color: #9ca3af; }
.sq-l-empty {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 34px 20px; text-align: center; color: #9ca3af; font-size: 13px;
}
.sq-l-empty i { font-size: 26px; opacity: .35; }
/* Final BOQ: the session is identified by its id, not its plan-derived name */
.sq-boq-uid {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; color: #6b7280; white-space: nowrap;
}
/* The class's explicit display would otherwise win over the [hidden] UA rule,
   leaving the intro (and its padding gap) on screen after a selection is made. */
.sq-l-empty[hidden] { display: none; }

/* ── Engineering data-source cards (replaces the old 3-column modules table) ──
   One card per engineering module: icon + name, the saved-framing source select,
   and a status line. Scannable and clearly tied to the active structural link. */
.sq-mod-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(258px, 1fr)); gap: 12px;
}
.sq-mod-grid .sq-l-empty,
.sq-mod-grid .sq-mod-loading { grid-column: 1 / -1; }
.sq-mod-loading { padding: 14px; font-size: 12px; color: #9ca3af; font-style: italic; }
.sq-mod-card {
  border: 1px solid #ece8f5; border-radius: 12px; background: #fff;
  padding: 14px; display: flex; flex-direction: column; gap: 11px;
}
.sq-mod-card-head { display: flex; align-items: center; gap: 9px; }
.sq-mod-card-ico {
  width: 30px; height: 30px; border-radius: 8px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: #f3effb; color: #7c3aed; font-size: 13px;
}
.sq-mod-card-name { font-size: 13px; font-weight: 700; color: #2d1b69; }
.sq-mod-card-field label {
  display: block; font-size: 10px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: #9ca3af; margin-bottom: 4px;
}
.sq-mod-card-field .app-select { width: 100%; }
.sq-mod-card-status {
  font-size: 11px; min-height: 20px; display: flex; align-items: center;
  gap: 6px; flex-wrap: wrap;
}
.sq-mod-card-head .app-badge,
.sq-mod-card-head .sq-l-session-meta { margin-left: auto; }

/* ── Landing Zone 1 — workspace selection (Project → Loading) ─────────────── */
.sq-ws {
  display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap;
  background: #faf9fe; border: 1px solid #ece8f5; border-radius: 12px;
  padding: 14px 16px; margin-bottom: 18px;
}
.sq-ws-step { display: flex; align-items: flex-end; gap: 10px; }
.sq-ws-num {
  width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: #7c3aed; color: #fff; font-size: 12px; font-weight: 700;
  margin-bottom: 7px;
}
.sq-ws-field { display: flex; flex-direction: column; gap: 4px; min-width: 220px; }
.sq-ws-field label {
  font-size: 10px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: #6b7280;
}
.sq-ws-field .app-select { min-width: 220px; }
.sq-ws-sep { color: #c4b5fd; font-size: 13px; margin-bottom: 9px; }

/* ── Landing Zone 2 — framing assignment (systems strip + floor checklist) ─── */
.sq-mod-grid { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
.sq-mod-sys-strip { display: flex; flex-wrap: wrap; gap: 5px; }
.sq-sys-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10px; font-weight: 600; padding: 2px 7px; border-radius: 11px;
  background: #f3f4f6; color: #4b5563; border: 1px solid #e5e7eb;
}
.sq-sys-chip em { font-style: normal; font-weight: 700; opacity: .8; }
.sq-sys-chip.sq-sys-designed { background: #ecfdf5; color: #047857; border-color: #a7f3d0; }
.sq-sys-chip.sq-sys-manual   { background: #fff7ed; color: #b45309; border-color: #fed7aa; }
.sq-sys-chip.sq-sys-partial  { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }

.sq-mod-floor-head {
  display: flex; align-items: center; justify-content: space-between;
  margin: 2px 0 5px; gap: 8px;
}
.sq-mod-checkall {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 700; color: #4b5563; cursor: pointer;
}
.sq-mod-floor-list {
  max-height: 230px; overflow-y: auto; border: 1px solid #f0eef7;
  border-radius: 8px; padding: 3px;
}
.sq-mod-floor-row {
  display: flex; align-items: center; gap: 8px; padding: 4px 6px;
  border-radius: 6px; cursor: pointer; font-size: 12px;
}
.sq-mod-floor-row:hover { background: #faf9fe; }
.sq-floor-lbl { flex: 1; color: #374151; font-weight: 600; }
.sq-floor-tag {
  font-size: 9px; font-weight: 700; padding: 1px 5px; border-radius: 4px;
  text-transform: uppercase; letter-spacing: .03em;
}
.sq-floor-tag.sq-floor-data   { background: #d1fae5; color: #065f46; }
.sq-floor-tag.sq-floor-manual { background: #fef3c7; color: #92400e; }
.sq-floor-cur {
  font-size: 10px; color: #6d28d9; background: #f3effb;
  padding: 1px 6px; border-radius: 10px; max-width: 110px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sq-mod-apply { display: flex; gap: 8px; }
.sq-mod-apply[hidden] { display: none; }

/* ── Landing Zone 3 — compact floors table + per-floor framing badge ──────── */
.sq-floor-fr {
  display: inline-flex; align-items: center; gap: 4px; margin-left: 8px;
  font-size: 10px; font-weight: 600; padding: 1px 7px; border-radius: 10px;
  background: #f3effb; color: #6d28d9; vertical-align: middle;
}
.sq-floor-fr--none { background: #fef2f2; color: #b91c1c; }

/* ── WSF component picker (shared) ──────────────────────────────────────────
   Floor × component confirmation tables + the per-cell product picker. Lives
   here (not page-local) so the Modules-table sub-row and any other consumer
   can render it. Pairs with the universal .ls-tbl table classes. ─────────── */
.sq-ws-section { margin-bottom: 20px; }
.sq-ws-title-inner { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sq-ws-title-name {
  border-radius: 20px; padding: 2px 12px; font-size: 13px; font-weight: 700;
  background: rgba(255,255,255,.2); color: #fff; white-space: nowrap;
}
.sq-ws-title-type { font-size: 12px; opacity: .85; }
.sq-ws-title-meta { display: flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.sq-ws-title-tag {
  background: rgba(255,255,255,.2); border-radius: 6px; padding: 2px 9px;
  font-size: 11px; color: rgba(255,255,255,.9); font-weight: 500; white-space: nowrap;
}
.sq-ws-title-tag strong { color: #fff; font-weight: 700; }
.sq-th-orient-sub { font-size: 9px; font-weight: 400; opacity: .65; }
.ls-tbl .sq-th-floor  { min-width: 64px; }
.ls-tbl .sq-th-height { min-width: 80px; text-align: right; }
.ls-tbl td.sq-td-height small { font-weight: 400; color: #9ca3af; font-size: 10px; margin-left: 2px; }

.wsq-cell-name { font-size: 10px; font-weight: 600; color: #374151; line-height: 1.3; margin-bottom: 1px; white-space: normal; }
.wsq-cell-dim  { font-size: 10px; color: #7c3aed; font-variant-numeric: tabular-nums; margin-bottom: 2px; white-space: nowrap; }
.wsq-cell-sku  { font-size: 9px; color: #9ca3af; font-family: monospace; margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.wsq-orient-toggle { display: flex; gap: 0; }
.wsq-orient-btn {
  font-size: 10px; font-weight: 700; padding: 2px 7px; border: 1px solid #c4b5fd;
  background: #f5f3ff; color: #6d28d9; cursor: pointer; line-height: 1.4; transition: background .1s;
}
.wsq-orient-btn:first-child { border-radius: 4px 0 0 4px; }
.wsq-orient-btn:last-child  { border-radius: 0 4px 4px 0; border-left: none; }
.wsq-orient-active { background: #7c3aed; color: #fff; border-color: #6d28d9; }
.wsq-orient-lbl { font-size: 9px; color: #9ca3af; margin-top: 3px; text-align: center; white-space: nowrap; }

.wsq-cell-actions { display: flex; align-items: center; gap: 5px; margin-top: 3px; }
.wsq-pick-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 4px; border: 1px solid #e5d9ff;
  background: #f5f3ff; color: #7c3aed; cursor: pointer; flex-shrink: 0; padding: 0;
  transition: background .15s, border-color .15s;
}
.wsq-pick-icon:hover { background: #ede9fe; border-color: #a78bfa; }

.wsq-picker-opt {
  display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px;
  border: 1px solid #e5e7eb; border-radius: 8px; cursor: pointer; margin-bottom: 6px;
  transition: border-color .15s, background .15s; user-select: none;
}
.wsq-picker-opt:hover { border-color: #7c3aed; background: #f5f3ff; }
.wsq-picker-opt.wsq-picker-selected { border-color: #7c3aed; background: #ede9fe; }
.wsq-picker-opt input[type=radio] { accent-color: #7c3aed; margin-top: 3px; flex-shrink: 0; }
.wsq-picker-opt-body { flex: 1; min-width: 0; }
.wsq-picker-opt-name { font-size: 12px; font-weight: 600; color: #111827; }
.wsq-picker-opt-dim  { font-size: 11px; color: #7c3aed; margin-top: 1px; }
.wsq-picker-opt-code { font-size: 9px; color: #9ca3af; font-family: monospace; margin-top: 2px; }

/* ── WSF systems — collapsed summary rows + slide-over edit drawer ──────────
   List shows one read-only row per wall system; editing happens in a right-hand
   drawer (master–detail). The editable block stays in the DOM (hidden / moved
   into the drawer) so Confirm still gathers every cell. No inline CSS. ─────── */
.wsf-list { display: flex; flex-direction: column; gap: 8px; }

/* Summary row */
.wsf-sys-row {
  display: flex; align-items: center; gap: 14px;
  padding: 11px 14px;
  background: #fff;
  border: 1px solid #e9e4f5;
  border-radius: 10px;
  cursor: pointer;
  transition: border-color .12s, box-shadow .12s;
}
.wsf-sys-row:hover { border-color: #c9bbef; box-shadow: 0 2px 10px rgba(124,58,237,.07); }
.wsf-row-main { display: flex; align-items: center; gap: 9px; flex-shrink: 0; }
.wsf-sys-strip { width: 4px; height: 22px; border-radius: 3px; background: #7c3aed; flex-shrink: 0; }
.wsf-sys-strip.ext      { background: #2563eb; }
.wsf-sys-strip.party    { background: #d97706; }
.wsf-sys-strip.fire-ext,
.wsf-sys-strip.fire-int { background: #dc2626; }
.wsf-sys-strip.frw      { background: #db2777; }
.wsf-sys-name { font-size: 14px; font-weight: 800; color: #312e81; white-space: nowrap; }
.wsf-sys-type { font-size: 10px; font-weight: 700; color: #9ca3af; text-transform: uppercase; letter-spacing: .05em; }

.wsf-row-specs { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; flex: 1; min-width: 0; }
.wsf-spec {
  font-size: 11px; color: #6b7280;
  background: #f6f4fb; border: 1px solid #efeafa; border-radius: 6px;
  padding: 2px 9px; white-space: nowrap;
}
.wsf-spec strong { color: #312e81; font-weight: 700; }
.wsf-spec-muted { background: transparent; border: none; color: #9ca3af; }
.wsf-spec-manual { color: #92400e; background: #fffbeb; border-color: #fde68a; font-weight: 700; }
.wsf-spec-manual i { font-size: 9px; margin-right: 3px; }

.wsf-row-edit {
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  font-size: 12px; font-weight: 600; color: #6d28d9;
  background: #f1ecfe; border: 1px solid #ddd6fe; border-radius: 8px;
  padding: 6px 12px; cursor: pointer; white-space: nowrap;
  transition: background .12s, border-color .12s;
}
.wsf-row-edit:hover { background: #e6defb; border-color: #c4b5fd; }
.wsf-row-edit .fa-chevron-right { font-size: 9px; opacity: .7; }

/* ── Edit drawer (slide-over) ── */
.wsf-drawer-scrim {
  position: fixed; inset: 0; z-index: 1200;
  background: rgba(17,12,40,.38);
  opacity: 0; transition: opacity .2s;
}
.wsf-drawer-scrim.wsf-drawer-on { opacity: 1; }
.wsf-drawer {
  position: fixed; top: 0; right: 0; z-index: 1201;
  height: 100vh; width: min(520px, 94vw);
  background: #fff;
  display: flex; flex-direction: column;
  box-shadow: -12px 0 40px rgba(17,12,40,.18);
  transform: translateX(100%); transition: transform .22s ease;
}
.wsf-drawer.wsf-drawer-on { transform: translateX(0); }
.wsf-drawer[hidden], .wsf-drawer-scrim[hidden] { display: none; }
.wsf-drawer-hd {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  padding: 16px 20px; border-bottom: 1px solid #efeafa;
}
.wsf-drawer-title { font-size: 17px; font-weight: 800; color: #312e81; }
.wsf-drawer-sub { font-size: 12px; color: #9ca3af; margin-top: 2px; }
.wsf-drawer-close {
  width: 30px; height: 30px; flex-shrink: 0;
  border: none; background: #f3f0fb; border-radius: 8px;
  color: #6b7280; cursor: pointer; font-size: 15px;
}
.wsf-drawer-close:hover { background: #e9e3f8; }
.wsf-drawer-body { flex: 1; overflow-y: auto; padding: 18px 20px; }
.wsf-drawer-foot { padding: 12px 20px; border-top: 1px solid #efeafa; display: flex; justify-content: flex-end; }

.wsf-drawer-specs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.wsf-drawer-note {
  flex: 1 1 100%;
  display: flex; align-items: center; gap: 8px;
  font-size: 11.5px; font-weight: 600;
  border-radius: 8px; padding: 8px 12px; margin-bottom: 2px;
}
.wsf-drawer-note--warn { color: #92400e; background: #fffbeb; border: 1px solid #fde68a; }
.wsf-drawer-note--fail { color: #991b1b; background: #fef2f2; border: 1px solid #fecaca; }

/* Save gated until all WSF cells finish calculating */
#btnWsfSave:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; filter: grayscale(.25); }
.wsf-drawer-chip {
  display: flex; flex-direction: column; gap: 1px;
  background: #f8f7fc; border: 1px solid #ece8f6; border-radius: 8px; padding: 6px 12px; min-width: 78px;
}
.wsf-drawer-chip-l { font-size: 9px; font-weight: 700; color: #9ca3af; text-transform: uppercase; letter-spacing: .05em; }
.wsf-drawer-chip-v { font-size: 13px; font-weight: 700; color: #312e81; }

.wsf-drawer-sec { margin-bottom: 18px; }
.wsf-drawer-sectitle { font-size: 11px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: .05em; margin-bottom: 8px; }
.wsf-drawer-diagram {
  background: #fafafe; border: 1px solid #ece8f6; border-radius: 10px;
  padding: 18px; display: flex; justify-content: center;
}
.wsf-drawer-diagram img, .wsf-drawer-diagram svg { cursor: default !important; }
.wsf-d-stack { display: flex; flex-direction: column; align-items: center; gap: 0; }

/* Editable block (lives in the drawer once opened) */
.wsf-edit-orient { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.wsf-edit-lbl { font-size: 11px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: .05em; }
.wsf-edit-orient .wsf-orient-cell { display: flex; align-items: center; gap: 8px; }
.wsf-edit-orient .wsq-orient-lbl { margin-top: 0; }
.wsf-edit-grid { display: flex; flex-direction: column; gap: 8px; }

/* Framing details — connections + anchors captured into the saved framing */
.wsf-fdetails {
  background: #fbfaff; border: 1px solid #ece8f6; border-radius: 10px;
  padding: 12px 14px; margin-bottom: 16px;
}
.wsf-fd-title {
  font-size: 11px; font-weight: 700; color: #6b7280;
  text-transform: uppercase; letter-spacing: .05em; margin-bottom: 10px;
}
.wsf-fd-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px;
}
.wsf-fd-field {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #78716c;
}
.wsf-fd-field select {
  font-size: 12px; font-weight: 500; color: #1f2937;
  border: 1px solid #e5e7eb; border-radius: 7px; padding: 6px 8px; background: #fff;
  font-family: inherit; text-transform: none; letter-spacing: 0; cursor: pointer;
}
.wsf-fd-field select:focus { outline: none; border-color: #7c3aed; box-shadow: 0 0 0 2px rgba(124,58,237,.12); }

/* Manual framing entry (floors with no valid design) */
.wsf-manual {
  background: #fffbeb; border: 1px solid #fde68a; border-radius: 10px;
  padding: 12px 14px; margin-bottom: 16px;
}
.wsf-manual-hd { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.wsf-manual-tag {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: #92400e; background: #fef3c7; border: 1px solid #fcd34d; border-radius: 6px; padding: 3px 8px;
}
.wsf-manual-hint { font-size: 11px; color: #92400e; }
.wsf-manual-fields { display: flex; flex-wrap: wrap; gap: 12px; }
.wsf-manual-field {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #78716c;
  flex: 1 1 130px;
}
.wsf-manual-field input {
  font-size: 13px; font-weight: 600; color: #1f2937;
  border: 1px solid #e7c98a; border-radius: 7px; padding: 7px 9px; background: #fff;
  font-family: inherit; text-transform: none; letter-spacing: 0;
}
.wsf-manual-field input:focus { outline: none; border-color: #d97706; box-shadow: 0 0 0 2px rgba(217,119,6,.14); }

/* Component line — role | product select | sku */
.wsf-comp {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px;
  background: #fdfcff;
  border: 1px solid #eee9f7;
  border-radius: 8px;
  min-width: 0;
}
.wsf-comp-role {
  flex: 0 0 66px;
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: #9ca3af;
}
.wsf-comp-role.ct-lining     { color: #4338ca; }
.wsf-comp-role.ct-framing    { color: #6d28d9; }
.wsf-comp-role.ct-track      { color: #1d4ed8; }
.wsf-comp-role.ct-nogging    { color: #b45309; }
.wsf-comp-role.ct-insulation { color: #0d9488; }
.wsf-comp-role.ct-anchor,
.wsf-comp-role.ct-other      { color: #6b7280; }
.wsf-comp-sel {
  flex: 1; min-width: 0;
  font-size: 12px; color: #374151;
  border: 1px solid #e5e7eb; border-radius: 7px;
  padding: 6px 9px; background: #fff; cursor: pointer; appearance: auto;
  transition: border-color .12s, box-shadow .12s;
}
.wsf-comp-sel:hover  { border-color: #c4b5fd; }
.wsf-comp-sel:focus  { outline: none; border-color: #7c3aed; box-shadow: 0 0 0 2px rgba(124,58,237,.12); }
.wsf-comp-sku  { flex: 0 0 auto; font-size: 10px; color: #9ca3af; font-family: ui-monospace, monospace; }
.wsf-comp-name { flex: 1; min-width: 0; font-size: 12px; font-weight: 600; color: #374151; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wsf-comp-nosku { flex: 0 0 auto; font-size: 10px; color: #d1d5db; font-style: italic; }

/* Read-only ceiling system list */
.sq-ro-system { border: 1px solid #e5e7eb; border-radius: 8px; margin-bottom: 10px; overflow: hidden; }
.sq-ro-system-head { background: #f5f3ff; padding: 8px 12px; font-size: 12px; font-weight: 700; color: #5b21b6; }
.sq-ro-comp { display: flex; justify-content: space-between; gap: 10px; padding: 6px 12px; border-top: 1px solid #f1edfb; font-size: 11px; }
.sq-ro-comp .sq-ro-code { color: #9ca3af; font-family: monospace; }


/* ════════════════════════════════════════════════════
   Vertical Toolbar  (AutoCAD-style floating toolbar)
   Shared by SmartQuote drawing interface and SmartSpec.
   ════════════════════════════════════════════════════ */

.vertical-toolbar {
    position: absolute;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
    width: 48px;
    background: #F5F4F1;
    color: #444441;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0 0 3px;
    box-shadow: 2px 0 8px rgba(0,0,0,0.18);
    z-index: 200;
    overflow-y: auto;
    overflow-x: hidden;
    border-radius: 0 8px 8px 0;
    user-select: none;
    touch-action: none;
    max-height: calc(100% - 16px);
}
.vertical-toolbar.snapped-right {
    border-radius: 8px 0 0 8px;
    box-shadow: -2px 0 8px rgba(0,0,0,0.18);
}
.vertical-toolbar.snapped-top {
    flex-direction: row;
    width: auto !important;
    height: 48px !important;
    padding: 0;
    border-radius: 0 0 8px 8px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.18);
    max-height: none;
    max-width: calc(100% - 16px);
    overflow-x: auto;
    overflow-y: hidden;
}
.vertical-toolbar.snapped-bottom {
    flex-direction: row;
    width: auto !important;
    height: 48px !important;
    padding: 0;
    border-radius: 8px 8px 0 0;
    box-shadow: 0 -2px 8px rgba(0,0,0,0.18);
    max-height: none;
    max-width: calc(100% - 16px);
    overflow-x: auto;
    overflow-y: hidden;
}
.vertical-toolbar.snapped-top .toolbar-drag-handle,
.vertical-toolbar.snapped-bottom .toolbar-drag-handle {
    width: 20px;
    height: 100%;
    padding: 0;
    border-bottom: none;
    border-right: 0.5px solid #D4D2CF;
    flex-direction: column;
    flex-shrink: 0;
}
.vertical-toolbar.snapped-top .toolbar-section,
.vertical-toolbar.snapped-bottom .toolbar-section {
    width: auto;
    height: 100%;
    border-bottom: none;
    border-right: 0.5px solid #D4D2CF;
    padding: 0 2px;
    display: flex;
    flex-direction: row;
    align-items: center;
}
.vertical-toolbar.snapped-top .toolbar-section:last-child,
.vertical-toolbar.snapped-bottom .toolbar-section:last-child {
    border-right: none;
}
.vertical-toolbar.snapped-top .tool-btn,
.vertical-toolbar.snapped-bottom .tool-btn {
    margin: auto 2px;
    flex-shrink: 0;
}
.vertical-toolbar.snapped-top .color-picker-wrapper,
.vertical-toolbar.snapped-bottom .color-picker-wrapper {
    margin: auto 2px;
    flex-shrink: 0;
}
.vertical-toolbar.dragging {
    opacity: 0.9;
    border-radius: 8px !important;
    box-shadow: 0 6px 24px rgba(0,0,0,0.28) !important;
}
.toolbar-drag-handle {
    width: 100%;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4px 0 3px;
    cursor: grab;
    color: #b0aeaa;
    font-size: 12px;
    border-bottom: 0.5px solid #D4D2CF;
}
.toolbar-drag-handle:hover { color: #555; background: rgba(0,0,0,0.04); }
.toolbar-drag-handle:active { cursor: grabbing; }

.toolbar-section {
    width: 100%;
    border-bottom: 0.5px solid #D4D2CF;
    padding: 3px 0;
}
.toolbar-section:last-child { border-bottom: none; }

.tool-btn {
    width: 44px;
    height: 44px;
    margin: 2px auto;
    background: #FFFFFF;
    border: 1px solid #E8E6E1;
    border-radius: 6px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s ease;
    color: #444441;
    box-shadow: none;
    position: relative;
    overflow: hidden;
    font-size: 11px;
}
.tool-btn::before {
    content: '';
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background: none;
    opacity: 0;
    transition: opacity 0.2s;
}
.tool-btn:hover {
    background: #E9E7E2;
    border-color: #D4D2CF;
    color: #2d2d2b;
    transform: none;
    box-shadow: none;
}
.tool-btn:hover::before { opacity: 0; }
.tool-btn.active {
    background: #0078d4;
    border-color: #0078d4;
    color: white;
    box-shadow: none;
    transform: none;
}
.tool-btn.active::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 80%;
    height: 0px;
    background: transparent;
    box-shadow: none;
}
.tool-btn i {
    font-size: 20px;
    margin-bottom: 2px;
    color: #444441;
}
.tool-btn span {
    font-size: 8px;
    text-align: center;
    font-weight: 500;
    color: #444441;
}
.tool-btn.active i,
.tool-btn.active span { color: white; }

.color-picker-wrapper {
    width: 44px;
    height: 44px;
    margin: 2px auto;
    background: #FFFFFF;
    border: 1px solid #E8E6E1;
    border-radius: 6px;
    padding: 2px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    transition: all 0.2s ease;
}
.color-picker-wrapper:hover {
    background: #E9E7E2;
    border-color: #D4D2CF;
}
.color-picker-wrapper input[type="color"] {
    width: 36px;
    height: 28px;
    border: none;
    cursor: pointer;
    padding: 0;
    background: none;
}
.color-picker-wrapper label {
    font-size: 8px;
    color: #888;
    text-align: center;
    margin-top: 1px;
}

/* ─── end Vertical Toolbar ─── */


/* ════════════════════════════════════════════════════
   Inspector Panel  (bottom drawer)
   Shared by SmartQuote drawing interface and SmartSpec.
   ════════════════════════════════════════════════════ */

.insp-panel {
    flex-shrink: 0;
    background: #fff;
    border-top: 2px solid #e2d9f3;
    display: flex;
    flex-direction: column;
    height: auto;          /* size to content (header + rows + footer) … */
    min-height: 38px;
    max-height: 50vh;      /* … capped at half the viewport, then the table scrolls */
    transition: height 0.05s linear;
    position: relative;
    z-index: 10;
}
.insp-panel.resizing { transition: none; }
.insp-panel.collapsed { height: 38px; }

/* ── Side-by-side layout: the SmartSpec inspector is a LEFT pane, not a bottom
      drawer. Scoped to the #side-panel id so shared .insp-panel users
      (residential IFC, SmartQuote) keep the drawer behaviour. ── */
#side-panel {
  order: -1;                 /* sit left of the 3D viewer */
  width: 420px; min-width: 220px; max-width: 60%;
  height: auto; min-height: 0; max-height: none;   /* stretch to full column height */
  align-self: stretch;
  border-top: none;
  border-right: 2px solid #e2d9f3;
}
/* min-width:220px above always wins over a smaller width, so collapsed must
   override it too or the panel stays pinned at 220px with everything hidden
   inside — a blank gap instead of a slim 40px rail. */
#side-panel.collapsed { width: 40px; min-width: 40px; max-width: 40px; height: auto; }
#side-panel.collapsed .insp-tabs,
#side-panel.collapsed .insp-actions { display: none; }
#side-panel.collapsed .insp-header { padding: 0; justify-content: center; }
/* Collapsed, the rail IS the toggle: stretch the tinted header over the whole
   strip and centre the chevron in it, instead of a 38px cap of colour above a
   white void with the chevron stranded at the top. */
#side-panel.collapsed { background: var(--tbl-head-bg, #f5f3ff); }
#side-panel.collapsed .insp-header {
  flex: 1 1 auto; height: auto; align-items: center; border-bottom: none;
}
/* Resize handle moves to the RIGHT edge (horizontal drag). */
#side-panel .insp-resize-handle {
  top: 0; bottom: 0; left: auto; right: -4px;
  width: 8px; height: auto; cursor: ew-resize;
}
#side-panel .insp-resize-handle::after { width: 3px; height: 40px; }

/* ── Compact 2-line card layout for the SmartSpec inspector list ──────────────
   The wide multi-column table can't fit the narrow left pane, so each system
   renders as a compact card: line 1 = identity (name + supplier/code + actions),
   line 2 = flags + performance, line 3 = notes. This is pure CSS over the
   existing table markup (walls & ceilings, SSR + JS renderers), so every row
   handler, data-attr and the component-expansion sub-rows keep working. */
#side-panel .insp-table,
#side-panel .insp-table > thead,
#side-panel .insp-table > tbody { display: block; width: 100%; }
#side-panel .insp-table > thead { display: none; }   /* columns no longer align */
#side-panel .insp-table-wrap { overflow-x: hidden; }  /* no more sideways scroll */

#side-panel .insp-table tr.line-item {
  display: flex; flex-wrap: wrap; align-items: center;
  column-gap: 6px; row-gap: 2px;
  padding: 6px 11px; border-bottom: 1px solid #f0f1f5;
  transition: background .12s;
}
#side-panel .insp-table tr.line-item:hover { background: #faf9fe; }
#side-panel .insp-table tr.line-item.selected { background: #f3f0fd; }
#sb-walls-table tr.line-item.selected { box-shadow: inset 3px 0 0 #7c3aed; }
#sb-ceilings-table tr.line-item.selected { box-shadow: inset 3px 0 0 #0369a1; }
/* width:auto overrides the base ".insp-table td { width:1% }" shrink trick, which
   otherwise collapses every flex-item cell to a few px and overflows the text. */
#side-panel .insp-table tr.line-item > td { padding: 0; border: none; font-size: 12px; width: auto; }

/* line 1 — system identity */
#side-panel tr.line-item > td:has(.insp-sys-dot) { order: 1; white-space: nowrap; }
/* The colour square marked wall (purple) vs ceiling (blue) — redundant now that
   each lives in its own tab, so hide it and keep just the expand toggle. */
#side-panel .insp-sys-dot { display: none; }
#side-panel tr.line-item > td:has(.insp-name-input) { order: 2; flex: 0 1 auto; min-width: 0; }
#side-panel tr.line-item > td:has(.insp-name-input) + td { order: 3; }        /* supplier badge */
#side-panel tr.line-item > td:has(.insp-name-input) + td + td { order: 4; }    /* code + modified pill */
#side-panel tr.line-item > td:has(.insp-td-actions) { order: 5; margin-left: auto; }

/* Forced break after the identity line: repurpose the always-empty "Other" perf
   cell (walls col 10, ceilings col 9) as a zero-height full-width spacer. */
#sb-walls-table tr.line-item > td.insp-perf-cell:nth-child(10),
#sb-ceilings-table tr.line-item > td.insp-perf-cell:nth-child(9) {
  order: 6; flex: 0 0 100%; height: 0; padding: 0; margin: 0; overflow: hidden; visibility: hidden;
}

/* line 2 — flags + performance, rendered as labelled pill-chips (the header row
   is gone, so every value names itself). */
#side-panel tr.line-item > td.insp-flag-cell {
  order: 12; display: inline-flex; align-items: center; gap: 5px;
  padding: 1px 8px 1px 9px; border-radius: 999px;
  background: #f4f5f8; border: 1px solid #e9ebf0;
  font-size: 9.5px; letter-spacing: .04em; text-transform: uppercase; font-weight: 700; color: #9aa2b1;
}
#side-panel tr.line-item > td.insp-flag-cell--active { order: 11; }
/* checked flags read as "on" with an accent tint */
#side-panel tr.line-item > td.insp-flag-cell:has(.insp-flag:checked) {
  background: #f0ebfe; border-color: #dccdfb; color: #6d28d9;
}
#side-panel .insp-flag { accent-color: #7c3aed; width: 13px; height: 13px; margin: 0; cursor: pointer; }

/* Active flag reads as a switch, not a checkbox — a plain tick is easy to
   mistake for "this row is selected" rather than "excluded from reports and
   calculations when off", which is a much bigger effect than Wet/Sealed. */
#side-panel .insp-flag--switch {
  appearance: none; -webkit-appearance: none; accent-color: unset;
  width: 26px; height: 14px; border-radius: 999px; position: relative;
  background: #cbd1dc; border: none; margin: 0; cursor: pointer;
  transition: background .15s ease; flex-shrink: 0;
}
#side-panel .insp-flag--switch::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 10px; height: 10px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,.3); transition: left .15s ease;
}
#side-panel .insp-flag--switch:checked { background: #7c3aed; }
#side-panel .insp-flag--switch:checked::after { left: 14px; }

#side-panel tr.line-item > td.insp-perf-cell {
  order: 15; display: inline-flex; align-items: baseline; gap: 4px;
  padding: 1px 8px; border-radius: 6px; background: #eef2f7;
  font-size: 10.5px; font-weight: 600; color: #334155; white-space: nowrap;
}
/* Hide empty (grey dash) and voided (amber dash) performance cells — the MODIFIED
   pill already explains why a modified system carries no ratings. */
#side-panel tr.line-item > td.insp-perf-cell:has(> span[style*="9ca3af"]),
#side-panel tr.line-item > td.insp-perf-cell:has(> .insp-perf-void) { display: none; }

/* Inline labels for the flags + the values that don't name themselves (FRL, width). */
#side-panel tr.line-item > td.insp-flag-cell--active::before { content: "Active"; }
#side-panel tr.line-item > td.insp-flag-cell[data-sealed-cell]::before { content: "Sealed"; }
#side-panel tr.line-item > td.insp-flag-cell:not(.insp-flag-cell--active):not([data-sealed-cell])::before { content: "Wet"; }
#side-panel tr.line-item > td.insp-perf-cell::before { color: #94a3b8; font-weight: 700; font-size: 9px; text-transform: uppercase; letter-spacing: .03em; }
#sb-walls-table tr.line-item > td.insp-perf-cell:nth-child(6)::before,
#sb-ceilings-table tr.line-item > td.insp-perf-cell:nth-child(6)::before { content: "FRL"; }
#sb-walls-table tr.line-item > td.insp-perf-cell:nth-child(9)::before { content: "W"; }

/* notes — always its own full-width third row. */
#side-panel tr.line-item > td:has(.insp-notes-input) { order: 30; flex: 1 1 100%; min-width: 0; }
/* Empty notes stay low-profile (italic, dim) so they don't read as filled. */
#side-panel .insp-notes-input:placeholder-shown:not(:focus) { opacity: .5; font-style: italic; }

/* Cleaner, lighter inline inputs so the card reads like a card, not a form. */
#side-panel .insp-name-input {
  font-weight: 600; font-size: 12.5px; box-sizing: border-box;
  /* size the input to its text so the supplier/code sit right beside the tag
     (field-sizing: Chromium 123+; falls back to the default input width). */
  field-sizing: content; width: auto; min-width: 46px; max-width: 200px;
  border: 1px solid transparent; background: transparent; padding: 2px 5px; border-radius: 5px;
}
#side-panel .insp-notes-input {
  font-size: 11px; width: 100%; min-width: 0; box-sizing: border-box;
  border: 1px solid transparent; background: transparent; padding: 2px 5px; border-radius: 5px;
}
#side-panel .insp-name-input:hover,
#side-panel .insp-notes-input:hover { border-color: #e2e8f0; }
#side-panel .insp-name-input:focus,
#side-panel .insp-notes-input:focus { border-color: #c4b5fd; background: #fff; outline: none; }

/* Inline add-row (ghost): keep its hint visible instead of letting the name grow. */
#side-panel tr.line-item[data-wt-pk="new"] > td:has(.insp-name-input) { flex: 0 0 auto; min-width: 92px; }
#side-panel tr.line-item[data-wt-pk="new"] > td[colspan] { order: 4; flex: 1 1 auto; }

/* Component-expansion sub-rows: a clean indented list, one component per line —
   [layer chip] [supplier] [product name, grows + truncates] [code]. The old
   "LAYER SUPPLIER PRODUCT CODE" header cramped together, so it's dropped. */
#side-panel .insp-comp-header { display: none; }
#side-panel .insp-comp-row {
  display: flex; align-items: center; gap: 8px;
  padding: 3px 11px 3px 30px; font-size: 11px;
  background: #fbfbfe; border-bottom: 1px solid #f3f2f9;
}
#side-panel .insp-comp-row:hover { background: #f6f4fd; }
/* reset the base ".insp-table td { width:1% }" shrink trick that jammed the cells */
#side-panel .insp-comp-row > td { width: auto; padding: 0; border: none; }
#side-panel .insp-comp-row > td:first-child,          /* empty lead cell   */
#side-panel .insp-comp-row > td[colspan] { display: none; }   /* empty tail cell */
#side-panel .insp-comp-row > td:nth-child(2) { flex: 0 0 auto; }   /* layer chip */
#side-panel .insp-comp-row .insp-comp-supplier {
  flex: 0 0 auto; color: #94a3b8; font-size: 10px; font-weight: 500;
}
#side-panel .insp-comp-row .insp-comp-name {
  flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-weight: 600; color: #334155;
}
#side-panel .insp-comp-row .insp-comp-code {
  flex: 0 0 auto; margin-left: auto; padding-left: 6px; color: #9aa2b1; font-size: 10px;
}

.insp-resize-handle {
    position: absolute;
    top: -4px;
    left: 0; right: 0;
    height: 8px;
    cursor: ns-resize;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
}
.insp-resize-handle::after {
    content: '';
    display: block;
    width: 40px;
    height: 3px;
    border-radius: 2px;
    background: #d8b4fe;
    opacity: 0;
    transition: opacity 0.15s;
}
.insp-resize-handle:hover::after,
.insp-panel.resizing .insp-resize-handle::after { opacity: 1; }

.insp-header {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    padding: 0 10px;
    height: 38px;
    background: var(--tbl-head-bg, #f5f3ff);
    border-bottom: 1px solid var(--tbl-head-border, #ddd6fe);
    gap: 0;
}
.insp-tabs { display: flex; align-items: stretch; gap: 0; flex: 1; height: 100%; }
.insp-tab {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 0 14px; font-size: 12px; font-weight: 600; color: #6b7280;
    background: none; border: none; border-bottom: 2px solid transparent;
    cursor: pointer; white-space: nowrap; height: 100%;
    transition: color 0.12s, border-color 0.12s;
}
.insp-tab:hover { color: #374151; }
.insp-tab.active { color: #6d28d9; border-bottom-color: #6d28d9; }
.insp-tab-badge {
    background: #6d28d9; color: #fff; border-radius: 99px;
    font-size: 10px; font-weight: 700; padding: 1px 6px;
    min-width: 18px; text-align: center;
}
/* ── Tooltip for [data-tip] ──
   Body-level + fixed: the inspector's sticky headers sit inside an
   overflow:auto wrapper that clips anything in flow (which is why the native
   title never showed). Positioned by sbTipShow. */
.sb-tip {
  display: none; position: fixed; z-index: 9700; max-width: 260px;
  padding: 6px 9px; border-radius: 6px; pointer-events: none;
  background: #1f2937; color: #fff; font-size: 11.5px; line-height: 1.45;
  box-shadow: 0 6px 20px rgba(15,10,30,.22); white-space: normal;
}

/* ── Design-classification flag columns (Active / Wet / Sealed) ── */
.insp-flag-th { width: 52px; text-align: center; }
.insp-flag-cell { text-align: center; white-space: nowrap; }
.insp-flag {
  width: 14px; height: 14px; margin: 0; cursor: pointer; accent-color: #7c3aed;
  vertical-align: middle;
}
/* The chip sits under the tick in its own cell, so it must not inherit the
   inline spacing the code-column version uses. */
.insp-flag-cell .insp-mod-flag { display: inline-block; margin: 2px 0 0; }

/* Not active → excluded from reports, certification and calculations. Grey the
   row so that reads at a glance, but keep the Active tick and the row actions
   at full strength: you still need to click them to bring it back. */
.insp-table tbody tr.insp-row-inactive > td { opacity: .4; }
.insp-table tbody tr.insp-row-inactive > td.insp-flag-cell--active,
.insp-table tbody tr.insp-row-inactive > td:last-child { opacity: 1; }
.insp-table tbody tr.insp-row-inactive .insp-name-input { text-decoration: line-through; }

/* ── "Modified from the tested system" markers ──
   The build-up no longer matches the tested specimen, so its FRL / Rw / R-value
   are withheld rather than shown against an assembly they weren't tested on. */
.insp-mod-flag {
  margin-left: 6px; padding: 1px 5px; border-radius: 99px; vertical-align: middle;
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  color: #b45309; background: #fef3c7; border: 1px solid #fde68a; cursor: help;
}
.insp-perf-void { color: #d97706; cursor: help; border-bottom: 1px dotted #fbbf24; }

.insp-actions { display: flex; align-items: center; gap: 6px; margin-left: 12px; }
.insp-add-menu { position: relative; }
.insp-add-chevron { font-size: 8px; margin-left: 3px; opacity: 0.7; }
.insp-add-dropdown {
  position: absolute; top: calc(100% + 5px); right: 0;
  background: #fff; border: 1.5px solid #e5e7eb; border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0,0,0,.12); min-width: 162px;
  z-index: 200; display: none; flex-direction: column; overflow: hidden;
}
.insp-add-dropdown.open { display: flex; }
.insp-add-dropdown button {
  background: none; border: none; padding: 9px 13px;
  text-align: left; font-size: 12px; color: #374151;
  cursor: pointer; display: flex; align-items: center; gap: 8px;
  white-space: nowrap;
}
.insp-add-dropdown button:hover { background: #f3f0ff; color: #6d28d9; }
.insp-add-dropdown button i { color: #7c3aed; font-size: 11px; width: 14px; text-align: center; }
.insp-action-btn {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 10px; font-size: 11px; font-weight: 600;
    border-radius: 6px; border: 1px solid; cursor: pointer;
    transition: opacity 0.15s; white-space: nowrap; font-family: inherit;
}
.insp-action-btn:hover { opacity: 0.8; }
.insp-action-btn--danger  { background: #fef2f2; color: #dc2626; border-color: #fecaca; }
.insp-action-btn--primary { background: #ede9fe; color: #6d28d9; border-color: #c4b5fd; }
.insp-action-btn--ifc     { background: #eef2ff; color: #4338ca; border-color: #c7d2fe; }
.insp-action-btn--ifc:disabled { opacity: 0.45; cursor: not-allowed; }
.insp-action-btn--bom     { background: #f0fdf4; color: #15803d; border-color: #bbf7d0; text-decoration: none; }
.insp-action-btn--ai      { background: #f9fafb; color: #6b7280; border-color: #e5e7eb; opacity: 0.55; cursor: not-allowed; }
.insp-action-btn--tpl     { background: #f5f3ff; color: #6d28d9; border-color: #c4b5fd; border-style: dashed; }
.insp-action-btn--tpl:hover { border-style: solid; }
.insp-actions-sep         { width: 1px; height: 20px; background: #e5e7eb; flex-shrink: 0; margin: 0 2px; }
.insp-toggle-btn {
    width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
    background: none; border: 1px solid #e5e7eb; border-radius: 5px;
    cursor: pointer; color: #6b7280; font-size: 10px; transition: background 0.12s; margin-left: 4px;
}
.insp-toggle-btn:hover { background: #f3f4f6; }

/* ── Inspection-panel type sub-tabs ── */
.insp-subtabs {
  flex-shrink: 0; display: flex; align-items: center; gap: 4px;
  padding: 6px 10px; background: #fbfaff; border-bottom: 1px solid #ece8f5;
  overflow-x: auto; white-space: nowrap;
}
.insp-panel.collapsed .insp-subtabs { display: none; }
.insp-subtab {
  flex-shrink: 0; padding: 4px 11px; font-size: 11px; font-weight: 600;
  color: #6b7280; background: #fff; border: 1px solid #e5e7eb; border-radius: 99px;
  cursor: pointer; font-family: inherit; transition: all .12s; white-space: nowrap;
}
.insp-subtab:hover { color: #6d28d9; border-color: #c4b5fd; background: #f5f3ff; }
.insp-subtab.active { color: #fff; background: #6d28d9; border-color: #6d28d9; }
.insp-subtab i { font-size: 10px; margin-right: 3px; opacity: .8; }
.insp-subtab-group {
  flex-shrink: 0; font-size: 9.5px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: #a78bfa; padding: 0 4px 0 8px;
}

/* ── Search box + filter controls (system library overlay) ── */
.sb-finder-search { position: relative; flex: 1 1 220px; min-width: 180px; max-width: 300px; }
.sb-finder-search i {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  color: #9ca3af; font-size: 12px; pointer-events: none;
}
.sb-finder-search input {
  width: 100%; height: 30px; padding: 0 10px 0 30px; font-size: 12px;
  border: 1px solid #d1d5db; border-radius: 6px; outline: none; font-family: inherit;
}
.sb-finder-search input:focus { border-color: #a78bfa; }
.sb-ff-group { display: flex; align-items: center; gap: 4px; }
.sb-ff-lbl { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: #9ca3af; margin-right: 1px; }
.sb-ff-clear {
  width: 26px; height: 26px; border: 1px solid #e5e7eb; border-radius: 6px; background: #fff;
  color: #9ca3af; cursor: pointer; font-size: 11px; margin-left: auto;
}
.sb-ff-clear:hover { background: #fef2f2; color: #dc2626; border-color: #fecaca; }

/* ── Template picker ("which template?" behind the inspector Template button) ── */
.sb-tpl-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
.sb-tpl-group {
  grid-column: 1 / -1; font-size: 9.5px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: #9ca3af; padding: 8px 2px 2px;
}
.sb-tpl-card {
  display: flex; align-items: center; gap: 9px; text-align: left;
  padding: 11px 12px; font-size: 12.5px; font-weight: 600; font-family: inherit;
  color: #374151; background: #fff; border: 1px solid #e5e7eb; border-radius: 8px;
  cursor: pointer; transition: all .12s;
}
.sb-tpl-card:hover { color: #6d28d9; border-color: #c4b5fd; background: #f5f3ff; }
.sb-tpl-card i { color: #7c3aed; font-size: 13px; width: 15px; text-align: center; flex-shrink: 0; }
.sb-tpl-card span { overflow: hidden; text-overflow: ellipsis; }
.sb-tpl-card--blank { border-style: dashed; }

/* ── Components column: layer editor above, builder bar pinned at its foot.
      Revealed by #sb-build-area.building; hidden (zero width) otherwise. ── */
#sb-left-col { display: none; }
#sb-build-area.building #sb-left-col {
  display: flex; flex-direction: column; min-height: 0;
  width: 320px; flex-shrink: 0;
  border-right: 1px solid #ece8f5; background: #fbfafe;
}

/* ── Builder bar (foot of the components column while building) ── */
#sb-builder-bar {
  flex-shrink: 0; display: flex; flex-direction: column; gap: 7px;
  padding: 10px 12px; background: #faf8ff; border-top: 1px solid #ede9fe;
}
.sb-bb-row { display: flex; align-items: center; gap: 8px; }
.sb-bb-row--btns > * { flex: 1; justify-content: center; }
.sb-bb-badge {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: #6d28d9; background: #ede9fe; border-radius: 99px; padding: 3px 9px; white-space: nowrap;
}
#sb-bb-name {
  flex: 1; min-width: 0; height: 30px; padding: 0 10px; font-size: 13px;
  border: 1px solid #d1d5db; border-radius: 6px; outline: none; font-family: inherit;
}
#sb-bb-name:focus { border-color: #a78bfa; }
.sb-bb-cancel {
  height: 30px; padding: 0 12px; font-size: 12px; font-weight: 600; font-family: inherit;
  color: #6b7280; background: #fff; border: 1px solid #e5e7eb; border-radius: 6px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px;
}
.sb-bb-cancel:hover { background: #f9fafb; }
.sb-bb-save { height: 30px; padding: 0 14px; font-size: 12px; }
.sb-bb-save:disabled { opacity: .5; cursor: not-allowed; }

/* ── Interactive 2D layer editor (Section view) ── */
/* Scrolls inside the components column; the builder bar below it stays put. */
#sb-layer-stack {
  flex: 1; min-height: 0; overflow-y: auto; padding: 10px 12px 24px;
}
/* Tri-pane overlay: Perspective (left) | Section (top-right) / Plan (bottom-right).
   Left split at 56% must match _TRI_LEFT_FRAC in the renderer. */
/* Tri-pane = three real bordered container cells overlaid on the single canvas.
   The 6px gutter (--sb-tri-gut) + 56%/50% split MUST match the inset viewports in
   _renderTriple and _TRI_LEFT_FRAC in the renderer. pointer-events:none so the canvas
   underneath still receives mouse input (routed per pane by _triPaneAt). */
#sb-tri-labels {
  position: absolute; inset: 0; pointer-events: none; --sb-tri-gut: 6px;
  user-select: none; -webkit-user-select: none;   /* no blue text-select on drag */
}
.sb-tri-pane {
  position: absolute; pointer-events: none; z-index: 4;
  border: 1px solid #cbd5e1; border-radius: 0; background: transparent;
  transition: border-color .1s ease;
}
/* Active viewport (cursor is over it): crisp accent edge, no shadow/radius */
.sb-tri-pane.is-hovered { border-color: #7c3aed; box-shadow: inset 0 0 0 1px #7c3aed; }
:root[data-theme="dark"] .sb-tri-pane { border-color: #3a4150; }
:root[data-theme="dark"] .sb-tri-pane.is-hovered { border-color: #a78bfa; box-shadow: inset 0 0 0 1px #a78bfa; }
/* Perspective on top (full width); Section + Plan share a smaller bottom row. */
.sb-tri-pane--persp {
  left: var(--sb-tri-gut); right: var(--sb-tri-gut); top: var(--sb-tri-gut);
  bottom: calc(38% + var(--sb-tri-gut));
}
.sb-tri-pane--section {
  left: var(--sb-tri-gut); top: calc(62% + var(--sb-tri-gut));
  right: calc(50% + var(--sb-tri-gut)); bottom: var(--sb-tri-gut);
}
.sb-tri-pane--plan {
  left: calc(50% + var(--sb-tri-gut)); top: calc(62% + var(--sb-tri-gut));
  right: var(--sb-tri-gut); bottom: var(--sb-tri-gut);
}
.sb-tri-lbl {
  position: absolute; left: 10px; top: 7px; pointer-events: none;
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: #94a3b8;
}
.sb-ls-empty-msg { text-align: center; color: #9ca3af; font-size: 12px; padding: 28px 0; }
.sb-layer-strip {
  display: flex; align-items: stretch; gap: 0; overflow: hidden;
  background: #fff; border: 1px solid #e9e5f5; border-radius: 9px; cursor: pointer;
  transition: border-color .12s, box-shadow .12s;
}
.sb-layer-strip:hover { border-color: #c4b5fd; box-shadow: 0 1px 6px rgba(124,58,237,.08); }
.sb-layer-strip.dragging { opacity: .45; border-style: dashed; }
/* Selected layer (clicked in the list or picked in the 3D) — accent edge that
   matches the viewport highlight. */
.sb-layer-strip.ring-3d-highlight {
  border-color: #7c3aed; background: #f5f3ff;
  box-shadow: 0 0 0 1px #7c3aed, 0 1px 8px rgba(124,58,237,.16);
}
:root[data-theme="dark"] .sb-layer-strip.ring-3d-highlight {
  border-color: #a78bfa; background: rgba(124,58,237,.14);
  box-shadow: 0 0 0 1px #a78bfa;
}
/* ── Right-click menu (component cards + inspector rows) ── */
.sb-ctx-menu {
  display: none; position: fixed; z-index: 9600; min-width: 178px; padding: 4px;
  background: #fff; border: 1px solid #e5e7eb; border-radius: 8px;
  box-shadow: 0 8px 26px rgba(15,10,30,.16);
}
.sb-ctx-menu button {
  display: flex; align-items: center; gap: 9px; width: 100%; padding: 7px 10px;
  background: none; border: none; border-radius: 5px; cursor: pointer;
  font-family: inherit; font-size: 12px; color: #374151; text-align: left; white-space: nowrap;
}
.sb-ctx-menu button:hover { background: #f5f3ff; color: #6d28d9; }
.sb-ctx-menu button i { width: 14px; text-align: center; opacity: .75; font-size: 11px; }
.sb-ctx-menu button.danger { color: #b91c1c; }
.sb-ctx-menu button.danger:hover { background: #fef2f2; }
.sb-ctx-sep { height: 1px; margin: 4px 6px; background: #f1f5f9; }

/* Where the dragged card will land. Inset bars, because .sb-layer-strip clips
   overflow; declared last so they win over the hover / highlight box-shadows. */
.sb-layer-strip.drop-above { box-shadow: inset 0 3px 0 0 #7c3aed; border-color: #c4b5fd; }
.sb-layer-strip.drop-below { box-shadow: inset 0 -3px 0 0 #7c3aed; border-color: #c4b5fd; }

/* ── 3D component leader tags (system builder viewport) ─────────────────── */
#sb-tag-overlay { position: absolute; inset: 0; pointer-events: none; z-index: 6; display: none; }
#sb-tag-overlay svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
#sb-tag-overlay svg line { stroke: #94a3b8; stroke-width: 1; }
#sb-tag-overlay svg line.sel { stroke: #7c3aed; stroke-width: 1.4; }
.sb-tag-chip {
  position: absolute; pointer-events: auto; cursor: pointer; user-select: none;
  font-size: 10px; font-weight: 600; line-height: 17px; white-space: nowrap;
  color: #475569; background: rgba(255,255,255,.94);
  border: 1px solid #cbd5e1; border-radius: 3px; padding: 0 6px;
}
.sb-tag-chip:hover { border-color: #7c3aed; color: #5b21b6; }
.sb-tag-chip.is-selected { background: #7c3aed; border-color: #7c3aed; color: #fff; }
.sb-tag-chip.is-off { opacity: .45; text-decoration: line-through; }
/* ── 3D viewport tools: measure overlay + tool sliders ──────────────────── */
#sb-measure-overlay { position: absolute; inset: 0; pointer-events: none; z-index: 7; display: none; }
#sb-measure-overlay svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
#sb-measure-overlay svg line { stroke: #0ea5e9; stroke-width: 1.5; }
#sb-measure-overlay svg circle { fill: #0ea5e9; stroke: #fff; stroke-width: 1; }
.sb-measure-lbl {
  position: absolute; transform: translate(-50%, -135%); pointer-events: none;
  font-size: 10.5px; font-weight: 700; color: #0c4a6e; white-space: nowrap;
  background: rgba(224,242,254,.95); border: 1px solid #7dd3fc; border-radius: 3px; padding: 1px 7px;
}
.sb-measure-lbl span { font-weight: 500; color: #0369a1; }
/* Bottom-left so they never collide with the wrapping tool row up top. */
#sb-3d-sliders { position: absolute; bottom: 8px; left: 8px; display: flex; flex-direction: column; gap: 4px; z-index: 10; }
#sb-3d-sliders > div {
  display: flex; align-items: center; gap: 7px; padding: 3px 9px;
  background: rgba(255,255,255,.94); border: 1px solid #d1d5db; border-radius: 5px;
  font-size: 10px; color: #5b21b6;
}
#sb-3d-sliders input[type="range"] { width: 130px; height: 4px; accent-color: #7c3aed; }
.sb-ls-bar { width: 4px; flex-shrink: 0; align-self: stretch; }
.sb-ls-handle { display: flex; align-items: center; color: #cbd5e1; cursor: grab; font-size: 12px; padding: 0 4px 0 8px; flex-shrink: 0; }
.sb-ls-handle:active { cursor: grabbing; }
.sb-ls-body { flex: 1; min-width: 0; padding: 7px 4px 7px 0; display: flex; flex-direction: column; gap: 1px; justify-content: center; }
.sb-ls-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.sb-ls-typetag {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: #94a3b8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sb-ls-supplier { font-size: 10.5px; font-weight: 700; color: #7c3aed; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 50%; flex-shrink: 0; }
.sb-ls-pname { font-size: 13px; font-weight: 500; color: #1f2937; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sb-ls-code { font-size: 10.5px; color: #64748b; font-family: 'JetBrains Mono', 'Fira Mono', monospace; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sb-ls-body .sb-ls-empty { color: #a78bfa; font-style: italic; font-size: 13px; }
.sb-ls-x {
  flex-shrink: 0; width: 30px; align-self: stretch; border: none; background: none; color: #cbd5e1;
  cursor: pointer; font-size: 12px;
}
.sb-ls-x:hover { background: #fef2f2; color: #dc2626; }
/* Insert zone between strips */
/* Add-a-layer affordance between cards. It used to be opacity:0 until hovered,
   which made it undiscoverable — you had to know it was there. Keep it visible
   at rest and let hover promote it. */
.sb-ls-insert {
  position: relative; height: 20px; display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.sb-ls-insert > span {
  position: relative; z-index: 1;
  width: 20px; height: 20px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-size: 9px; color: #8b5cf6; background: #fff; border: 1px solid #ddd6fe;
  opacity: .75; transition: opacity .12s, background .12s, color .12s, border-color .12s, transform .12s;
}
.sb-ls-insert:hover > span {
  opacity: 1; color: #fff; background: #7c3aed; border-color: #7c3aed; transform: scale(1.12);
}
.sb-ls-insert::before {
  content: ''; position: absolute; left: 10px; right: 10px; top: 50%; height: 1px; background: #ede9fe;
}
.sb-ls-insert:hover::before { background: #c4b5fd; }
.sb-ls-typepicker {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%); z-index: 50; margin-top: 2px;
  background: #fff; border: 1px solid #e5e7eb; border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.14);
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 2px; padding: 6px; min-width: 220px;
}
.sb-ls-typepicker button {
  text-align: left; font-size: 11.5px; padding: 6px 9px; border: none; background: none; border-radius: 5px;
  color: #374151; cursor: pointer; font-family: inherit; white-space: nowrap;
}
.sb-ls-typepicker button:hover { background: #f3f0ff; color: #6d28d9; }
.sb-ls-tp-group {
  grid-column: 1 / -1; font-size: 9.5px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: #9ca3af; padding: 7px 9px 3px; margin-top: 2px;
  border-top: 1px solid #f1f5f9;
}
.sb-ls-tp-group:first-child { border-top: none; margin-top: 0; }
/* Pre-rendered 3D thumbnail (SystemThumbnail) — plain img, no client render */
.sb-thumb-img { width: 100%; height: 100%; object-fit: contain; border-radius: 4px; }
/* The system-info modal reuses the shared .dp-* "Universal detail-modal building
   blocks" + .cp-modal-overlay (see "Detail modal" section above) — no bespoke CSS. */

/* ── Library browser overlay (categorised catalog, card grid) ── */
.sb-lib-shell {
  width: min(1280px, calc(100vw - 48px)); height: calc(100vh - 64px);
  background: #fff; border-radius: 12px; overflow: hidden;
  display: flex; flex-direction: column;
  box-shadow: 0 24px 64px rgba(30, 20, 70, .35);
}
.sb-lib-head {
  flex-shrink: 0; display: flex; align-items: center; gap: 12px;
  padding: 11px 14px; border-bottom: 1px solid #f1eefb; background: #fbfaff;
}
.sb-lib-title { font-size: 14px; font-weight: 700; color: #4c1d95; white-space: nowrap; }
.sb-lib-title i { margin-right: 6px; color: #7c3aed; }
.sb-lib-search { flex: 0 1 340px; }
.sb-lib-count { margin-left: auto; font-size: 12px; font-weight: 600; color: #6b7280; white-space: nowrap; }
/* Filter bar — its own row so controls never crowd the title/search */
.sb-lib-filters {
  flex-shrink: 0; display: flex; align-items: center; gap: 6px 10px; flex-wrap: wrap;
  padding: 8px 14px; border-bottom: 1px solid #ece8f5; background: #fff;
}
.sb-lib-filters .sb-ff,
.sb-lib-filters .sb-ff-num {
  height: 26px; font-size: 11px; border: 1px solid #d1d5db; border-radius: 6px;
  background: #fff; color: #374151; padding: 0 6px; outline: none; font-family: inherit;
}
.sb-lib-filters .sb-ff { cursor: pointer; max-width: 190px; }
.sb-lib-filters .sb-ff:focus,
.sb-lib-filters .sb-ff-num:focus { border-color: #a78bfa; }
.sb-lib-filters .sb-ff-num { width: 56px; }
.sb-lib-body { flex: 1 1 auto; min-height: 0; display: flex; }
.sb-lib-tree {
  flex: 0 0 240px; overflow-y: auto; border-right: 1px solid #ece8f5;
  background: #fbfaff; padding: 10px 8px 16px;
}
.sb-lib-tree-section {
  font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: #a78bfa; padding: 10px 8px 4px;
}
.sb-lib-node {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 5px 8px; border: none; background: none; border-radius: 6px;
  font-size: 12px; font-weight: 600; color: #374151; cursor: pointer;
  font-family: inherit; text-align: left; transition: background .1s;
}
.sb-lib-node:hover { background: #f5f3ff; color: #6d28d9; }
.sb-lib-node.active { background: #ede9fe; color: #5b21b6; }
.sb-lib-node--leaf { padding-left: 22px; font-weight: 500; }
.sb-lib-node-lbl { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sb-lib-node-n { flex-shrink: 0; font-size: 10.5px; font-weight: 600; color: #9ca3af; }
.sb-lib-node.active .sb-lib-node-n { color: #7c3aed; }
.sb-lib-grid-wrap { flex: 1 1 auto; min-width: 0; overflow-y: auto; padding: 14px; }
.sb-lib-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
.sb-lib-card {
  position: relative; display: flex; flex-direction: column; overflow: hidden;
  background: #fff; border: 1px solid #e5e7eb; border-radius: 10px;
  cursor: pointer; transition: border-color .12s, box-shadow .12s;
}
.sb-lib-card:hover { border-color: #c4b5fd; box-shadow: 0 4px 14px rgba(109, 40, 217, .10); }
.sb-lib-card-img {
  position: relative; /* anchors the absolute clip wrapper sbDrawThumb injects */
  height: 130px; background: #f0f4f8; display: flex; align-items: center; justify-content: center;
  border-bottom: 1px solid #f1f5f9;
}
.sb-lib-card-img img { width: 100%; height: 100%; object-fit: cover; }
/* Server-rendered SVG sections are portrait; cover would crop the outer linings */
.sb-lib-card-img img[src$=".svg"] { object-fit: contain; padding: 4px 0; }
.sb-lib-card-img i { font-size: 26px; color: #d8b4fe; opacity: .4; }
/* Component legend under the 2D cross-section thumbnail */
.sb-thumb-legend {
  flex-shrink: 0; padding: 3px 7px 4px; background: rgba(255, 255, 255, .92);
  border-top: 1px solid #eef2f7; display: flex; flex-direction: column; gap: 1px;
  text-align: left;
}
.sb-tlg-row {
  font-size: 9px; line-height: 1.3; color: #475569;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sb-tlg-row.sb-tlg-frame { color: #6d28d9; font-weight: 600; }
.sb-tlg-row.sb-tlg-more { color: #94a3b8; font-style: italic; }
.sb-tlg-n { color: #94a3b8; font-weight: 600; margin-right: 3px; }
.sb-lib-card-body { padding: 8px 10px 10px; display: flex; flex-direction: column; gap: 5px; }
.sb-lib-card-code { font-size: 12.5px; font-weight: 700; color: #111827; }
.sb-lib-card-sup { font-size: 11px; font-weight: 600; }
.sb-lib-card-badges { display: flex; flex-wrap: wrap; gap: 4px; }
.sb-lib-card-add {
  position: absolute; top: 8px; right: 8px; padding: 3px 10px; font-size: 11px;
  opacity: 0; transition: opacity .1s;
}
.sb-lib-card:hover .sb-lib-card-add { opacity: 1; }
.sb-lib-grid-msg { grid-column: 1 / -1; padding: 40px 16px; text-align: center; color: #9ca3af; font-size: 12.5px; }
.sb-lib-grid-msg--err { color: #ef4444; }
.insp-subtab--lib { margin-left: auto; color: #6d28d9; border-color: #c4b5fd; background: #f5f3ff; }

.insp-body { flex: 1; overflow: hidden; display: flex; flex-direction: column; }
.insp-panel.collapsed .insp-body,
.insp-panel.collapsed .insp-footer { display: none; }

.insp-tab-content { display: none; flex: 1; overflow: hidden; flex-direction: column; }
.insp-tab-content.active { display: flex; }
.insp-table-wrap { flex: 1; overflow: auto; }
.insp-table { width: 100%; border-collapse: collapse; font-size: var(--tbl-font); }
.insp-table thead th {
    position: sticky; top: 0; background: var(--tbl-head-bg);
    font-size: var(--tbl-head-font); font-weight: 600; letter-spacing: normal; text-transform: none; color: var(--tbl-head-color);
    padding: var(--tbl-head-pad); border-bottom: 1px solid var(--tbl-head-border);
    white-space: nowrap; text-align: left;
}
.insp-table tbody tr { border-bottom: 1px solid var(--tbl-border); transition: background 0.1s; cursor: pointer; }
.insp-table tbody tr:hover { background: var(--tbl-row-hover); }
/* The row whose system is loaded in the builder. The tint alone reads as hover,
   so anchor it with an accent bar and keep it while hovering other rows. */
.insp-table tbody tr.selected,
.insp-table tbody tr.selected:hover { background: var(--tbl-row-selected); }
.insp-table tbody tr.selected { box-shadow: inset 3px 0 0 #7c3aed; }
.insp-table tbody tr.selected .insp-name-input { font-weight: 700; color: #5b21b6; }
.insp-table td { padding: var(--tbl-cell-pad); color: var(--tbl-cell-color); vertical-align: middle; white-space: nowrap; width: 1%; }
.insp-table th:last-child,
.insp-table td:last-child { width: auto; text-align: right; }
.insp-sys-dot { width: 10px; height: 10px; border-radius: 2px; display: inline-block; flex-shrink: 0; }
.insp-type-chip {
    display: inline-block; padding: 1px 6px; border-radius: 4px;
    font-size: 10px; font-weight: 600; text-transform: capitalize;
}
.insp-type-chip.wall      { background: #ede9fe; color: #6d28d9; }
.insp-type-chip.ceiling   { background: #e0f2fe; color: #0369a1; }
.insp-type-chip.reference { background: #f3f4f6; color: #6b7280; }
.insp-td-num { font-variant-numeric: tabular-nums; color: #374151; }
.insp-td-num-sub { display: block; font-size: 10px; color: #9ca3af; }
.insp-td-actions { display: flex; gap: 4px; justify-content: flex-end; }
.insp-icon-btn {
    width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;
    border-radius: 4px; border: none; cursor: pointer; font-size: 10px; transition: background 0.12s;
}
.insp-icon-btn.view { background: #f3f4f6; color: #555; }
.insp-icon-btn.view:hover { background: #e5e7eb; }
.insp-icon-btn.dup { background: #f5f3ff; color: #6d28d9; }
.insp-icon-btn.dup:hover { background: #ede9fe; }
.insp-icon-btn.del { background: #fee2e2; color: #dc2626; }
.insp-icon-btn.del:hover { background: #fecaca; }
.insp-row-btns { display: flex; gap: 4px; }
.insp-row-edit-btns { display: none; gap: 4px; }
.insp-icon-btn.save { background: #d1fae5; color: #059669; }
.insp-icon-btn.save:hover:not(:disabled) { background: #a7f3d0; }
.insp-icon-btn.save:disabled { background: #f3f4f6; color: #d1d5db; cursor: not-allowed; }
.insp-icon-btn.disc { background: #fee2e2; color: #dc2626; }
.insp-icon-btn.disc:hover { background: #fecaca; }
.insp-icon-btn.chg { background: #ede9fe; color: #7c3aed; }
.insp-icon-btn.chg:hover { background: #ddd6fe; }
.insp-empty {
    display: flex; flex-direction: column; align-items: center;
    justify-content: center; padding: 30px; color: #9ca3af; font-size: 12px; gap: 8px;
}
.insp-footer {
    flex-shrink: 0; display: flex; align-items: center; gap: 8px;
    padding: 5px 14px; background: #faf9fc; border-top: 1px solid #ece8f5;
    font-size: 11px; color: #6b7280; white-space: nowrap; overflow: hidden;
}
/* SmartSpec finder footer — compact (half height) */
#insp-footer { padding: 2px 12px; font-size: 10.5px; line-height: 1.3; min-height: 0; }
#insp-footer i { font-size: 9px; }
.insp-foot-div { color: #d1d5db; }
.insp-foot-val { font-weight: 600; color: #374151; }
.insp-foot-hint { margin-left: auto; color: #9ca3af; font-style: italic; }
/* Compact footer for the SmartSpec finder panel */
#insp-footer { padding: 2px 12px; gap: 5px; font-size: 10px; line-height: 1.4; min-height: 20px; }
#insp-footer .insp-foot-val { font-size: 11px; }

/* Systems tab */
.insp-systems-body { flex: 1; overflow-y: auto; padding: 4px 0 8px; }
.insp-sec-label {
    font-size: 10px; font-weight: 700; letter-spacing: 0.05em; color: #6b7280;
    padding: 6px 12px 2px; display: flex; align-items: center; gap: 4px;
}

/* Stats tab */
.insp-stats-body {
    flex: 1; display: flex; align-items: center;
    justify-content: center; gap: 40px; padding: 12px;
}
.insp-stat-chip { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.insp-stat-num { font-size: 32px; font-weight: 700; color: #6d28d9; line-height: 1; }
.insp-stat-lbl { font-size: 11px; color: #9ca3af; font-weight: 500; }

/* Component expand rows — chevron rotates 90° (right → down) when expanded,
   same pattern as .sq-l-caret elsewhere in the app. */
.insp-expand-btn {
    background: none; border: none; border-radius: 5px;
    width: 18px; height: 18px; font-size: 10px; line-height: 1;
    cursor: pointer; color: #7c3aed; display: inline-flex;
    align-items: center; justify-content: center; padding: 0;
    margin-left: 4px; flex-shrink: 0;
    transition: background .12s, transform .15s;
}
.insp-expand-btn:hover { background: #ede9fe; }
.insp-expand-btn.open { transform: rotate(90deg); }
.insp-expand-btn:disabled { cursor: default; opacity: .6; }
.insp-comp-row { display: none; background: #f9f8ff; }
.insp-comp-row.visible { display: table-row; }
.insp-comp-header { display: table-row; background: #f3f0fd; }
.insp-comp-header td {
    padding: 3px 10px 3px 22px;
    font-size: 9px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
    color: #9ca3af; border-bottom: 1px solid #e9e7fc;
}

/* Clickable system dot → opens a colour-swatch popover */
.insp-sys-dot { cursor: pointer; }
.insp-sys-dot:hover { outline: 2px solid rgba(0,0,0,.15); outline-offset: 1px; }
.insp-color-pop {
    position: fixed; z-index: 10001;
    display: flex; flex-wrap: wrap; gap: 4px; width: 132px;
    padding: 6px; background: #fff;
    border: 1px solid #d4d2cf; border-radius: 8px;
    box-shadow: 0 4px 14px rgba(0,0,0,.18);
}
.insp-color-pop .icp-sw {
    width: 20px; height: 20px; border-radius: 5px;
    border: 1px solid rgba(0,0,0,.15); cursor: pointer; padding: 0;
}
.insp-color-pop .icp-sw:hover { transform: scale(1.15); }
.insp-color-pop .icp-reset {
    width: 20px; height: 20px; border-radius: 5px; cursor: pointer;
    border: 1px solid #e5e7eb; background: #f3f4f6; color: #6b7280; font-size: 10px;
}
.insp-color-pop .icp-reset:hover { background: #e5e7eb; }

/* Count types panel (Counts tab) */
.insp-counts-body { padding: 8px 10px; }
.cnt-add-btn {
    border: 1px solid #e5e7eb; background: #f3f4f6; color: #374151;
    font-size: 10px; font-weight: 600; border-radius: 5px; padding: 2px 8px; cursor: pointer;
}
.cnt-add-btn:hover { background: #ede9fe; color: #6d28d9; }
.cnt-list { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.cnt-empty { font-size: 11px; color: #9ca3af; padding: 8px 2px; }
.cnt-row {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 8px; border: 1px solid #ececec; border-radius: 6px; cursor: pointer;
}
.cnt-row:hover { background: #faf9ff; }
.cnt-row.active { border-color: #7c3aed; background: #f5f3ff; box-shadow: inset 3px 0 0 #7c3aed; }
.cnt-row .cnt-swatch { width: 14px; height: 14px; border-radius: 50%; border: 1px solid rgba(0,0,0,.15); }
.cnt-row .cnt-name { font-size: 12px; font-weight: 600; color: #374151; flex: 1; }
.cnt-row .cnt-sku {
    border: 1px dashed #cbd5e1; background: #fff; color: #94a3b8;
    font-size: 9px; border-radius: 4px; padding: 1px 6px; cursor: pointer; white-space: nowrap;
}
.cnt-row .cnt-sku.linked { border-style: solid; border-color: #16a34a; color: #16a34a; background: #f0fdf4; }
.cnt-row .cnt-sku:hover { border-color: #7c3aed; color: #7c3aed; }
.cnt-row .cnt-tally { font-size: 13px; font-weight: 700; color: #111827; min-width: 22px; text-align: right; }
.cnt-row .cnt-del { border: none; background: none; color: #9ca3af; cursor: pointer; font-size: 11px; }
.cnt-row .cnt-del:hover { color: #dc2626; }

/* Hidden line/area row (canvas visibility off) */
.line-item.row-hidden { opacity: .45; }
.line-item.row-hidden .insp-sys-name { text-decoration: line-through; }

/* Row highlight when a system is selected in the Systems tab */
.line-item.insp-row-highlight { background: #dbeafe !important; box-shadow: inset 3px 0 0 #2563eb; }
/* Sub-header row labelling the expanded component columns */
.insp-comp-head td {
    font-size: 9px; font-weight: 700; color: #9ca3af;
    text-transform: uppercase; letter-spacing: .04em;
    background: #f1eefc; border-bottom: 1px solid #e9e7fc;
}
.insp-comp-row td {
    padding: 3px 10px 3px 22px;
    font-size: 11px; color: #6b7280;
    border-bottom: 1px dashed #e9e7fc;
}
.insp-comp-name { font-weight: 600; color: #374151; }
.insp-comp-supplier { color: #6b7280; }
.insp-comp-code { font-family: monospace; font-size: 10px; color: #6366f1; white-space: nowrap; }
.insp-comp-desc { color: #6b7280; }
.insp-comp-tag {
    display: inline-block;
    padding: 1px 7px; border-radius: 999px;
    background: #ede9fe; color: #6d28d9;
    font-size: 9px; font-weight: 600; text-transform: uppercase;
    letter-spacing: .03em; white-space: nowrap;
}
.insp-comp-layer {
    font-size: 10px; color: #a5b4fc;
    margin-left: 5px; font-family: monospace;
}
.insp-comp-price { color: #059669; font-weight: 500; }

/* InspTextStrong (cell-strong) — canonical inspection typography: weight 600, body-dark.
   Use on labels, values, names and any strong text inside inspection panels. */

/* InspInput — universal inline editable field for inspection panels */
.insp-name-input {
    border: none; outline: none; background: transparent;
    font-size: 12px; font-weight: 600; color: #1f2937;
    width: 100%; min-width: 60px;
    padding: 1px 3px; border-radius: 3px;
    transition: background .15s;
}
.insp-name-input:hover,
.insp-name-input:focus { background: #faf5ff; }

.insp-notes-input {
    border: none; outline: none; background: transparent;
    font-size: 11px; color: #6b7280; width: 100%; min-width: 180px;
    padding: 1px 3px; border-radius: 3px;
    transition: background .15s;
}
.insp-notes-input:hover,
.insp-notes-input:focus { background: #f9fafb; }

/* InspPerfCell — performance / spec data cell in inspection table rows */
.insp-perf-cell { font-size: 11px; color: #374151; white-space: nowrap; vertical-align: middle; padding: 0 8px; }

/* InspBadge — universal inline badge for inspection panels.
   Replaces insp-type-chip, insp-type-tag, lib-type-badge.
   Modifiers: --primary --success --danger --info --warning --wall --ceiling */
.insp-badge {
    display: inline-flex; align-items: center;
    padding: 1px 6px; border-radius: 4px;
    font-size: 10px; font-weight: 600; white-space: nowrap;
    background: #f3f4f6; color: #6b7280;
}
.insp-badge--primary { background: #ede9fe; color: #6d28d9; }
.insp-badge--success { background: #d1fae5; color: #059669; }
.insp-badge--danger  { background: #fee2e2; color: #dc2626; }
.insp-badge--info    { background: #dbeafe; color: #1e40af; }
.insp-badge--warning { background: #fef3c7; color: #b45309; }
.insp-badge--wall    { background: #ede9fe; color: #6d28d9; }
.insp-badge--ceiling { background: #e0f2fe; color: #0369a1; }

/* ─── end Inspector Panel ─── */

.app-inbox-av {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--brand-light);
  color: var(--brand);
  font-size: 10px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-top: 1px;
}

.app-inbox-body {
  flex: 1;
  min-width: 0;
}

.app-inbox-from {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-primary);
}

.app-inbox-subject {
  font-size: 12px;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-inbox-time {
  font-size: 10px;
  color: var(--text-tertiary);
  flex-shrink: 0;
  margin-top: 2px;
}

.app-unread {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brand);
  flex-shrink: 0;
  margin-top: 6px;
}

/* DBS Animations */
@keyframes appFadeUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.app-stat {
  animation: appFadeUp 0.35s ease both;
}

.app-stat:nth-child(1) {
  animation-delay: 0.05s;
}

.app-stat:nth-child(2) {
  animation-delay: 0.1s;
}

.app-stat:nth-child(3) {
  animation-delay: 0.15s;
}

.app-stat:nth-child(4) {
  animation-delay: 0.2s;
}

.app-tile {
  animation: appFadeUp 0.35s ease both;
}

.app-tile:nth-child(1) {
  animation-delay: 0.1s;
}

.app-tile:nth-child(2) {
  animation-delay: 0.13s;
}

.app-tile:nth-child(3) {
  animation-delay: 0.16s;
}

.app-tile:nth-child(4) {
  animation-delay: 0.19s;
}

.app-tile:nth-child(5) {
  animation-delay: 0.22s;
}

.app-tile:nth-child(6) {
  animation-delay: 0.25s;
}

.app-tile:nth-child(7) {
  animation-delay: 0.28s;
}

/* Preserve animations on consolidated app-cardbox--tile */
.app-cardbox--tile {
  animation: appFadeUp 0.35s ease both;
}

.app-cardbox--tile:nth-child(1) {
  animation-delay: 0.1s;
}

.app-cardbox--tile:nth-child(2) {
  animation-delay: 0.13s;
}

.app-cardbox--tile:nth-child(3) {
  animation-delay: 0.16s;
}

.app-cardbox--tile:nth-child(4) {
  animation-delay: 0.19s;
}

.app-cardbox--tile:nth-child(5) {
  animation-delay: 0.22s;
}

.app-cardbox--tile:nth-child(6) {
  animation-delay: 0.25s;
}

.app-cardbox--tile:nth-child(7) {
  animation-delay: 0.28s;
}

.app-panel {
  animation: appFadeUp 0.4s ease both;
}

.app-panel:nth-child(1) {
  animation-delay: 0.2s;
}

.app-panel:nth-child(2) {
  animation-delay: 0.25s;
}

.app-panel:nth-child(3) {
  animation-delay: 0.3s;
}

/* DBS Responsive */
@media (max-width: 1200px) {
  .app-apps {
    grid-template-columns: repeat(4, 1fr);
  }
}

@media (max-width: 1024px) {
  .app-stats {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 900px) {
  .app-apps {
    grid-template-columns: repeat(4, 1fr);
  }
  .app-panels {
    grid-template-columns: 1fr;
  }
}

/* Phone: the sidebar is an off-canvas drawer. Closed by default; the toggle
   (.app-nav-toggle) adds .app-layout--nav-open, the overlay closes it. The
   grid collapses to one column so the page uses the full width. The
   !important flags beat the :has() column rules above, which set a 280px
   first column even though the sidebar no longer sits in it. */
@media (max-width: 767.98px) {
  .app-layout {
    grid-template-columns: minmax(0, 1fr) !important;
  }
  .app-layout > .app-topbar,
  .app-layout > .app-workspace {
    grid-column: 1 !important;
  }
  .app-layout > .app-topbar .app-topbar-bar {
    padding-left: 52px;
  }
  .app-sidebar {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    width: min(var(--sidebar-w), 85vw);
    z-index: 60;
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform 0.2s ease, visibility 0s linear 0.2s;
    box-shadow: none;
  }
  .app-layout--nav-open .app-sidebar {
    transform: none;
    visibility: visible;
    transition: transform 0.2s ease;
    box-shadow: 0 0 24px rgba(0, 0, 0, 0.25);
  }
  .app-sidebar-collapse-btn {
    display: none;
  }
  .app-layout > .app-nav-toggle {
    display: inline-flex;
  }
  .app-layout--nav-open .app-nav-toggle {
    display: none;
  }
  .app-layout--nav-open .app-nav-overlay {
    display: block;
  }
}

/* Drawer toggle + overlay (phone only; hidden on desktop) */
.app-nav-toggle {
  display: none;
  position: fixed;
  top: 8px;
  left: 10px;
  z-index: 55;
  width: 36px;
  height: 36px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-primary);
  cursor: pointer;
}
.app-nav-toggle:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
.app-nav-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 58;
  background: rgba(0, 0, 0, 0.45);
}

/* Sidebar groups and plan locks */
[x-cloak] { display: none !important; }
.app-nav-sub {
  padding-left: 28px;
  font-size: 13px;
}
.app-nav-group-btn {
  width: 100%;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
}
.app-nav-chev {
  margin-left: auto;
  font-size: 11px !important;
  transition: transform 0.15s;
}
.app-nav-chev--open {
  transform: rotate(180deg);
}
.app-nav-item .app-nav-lock {
  margin-left: auto;
  font-size: 11px;
  width: auto;
  color: var(--text-tertiary);
}
.app-sidebar--collapsed .app-nav-sub {
  padding-left: 10px;
}

.flr-geom-section {
  border-bottom: 1px solid #e5e7eb;
  padding-bottom: 12px;
}

.flr-section-title {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: #64748b;
  margin-bottom: 12px;
}

.flr-geom-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.flr-geom-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.flr-geom-label {
  font-size: 12px;
  font-weight: 600;
  color: #1e293b;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}

.flr-geom-unit {
  font-size: 11px;
  font-weight: 500;
  color: #94a3b8;
}

.flr-geom-input {
  width: 100%;
  height: 40px;
  padding: 6px 10px;
  border: 1px solid #d1d5db;
  border-radius: 10px;
  font-size: 12px;
  color: #1f2937;
  background: #fff;
  box-sizing: border-box;
}

.flr-geom-input:focus {
  outline: none;
  border-color: #a78bfa;
  box-shadow: 0 0 0 2px rgba(167,139,250,.14);
}

.flr-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 10px;
  background: #fff;
  margin: 0;
  border: 1px solid #e5e7eb;
  border-radius: 0;
  table-layout: fixed;
}

.flr-table thead {
  background: var(--tbl-head-bg);
}

.flr-table th {
  padding: var(--tbl-head-pad);
  text-align: left;
  font-weight: 700;
  color: var(--tbl-head-color);
  font-size: var(--tbl-head-font);
  text-transform: uppercase;
  letter-spacing: .04em;
  border-bottom: 1px solid var(--tbl-head-border);
  border-right: 1px solid var(--tbl-border);
}

.flr-table th:last-child { border-right: none; }

.flr-table tbody tr {
  border-bottom: 1px solid #e5e7eb;
  transition: background .15s ease;
}

.flr-table tbody tr:nth-child(even) {
  background: #fafafa;
}

.flr-table tbody tr:hover {
  background: var(--tbl-row-hover);
}

.flr-table tbody tr:last-child {
  border-bottom: none;
}

.flr-row-invalid {
  background: #fee2e2 !important;
}

.flr-table td {
  padding: 0;
  color: #374151;
  border-bottom: 1px solid #e5e7eb;
  border-right: 1px solid #e5e7eb;
}

.flr-table td:last-child { border-right: none; }

.flr-table tbody tr:last-child td {
  border-bottom: none;
}

.flr-col-name { text-align: left; width: 16%; }

.flr-col-rl,
.flr-col-height,
.flr-col-thk {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.flr-col-rl { width: 12%; }
.flr-col-height { width: 13%; }
.flr-col-type { text-align: left; width: 33%; }
.flr-col-thk { width: 12%; }

.flr-col-actions {
  text-align: center;
  width: 14%;
}

.flr-calc-value {
  padding: 8px;
  font-size: 10px;
  color: #64748b;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  height: 34px;
  box-sizing: border-box;
}

.flr-tbl-in {
  width: 100%;
  height: 34px;
  padding: 4px 8px;
  border: none;
  border-radius: 0;
  font-size: 10px;
  color: #1f2937;
  background: #fff;
  box-sizing: border-box;
}

.flr-col-rl .flr-tbl-in,
.flr-col-thk .flr-tbl-in {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.flr-tbl-in:focus {
  outline: none;
  box-shadow: inset 0 0 0 1px #cbd5e1;
}

.flr-tbl-sel {
  width: 100%;
  height: 34px;
  padding: 4px 18px 4px 8px;
  border: none;
  border-radius: 0;
  font-size: 10px;
  color: #1f2937;
  background: #fff;
  box-sizing: border-box;
}

.flr-tbl-sel:focus {
  outline: none;
  box-shadow: inset 0 0 0 1px #cbd5e1;
}

.flr-del-tbl {
  background: transparent;
  border: none;
  border-radius: 0;
  color: #94a3b8;
  width: 100%;
  height: 34px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  flex-shrink: 0;
  opacity: .45;
  transition: color .15s ease, background .15s ease, opacity .15s ease;
}

.flr-table tbody tr:hover .flr-del-tbl {
  opacity: .95;
}

.flr-del-tbl:hover {
  color: #ef4444;
  background: #fef2f2;
}

/* Footer action under the floors table. Aligned to the table's cell padding so
   it reads as the last row rather than a detached strip — and sized to its own
   label: the table is as wide as the pressure columns need, so a full-width
   button rendered as a metre of empty chrome. */
.flr-add-wrap {
  padding: 8px 14px;   /* 14px = the x half of --tbl-cell-pad */
  border-top: 1px solid var(--tbl-border, #f3f4f6);
}

.flr-add-btn.app-btn {
  color: var(--brand, #8e75da);
  border-color: var(--brand-mid, #a78bfa);
}
/* ═══════════════════════════════════════════════════════════ */


/* ── Drawing File Uploader (dfu-*) ────────────────────────
   Reusable drop-zone + per-file type assignment.
   Used via {% include "includes/drawing_uploader.html" %}
   across Projects, SmartQuote, SmartSpec, Reviews, etc.
   ──────────────────────────────────────────────────────── */
.dfu-zone {
  border: 2px dashed #c4b5fd;
  border-radius: 10px;
  padding: 24px 20px 20px;
  text-align: center;
  cursor: pointer;
  background: #fdfaff;
  transition: border-color .15s, background .15s;
  outline: none;
  position: relative;
}
.dfu-zone:hover,
.dfu-zone:focus { border-color: #8e75da; background: #f5f0ff; }
.dfu-zone.drag-over { border-color: #8e75da; background: #ede9fe; }
.dfu-zone.has-files { border-style: solid; border-color: #c4b5fd; background: #faf8ff; padding: 14px 20px; }
.dfu-zone-icon { font-size: 24px; color: #c4b5fd; margin-bottom: 6px; }
.dfu-zone.has-files .dfu-zone-icon { font-size: 18px; }
.dfu-zone-text { font-size: 12px; color: #4b5563; }
.dfu-zone-text strong { color: #8e75da; }
.dfu-browse-link { color: #8e75da; font-weight: 600; text-decoration: underline; cursor: pointer; }
.dfu-zone-hint { font-size: 13px; color: #9ca3af; margin-top: 4px; }
.dfu-error { color: #dc2626; font-size: 12px; margin-top: 6px; }

/* File list */
.dfu-list { margin-top: 10px; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden; }
.dfu-list-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 7px 12px; background: #f9fafb;
  border-bottom: 1px solid #e5e7eb; font-size: 11.5px; color: #6b7280; font-weight: 500;
}
.dfu-list-clear {
  font-size: 11px; color: #9ca3af; background: none; border: none; cursor: pointer;
  padding: 2px 6px; border-radius: 4px; transition: color .1s, background .1s;
}
.dfu-list-clear:hover { color: #dc2626; background: #fef2f2; }
.dfu-item {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; font-size: 12px; color: #374151;
  border-bottom: 1px solid #f3f4f6; background: #fff;
}
.dfu-item:last-child { border-bottom: none; }
.dfu-item-ext {
  font-size: 9px; font-weight: 700; color: #8e75da;
  background: #ede9fe; border-radius: 4px; padding: 2px 5px;
  text-transform: uppercase; flex-shrink: 0; letter-spacing: .04em; min-width: 30px; text-align: center;
}
.dfu-item-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.dfu-item-type {
  flex-shrink: 0; font-size: 11.5px;
  border: 1px solid #e5e7eb; border-radius: 6px;
  padding: 3px 6px; color: #374151; background: #f9fafb;
  cursor: pointer; min-width: 140px;
}
.dfu-item-type:focus { outline: 2px solid #8e75da; outline-offset: 1px; }
.dfu-item-dir {
  flex-shrink: 0; font-size: 11.5px;
  border: 1px solid #e5e7eb; border-radius: 6px;
  padding: 3px 6px; color: #374151; background: #f9fafb;
  cursor: pointer; min-width: 100px;
}
.dfu-item-dir:focus { outline: 2px solid #8e75da; outline-offset: 1px; }
.dfu-item-size { font-size: 11px; color: #9ca3af; flex-shrink: 0; min-width: 42px; text-align: right; }
.dfu-item-rm {
  background: none; border: none; color: #d1d5db; cursor: pointer;
  padding: 3px 6px; font-size: 12px; flex-shrink: 0; line-height: 1;
  border-radius: 4px; transition: color .1s, background .1s;
}
.dfu-item-rm:hover { color: #dc2626; background: #fef2f2; }
.dfu-item-warn { color: #d97706; font-size: 11px; flex-shrink: 0; }


/* ============================================================================
   Library workspace shared widgets — import modal, audit history, archive
   (used via static/js/library_workspace.js across all Engineering Libraries)
   ==========================================================================*/

/* Import modal */
.libws-overlay {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(17, 24, 39, .45);
  display: none; align-items: center; justify-content: center;
}
.libws-overlay.open { display: flex; }
.libws-modal {
  background: #fff; border-radius: 12px; width: 440px; max-width: 92vw;
  box-shadow: 0 20px 60px rgba(0, 0, 0, .25); overflow: hidden;
  display: flex; flex-direction: column;
}
.libws-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px; background: #ede9fc; border-bottom: 1px solid #d8ccee;
  font-weight: 700; font-size: 13px; color: #5b4282; text-transform: capitalize;
}
.libws-x {
  background: none; border: none; font-size: 20px; line-height: 1;
  color: #6b7280; cursor: pointer;
}
.libws-modal-body { padding: 16px; }
.libws-modal-foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 12px 16px; border-top: 1px solid #eef0f3; background: #fafafe;
}
.libws-hint { font-size: 12px; color: #6b7280; margin: 0 0 12px; line-height: 1.5; }
.libws-file { width: 100%; font-size: 12px; margin-bottom: 10px; }
.libws-btn {
  padding: 6px 14px; font-size: 12px; font-weight: 600; border-radius: 6px;
  border: 1px solid #d8ccee; background: #fff; color: #5b4282; cursor: pointer;
}
.libws-btn-primary { background: #7c5fb3; color: #fff; border-color: #7c5fb3; }
.libws-ok { font-size: 12px; color: #065f46; background: #d1fae5; padding: 8px 10px; border-radius: 6px; }
.libws-err { font-size: 12px; color: #991b1b; background: #fee2e2; padding: 8px 10px; border-radius: 6px; }
.libws-errlist { font-size: 11px; color: #991b1b; margin: 8px 0 0; padding-left: 18px; max-height: 160px; overflow-y: auto; }

/* Audit history timeline */
.libws-hist-empty { font-size: 12px; color: #9ca3af; padding: 8px 0; }
.libws-hist-item { border-left: 2px solid #ddd6f4; padding: 6px 0 6px 10px; margin-bottom: 6px; }
.libws-hist-head { display: flex; align-items: center; gap: 8px; font-size: 11px; }
.libws-hist-type { font-weight: 700; padding: 1px 7px; border-radius: 99px; font-size: 10px; }
.libws-hist-created { background: #d1fae5; color: #065f46; }
.libws-hist-changed { background: #dbeafe; color: #1e40af; }
.libws-hist-deleted { background: #fee2e2; color: #991b1b; }
.libws-hist-when { color: #374151; }
.libws-hist-who { color: #9ca3af; margin-left: auto; }
.libws-hist-change { font-size: 11px; color: #4b5563; padding: 2px 0 0 2px; }

/* Archived row + restore button
   lib-badge-archived is kept for compat; new code → app-badge--warning */
.lib-row-archived { opacity: .6; }
.lib-badge-archived {
  display: inline-flex;
  align-items: center;
  font-size: var(--tb-font-label, 10px);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 99px;
  border: 1px solid var(--warning-border, #fcd34d);
  background: var(--warning-bg,     #fef3c7);
  color:      var(--warning,        #92400e);
  white-space: nowrap;
}
/* lib-restore-btn kept for compat; new code → app-btn-ghost */
.lib-restore-btn {
  display: inline-flex;
  align-items: center;
  font-size: var(--tb-font-label, 10px);
  font-weight: 600;
  padding: 3px 9px;
  border-radius: var(--tb-radius, 6px);
  border: 1px solid var(--border-strong, rgba(142,117,218,.25));
  background: var(--surface, #fff);
  color: var(--text-secondary, #6b6886);
  cursor: pointer;
  transition: background .12s;
}
.lib-restore-btn:hover {
  background:   var(--brand-light, #e8e3f5);
  border-color: var(--brand-mid,   #a78bfa);
  color:        var(--brand,       #8e75da);
}


/* ─── Workspace section title ─── */
.ws-section-title {
  font-size: var(--fs-xl, 14px);
  font-weight: 600;
  color: #1f2937;
  margin: 0 0 16px;
  line-height: 1.3;
}


/* ════════════════════════════════════════════════════
   Minimal table input — tbl-input
   For inputs embedded directly in table cells.
   Transparent background + underline-only at rest;
   subtle highlight on hover/focus. No bordered-box look.
   ════════════════════════════════════════════════════ */
.tbl-input {
  width: 100%;
  border: none;
  border-bottom: 1px solid transparent;
  border-radius: 0;
  background: transparent;
  padding: 2px 2px;
  font-size: var(--fs-md, 12px);
  font-family: inherit;
  color: #374151;
  outline: none;
  transition: border-color .15s, background .15s;
  box-sizing: border-box;
}
.tbl-input:hover  { border-bottom-color: #d1d5db; }
.tbl-input:focus  { border-bottom-color: #7c3aed; background: rgba(124,58,237,.03); }
.tbl-input--dirty { border-bottom-color: #f59e0b !important; }
.tbl-input--saved { border-bottom-color: #10b981 !important; }
/* Number variant — right-aligned */
.tbl-input[type="number"],
.tbl-input--num { text-align: right; }


/* ════════════════════════════════════════════════════
   Detail panel input — detail-panel-input
   For inputs inside right-rail edit panels / modals.
   Replaces repeated inline style="border:1px solid #d8ccee;
   border-radius:5px;padding:3px 7px;font-size:12px;min-width:0;"
   ════════════════════════════════════════════════════ */
.detail-panel-input {
  flex: 1;
  border: 1px solid #d8ccee;
  border-radius: 5px;
  padding: 3px 7px;
  font-size: var(--fs-md, 12px);
  font-family: inherit;
  min-width: 0;
  background: #fff;
  color: #374151;
  outline: none;
  transition: border-color .15s, box-shadow .15s;
  box-sizing: border-box;
}
.detail-panel-input:focus {
  border-color: #7c3aed;
  box-shadow: 0 0 0 2px rgba(124,58,237,.08);
}


/* ════════════════════════════════════════════════════
   Project status badge — proj-status-badge
   Semantic state indicator for project workflow status.
   Moved from per-template <style> blocks to shared CSS.
   ════════════════════════════════════════════════════ */
.proj-status-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 9px;
  border-radius: 99px;
  font-size: var(--fs-base, 11px);
  font-weight: 500;
  white-space: nowrap;
}
.proj-status-planning      { background: #eff6ff; color: #2563eb; }
.proj-status-design        { background: #f0fdf4; color: #16a34a; }
.proj-status-construction  { background: #f0f9ff; color: #0284c7; }
.proj-status-completed     { background: #f0fdf4; color: #15803d; }
.proj-status-documentation { background: #fdf4ff; color: #9333ea; }
.proj-status-approval      { background: #fff7ed; color: #ea580c; }
.proj-status-tender        { background: #fefce8; color: #ca8a04; }
.proj-status-on_hold       { background: #fef2f2; color: #dc2626; }
.proj-status-active        { background: #f0fdf4; color: #16a34a; }
.proj-status-pending       { background: #fefce8; color: #ca8a04; }


/* ════════════════════════════════════════════════════
   Supplier plain label — pl-supplier-label
   Replaces pill/badge supplier display with plain branded text.
   Uses --supplier-color CSS variable set by JS for
   per-supplier brand colour without a badge background.
   ════════════════════════════════════════════════════ */
.pl-supplier-label {
  font-size: var(--fs-base, 11px);
  font-weight: 600;
  color: var(--supplier-color, var(--brand, #8e75da));
  white-space: nowrap;
  letter-spacing: .01em;
}


/* ════════════════════════════════════════════════════
   litespec-table — compact key/value detail table
   Used in project workspace overview panels.
   ════════════════════════════════════════════════════ */
.litespec-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--tbl-font);
}
.litespec-table th,
.litespec-table td {
  padding: var(--tbl-cell-pad);
  vertical-align: top;
  border-bottom: 1px solid var(--tbl-border);
  text-align: left;
}
.litespec-table th {
  width: 140px;
  font-weight: 700;
  color: var(--tbl-head-color);
  font-size: var(--tbl-head-font);
  text-transform: uppercase;
  letter-spacing: .04em;
  white-space: nowrap;
}
.litespec-table td { color: var(--tbl-cell-color); }
.litespec-table tr:last-child th,
.litespec-table tr:last-child td { border-bottom: none; }


/* ════════════════════════════════════════════════════════════════════
   WORKSPACE DESIGN SYSTEM (WDS)
   Single source of truth for the modern workspace standard:
   tokens → cards → page header / back nav → detail panel → tables →
   list views → icon system → empty / loading states.
   All modules consume these classes; no module-specific re-implementations.
   ════════════════════════════════════════════════════════════════════ */

:root {
  /* Elevation scale — neutral, soft (Linear / Stripe style) */
  --shadow-xs: 0 1px 2px rgba(16, 24, 40, .05);
  --shadow-sm: 0 1px 3px rgba(16, 24, 40, .07), 0 1px 2px rgba(16, 24, 40, .04);
  --shadow-md: 0 4px 12px rgba(16, 24, 40, .08);
  --shadow-lg: 0 12px 32px rgba(16, 24, 40, .14);

  /* Spacing rhythm */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;

  /* Surface + border (neutral language; brand reserved for accents) */
  --wds-border:        #e5e7eb;
  --wds-border-subtle: #f3f4f6;
  --wds-surface:       #ffffff;
  --wds-surface-2:     #f9fafb;
  --wds-radius:        8px;
  --wds-radius-lg:     12px;

  /* Semantic icon / action colours */
  --icon-primary: #7c5fb3;
  --icon-success: #059669;
  --icon-warning: #d97706;
  --icon-danger:  #dc2626;
  --icon-info:    #2563eb;
  --icon-muted:   #9ca3af;
}

/* ── Workspace page container ─────────────────────────
   Standard scroll + width treatment for app-workspace
   content. Replaces ad-hoc container/mx-auto wrappers.
   .ws-page          — fluid, consistent padding rhythm
   .ws-page--narrow  — centred reading width (hubs, forms)
   .ws-page--wide    — data-dense tables
   ─────────────────────────────────────────────────── */
.ws-page {
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  padding: var(--space-5) var(--space-6) var(--space-8);
}
.ws-page--narrow { max-width: 920px; }
.ws-page--wide   { max-width: none; }

/* The workspace itself owns scrolling — identical across modules */
.app-workspace { overflow-y: auto; background: var(--wds-surface-2); }
.app-workspace > .ws-page { flex-shrink: 0; }

/* Subtle dotted background — hub / landing surfaces */
.ws-bg-dots {
  background-color: #f4f3fa;
  background-image: radial-gradient(circle, #c4b5fd 1px, transparent 1px);
  background-size: 24px 24px;
  min-height: 100%;
}

/* 4-column hub grid variant */
.lib-hub-grid--4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 960px) { .lib-hub-grid--4 { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 720px) { .lib-hub-grid--4 { grid-template-columns: repeat(2, 1fr); } }

/* ════════════════════════════════════════════════════
   Universal Card System
   card-default | card-elevated | card-flat |
   card-compact | card-detail | card-list
   Consistent radius, shadow, padding, hover.
   ════════════════════════════════════════════════════ */
.card-default,
.card-elevated,
.card-flat,
.card-compact,
.card-detail,
.card-list {
  background: var(--wds-surface);
  border: 1px solid var(--wds-border);
  border-radius: var(--wds-radius-lg);
  box-sizing: border-box;
  min-width: 0;
}

.card-default  { padding: var(--space-5); box-shadow: var(--shadow-xs); }
.card-compact  { padding: var(--space-3); box-shadow: var(--shadow-xs); }

.card-elevated {
  padding: var(--space-5);
  border-color: var(--wds-border-subtle);
  box-shadow: var(--shadow-md);
  transition: box-shadow .15s ease, transform .15s ease;
}
.card-elevated:hover { box-shadow: var(--shadow-lg); }

.card-flat {
  padding: var(--space-5);
  background: var(--wds-surface-2);
  border-color: transparent;
  box-shadow: none;
}

/* Detail card — sectioned head/body, zero own padding */
.card-detail { padding: 0; overflow: hidden; box-shadow: var(--shadow-xs); }
.card-detail .card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--wds-border-subtle);
  font-size: var(--fs-xl, 14px);
  font-weight: 600;
  color: #1f2937;
}
.card-detail .card-body { padding: var(--space-4); }

/* List card — row container, zero own padding */
.card-list { padding: 0; overflow: hidden; box-shadow: var(--shadow-xs); }
.card-list .card-list-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--wds-border-subtle);
  text-decoration: none;
  color: inherit;
  transition: background .12s;
}
.card-list .card-list-row:last-child { border-bottom: none; }
.card-list .card-list-row:hover { background: #faf9ff; }

/* Card typography hierarchy */
.card-title { font-size: var(--fs-xl, 14px); font-weight: 600; color: #1f2937; margin: 0; }
.card-sub   { font-size: var(--fs-md, 12px); color: #6b7280; margin: 2px 0 0; }

/* ════════════════════════════════════════════════════
   Universal Page Header + Back Navigation
   breadcrumb / back / title / subtitle / actions —
   rendered by templates/components/page_header.html
   ════════════════════════════════════════════════════ */
.page-header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}
.page-header-main { flex: 1; min-width: 0; }

.page-breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  font-size: var(--fs-md, 12px);
  color: var(--icon-muted);
  margin: 0 0 4px;
}
.page-breadcrumb a {
  color: #6b7280;
  text-decoration: none;
  transition: color .12s;
}
.page-breadcrumb a:hover { color: var(--icon-primary); }
.page-breadcrumb .crumb-sep { font-size: 9px; color: #d1d5db; }
.page-breadcrumb .crumb-current { color: #374151; font-weight: 500; }

.page-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 18px;
  font-weight: 700;
  color: #17152e;
  margin: 0;
  line-height: 1.25;
}
.page-title-icon {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  background: linear-gradient(135deg, #ede9fe, #ddd6f4);
  color: var(--icon-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  flex-shrink: 0;
}
.page-subtitle {
  font-size: var(--fs-md, 12px);
  color: #6b7280;
  margin: 3px 0 0;
}

.page-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
  padding-top: 2px;
}

/* PageBackButton — universal back navigation (no history-only hacks) */
.page-back-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  min-width: 32px;
  border-radius: var(--wds-radius);
  border: 1px solid var(--wds-border);
  background: var(--wds-surface);
  color: #6b7280;
  font-size: 13px;
  text-decoration: none;
  cursor: pointer;
  flex-shrink: 0;
  margin-top: 1px;
  transition: background .12s, color .12s, border-color .12s, transform .12s;
}
.page-back-btn:hover {
  background: #f5f3ff;
  border-color: #ddd6f4;
  color: var(--icon-primary);
}
.page-back-btn:hover i { transform: translateX(-1px); }
.page-back-btn i { transition: transform .15s ease; }
.page-back-btn:focus-visible { outline: 2px solid var(--icon-primary); outline-offset: 1px; }

/* ════════════════════════════════════════════════════
   Shared right-rail detail panel — detail-panel
   Replaces per-template #xxDetailPanel <style> blocks
   across all library / catalog manage workspaces.
   ════════════════════════════════════════════════════ */
.detail-panel {
  position: fixed;
  top: var(--topbar-offset, 125px);
  right: 0;
  bottom: 0;
  width: 400px;
  max-width: 94vw;
  background: var(--wds-surface);
  border-left: 1px solid var(--wds-border);
  box-shadow: -4px 0 20px rgba(0, 0, 0, .08);
  z-index: 200;
  transform: translateX(100%);
  transition: transform .2s ease;
  display: flex;
  flex-direction: column;
}
.detail-panel.open { transform: translateX(0); }
.detail-panel--sm { width: 380px; }
.detail-panel--md { width: 420px; }
.detail-panel--lg { width: 460px; }

/* Catalog manage right-rail panel — match library detail panels
   (full height + fixed width). ID selector overrides the conflicting
   .detail-panel.open width rule from the engineering slide-out panel. */
#pmDetailPanel {
  top: 0;
  right: 0;
  bottom: 0;
  width: 420px;
  max-width: 94vw;
  z-index: 9000;
  overflow-y: auto;
}
#pmDetailPanel.open { width: 420px; }
#pmDetailPanel.detail-panel--sm,
#pmDetailPanel.detail-panel--sm.open { width: 380px; }
#pmDetailPanel.detail-panel--lg,
#pmDetailPanel.detail-panel--lg.open { width: 460px; }

.detail-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 12px var(--space-4);
  background: #ede9fc;
  border-bottom: 1px solid #d8ccee;
  flex-shrink: 0;
}
.detail-panel-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 700;
  font-size: 13px;
  color: #5b4282;
}
.detail-panel-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.detail-panel-body {
  padding: var(--space-4);
  flex: 1;
  overflow-y: auto;
}

/* Detail-panel action buttons (Edit / Save / Archive / Cancel) */
.dp-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  font-size: 11px;
  font-weight: 600;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  background: #e5e7eb;
  color: #374151;
  transition: filter .12s, background .12s;
}
.dp-btn:hover { filter: brightness(.95); }
.dp-btn[hidden] { display: none; }
.dp-btn--primary { background: var(--icon-primary); color: #fff; }
.dp-btn--success { background: var(--icon-success); color: #fff; }
.dp-btn--warning { background: #f59e0b; color: #fff; }
.dp-btn--danger  { background: var(--icon-danger); color: #fff; }

/* Fixed-width label variant for detail-panel edit forms */
.detail-label--fixed { flex: 0 0 135px; }
.detail-row--center { align-items: center; }
.detail-row--top { align-items: flex-start; }
.detail-hint { font-size: 10.5px; color: var(--icon-muted); margin-top: 4px; padding: 2px 0; }
.detail-code {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  font-weight: 700;
  color: #374151;
}
.detail-checkbox { width: 16px; height: 16px; }
.detail-color-input {
  width: 34px;
  height: 28px;
  border: 1px solid #d8ccee;
  border-radius: 5px;
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
}
.detail-panel-input--mono { font-family: 'JetBrains Mono', monospace; margin-left: 6px; }
.detail-form-actions {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  justify-content: flex-end;
}
.detail-add-row { margin-top: 8px; }
/* Inline colour swatch (dynamic background set via style attr) */
.color-swatch {
  display: inline-block;
  width: 11px;
  height: 11px;
  border-radius: 3px;
  border: 1px solid rgba(0, 0, 0, .15);
  vertical-align: middle;
  margin-right: 6px;
}
.detail-unit { color: var(--icon-muted); font-weight: 400; font-size: 10px; }
.detail-empty { color: #d1d5db; }
.detail-note { font-size: var(--fs-md, 12px); color: #374151; padding: 4px 0; }
.detail-panel-textarea {
  width: 100%;
  border: 1px solid #d8ccee;
  border-radius: 5px;
  padding: 5px 7px;
  font-size: var(--fs-md, 12px);
  font-family: inherit;
  resize: vertical;
  box-sizing: border-box;
}
.detail-panel-textarea:focus {
  outline: none;
  border-color: #7c3aed;
  box-shadow: 0 0 0 2px rgba(124, 58, 237, .08);
}

/* ════════════════════════════════════════════════════
   Detail panel expand / maximize
   Works on all right-rail detail panel variants:
   #matDetailPanel, #sectionDetailPanel, #fixDetailPanel,
   #conDetailPanel, #lcDetailPanel, #pmDetailPanel,
   and .detail-panel (WDS catalog manage panels).
   ════════════════════════════════════════════════════ */
.dp-panel-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .45);
  z-index: 9998;
}
.dp-panel-backdrop.active { display: block; }

/* Expanded — wider rail */
#matDetailPanel.dp-expanded,
#sectionDetailPanel.dp-expanded,
#fixDetailPanel.dp-expanded,
#conDetailPanel.dp-expanded,
#lcDetailPanel.dp-expanded,
#pl-detail-panel.dp-expanded { width: 640px; }

#pmDetailPanel.dp-expanded,
.detail-panel.dp-expanded { width: 640px; max-width: 94vw; }

/* Maximized — covers full viewport */
#matDetailPanel.dp-maximized,
#sectionDetailPanel.dp-maximized,
#fixDetailPanel.dp-maximized,
#conDetailPanel.dp-maximized,
#lcDetailPanel.dp-maximized,
#pl-detail-panel.dp-maximized,
#pmDetailPanel.dp-maximized,
.detail-panel.dp-maximized {
  width: 100vw !important;
  max-width: 100vw !important;
  top: 0 !important;
  z-index: 9999;
}

/* ════════════════════════════════════════════════════
   Refactored Detail Panels (Material, Section, Fixing, Connector, Load Case)
   Full-height right slide-in structure matching pl-detail-panel
   ════════════════════════════════════════════════════ */

/* ── Material Detail Panel ── */
#matDetailPanel {
  position: fixed; top: 0; right: 0; bottom: 0; width: 420px;
  background: #fff; border-left: 1px solid #e5e7eb;
  box-shadow: -4px 0 20px rgba(0,0,0,.08);
  overflow-y: auto; z-index: 9000; transform: translateX(100%);
  transition: transform .2s ease; display: flex; flex-direction: column;
}
#matDetailPanel.open { transform: translateX(0); }
.mat-detail-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; background: #eee8f9;
  border-bottom: 1px solid #d8ccee; flex-shrink: 0;
}
.mat-detail-title { font-weight: 700; font-size: 13px; color: #5b4282; }
.mat-detail-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.mat-detail-body { flex: 1; overflow-y: auto; padding: 16px; }
.mat-detail-btn {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px 10px;
  font-size: 11px; font-weight: 600; border: none; border-radius: 6px;
  cursor: pointer; background: #e5e7eb; color: #374151;
  transition: filter .12s, background .12s;
}
.mat-detail-btn:hover { filter: brightness(.95); }
.mat-detail-btn[hidden] { display: none; }
.mat-detail-btn--primary { background: var(--icon-primary); color: #fff; }
.mat-detail-btn--success { background: var(--icon-success); color: #fff; }
.mat-detail-btn--warning { background: #f59e0b; color: #fff; }

/* ── Section Detail Panel ── */
#sectionDetailPanel {
  position: fixed; top: 0; right: 0; bottom: 0; width: 420px;
  background: #fff; border-left: 1px solid #e5e7eb;
  box-shadow: -4px 0 20px rgba(0,0,0,.08);
  overflow-y: auto; z-index: 9000; transform: translateX(100%);
  transition: transform .2s ease; display: flex; flex-direction: column;
}
#sectionDetailPanel.open { transform: translateX(0); }
.section-detail-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; background: #eee8f9;
  border-bottom: 1px solid #d8ccee; flex-shrink: 0;
}
.section-detail-title { font-weight: 700; font-size: 13px; color: #5b4282; }
.section-detail-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.section-detail-body { flex: 1; overflow-y: auto; padding: 16px; }
.section-detail-btn {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px 10px;
  font-size: 11px; font-weight: 600; border: none; border-radius: 6px;
  cursor: pointer; background: #e5e7eb; color: #374151;
  transition: filter .12s, background .12s;
}
.section-detail-btn:hover { filter: brightness(.95); }
.section-detail-btn[hidden] { display: none; }
.section-detail-btn--primary { background: var(--icon-primary); color: #fff; }
.section-detail-btn--success { background: var(--icon-success); color: #fff; }

/* ── Fixing Detail Panel ── */
#fixDetailPanel {
  position: fixed; top: 0; right: 0; bottom: 0; width: 420px;
  background: #fff; border-left: 1px solid #e5e7eb;
  box-shadow: -4px 0 20px rgba(0,0,0,.08);
  overflow-y: auto; z-index: 9000; transform: translateX(100%);
  transition: transform .2s ease; display: flex; flex-direction: column;
}
#fixDetailPanel.open { transform: translateX(0); }
.fix-detail-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; background: #eee8f9;
  border-bottom: 1px solid #d8ccee; flex-shrink: 0;
}
.fix-detail-title { font-weight: 700; font-size: 13px; color: #5b4282; }
.fix-detail-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.fix-detail-body { flex: 1; overflow-y: auto; padding: 16px; }
.fix-detail-btn {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px 10px;
  font-size: 11px; font-weight: 600; border: none; border-radius: 6px;
  cursor: pointer; background: #e5e7eb; color: #374151;
  transition: filter .12s, background .12s;
}
.fix-detail-btn:hover { filter: brightness(.95); }
.fix-detail-btn[hidden] { display: none; }
.fix-detail-btn--success { background: var(--icon-success); color: #fff; }
.fix-detail-btn--warning { background: #f59e0b; color: #fff; }

/* ── Connector Detail Panel ── */
#conDetailPanel {
  position: fixed; top: 0; right: 0; bottom: 0; width: 420px;
  background: #fff; border-left: 1px solid #e5e7eb;
  box-shadow: -4px 0 20px rgba(0,0,0,.08);
  overflow-y: auto; z-index: 9000; transform: translateX(100%);
  transition: transform .2s ease; display: flex; flex-direction: column;
}
#conDetailPanel.open { transform: translateX(0); }
.con-detail-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; background: #eee8f9;
  border-bottom: 1px solid #d8ccee; flex-shrink: 0;
}
.con-detail-title { font-weight: 700; font-size: 13px; color: #5b4282; }
.con-detail-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.con-detail-body { flex: 1; overflow-y: auto; padding: 16px; }
.con-detail-btn {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px 10px;
  font-size: 11px; font-weight: 600; border: none; border-radius: 6px;
  cursor: pointer; background: #e5e7eb; color: #374151;
  transition: filter .12s, background .12s;
}
.con-detail-btn:hover { filter: brightness(.95); }
.con-detail-btn[hidden] { display: none; }
.con-detail-btn--primary { background: var(--icon-primary); color: #fff; }
.con-detail-btn--success { background: var(--icon-success); color: #fff; }
.con-detail-btn--warning { background: #f59e0b; color: #fff; }

/* ── Load Case Detail Panel ── */
#lcDetailPanel {
  position: fixed; top: 0; right: 0; bottom: 0; width: 420px;
  background: #fff; border-left: 1px solid #e5e7eb;
  box-shadow: -4px 0 20px rgba(0,0,0,.08);
  overflow-y: auto; z-index: 9000; transform: translateX(100%);
  transition: transform .2s ease; display: flex; flex-direction: column;
}
#lcDetailPanel.open { transform: translateX(0); }
.lc-detail-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; background: #eee8f9;
  border-bottom: 1px solid #d8ccee; flex-shrink: 0;
}
.lc-detail-title { font-weight: 700; font-size: 13px; color: #5b4282; }
.lc-detail-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.lc-detail-body { flex: 1; overflow-y: auto; padding: 16px; }
.lc-detail-btn {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px 10px;
  font-size: 11px; font-weight: 600; border: none; border-radius: 6px;
  cursor: pointer; background: #e5e7eb; color: #374151;
  transition: filter .12s, background .12s;
}
.lc-detail-btn:hover { filter: brightness(.95); }
.lc-detail-btn[hidden] { display: none; }
.lc-detail-btn--success { background: var(--icon-success); color: #fff; }
.lc-detail-btn--warning { background: #f59e0b; color: #fff; }

/* ════════════════════════════════════════════════════
   Data table extensions — density modes + states
   primary-table is the universal grid; default density
   is Comfortable. Libraries/catalog opt into Compact.
   ════════════════════════════════════════════════════ */
/* Compact — data-dense reference tables (still readable: only ~25% tighter) */
.primary-table--compact thead th { padding: 7px 12px; }
.primary-table--compact td       { padding: 6px 12px; white-space: nowrap; }
/* Dense — maximum rows on screen (calc grids, large catalogues) */
.primary-table--dense thead th { padding: 4px 9px; font-size: 11px; }
.primary-table--dense td       { padding: 4px 9px; font-size: 12px; white-space: nowrap; }
/* Spacious — content-led browsing */
.primary-table--spacious thead th { padding: 12px 16px; }
.primary-table--spacious td       { padding: 12px 16px; }

/* Sticky header polish — subtle separation while scrolling */
.primary-table thead th { z-index: 2; box-shadow: 0 1px 0 var(--wds-border); }

/* Optional zebra striping */
.primary-table--striped tbody tr:nth-child(even) { background: #fcfcfe; }
.primary-table--striped tbody tr:hover { background: #faf9ff; }

/* Table state cells — Loading / empty / error rows */
.cell-state {
  text-align: center;
  padding: 30px 10px !important;
  color: var(--icon-muted);
  font-size: var(--fs-md, 12px);
}
.cell-state--error { color: var(--icon-danger); }
.cell-strong { font-weight: 600; color: #374151; }
.cell-mono { font-family: 'JetBrains Mono', monospace; font-size: 12px; }
.cell-muted { color: #6b7280; font-size: 11px; }
.td-nowrap { white-space: nowrap; }
.txt-warn-xs { color: #b45309; font-size: 10px; font-weight: 600; }
.u-mr-6 { margin-right: 6px; }

/* Status pill — Active / Inactive (shared by every workspace table)
   Kept for backward-compat; new code should use app-badge--success / app-badge--danger */
.status-pill {
  display: inline-flex;
  align-items: center;
  font-size: var(--tb-font-label, 10px);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 99px;
  white-space: nowrap;
  border: 1px solid transparent;
}
.status-pill--on  {
  background:   var(--success-bg,     #d1fae5);
  color:        var(--success,        #065f46);
  border-color: var(--success-border, #a7f3d0);
}
.status-pill--off {
  background:   var(--danger-bg,     #fee2e2);
  color:        var(--danger,        #991b1b);
  border-color: var(--danger-border, #fca5a5);
}

/* ════════════════════════════════════════════════════
   List view infrastructure — ws-view-toggle + lv-row
   Card ⇄ List switching for catalog / libraries.
   ════════════════════════════════════════════════════ */
.ws-view-toggle {
  display: inline-flex;
  border: 1px solid var(--wds-border);
  border-radius: var(--wds-radius);
  overflow: hidden;
  background: var(--wds-surface);
}
.ws-view-toggle button {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  font-size: 11.5px;
  font-weight: 600;
  border: none;
  background: transparent;
  color: #6b7280;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.ws-view-toggle button + button { border-left: 1px solid var(--wds-border); }
.ws-view-toggle button:hover { background: var(--wds-surface-2); }
.ws-view-toggle button.active { background: #ede9fc; color: #5b4282; }

/* Dense row-based list view */
.lv-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 7px var(--space-4);
  border-bottom: 1px solid var(--wds-border-subtle);
  background: var(--wds-surface);
  cursor: pointer;
  transition: background .1s;
  text-decoration: none;
  color: inherit;
  min-width: 0;
}
.lv-row:hover { background: #faf9ff; }
.lv-row.selected { background: #ede9fe; }
.lv-row-icon {
  width: 26px;
  height: 26px;
  border-radius: 6px;
  background: #eee8f9;
  color: var(--icon-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  flex-shrink: 0;
}
.lv-row-name { font-size: 12px; font-weight: 600; color: #374151; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lv-row-meta { font-size: 11px; color: var(--icon-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lv-row-end  { margin-left: auto; display: inline-flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }

/* ════════════════════════════════════════════════════
   Icon system — semantic colours + micro-animations
   Action icon mapping (use everywhere):
     add fa-plus | edit fa-pencil-alt | delete fa-trash-can |
     archive fa-box-archive | copy fa-copy | duplicate fa-clone |
     export fa-file-export | import fa-file-import |
     download fa-download | upload fa-upload | view fa-eye |
     search fa-magnifying-glass | settings fa-gear |
     refresh fa-rotate-right
   ════════════════════════════════════════════════════ */
.ic-primary { color: var(--icon-primary); }
.ic-success { color: var(--icon-success); }
.ic-warning { color: var(--icon-warning); }
.ic-danger  { color: var(--icon-danger); }
.ic-info    { color: var(--icon-info); }
.ic-muted   { color: var(--icon-muted); }

/* Micro-animations — fast, subtle, professional */
.ic-anim { transition: transform .15s ease, color .15s ease; display: inline-block; }
.ic-anim:hover,
button:hover > .ic-anim,
a:hover > .ic-anim { transform: translateY(-1px); }
.ic-scale:hover,
button:hover > .ic-scale,
a:hover > .ic-scale { transform: scale(1.12); }
.ic-rotate { transition: transform .18s ease; display: inline-block; }
.ic-rotate.open { transform: rotate(90deg); }
.ic-spin { animation: ic-spin .8s linear infinite; display: inline-block; }
@keyframes ic-spin { to { transform: rotate(360deg); } }

/* Accessible icon button — 28px visual, ≥32px touch target */
.ws-icon-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  min-width: 28px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: #6b7280;
  font-size: 12px;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.ws-icon-btn::after { content: ''; position: absolute; inset: -3px; }
.ws-icon-btn:hover { background: #f3f0fa; color: var(--icon-primary); }
.ws-icon-btn:focus-visible { outline: 2px solid var(--icon-primary); outline-offset: 1px; }
.ws-icon-btn--danger:hover { background: #fee2e2; color: var(--icon-danger); }

/* ════════════════════════════════════════════════════
   Child-record editor widgets — child-btn / child-form
   Inline sub-tables inside detail panels (capacity sets,
   hole patterns, components…). Shared by all libraries.
   ════════════════════════════════════════════════════ */
.child-btn {
  padding: 2px 7px;
  font-size: 10px;
  font-weight: 600;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: filter .12s;
}
.child-btn:hover { filter: brightness(.95); }
.child-btn.edit    { background: #ede9fc; color: #5b4282; }
.child-btn.del     { background: #fee2e2; color: #b91c1c; }
.child-btn.add     { background: var(--icon-success); color: #fff; padding: 3px 10px; font-size: 11px; }
.child-btn.neutral { background: #e5e7eb; color: #374151; }

.child-form {
  background: var(--wds-surface-2);
  border: 1px solid var(--wds-border);
  border-radius: var(--wds-radius);
  padding: 10px;
  margin-top: 8px;
}
.child-form .cf-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.child-form label { display: block; font-size: 10px; color: #6b7280; font-weight: 600; margin-bottom: 1px; }
.child-form input,
.child-form select {
  width: 100%;
  border: 1px solid #d8ccee;
  border-radius: 5px;
  padding: 3px 6px;
  font-size: 11px;
  box-sizing: border-box;
}
.child-form .cf-full { grid-column: 1 / -1; }

/* ════════════════════════════════════════════════════
   Empty / loading states — shared across all modules
   ════════════════════════════════════════════════════ */
.ws-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-8) var(--space-5);
  text-align: center;
}
.ws-empty i { font-size: 26px; color: #d1d5db; }
.ws-empty-title { font-size: var(--fs-xl, 14px); font-weight: 600; color: #374151; margin: 0; }
.ws-empty-sub { font-size: var(--fs-md, 12px); color: var(--icon-muted); margin: 0; }
.ws-empty .ws-empty-action { margin-top: var(--space-2); }

.ws-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-8) var(--space-5);
  color: var(--icon-muted);
  font-size: var(--fs-md, 12px);
}
.ws-loading i { animation: ic-spin .8s linear infinite; }


/* ════════════════════════════════════════════════════════════════
   AI-DETECTED SYSTEMS  (.ds-*)
   The SmartSpec "detected systems + catalog matching" cards rendered by
   renderDetectedSystems() in smartspec.js. Built on WDS tokens + app-badge.
   Theme accent switches wall (brand) ↔ ceiling (info) via .ds-scan--ceiling,
   which only re-points the --ds-* custom properties.
   ════════════════════════════════════════════════════════════════ */
.ds-scan {
  /* Accent palette — wall (brand violet) by default */
  --ds-accent:      var(--brand, #8e75da);
  --ds-accent-deep: #6d28d9;
  --ds-tint:        #faf8ff;
  --ds-tint-2:      #f5f3ff;
  --ds-head-bg:     #f8f5ff;
  --ds-line:        #ede9fe;

  background: var(--wds-surface, #fff);
  border: 1px solid var(--wds-border, #e5e7eb);
  border-radius: var(--wds-radius-lg, 12px);
  box-shadow: var(--shadow-xs);
  overflow: hidden;
  margin-bottom: var(--space-5, 20px);
}
.ds-scan--ceiling {
  --ds-accent:      #0891b2;
  --ds-accent-deep: #0e7490;
  --ds-tint:        #f0f9ff;
  --ds-tint-2:      #ecfeff;
  --ds-head-bg:     #f0f9ff;
  --ds-line:        #bae6fd;
}

/* ── Scan header bar ── */
.ds-scan__head {
  display: flex;
  align-items: center;
  gap: var(--space-3, 12px);
  padding: var(--space-3, 12px) var(--space-4, 16px);
  background: var(--ds-head-bg);
  border-bottom: 1px solid var(--ds-line);
}
.ds-scan__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px; height: 30px;
  flex-shrink: 0;
  border-radius: 7px;
  color: #fff; font-size: .8rem;
  background: linear-gradient(135deg, var(--ds-accent), var(--ds-accent-deep));
}
.ds-scan__titles { flex: 1; min-width: 0; }
.ds-scan__title {
  font-size: .82rem; font-weight: 700; color: #1e293b;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ds-scan__file {
  font-size: .68rem; color: #94a3b8; margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ds-scan__del { color: var(--icon-danger, #dc2626); }
.ds-scan__del:hover {
  background: #fff1f2; border-color: #fecdd3; color: #e11d48;
}

/* ── Cards grid ── */
.ds-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-3, 12px);
  padding: var(--space-3, 12px) var(--space-4, 16px) var(--space-4, 16px);
}

/* ── Per-type card ── */
.ds-card {
  display: flex;
  flex-direction: column;
  min-height: 280px;
  background: var(--ds-tint);
  border: 1px solid var(--ds-line);
  border-radius: var(--wds-radius, 10px);
  overflow: hidden;
  transition: box-shadow .15s ease, border-color .15s ease, transform .15s ease;
}
.ds-card:hover {
  border-color: var(--ds-accent);
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}
.ds-card__head {
  flex-shrink: 0;
  padding: 11px 14px 7px;
  border-bottom: 1px solid var(--wds-border-subtle, #f1f5f9);
}
.ds-card__code {
  font-size: 1rem; font-weight: 700; color: #1e293b;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ds-card__row {
  flex-shrink: 0;
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 6px;
  padding: 6px 14px;
  min-height: 32px;
  border-bottom: 1px solid var(--ds-line);
}
.ds-card__supplier {
  font-size: .68rem; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 90px;
}
.ds-chip-code {
  font-size: .68rem; font-weight: 600;
  font-family: ui-monospace, monospace;
  color: #6366f1; background: #eef2ff;
  padding: 2px 7px; border-radius: 4px; white-space: nowrap;
}
.ds-chip-ai {
  font-size: .68rem; font-weight: 600;
  color: #7c3aed; background: var(--brand-light, #ede9fe);
  padding: 2px 7px; border-radius: 4px; white-space: nowrap;
}

/* Fire / acoustic tags reuse app-badge; thin variants here */
.ds-tag-fire {
  font-size: .68rem; background: #fef2f2; color: #dc2626;
  padding: 2px 7px; border-radius: 99px; white-space: nowrap;
}
.ds-tag-acoustic {
  font-size: .68rem; background: #eff6ff; color: #2563eb;
  padding: 2px 7px; border-radius: 99px; white-space: nowrap;
}

/* ── Matched-catalog block (the "suggestions") ── */
.ds-card__matches {
  flex-shrink: 0;
  padding: 6px 14px 8px;
  border-bottom: 1px solid var(--ds-line);
}
.ds-card__matches-label {
  display: flex; align-items: center; gap: 4px;
  font-size: .6rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ds-accent); margin-bottom: 4px;
}
.ds-match-list { display: flex; flex-wrap: wrap; gap: 4px; }
.ds-match-pill {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: .68rem; font-family: ui-monospace, monospace;
  background: var(--ds-tint-2);
  border: 1px solid var(--ds-line);
  color: var(--ds-accent-deep);
  padding: 2px 8px; border-radius: 5px;
  cursor: pointer; white-space: nowrap;
  transition: background .12s, border-color .12s;
}
.ds-match-pill:hover {
  background: var(--brand-light, #ede9fe);
  border-color: var(--ds-accent);
}
.ds-match-pill .ds-match-size {
  font-size: .6rem; font-family: system-ui, sans-serif; color: #8b5cf6;
}
.ds-match-empty {
  font-size: .64rem; color: #b8a8d8; font-style: italic;
}

/* ── Visualization (SVG + layer labels) ── */
.ds-card__viz {
  flex: 1;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px;
  background: var(--ds-tint-2);
}
.ds-card__labels {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column;
  align-items: flex-end; justify-content: center;
  gap: 1px; overflow: hidden;
}
.ds-card__label {
  font-size: .62rem; color: #475569; line-height: 1.35;
  text-align: right; max-width: 160px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ds-card__svg { flex-shrink: 0; }

/* ── Footer actions ── */
.ds-card__foot {
  flex-shrink: 0;
  display: flex; justify-content: flex-end; gap: 6px;
  padding: 8px 14px;
  border-top: 1px solid var(--ds-line);
}
/* compact buttons inside cards */
.ds-card__foot .app-btn { height: 28px; padding: 0 11px; font-size: .72rem; }


/* ════════════════════════════════════════════════════════════════
   Project picker modal  (shared: SmartSpec, Structural Actions)
   Matches the clean "confirm" modal aesthetic: edge-to-edge colour
   banner header + icon + close button, neat fixed-size card grid.
   ════════════════════════════════════════════════════════════════ */
.projpick-overlay {
  display: none;
  position: fixed; inset: 0; z-index: 9998;
  background: rgba(15, 10, 40, .55);
  backdrop-filter: blur(4px);
  align-items: center; justify-content: center;
  padding: 24px 12px;
}
.projpick-overlay.show { display: flex; }

.projpick-box {
  background: #fff; border-radius: 12px;
  width: 560px; max-width: 95vw;
  box-shadow: 0 24px 64px rgba(0, 0, 0, .28);
  overflow: hidden;
  animation: projpickIn .2s ease-out;
}
@keyframes projpickIn {
  from { opacity: 0; transform: translateY(-14px); }
  to   { opacity: 1; transform: translateY(0); }
}

.projpick-header {
  display: flex; align-items: center; gap: 12px;
  padding: 18px 20px;
  background: linear-gradient(135deg, #f5f3ff, #faf5ff);
  border-bottom: 1px solid #e9d5ff;
}
.projpick-icon {
  width: 40px; height: 40px; border-radius: 10px; flex-shrink: 0;
  background: linear-gradient(135deg, #7c3aed, #6d28d9); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 17px;
}
.projpick-titles { flex: 1; min-width: 0; }
.projpick-title  { font-size: 15px; font-weight: 700; color: #4c1d95; line-height: 1.2; }
.projpick-sub    { font-size: 12px; color: #7c3aed; margin-top: 2px; }
.projpick-close {
  background: rgba(124, 58, 237, .1); border: none; color: #7c3aed;
  width: 28px; height: 28px; border-radius: 7px; cursor: pointer; font-size: 14px;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  transition: background .15s;
}
.projpick-close:hover { background: rgba(124, 58, 237, .2); }

.projpick-body {
  padding: 18px 20px 20px;
  max-height: 60vh; overflow-y: auto;
}
.projpick-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.projpick-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: 7px;
  padding: 14px; height: 108px; box-sizing: border-box;
  background: #f9fafb; border: 1.5px solid #e5e7eb; border-radius: 10px;
  cursor: pointer; text-align: left; transition: all .15s ease;
}
.projpick-card:hover {
  background: #f5f3ff; border-color: #a78bfa;
  box-shadow: 0 4px 14px rgba(109, 40, 217, .12); transform: translateY(-1px);
}
.projpick-card:active { transform: translateY(0); }
.projpick-card-ico  { font-size: 20px; color: #7c3aed; }
.projpick-card--standalone .projpick-card-ico { color: #9ca3af; }
.projpick-card-name { font-size: 13px; font-weight: 600; color: #1f2937; line-height: 1.3; word-break: break-word; }
.projpick-card-desc { font-size: 11px; color: #9ca3af; margin-top: auto; }

@media (max-width: 560px) {
  .projpick-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ── Settings-area sub-navigation ─────────────────────────────────────────── */
.settings-subnav {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  margin: 4px 0 22px;
  padding-bottom: 8px;
  border-bottom: 1px solid #e5e7eb;
}
.settings-subnav-item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 9px;
  font-size: 13px;
  font-weight: 600;
  color: #6b7280;
  text-decoration: none;
  transition: background .15s, color .15s;
}
.settings-subnav-item i { font-size: 13px; opacity: .85; }
.settings-subnav-item:hover { background: #f3f0fb; color: #4c1d95; }
.settings-subnav-item.active { background: #ede9fe; color: #6d28d9; }

/* ─────────────────────────────────────────────────────────────────────────
   Project work-tree ("Manage" tab in the workspace hub)
   Renders inside .wsh-stage-host; reuses .app-btn* and .dp-status colours.
   ───────────────────────────────────────────────────────────────────────── */
.worktree { max-width: 960px; margin: 0 auto; }
/* Modal variant: fill the detail modal width, action buttons right-aligned. */
.worktree--modal { max-width: none; margin: 0; }
.worktree-head--compact { margin-bottom: 12px; justify-content: flex-end; }
.worktree-head { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 18px; }
.worktree-head-text { min-width: 0; flex: 1; }
.worktree-title { display: flex; align-items: center; gap: 10px; margin: 0;
  font-size: 1.15rem; font-weight: 600; color: var(--text-primary); letter-spacing: -.01em; }
.worktree-title i { color: #8e75da; }
.worktree-sub { margin: 4px 0 0; font-size: .82rem; color: var(--text-secondary); }
.worktree-head-actions { display: flex; gap: 8px; flex-shrink: 0; }
.worktree-loading, .worktree-error { padding: 40px; text-align: center; color: var(--text-secondary); }
.worktree-error { color: #b91c1c; }

.wt-branch { border: 1px solid #e6e3f0; border-radius: 12px; background: #fff;
  margin-bottom: 12px; overflow: hidden; }
.wt-branch-head { display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 12px 14px; border: 0; background: #faf9fe; cursor: pointer;
  font-family: inherit; text-align: left; color: var(--text-primary); transition: background .15s; }
.wt-branch-head:hover { background: #f3f0fb; }
.wt-branch-chev { font-size: .72rem; color: var(--text-tertiary); transition: transform .18s; }
.wt-branch:not(.is-open) .wt-branch-chev { transform: rotate(-90deg); }
.wt-branch-icon { font-size: .9rem; color: #8e75da; width: 18px; text-align: center; }
.wt-branch-label { flex: 1; font-size: .9rem; font-weight: 600; }
.wt-branch-count { min-width: 22px; padding: 1px 8px; border-radius: 999px;
  background: #ede9fe; color: #6d28d9; font-size: .74rem; font-weight: 600; text-align: center; }
.wt-branch-nodes { display: block; }
.wt-branch:not(.is-open) .wt-branch-nodes { display: none; }
.wt-empty { padding: 12px 16px 14px 42px; font-size: .8rem; color: var(--text-tertiary); }

.wt-node { border-top: 1px solid #f1eff8; }
.wt-node-row { display: flex; align-items: center; gap: 10px; padding: 9px 14px 9px 16px; }
.wt-node--child .wt-node-row { padding-left: 42px; background: #fcfbff; }
.wt-node-row:hover { background: #f7f5fd; }
.wt-node-chev { font-size: .68rem; color: var(--text-tertiary); cursor: pointer; width: 14px;
  text-align: center; transition: transform .18s; }
.wt-node:not(.is-open) > .wt-node-row .wt-node-chev { transform: rotate(-90deg); }
.wt-node-chev-sp { display: inline-block; width: 14px; }
.wt-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: #cbd5e1; flex-shrink: 0; }
.wt-status { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: currentColor; flex-shrink: 0; }
.wt-node-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* Report / takeoff / calculation names are long and their distinguishing part
   is often at the END ("…-18/07/2026", "…-GROUND FLOOR"), so a single
   ellipsised line hid exactly what tells two rows apart. Wrap to two lines and
   break inside unspaced names; the title attribute covers the rare third line. */
.wt-node-label { font-size: .86rem; font-weight: 600; color: var(--text-primary);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: anywhere; line-height: 1.3; }
.wt-node-sub { font-size: .72rem; color: var(--text-tertiary); }
.wt-children { display: block; }
.wt-node:not(.is-open) > .wt-children { display: none; }

.wt-node-actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.wt-ic { width: 30px; height: 30px; border: 0; border-radius: 8px; background: transparent;
  color: var(--text-secondary); cursor: pointer; font-size: .8rem; display: inline-flex;
  align-items: center; justify-content: center; transition: background .15s, color .15s; }
.wt-ic:hover { background: #ede9fe; color: #6d28d9; }
.wt-ic.del:hover { background: #fee2e2; color: #dc2626; }
.wt-toggle { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px;
  border: 1px solid transparent; border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: .72rem; font-weight: 600; transition: .15s; }
.wt-toggle.is-on  { background: #dcfce7; color: #15803d; border-color: #bbf7d0; }
.wt-toggle.is-on:hover { background: #bbf7d0; }
.wt-toggle.is-off { background: var(--neutral-bg); color: var(--text-tertiary); border-color: var(--neutral-border); }
.wt-toggle.is-off:hover { background: var(--neutral-border); color: var(--text-secondary); }
.wt-toggle i { font-size: .82rem; }

/* ════════════════════════════════════════════════════
   Workspace hub (projects/workspace/hub.html)
   The hub rides the standard app shell, so the global .app-sidebar and
   .app-topbar are base.html's. This block owns only the stage host, the
   Overview dependency graph (.wsg-*) and the topbar stage pills.
   ════════════════════════════════════════════════════ */
@view-transition { navigation: auto; }

/* ── Stage host + panels ── */
.wsh-stage-host { position: relative; flex: 1; min-height: 0; background: #f4f5f8; }
.wsh-panel { position: absolute; inset: 0; display: none; overflow: auto; }
.wsh-panel.is-active { display: block; }
.wsh-panel:not(.wsh-panel--frame) { padding: 20px 24px; }
.wsh-panel--frame { overflow: hidden; padding: 0; }
.wsh-frame { width: 100%; height: 100%; border: 0; display: block; background: #fff; }
.wsh-loading, .wsh-error { padding: 48px; text-align: center; color: #64748b; }
.wsh-error { color: #b91c1c; }

/* ── Toast ── */
.wsh-toast {
  position: fixed; bottom: 24px; right: 24px; background: #120d2b;
  border: 1px solid rgba(255, 255, 255, .28); color: #fff; z-index: 9999;
  padding: 12px 18px; border-radius: 10px; font-weight: 600; box-shadow: 0 8px 28px rgba(0, 0, 0, .5);
}
.wsh-toast.is-error { background: #7f1d1d; border-color: rgba(248, 113, 113, .4); }

/* ── Overview: the stage dependency graph ──
   Fixed layout, no pan/zoom/drag: seven nodes fit any sane viewport, so an
   interactive canvas would cost UX and buy nothing. Cards sit over a single
   SVG edge layer; an amber dashed edge means the upstream changed after the
   downstream last ran (projects/workflow.py stage_edges). */
.wsh-panel--overview { padding: 22px 26px 28px; }

/* Two columns: the graph says what state each step is in, the rail (the former
   Manage tab) is where you act on it. Kept on one screen so diagnosing and
   fixing are not two different places. The rail collapses, and auto-stacks
   underneath once the graph beside it would fall below MIN_SCALE (hub.html). */
.wsg-overview {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1fr) 400px; gap: 22px;
  align-items: start;
}
.wsg-overview.is-stacked,
.wsg-overview.is-rail-hidden { grid-template-columns: minmax(0, 1fr); }
.wsg-overview.is-rail-hidden .wsg-rail { display: none; }
.wsg-graph { min-width: 0; }
.wsg-rail { min-width: 0; }
.wsg-overview.is-stacked .wsg-rail { border-top: 1px solid var(--border); padding-top: 20px; }

.wsg-rail-toggle {
  position: absolute; top: -4px; right: 0; z-index: 2;
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 9px;
  border: 1px solid var(--border); border-radius: 99px; background: var(--surface);
  color: var(--text-secondary); font-size: .72rem; cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.wsg-rail-toggle:hover { background: var(--brand-light); color: var(--brand); border-color: var(--brand); }
.wsg-overview.is-stacked .wsg-rail-toggle { display: none; }

.wsg-head { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; padding-right: 120px; }
.wsg-head-label { font-size: .78rem; color: var(--text-secondary); white-space: nowrap; }
.wsg-progress { width: 180px; height: 6px; background: var(--brand-light); border-radius: 99px; overflow: hidden; }
.wsg-progress-bar { height: 100%; background: var(--brand); transition: width .4s ease; }
.wsg-head-warn {
  font-size: .74rem; font-weight: 600; color: #b45309; background: var(--warning-bg);
  border: 1px solid var(--warning-border); border-radius: 99px; padding: 3px 11px;
}

/* Viewport clips the scaled canvas so a narrow window shrinks the graph
   instead of growing a horizontal scrollbar. */
.wsg-viewport { overflow: hidden; }
.wsg-canvas {
  position: relative; transform-origin: top left;
  --wsg-edge: rgba(142, 117, 218, .38);
  --wsg-edge-stale: #d97706;
}
.wsg-edges { position: absolute; top: 0; left: 0; pointer-events: none; }

.wsg-node {
  position: absolute; width: 168px; height: 98px; box-sizing: border-box;
  display: flex; flex-direction: column; gap: 4px; text-align: left;
  padding: 10px 12px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); cursor: pointer; font-family: inherit;
  transition: border-color .12s, box-shadow .12s;
}
.wsg-node:hover { border-color: var(--brand); box-shadow: 0 2px 10px rgba(142, 117, 218, .18); }
.wsg-node--stale { border-color: var(--warning-border); background: #fffdf7; }
.wsg-node--empty { background: var(--neutral-bg); }
.wsg-node-title {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: .82rem; font-weight: 600; color: var(--text-primary);
}
.wsg-node--empty .wsg-node-title { color: var(--text-secondary); }

.wsg-check {
  display: flex; align-items: center; gap: 6px; min-width: 0;
  font-size: .68rem; color: var(--text-tertiary); line-height: 1.3;
}
.wsg-check span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wsg-check.is-done { color: var(--text-secondary); }
.wsg-check i { font-size: .58rem; flex-shrink: 0; color: var(--text-tertiary); }
.wsg-check.is-done i { color: var(--success); }

.wsg-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; display: inline-block; }
.wsg-dot--current { background: var(--success); }
.wsg-dot--stale { background: #d97706; }
.wsg-dot--empty { background: var(--neutral-border); }

.wsg-legend {
  display: flex; gap: 18px; flex-wrap: wrap; margin-top: 22px;
  font-size: .72rem; color: var(--text-secondary);
}
.wsg-legend span { display: inline-flex; align-items: center; gap: 6px; }
.wsg-legend-edge::before {
  content: ''; display: inline-block; width: 22px; height: 0;
  border-top: 2px dashed #d97706;
}

/* ── Topbar stage pills (components/input_panel_topbar/_stage_pills.html) ── */
.wsg-pills { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.wsg-pill {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 11px;
  border: 1px solid var(--border); border-radius: 99px; background: var(--surface);
  color: var(--text-secondary); font-family: inherit; font-size: .74rem;
  cursor: pointer; white-space: nowrap;
  transition: background .12s, color .12s, border-color .12s;
}
.wsg-pill:hover { background: var(--brand-light); color: var(--brand); }
.wsg-pill.is-current {
  background: var(--brand-light); border-color: var(--brand);
  color: var(--brand); font-weight: 600;
}
.wsg-pill.is-stale { border-color: var(--warning-border); }
.wsg-pill i { font-size: .7rem; }

/* ─────────────────────────────────────────────────────────────────────────
   APPEND-ONLY (Phase 7 worktree change hub). Two-column Manage tab: tree on
   the left, change-impact preview panel on the right. Reuses .dp-status colours
   and .app-btn* / .app-input; only the layout + impact/editor chrome is new.
   (Concurrent agents may append further blocks below this one.)
   ───────────────────────────────────────────────────────────────────────── */
.worktree--hub { max-width: 1180px; }
.worktree-main { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 18px; align-items: start; }
@media (max-width: 900px) { .worktree-main { grid-template-columns: 1fr; } }

/* ── Rail mode: the same fragment inside the hub Overview's right column ──
   Scoped by ancestor rather than a modifier class so the fragment stays
   byte-identical for its other host (the Projects-list modal). The tree's own
   two columns collapse to one and the impact preview stacks beneath it. */
.wsg-rail .worktree--hub { max-width: none; }
.wsg-rail .worktree-main { grid-template-columns: minmax(0, 1fr); gap: 14px; }
.wsg-rail .worktree-head { flex-direction: column; align-items: stretch; gap: 10px; margin-bottom: 14px; }
.wsg-rail .worktree-title { font-size: .92rem; }
.wsg-rail .worktree-sub { font-size: .74rem; }
.wsg-rail .worktree-head-actions .app-btn { flex: 1; justify-content: center; }
/* Bound the tree so a long project scrolls inside the rail instead of pushing
   the graph off the top of the page. */
.wsg-rail .worktree-body { max-height: 46vh; overflow: auto; }
.wsg-rail .worktree-impact { position: static; }

/* Stacked (narrow viewport): the rail spans the full width under the graph, so
   give the tree its own two columns back and drop the height cap. */
.wsg-overview.is-stacked .wsg-rail .worktree-main { grid-template-columns: minmax(0, 1fr) 340px; gap: 18px; }
.wsg-overview.is-stacked .wsg-rail .worktree-head { flex-direction: row; align-items: flex-start; }
.wsg-overview.is-stacked .wsg-rail .worktree-head-actions .app-btn { flex: none; }
.wsg-overview.is-stacked .wsg-rail .worktree-body { max-height: none; overflow: visible; }
.wsg-overview.is-stacked .wsg-rail .worktree-impact { position: sticky; top: 8px; }
@media (max-width: 900px) {
  .wsg-overview.is-stacked .wsg-rail .worktree-main { grid-template-columns: minmax(0, 1fr); }
}

.wt-node-row { cursor: pointer; }
.wt-node.is-selected > .wt-node-row { background: #ede9fe; box-shadow: inset 3px 0 0 #8e75da; }
.wt-node.is-selected > .wt-node-row .wt-node-label { color: #5b21b6; }

/* ── Impact preview panel ── */
.worktree-impact { position: sticky; top: 8px; border: 1px solid #e6e3f0; border-radius: 12px;
  background: #fff; overflow: hidden; min-height: 220px; }
.wt-impact-empty { padding: 40px 24px; text-align: center; color: var(--text-tertiary); }
.wt-impact-empty i { font-size: 1.6rem; color: #c7bdf0; margin-bottom: 10px; display: block; }
.wt-impact-empty p { margin: 0; font-size: .82rem; }
.wt-impact-head { padding: 14px 16px; border-bottom: 1px solid #f1eff8; background: #faf9fe; }
.wt-impact-title { font-size: .92rem; font-weight: 600; color: var(--text-primary);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: anywhere; line-height: 1.3; }
.wt-impact-type { font-size: .68rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-tertiary); margin-top: 2px; }
.wt-impact-body { padding: 12px 16px; }
.wt-impact-note { font-size: .8rem; color: var(--text-secondary); line-height: 1.5; }
.wt-impact-group { margin-bottom: 14px; }
.wt-impact-group:last-child { margin-bottom: 0; }
.wt-impact-group-head { display: flex; align-items: center; gap: 8px; font-size: .74rem;
  font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: #475569; margin-bottom: 7px; }
.wt-impact-group-head .dp-status { font-size: .72rem; }
.wt-impact-gcount { min-width: 20px; padding: 0 7px; border-radius: 999px; background: var(--neutral-bg);
  color: var(--text-secondary); font-size: .7rem; font-weight: 600; text-align: center; }
.wt-impact-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.wt-impact-list li { display: flex; flex-direction: column; gap: 2px;
  padding: 8px 10px; border: 1px solid #f1eff8; border-radius: 9px; background: #fcfbff; }
.wt-impact-label { font-size: .82rem; font-weight: 600; color: var(--text-primary); }
.wt-impact-detail { font-size: .74rem; color: var(--text-secondary); line-height: 1.4; }

/* ── Inline opening-sweep editor (wall types) ── */
.wt-impact-foot { padding: 12px 16px 16px; border-top: 1px solid #f1eff8; }
.wt-osweep-head { display: flex; align-items: center; justify-content: space-between;
  font-size: .78rem; font-weight: 600; color: var(--text-primary); margin-bottom: 10px; }
.wt-osweep-head i { color: #8e75da; margin-right: 4px; }
.wt-osweep-toggle { display: inline-flex; align-items: center; gap: 6px; font-weight: 600;
  font-size: .74rem; color: #475569; cursor: pointer; }
.wt-osweep-fields { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.wt-osweep-fields label { display: flex; flex-direction: column; gap: 3px;
  font-size: .72rem; font-weight: 600; color: var(--text-secondary); }
.wt-osweep-fields .app-input { font-size: .8rem; }
.wt-osweep-actions { display: flex; }
.wt-osweep-actions .app-btn { flex: 1; justify-content: center; }
.wt-osweep-hint { margin: 8px 0 0; font-size: .7rem; color: var(--text-tertiary); }

/* ── Framing verification state (.cert-state) ───────────────────────────────
   Shown wherever framing-derived numbers are presented or gated: the BOM, the
   report and the certification step. One definition so those surfaces cannot
   drift into describing the same state differently. */
.cert-state {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 12px 14px; border-radius: 10px;
    border: 1px solid transparent; font-size: 13px; line-height: 1.5;
    margin-bottom: 14px;
}
.cert-state i { margin-top: 2px; flex-shrink: 0; }
.cert-state strong { display: block; margin-bottom: 2px; }
.cert-state--verified   { background: #ecfdf5; border-color: #a7f3d0; color: #065f46; }
.cert-state--overridden { background: #fffbeb; border-color: #fde68a; color: #92400e; }
.cert-state--unverified { background: #fef2f2; border-color: #fecaca; color: #991b1b; }
/* Exactly which values departed from the design — a bare "was overridden" is
   not enough to act on. */
.cert-ovr { margin: 6px 0 0; padding-left: 18px; font-size: 12px; opacity: .9; }
.cert-ovr li { margin: 1px 0; }
/* A blocked action stays visible and explains itself rather than disappearing,
   so the step does not look broken or absent. */
.wsh-stage-cta.is-disabled { opacity: .55; cursor: not-allowed; pointer-events: none; }

/* ── Session boot / navigation loader (.sql-*) ──────────────────────────────
   Shared by the SmartQuote landing page (shown while navigating into a
   session) and the drawing canvas (shown until the plan is usable), so the
   wait looks like one continuous step rather than two different screens. */
.sql-overlay {
    position: fixed; inset: 0; z-index: 10060;
    background: rgba(8,12,20,.72);
    display: flex; align-items: center; justify-content: center;
}
.sql-overlay[hidden] { display: none; }
.sql-dialog {
    width: 300px; max-width: calc(100vw - 32px);
    background: var(--sqd-bg, #1e293b); border: 1px solid var(--sqd-border, #334155);
    border-radius: 14px; padding: 26px 22px; text-align: center;
    box-shadow: 0 24px 70px rgba(0,0,0,.6);
}
.sql-spinner {
    width: 34px; height: 34px; margin: 0 auto 14px;
    border: 3px solid rgba(148,163,184,.28);
    border-top-color: #7c3aed;
    border-radius: 50%;
    animation: sql-spin .8s linear infinite;
}
@keyframes sql-spin { to { transform: rotate(360deg); } }
.sql-title { color: #e2e8f0; font-size: 13px; font-weight: 600; }
.sql-sub { color: #94a3b8; font-size: 11px; margin-top: 5px; }

/* ── Reports & Certifications list (.rpt-*) ─────────────────────────────────
   A generated report is a certification record, not just a file: several
   issues of the same project routinely land on the same day, so the row has
   to carry the provenance that tells them apart — revision, exact time,
   author, document reference, and the categories that actually went into the
   PDF. Without that the list reads as three identical rows. */
.rpt-row {
    display: flex; align-items: flex-start; gap: 14px;
    padding: 14px 20px;
    transition: background .12s ease;
}
.rpt-row:hover { background: #fafafa; }
.rpt-row + .rpt-row { border-top: 1px solid #eef0f4; }

/* Fixed width so the titles line up down the column regardless of Rev digits. */
.rpt-rev {
    flex-shrink: 0; width: 50px; margin-top: 1px;
    text-align: center;
    font-size: 10px; font-weight: 700; letter-spacing: .03em;
    color: #6d28d9; background: #f5f2ff; border: 1px solid #e2d9fb;
    border-radius: 6px; padding: 4px 0;
}
.rpt-rev--stale { color: #9ca3af; background: #f9fafb; border-color: #e5e7eb; }

.rpt-body { flex: 1; min-width: 0; }
.rpt-title-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rpt-title { font-size: 13px; font-weight: 600; color: #111827; margin: 0; }

/* Status: dot + word, sitting with the title rather than buried in the meta
   line, because it gates whether Download is even there. */
.rpt-status { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600; }
.rpt-status i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.rpt-status--ready { color: #059669; }
.rpt-status--busy  { color: #2563eb; }
.rpt-status--busy i { animation: rpt-pulse 1.2s ease-in-out infinite; }
.rpt-status--error { color: #dc2626; }
.rpt-status--draft { color: #9ca3af; }
@keyframes rpt-pulse { 50% { opacity: .3; } }

/* Bullet separators, so the provenance reads as one line of facts instead of
   four unrelated columns. */
.rpt-meta {
    display: flex; align-items: center; flex-wrap: wrap;
    gap: 0 8px; margin-top: 5px;
    font-size: 11px; color: #6b7280;
}
.rpt-meta > * + *::before { content: "·"; margin-right: 8px; color: #d1d5db; }
.rpt-meta time { font-variant-numeric: tabular-nums; }
.rpt-ref {
    font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 10px; color: #9ca3af; letter-spacing: .02em;
}
/* The revision's own description — the reason this issue exists, so it carries
   the weight of the meta line rather than sitting at its grey default. */
.rpt-revnote { color: #4b5563; font-weight: 600; }
/* Issued = downloaded, which is what froze the revision. Stated on the row so
   the next generate bumping the number is never a surprise. */
.rpt-issued { display: inline-flex; align-items: center; gap: 4px; color: #6d28d9; font-weight: 600; }
.rpt-issued i { font-size: 9px; }
.rpt-unissued { color: #9ca3af; font-style: italic; }

.rpt-cats { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; }
.rpt-cat {
    font-size: 10px; font-weight: 600; line-height: 1.6;
    padding: 1px 7px; border-radius: 4px;
    background: #f3f4f6; color: #4b5563; border: 1px solid #e8eaee;
}
.rpt-cat--pricing { background: #ecfdf5; color: #047857; border-color: #a7f3d0; }

.rpt-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.rpt-err { margin: 6px 0 0; font-size: 11px; color: #b91c1c; }
