/* Azure Solution Designer — shared stylesheet
   Fluent-inspired: Segoe UI, Azure blue accent, soft depth shadows, 4px radius. */

:root {
  --c-primary: #0078D4;
  --c-primary-dark: #005A9E;
  --c-primary-darker: #004578;
  --c-primary-light: #DEECF9;
  --c-primary-lighter: #EFF6FC;
  --c-accent: #50E6FF;
  --c-bg: #FAF9F8;
  --c-surface: #FFFFFF;
  --c-border: #E1DFDD;
  --c-border-strong: #C8C6C4;
  --c-text: #201F1E;
  --c-text-secondary: #605E5C;
  --c-text-tertiary: #8A8886;
  --c-success: #107C10;
  --c-danger: #D13438;
  --radius-sm: 2px;
  --radius: 4px;
  --radius-lg: 8px;
  --shadow-2: 0 1.6px 3.6px rgba(0,0,0,.132), 0 0.3px 0.9px rgba(0,0,0,.108);
  --shadow-4: 0 3.2px 7.2px rgba(0,0,0,.132), 0 0.6px 1.8px rgba(0,0,0,.108);
  --shadow-8: 0 6.4px 14.4px rgba(0,0,0,.132), 0 1.2px 3.6px rgba(0,0,0,.108);
  --shadow-16: 0 12.8px 28.8px rgba(0,0,0,.132), 0 2.4px 7.2px rgba(0,0,0,.108);
  --font: "Segoe UI", "Segoe UI Web", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  color: var(--c-text);
  background: var(--c-bg);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--c-primary); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font-family: inherit; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 16px;
  font-size: 13.5px;
  font-weight: 600;
  border-radius: var(--radius);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background .1s ease, border-color .1s ease, transform .05s ease;
  white-space: nowrap;
}
.btn:active { transform: translateY(0.5px); }
.btn-primary { background: var(--c-primary); color: #fff; }
.btn-primary:hover { background: var(--c-primary-dark); }
.btn-secondary { background: var(--c-surface); color: var(--c-text); border-color: var(--c-border-strong); }
.btn-secondary:hover { background: var(--c-primary-lighter); border-color: var(--c-primary); }
.btn-ghost { background: transparent; color: var(--c-text-secondary); border-color: transparent; }
.btn-ghost:hover { background: rgba(0,0,0,.04); color: var(--c-text); }
.btn-danger { background: transparent; color: var(--c-danger); border-color: var(--c-border-strong); }
.btn-danger:hover { background: #FDF3F4; border-color: var(--c-danger); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn svg { width: 16px; height: 16px; flex-shrink: 0; }

/* ---------- Scrollbars ---------- */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #D2D0CE; border-radius: 10px; border: 2px solid var(--c-bg); }
::-webkit-scrollbar-thumb:hover { background: var(--c-border-strong); }

/* ================= OPENING PAGE ================= */
.topbar {
  height: 56px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 28px;
  background: var(--c-surface);
  border-bottom: 1px solid var(--c-border);
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand-mark {
  width: 30px; height: 30px; border-radius: 6px;
  background: linear-gradient(135deg, #1AA3FF 0%, #0078D4 55%, #004578 100%);
  display: flex; align-items: center; justify-content: center; color: #fff;
  box-shadow: var(--shadow-2);
}
.brand-mark svg { width: 17px; height: 17px; }
.brand-name { font-size: 15px; font-weight: 600; letter-spacing: .1px; }
.brand-sub { font-size: 11.5px; color: var(--c-text-tertiary); margin-top: -2px; }

.hero {
  padding: 56px 28px 32px;
  max-width: 1180px;
  margin: 0 auto;
}
.hero-eyebrow {
  font-size: 12px; font-weight: 700; color: var(--c-primary);
  text-transform: uppercase; letter-spacing: .6px; margin-bottom: 10px;
}
.hero h1 { font-size: 32px; font-weight: 600; margin: 0 0 8px; letter-spacing: -.2px; }
.hero p { font-size: 15px; color: var(--c-text-secondary); margin: 0 0 26px; max-width: 640px; line-height: 1.5; }

.toolbar-row {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  max-width: 1180px; margin: 0 auto; padding: 0 28px 20px;
}
.search-box {
  position: relative; flex: 1; max-width: 360px;
}
.search-box svg {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; color: var(--c-text-tertiary); pointer-events: none;
}
.search-box input {
  width: 100%; padding: 9px 12px 9px 34px; font-size: 13.5px;
  border: 1px solid var(--c-border-strong); border-radius: var(--radius);
  background: var(--c-surface); color: var(--c-text);
}
.search-box input:focus { outline: none; border-color: var(--c-primary); box-shadow: 0 0 0 1px var(--c-primary); }

.customer-section { max-width: 1180px; margin: 0 auto; padding: 0 28px 64px; }
.customer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 16px;
}
.customer-card {
  position: relative;
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-lg);
  padding: 20px; cursor: pointer; transition: box-shadow .15s ease, border-color .15s ease, transform .1s ease;
  display: flex; flex-direction: column; gap: 14px;
}
.customer-card:hover { box-shadow: var(--shadow-8); border-color: var(--c-border-strong); transform: translateY(-1px); }
.customer-card-delete {
  position: absolute; top: 12px; right: 12px; width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; background: none; border: none;
  color: var(--c-text-tertiary); cursor: pointer; opacity: 0; transition: opacity .12s ease, background .12s ease, color .12s ease;
}
.customer-card-delete svg { width: 13px; height: 13px; }
.customer-card:hover .customer-card-delete { opacity: 1; }
.customer-card-delete:hover { background: #FDF3F4; color: var(--c-danger); }
.customer-card-top { display: flex; align-items: center; gap: 12px; }
.avatar {
  width: 42px; height: 42px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 600; font-size: 14px; flex-shrink: 0;
}
.customer-card-name { font-size: 15px; font-weight: 600; }
.customer-card-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10.5px; font-weight: 600;
  color: var(--c-text-tertiary); background: var(--c-bg); border: 1px solid var(--c-border);
  border-radius: 4px; padding: 1px 5px; vertical-align: middle;
}
.customer-card-meta { font-size: 12px; color: var(--c-text-tertiary); margin-top: 2px; }
.customer-card-details { display: flex; flex-direction: column; gap: 4px; }
.detail-row { display: flex; justify-content: space-between; font-size: 12px; }
.detail-row .detail-label { color: var(--c-text-tertiary); }
.detail-row span:last-child { color: var(--c-text-secondary); font-weight: 500; }
.customer-card-stats {
  display: flex; gap: 18px; padding-top: 12px; border-top: 1px solid var(--c-border);
}
.stat { display: flex; flex-direction: column; gap: 2px; }
.stat-value { font-size: 16px; font-weight: 600; }
.stat-label { font-size: 11px; color: var(--c-text-tertiary); text-transform: uppercase; letter-spacing: .4px; }

.customer-card.new-card {
  display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 8px;
  border: 1.5px dashed var(--c-border-strong); background: transparent; min-height: 132px;
}
.customer-card.new-card:hover { border-color: var(--c-primary); background: var(--c-primary-lighter); }
.new-card-icon {
  width: 36px; height: 36px; border-radius: 50%; background: var(--c-primary-light);
  color: var(--c-primary); display: flex; align-items: center; justify-content: center;
}
.new-card-icon svg { width: 18px; height: 18px; }
.new-card-label { font-size: 13.5px; font-weight: 600; color: var(--c-primary); }

.empty-search { text-align: center; padding: 60px 20px; color: var(--c-text-tertiary); font-size: 13.5px; }

/* Modal */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.35);
  display: flex; align-items: center; justify-content: center; z-index: 100;
}
.modal {
  background: var(--c-surface); border-radius: var(--radius-lg); width: 420px; max-width: 90vw;
  box-shadow: var(--shadow-16); padding: 24px;
}
.modal h2 { font-size: 17px; font-weight: 600; margin: 0 0 4px; }
.modal p.hint { font-size: 12.5px; color: var(--c-text-tertiary); margin: 0 0 18px; }
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 12.5px; font-weight: 600; color: var(--c-text-secondary); margin-bottom: 5px; }
.field input, .field select {
  width: 100%; padding: 8px 10px; font-size: 13.5px; border: 1px solid var(--c-border-strong);
  border-radius: var(--radius); background: var(--c-surface); color: var(--c-text);
}
.field input:focus, .field select:focus { outline: none; border-color: var(--c-primary); box-shadow: 0 0 0 1px var(--c-primary); }
.field input[readonly] { background: var(--c-bg); color: var(--c-text-secondary); cursor: default; }
.field input[readonly]:focus { border-color: var(--c-border-strong); box-shadow: none; }
.field-hint { font-size: 11.5px; color: var(--c-text-tertiary); line-height: 1.5; margin: 6px 0 0; }
.field-hint code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; background: var(--c-bg); padding: 1px 4px; border-radius: 4px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 20px; }

/* Yes/No toggle switch (Route Table's "Propagate Gateway Routes" and
   anywhere else a binary setting reads better as a switch than a select). */
.toggle-switch-row { display: flex; align-items: center; gap: 8px; }
.toggle-switch { position: relative; display: inline-block; width: 38px; height: 21px; flex: none; }
.toggle-switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.toggle-switch .toggle-track { position: absolute; inset: 0; background: var(--c-border-strong); border-radius: 999px; transition: background .15s ease; pointer-events: none; }
.toggle-switch .toggle-track::before {
  content: ""; position: absolute; left: 2px; top: 2px; width: 17px; height: 17px;
  background: var(--c-surface); border-radius: 50%; box-shadow: var(--shadow-2); transition: transform .15s ease;
}
.toggle-switch input:checked + .toggle-track { background: var(--c-success); }
.toggle-switch input:checked + .toggle-track::before { transform: translateX(17px); }
.toggle-switch input:focus-visible + .toggle-track { outline: 2px solid var(--c-primary); outline-offset: 2px; }
.toggle-switch-label { font-size: 13px; color: var(--c-text-secondary); min-width: 24px; }

/* ================= BUILDER PAGE ================= */
.app-shell { height: 100vh; display: flex; flex-direction: column; }
.app-topbar {
  height: 52px; flex-shrink: 0; display: flex; align-items: center; gap: 14px;
  padding: 0 16px; background: var(--c-surface); border-bottom: 1px solid var(--c-border); z-index: 20;
}
.app-topbar .back-link {
  display: flex; align-items: center; gap: 6px; color: var(--c-text-secondary); font-size: 13px; font-weight: 600;
  padding: 6px 8px; border-radius: var(--radius);
}
.app-topbar .back-link:hover { background: rgba(0,0,0,.04); color: var(--c-text); text-decoration: none; }
.app-topbar .back-link svg { width: 15px; height: 15px; }
.topbar-divider { width: 1px; height: 24px; background: var(--c-border); }
.topbar-title { display: flex; flex-direction: column; line-height: 1.2; }
.topbar-title .customer-name { font-size: 14px; font-weight: 600; }
.topbar-title .canvas-label { font-size: 11px; color: var(--c-text-tertiary); }
.page-nav {
  display: flex; align-items: center; gap: 2px; background: var(--c-bg);
  border: 1px solid var(--c-border); border-radius: var(--radius); padding: 2px;
}
.page-nav-item {
  padding: 6px 12px; font-size: 12.5px; font-weight: 600; color: var(--c-text-secondary);
  border-radius: var(--radius-sm); text-decoration: none;
}
.page-nav-item:hover { background: rgba(0,0,0,.04); color: var(--c-text); text-decoration: none; }
.page-nav-item.active { background: var(--c-surface); color: var(--c-primary); box-shadow: var(--shadow-2); }

.topbar-spacer { flex: 1; }
.save-indicator { font-size: 12px; color: var(--c-text-tertiary); display: flex; align-items: center; gap: 5px; }
.save-indicator svg { width: 13px; height: 13px; color: var(--c-success); }

/* Global header controls: profile badge + settings cog (every page) */
.header-controls { display: flex; align-items: center; gap: 8px; flex-shrink: 0; margin-left: auto; }
.profile-badge {
  display: flex; align-items: center; gap: 8px; padding: 4px 10px 4px 4px; border-radius: 999px;
  border: 1px solid transparent; cursor: pointer; background: none;
}
.profile-badge:hover { background: rgba(0,0,0,.04); border-color: var(--c-border); }
.profile-avatar {
  width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0; background: var(--c-primary);
  color: #fff; font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.profile-text { display: flex; flex-direction: column; line-height: 1.2; text-align: left; }
.profile-name { font-size: 12.5px; font-weight: 600; color: var(--c-text); }
.profile-title { font-size: 10.5px; color: var(--c-text-tertiary); }
.icon-btn {
  width: 32px; height: 32px; flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  background: var(--c-surface); border: 1px solid var(--c-border-strong); border-radius: 50%;
  color: var(--c-text-secondary); cursor: pointer; padding: 0;
}
.icon-btn:hover { background: var(--c-primary-lighter); border-color: var(--c-primary); color: var(--c-primary); }
.icon-btn svg { width: 16px; height: 16px; }

/* Customer Workshop Mode toggle — sits with the profile/settings buttons
   in .header-controls on every page. Off state matches .icon-btn's
   neutral pill styling; the active state uses a distinct amber so it
   reads as a persistent "you're in front of a customer" reminder rather
   than blending into the rest of the header. */
.workshop-toggle-btn {
  display: flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px; flex-shrink: 0;
  background: var(--c-surface); border: 1px solid var(--c-border-strong); border-radius: 999px;
  color: var(--c-text-secondary); font-size: 12px; font-weight: 600; cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.workshop-toggle-btn svg { width: 15px; height: 15px; flex-shrink: 0; }
.workshop-toggle-btn:hover { background: var(--c-primary-lighter); border-color: var(--c-primary); color: var(--c-primary); }
.workshop-toggle-btn.active { background: #FFF4E5; border-color: #F5A623; color: #8A5300; }
.workshop-toggle-btn.active:hover { background: #FFE9C2; border-color: #E0940A; color: #6E4100; }

.app-body { flex: 1; display: flex; min-height: 0; position: relative; }

/* Connector key — a fixed corner overlay (child of .app-body, not the
   scrollable .canvas-wrap) so it stays put regardless of canvas scroll
   position or which connection types are currently used. */
.connector-legend {
  position: absolute; bottom: 16px; left: 280px; z-index: 15;
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-8); padding: 10px 12px; font-size: 11.5px; color: var(--c-text-secondary);
  display: flex; flex-direction: column; gap: 2px; max-width: 220px;
}
.connector-legend-title {
  font-size: 10.5px; font-weight: 600; color: var(--c-text-tertiary); text-transform: uppercase;
  letter-spacing: .03em; margin-bottom: 4px;
}
.connector-legend-hint { text-transform: none; font-weight: 400; letter-spacing: normal; }
.connector-legend-row {
  display: flex; align-items: center; gap: 8px; cursor: pointer; padding: 3px 5px; margin: 0 -5px;
  border-radius: 5px; transition: background .1s ease;
}
.connector-legend-row:hover { background: var(--c-primary-lighter); }
.connector-legend-row.active { background: var(--c-primary-lighter); font-weight: 600; color: var(--c-text); }
.connector-legend-swatch { width: 22px; height: 0; border-top-width: 2.5px; flex-shrink: 0; }

/* Palette */
.palette {
  width: 264px; flex-shrink: 0; background: var(--c-surface); border-right: 1px solid var(--c-border);
  overflow-y: auto; padding: 14px 10px 40px;
}
.palette-search { padding: 2px 4px 12px; }
.palette-search input {
  width: 100%; padding: 8px 10px 8px 30px; font-size: 13px; border: 1px solid var(--c-border-strong);
  border-radius: var(--radius); background: var(--c-bg); background-image: none;
}
.btn-block { width: 100%; justify-content: center; margin-top: 8px; }
.btn-block svg { width: 14px; height: 14px; }
.palette-group { margin-bottom: 4px; }
.palette-group-header {
  display: flex; align-items: center; gap: 6px; padding: 8px 8px; cursor: pointer;
  font-size: 11.5px; font-weight: 700; color: var(--c-text-secondary); text-transform: uppercase; letter-spacing: .5px;
  border-radius: var(--radius); user-select: none;
}
.palette-group-header:hover { background: rgba(0,0,0,.03); }
.palette-group-header svg { width: 11px; height: 11px; transition: transform .12s ease; color: var(--c-text-tertiary); }
.palette-group.collapsed .palette-group-header svg { transform: rotate(-90deg); }
.palette-group.collapsed .palette-items { display: none; }
.palette-items { display: flex; flex-direction: column; gap: 3px; padding-bottom: 8px; }

.palette-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 9px; border-radius: var(--radius);
  cursor: grab; border: 1px solid transparent; transition: background .1s ease, border-color .1s ease;
}
.palette-item:hover { background: var(--c-primary-lighter); border-color: var(--c-primary-light); }
.palette-item:active { cursor: grabbing; }
.palette-item.dragging { opacity: .4; }
.palette-item-icon {
  width: 30px; height: 30px; border-radius: 6px; display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.svc-icon-img { display: block; object-fit: contain; }
.palette-item-icon .svc-icon-img { width: 18px; height: 18px; }
.palette-item-text { display: flex; flex-direction: column; min-width: 0; }
.palette-item-name { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.palette-item-blurb { font-size: 11px; color: var(--c-text-tertiary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Resource library drawer (Browse resources / favorites) */
.resource-library-search { margin-bottom: 16px; }
.resource-library-group { margin-bottom: 22px; }
.resource-library-group-title { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--c-text-tertiary); margin-bottom: 4px; }
.resource-library-row { display: flex; align-items: center; gap: 10px; padding: 8px 4px; border-bottom: 1px solid var(--c-border); }
.resource-library-row:last-child { border-bottom: none; }
.resource-library-text { flex: 1; min-width: 0; }
.resource-library-name { font-size: 13px; font-weight: 600; }
.resource-library-blurb { font-size: 11.5px; color: var(--c-text-tertiary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.star-toggle { background: none; border: none; cursor: pointer; color: var(--c-text-tertiary); padding: 5px; border-radius: var(--radius); flex-shrink: 0; }
.star-toggle:hover { background: var(--c-primary-lighter); color: var(--c-primary); }
.star-toggle.active { color: #FFB900; }
.star-toggle svg { width: 18px; height: 18px; display: block; }

/* Canvas */
.canvas-wrap {
  flex: 1; position: relative; overflow: auto; background: var(--c-bg);
  background-image: radial-gradient(circle, #DCDAD8 1px, transparent 1px);
  background-size: 22px 22px;
}
.canvas {
  /* z-index:0 (not just position:relative) is what actually matters here —
     it makes .canvas establish its own stacking context, so a negative
     z-index on a descendant (e.g. .node.backdrop) only sinks it below its
     canvas siblings. Without this, position:relative alone creates no
     stacking context, and z-index:-1 descendants escape all the way to the
     page's root stacking context — rendering behind .canvas-wrap's own
     background and making them invisible. */
  position: relative; z-index: 0; width: 2200px; height: 1500px;
}
/* Deliberately NO explicit z-index here (and none on .node's base rule
   either) — #connectorLayer sits first in builder.html and .node boxes get
   appended after it in JS, so plain DOM order already paints every node
   ABOVE the connector layer, i.e. connectors run visually underneath node
   boxes. That's intentional: a connector should read as tucked behind
   whatever it's near, never drawn on top slicing across an unrelated box's
   face. Try not to reintroduce a z-index here — routing (see
   findRoutingObstacle/computeRoute in builder.js) is what keeps connectors
   from needing to cross a box in the first place; this is only the
   fallback for the rare case a route still can't clear one. */
#connectorLayer { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
/* IMPORTANT: this used to be a blanket "#connectorLayer path { fill: none;
   stroke: var(--c-border-strong) }" rule. Any CSS rule — even a plain
   element selector like that — always beats an SVG presentation attribute
   (the stroke="..."/fill="..." builder.js sets per connector type), no
   matter how low its specificity. That silently forced every connection
   line back to grey the moment it rendered, and also zeroed out the
   arrowhead markers' fill="${type.color}" via the same "fill: none".
   Scoping fill/stroke to only the specific classes that need their own
   fallback colour — and never matching the marker <path> elements inside
   <defs> — lets each connection's real per-type colour show through. */
#connectorLayer path.temp { fill: none; stroke: var(--c-primary); stroke-width: 2; stroke-dasharray: 5 4; }
#connectorLayer path.conn-hit { fill: none; stroke: transparent; stroke-width: 14; pointer-events: stroke; cursor: pointer; }
#connectorLayer path.conn-visible { fill: none; stroke-width: 2; pointer-events: none; }
#connectorLayer path.conn-visible.selected { stroke-width: 3; filter: drop-shadow(0 1px 3px rgba(0,0,0,.35)); }
#connectorLayer .conn-label-bg { fill: var(--c-surface); stroke: var(--c-border); stroke-width: 1; }
#connectorLayer .conn-label-text { font-family: var(--font); font-size: 10.5px; font-weight: 600; fill: var(--c-text-secondary); }

.canvas-empty-state {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  text-align: center; color: var(--c-text-tertiary); pointer-events: none; width: 320px;
}
.canvas-empty-state svg { width: 46px; height: 46px; margin-bottom: 14px; opacity: .55; }
.canvas-empty-state h3 { font-size: 15px; font-weight: 600; color: var(--c-text-secondary); margin: 0 0 6px; }
.canvas-empty-state p { font-size: 13px; margin: 0; line-height: 1.5; }

.canvas-drop-target { outline: 2px dashed var(--c-primary); outline-offset: -4px; background-color: rgba(0,120,212,.03); }

.node {
  position: absolute; width: 208px; background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-4); cursor: grab; user-select: none;
  transition: box-shadow .12s ease, border-color .12s ease;
}
.node:hover { box-shadow: var(--shadow-8); }
.node.selected { border-color: var(--c-primary); box-shadow: 0 0 0 2px var(--c-primary-light), var(--shadow-8); }
.node.dragging { cursor: grabbing; box-shadow: var(--shadow-16); z-index: 30; opacity: .96; }
.node-head { display: flex; align-items: center; gap: 9px; padding: 10px 10px 8px; }
.node-icon {
  width: 30px; height: 30px; border-radius: 6px; display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.node-icon .svc-icon-img { width: 18px; height: 18px; }
.node-title { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.node-name { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The resource's own name/detail — right-aligned, opposite the node-name
   label, in plain black regardless of the node's accent color. */
.node-meta {
  display: flex; flex-direction: column; align-items: flex-end; min-width: 0; max-width: 45%;
  flex-shrink: 0; margin-left: 6px;
}
.node-meta-primary {
  font-size: 12px; font-weight: 600; color: #000; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; max-width: 100%;
}
.node-meta-secondary {
  font-size: 10.5px; color: #000; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; max-width: 100%;
}
.node-delete {
  width: 20px; height: 20px; border-radius: 5px; border: none; padding: 0; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  background: transparent; color: #D13438;
}
.node-delete svg { width: 13px; height: 13px; }
.node-delete:hover { background: rgba(209, 52, 56, .12); }
.node-delete.disabled { color: var(--c-text-tertiary); cursor: not-allowed; }
.node-delete.disabled:hover { background: rgba(138, 136, 134, .12); }
/* Subnet's read-only NSG/Route Table hover badge, pinned to the node's own
   top-right corner (.node is already position:absolute, so this anchors to
   it directly with no extra wrapper needed the way .org-box-anchor is on
   Solution Overview's Topology diagram, below). */
.node > .subnet-badges { position: absolute; top: -8px; right: -8px; z-index: 5; }
/* VNet's manual Subscription tag (see renderNode in builder.js) — only
   rendered at all when the VNet isn't already inside a Subscription box, so
   it only ever appears where it's actually adding information. Pinned to
   the bottom-left corner so it never collides with the NSG/Route Table
   badge (top-right) or the connection handles (mid-left/right). Gold to
   match the Subscription colour used everywhere else (org-chart legend,
   Topology grouping, Canvas Subscription boxes). */
.node > .node-subscription-tag {
  position: absolute; left: 8px; bottom: -9px; z-index: 5;
  max-width: calc(100% - 16px); padding: 2px 8px; border-radius: 999px;
  background: #FFB900; color: #201F1E; border: 1.5px solid #D29200;
  font-size: 10.5px; font-weight: 700; line-height: 1.4;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  box-shadow: var(--shadow-2);
}
.node-body { padding: 0 10px 11px; font-size: 11.5px; color: var(--c-text-secondary); line-height: 1.55; }
.node-body .detail-row { display: flex; justify-content: space-between; gap: 8px; }
.node-body .detail-row + .detail-row { margin-top: 1px; }
.node-body .detail-key { color: var(--c-text-tertiary); }
.node-body .detail-val { font-weight: 600; color: var(--c-text); text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.node-body .unconfigured { font-style: italic; color: var(--c-text-tertiary); }

.node-handle {
  position: absolute; top: 50%; width: 12px; height: 12px; border-radius: 50%;
  background: var(--c-surface); border: 2px solid var(--c-primary); transform: translateY(-50%);
  cursor: crosshair; opacity: 0; transition: opacity .12s ease, transform .12s ease;
}
.node:hover .node-handle, .node.selected .node-handle { opacity: 1; }
.node-handle:hover { transform: translateY(-50%) scale(1.3); }
.node-handle.left { left: -7px; }
.node-handle.right { right: -7px; }

/* Containers — Management Group / Subscription / Resource Group */
.node.container {
  display: flex;
  flex-direction: column;
  padding: 0;
  background: rgba(255,255,255,.55);
  border-width: 1.5px;
}
.node.container > .node-head {
  flex: 0 0 auto;
  cursor: grab;
  border-bottom: 1px solid var(--c-border);
  padding: 10px 10px 9px;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.node.container.dragging > .node-head { cursor: grabbing; }
/* Subscription is a top-level organizational boundary — give it a light
   yellow tint so it reads as distinct from the neutral containers nested
   inside it. */
.node.container[data-service="subscription"] {
  background: #FFF8DC;
  border-color: #F2C811;
}
.node.container[data-service="subscription"] > .node-head {
  background: #FCEEA6;
  border-bottom-color: #E8CF5C;
}
/* Backdrop mode: the Subscription becomes a purely visual background frame
   sent behind every other root-level node (z-index below the implicit 0 of
   normal nodes), dashed + translucent so overlapping Regions/VWANs read
   clearly on top of it. It no longer holds real children (see
   resolveDropTarget / releaseChildrenToRoot in builder.js). */
.node.backdrop {
  z-index: -1;
  border-style: dashed;
  border-width: 2px;
}
.node.container[data-service="subscription"].backdrop {
  background: rgba(255, 248, 220, .65);
}
.node.container[data-service="subscription"].backdrop > .node-head {
  background: rgba(252, 238, 166, .8);
}
.node.backdrop .node-content-hint { max-width: 260px; margin: 0 auto; }
/* While actively dragging a backdrop node, keep it on top like any other
   node being dragged — it should only sink behind once you let go. */
.node.dragging.backdrop { z-index: 30; }
.node.container .node-content {
  flex: 1 1 auto;
  position: relative;
  overflow: visible;
  padding: 14px;
  background-image: radial-gradient(circle, rgba(0,0,0,.05) 1px, transparent 1px);
  background-size: 16px 16px;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
.node-content-hint {
  position: absolute; inset: 14px;
  border: 1.5px dashed var(--c-border-strong); border-radius: var(--radius);
  display: flex; align-items: center; justify-content: center;
  font-size: 11.5px; color: var(--c-text-tertiary); text-align: center; padding: 12px;
  pointer-events: none;
}
.resize-handle {
  position: absolute; right: 2px; bottom: 2px; width: 15px; height: 15px;
  cursor: nwse-resize; z-index: 2;
}
.resize-handle svg { width: 100%; height: 100%; color: var(--c-border-strong); }
.node.container:hover .resize-handle svg,
.node.container.selected .resize-handle svg { color: var(--c-text-tertiary); }

/* Detail panel */
.detail-panel {
  width: 0; flex-shrink: 0; background: var(--c-surface); border-left: 1px solid var(--c-border);
  overflow: hidden; transition: width .18s ease; display: flex; flex-direction: column;
}
.detail-panel.open { width: 320px; }
.detail-panel-inner { width: 320px; display: flex; flex-direction: column; height: 100%; }
.detail-header {
  display: flex; align-items: flex-start; gap: 12px; padding: 18px 18px 14px; border-bottom: 1px solid var(--c-border);
}
.detail-header .node-icon { width: 36px; height: 36px; }
.detail-header .node-icon .svc-icon-img { width: 22px; height: 22px; }
.detail-header-text { flex: 1; min-width: 0; }
.detail-header-text h3 { font-size: 15px; font-weight: 600; margin: 0 0 2px; }
.detail-header-text p { font-size: 11.5px; color: var(--c-text-tertiary); margin: 0; }
.panel-close { background: none; border: none; cursor: pointer; color: var(--c-text-tertiary); padding: 4px; border-radius: var(--radius); flex-shrink: 0; }
.panel-close:hover { background: rgba(0,0,0,.05); color: var(--c-text); }
.panel-close svg { width: 16px; height: 16px; display: block; }

.detail-body { flex: 1; overflow-y: auto; padding: 18px; }
.detail-body .field { margin-bottom: 16px; }
.detail-body .field label { display: flex; justify-content: space-between; }
.detail-footer { padding: 14px 18px; border-top: 1px solid var(--c-border); display: flex; gap: 8px; }
.detail-footer .btn-primary { flex: 1; justify-content: center; }

.panel-content-hidden { display: none; }

.panel-placeholder {
  flex: 1; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 10px;
  color: var(--c-text-tertiary); padding: 30px; text-align: center;
}
.panel-placeholder svg { width: 34px; height: 34px; opacity: .5; }
.panel-placeholder p { font-size: 12.5px; margin: 0; line-height: 1.5; }

/* ---------- Left sidebar navigation (doc pages) ---------- */

.app-sidebar {
  width: 264px; flex-shrink: 0; background: var(--c-surface); border-right: 1px solid var(--c-border);
  overflow-y: auto; padding: 14px 10px 40px;
}
.sidebar-canvas-link {
  display: flex; align-items: center; gap: 8px; padding: 9px 11px; margin-bottom: 14px; border-radius: var(--radius);
  font-size: 13px; font-weight: 700; color: var(--c-text); text-decoration: none; border: 1px solid var(--c-border-strong);
}
.sidebar-canvas-link:hover { background: var(--c-primary-lighter); border-color: var(--c-primary); text-decoration: none; }
.sidebar-canvas-link svg { width: 14px; height: 14px; flex-shrink: 0; }
.sidebar-group { margin-bottom: 18px; }
.sidebar-group-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--c-text-tertiary); padding: 6px 10px 4px; }
.sidebar-item {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; padding: 8px 10px; border-radius: var(--radius);
  font-size: 12.5px; font-weight: 600; color: var(--c-text-secondary); text-decoration: none; border: none; background: none; cursor: pointer;
  font-family: inherit; line-height: 1.3;
}
.sidebar-item:hover { background: rgba(0,0,0,.045); color: var(--c-text); text-decoration: none; }
.sidebar-item.active { background: var(--c-primary-lighter); color: var(--c-primary-dark); }
.sidebar-item-icon { flex-shrink: 0; width: 16px; text-align: center; }

/* ---------- Document-style pages (Structure, Landing Zone) ---------- */

.doc-page { flex: 1; overflow-y: auto; background: var(--c-bg); }
.doc-content { max-width: 1080px; margin: 0 auto; padding: 32px 28px 80px; }
/* Solution Overview's diagram benefits from the full page width (so a
   typical management group / subscription tree fits without needing to
   scroll) rather than the standard 1080px reading width every other doc
   page uses for forms and tables. */
.doc-content.doc-content-wide { max-width: none; }
/* Networking's tables (VNets/Subnets, NSGs, ASGs, Route Tables) needed more
   than the standard 1080px reading width to fit their columns without
   truncating — but doc-content-wide's fully unbounded width stretched them
   edge-to-edge on a wide monitor, spacing narrow columns (like the CIDR
   mask picker) far apart from their neighbors instead of sitting close
   together. This caps it at a fixed, comfortable width instead: enough
   room for every column, without the table stretching to fill whatever
   the viewport happens to be. */
.doc-content.doc-content-networking { max-width: 1440px; }
/* Solution Overview: the diagram's card hugs the actual rendered chart
   width instead of always spanning the full page, growing as management
   groups/subscriptions are added. Once the chart's natural width exceeds
   the available page width, .org-chart-scroll's own horizontal scroll
   (defined below) takes over rather than the card overflowing. */
.overview-diagram-section { width: fit-content; max-width: 100%; }
.overview-diagram-section .org-chart-scroll { width: fit-content; max-width: 100%; }
.overview-diagram-section .org-chart, .overview-diagram-section .org-chart-wrap { min-width: 0; }
/* Requirements page: the MoSCoW legend is reference text, not a data table —
   let it sit at a comfortable reading width instead of stretching the full
   page like the Functional/Non-Functional tables below it, and center it
   over them. Each definition row is forced to a shared min-height so the
   four priority rows line up evenly regardless of how many lines their
   definition text wraps to. */
.doc-page .naming-section.moscow-legend { max-width: 900px; margin-left: auto; margin-right: auto; }
.moscow-legend .naming-table td:first-child { height: 64px; }

.doc-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; margin-bottom: 28px; }
.doc-header-text h1 { font-size: 24px; font-weight: 600; margin: 0 0 6px; }
.doc-header-text p { font-size: 13.5px; color: var(--c-text-secondary); margin: 0; max-width: 640px; line-height: 1.5; }

/* In-page sub-navigation for long doc pages that combine several topics
   under one sidebar entry (currently just Networking: VNets/Subnets, NSGs,
   ASGs, Route Tables). Sticks to the top of .doc-page's own scroll area
   (not the window) as the page scrolls, so the jump links stay reachable;
   .doc-subsection below gets matching scroll-margin-top so an anchor jump
   (or clicking a link) doesn't tuck the section's heading behind this bar. */
.doc-subnav {
  position: sticky; top: 0; z-index: 5; display: flex; flex-wrap: wrap; gap: 6px;
  background: var(--c-bg); padding: 10px 0 14px; margin-bottom: 6px;
  border-bottom: 1px solid var(--c-border);
}
.doc-subnav-item {
  font-size: 12.5px; font-weight: 600; color: var(--c-text-secondary); text-decoration: none;
  padding: 6px 12px; border-radius: 999px; border: 1px solid transparent; white-space: nowrap;
}
.doc-subnav-item:hover { background: var(--c-surface); border-color: var(--c-border); color: var(--c-text-primary); }
.doc-subnav-item.active { background: var(--c-primary-lighter); color: var(--c-primary-dark); }
.doc-subsection { scroll-margin-top: 56px; }

/* Networking's VNets/Subnets section: one link per region (sourced from the
   Enterprise Landing Zone page) that switches which single region's VNet
   and Subnet tables are showing below — not sticky like .doc-subnav above
   (this is a switcher within one sub-section, not a jump-nav across the
   whole page), and visually smaller/secondary since it's one level nested. */
.region-subnav { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.region-subnav-item {
  font-size: 12px; font-weight: 600; color: var(--c-text-secondary); text-decoration: none;
  padding: 5px 12px; border-radius: 999px; border: 1px solid var(--c-border); white-space: nowrap; background: var(--c-surface);
}
.region-subnav-item:hover { border-color: var(--c-border-strong); color: var(--c-text-primary); }
.region-subnav-item.active { background: var(--c-primary); border-color: var(--c-primary); color: #fff; }
.doc-page .naming-section {
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-lg);
  padding: 20px 22px; margin-bottom: 20px;
}
.doc-page .naming-table th { padding-bottom: 8px; }
.doc-page .naming-table td { padding-bottom: 10px; }
.doc-page .naming-table tr + tr td { padding-top: 10px; }

.region-row {
  display: grid; grid-template-columns: 160px 1fr 32px; align-items: end; gap: 14px;
  padding: 10px 0; border-bottom: 1px solid var(--c-border);
}
.region-row:first-child { padding-top: 0; }
.region-row .region-row-name { font-size: 13px; font-weight: 600; padding-bottom: 9px; }
.region-row .field { margin-bottom: 0; }
.region-row .row-delete { background: none; border: none; color: var(--c-danger); cursor: pointer; padding: 6px; border-radius: var(--radius); margin-bottom: 1px; }
.region-row .row-delete:hover { background: #FDF3F4; }

/* Groups Regions under the Subscription they're actually nested inside on
   the Canvas (see ancestorSubscriptionNode/renderCanvasTopology in
   overview.js) — a left accent bar in the same gold used for "Subscription"
   in the org-chart legend above, so it's visually obvious this is a
   Subscription-level grouping and not just another region. Regions laid
   side by side within it, same as the flat layout before grouping existed,
   so a Subscription with several Regions still reads left to right. */
.topology-subscription { margin-bottom: 26px; padding-left: 14px; border-left: 3px solid #FFB900; }
.topology-subscription-title { font-size: 13.5px; font-weight: 700; margin: 0 0 10px; color: var(--c-text); }
.topology-subscription-regions { display: flex; gap: 22px; flex-wrap: wrap; align-items: flex-start; }
.topology-subscription-regions .topology-region { margin-bottom: 0; }

.topology-region { margin-bottom: 18px; }
.topology-region h4 { font-size: 12.5px; font-weight: 700; margin: 0 0 4px; color: var(--c-text-secondary); }
/* Unlike the base .org-chart-scroll (below), which scrolls internally
   rather than growing the page, the Topology diagram grows with its own
   content instead — its regions/VNets/Subnets already stretch the page
   width without limit (doc-content-wide on overview.html), so the browser's
   own page scroll takes over rather than a second, nested scrollport. This
   also fixes the Subnet NSG/Route Table hover popover getting clipped: a
   scrolling ancestor computes overflow-y:auto too (not just the overflow-x
   that's actually set), which clipped the popover whenever it neared this
   container's edge. */
.topology-region .org-chart-scroll { padding: 10px 10px 20px; border: 1px solid var(--c-border); border-radius: var(--radius); background: var(--c-bg); overflow: visible; }
.topology-clusters { display: flex; gap: 16px; flex-wrap: wrap; }
.topology-clusters .org-chart-scroll { flex: 0 0 auto; }

/* ---------- Shared pure-CSS org-chart tree ---------- */

.org-chart-scroll { overflow-x: auto; padding: 24px 10px 34px; }
.org-chart, .org-chart ul, .org-chart li { margin: 0; padding: 0; list-style: none; }
.org-chart { display: inline-flex; justify-content: center; min-width: 100%; }
/* Management Groups & Subscriptions diagram: subscriptions are pulled out
   of the tree and rendered as a row underneath, but each one is explicitly
   positioned (via JS, in common.js's positionOrgChartSubRow) directly
   under its real parent management group box and reconnected to it with a
   straight line — so the two tiers stay visually separated, and each
   subscription still lines up with its own MG, no matter how deep that
   MG sits in the hierarchy. */
.org-chart-wrap { position: relative; display: flex; flex-direction: column; align-items: center; min-width: 100%; }
.org-chart-sub-row {
  position: relative; align-self: stretch; min-height: 62px; margin-top: 56px; z-index: 1;
}
.org-chart-sub-row .org-box { position: absolute; top: 0; }
.org-chart-connectors { position: absolute; top: 0; left: 0; pointer-events: none; z-index: 0; }
.org-chart ul { display: flex; padding-top: 26px; position: relative; }
.org-chart li { display: flex; flex-direction: column; align-items: center; position: relative; padding: 26px 12px 0; }
/* The "trunk" line: connects a parent box's bottom edge down to the shared
   horizontal bar that distributes to its children (drawn by li::before/
   ::after below, which start only at the BOTTOM of this same 26px gap).
   Without this, every parent box floats above its children's connector
   with a visible, disconnected gap — this closes it. Targets any <ul> that
   is itself inside an <li> (i.e. every "children of X" list except the
   outermost one, which has nothing above it to connect to). */
.org-chart li > ul::before {
  content: ""; position: absolute; top: 0; left: 50%; width: 0; height: 26px;
  border-left: 2px solid var(--c-border-strong); z-index: 0;
}
.org-chart li::before, .org-chart li::after {
  content: ""; position: absolute; top: 0; width: 50%; height: 26px; border-top: 2px solid var(--c-border-strong);
}
.org-chart li::before { right: 50%; }
.org-chart li::after { left: 50%; border-left: 2px solid var(--c-border-strong); }
.org-chart li:first-child::before { border-color: transparent; }
.org-chart li:last-child::after { border-color: transparent; }
.org-chart li:last-child::before { border-right: 2px solid var(--c-border-strong); }
/* A box with a single child doesn't need the sibling-joining horizontal
   segments — just a plain vertical line straight down into its child, so
   the two boxes are actually connected instead of floating with a gap
   (this previously zeroed out the padding AND hid both pseudo-elements,
   leaving no line and no room to draw one). Declared after the first/
   last-child rules above so it wins the cascade — an only-child matches
   :first-child AND :last-child too, and their `border-color: transparent`
   would otherwise make this line invisible despite it being present. */
.org-chart li:only-child::before { content: none; }
.org-chart li:only-child::after { left: 50%; width: 0; border-top: none; border-left-color: var(--c-border-strong); }
.org-chart > ul > li { padding-top: 0; }
/* The outermost (tenant root) box has nothing above it to connect to. It's
   always an only-child itself, so this must win over the :only-child rule
   above — hence !important. */
.org-chart > ul > li::before, .org-chart > ul > li::after { display: none !important; }

.org-box {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border: 1.5px solid var(--c-border-strong); border-radius: 8px; padding: 10px 14px;
  background: var(--c-surface); box-shadow: var(--shadow-2); position: relative; z-index: 1;
  /* Fixed footprint for every box (root, management group, subscription,
     hub, spoke alike) so the whole diagram reads as a uniform grid instead
     of boxes sized to whatever their label happens to be. Longer labels
     wrap onto a second line rather than growing the box. */
  width: 176px; height: 68px; text-align: center; white-space: normal; overflow: hidden;
}
.org-box-label { justify-content: center; text-align: center; }
.org-box-label { font-size: 12.5px; font-weight: 700; display: flex; align-items: center; }
.org-box-label::before { content: ""; display: inline-block; width: 8px; height: 8px; border-radius: 2px; background: var(--c-border-strong); margin-right: 7px; flex-shrink: 0; }
.org-box-code { font-size: 10.5px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--c-text-tertiary); }
/* Names the real connector (relationship) a box is joined to its parent by
   — e.g. "VNet Peering" in that connector's own color — so the Topology
   section's tree lines aren't just an anonymous gray connector; you can see
   at a glance what actually links each resource to the one above it. */
.org-box-conn { display: flex; align-items: center; gap: 4px; font-size: 9.5px; font-weight: 600; }
.org-box-conn-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
/* Topology boxes get one extra line for org-box-conn, so they need a touch
   more height than the standard 68px — fixed (not min-height/auto), same
   reasoning as .org-box itself, so every box in this diagram stays uniform
   rather than the hub (no connLabel) sizing differently from its spokes. */
.topology-clusters .org-box { height: 84px; }
.org-box.kind-root { background: #F3F2F1; }
.org-box.kind-root .org-box-label::before { background: #201F1E; }
.org-box.kind-mg { background: #243A5E; border-color: #1B2C47; }
.org-box.kind-mg .org-box-label { color: #FFFFFF; }
.org-box.kind-mg .org-box-code { color: rgba(255,255,255,.75); }
.org-box.kind-sub { background: #FFB900; border-color: #D29200; }
.org-box.kind-sub .org-box-label { color: #201F1E; }
.org-box.kind-sub .org-box-code { color: rgba(32,31,30,.65); }
/* Management group / Subscription boxes are already color-coded by their
   own fill (dark blue vs. yellow), matching the legend below the diagram —
   so the little inline swatch square (org-box-label::before) would just be
   a redundant color chip repeating information the box itself and the
   legend already convey. Hidden only for these two kinds; root/hub/spoke
   boxes elsewhere (e.g. the Topology diagram) keep their swatch since those
   aren't solid-filled the same way. */
.org-box.kind-mg .org-box-label::before,
.org-box.kind-sub .org-box-label::before { display: none; }
.org-box.kind-hub { background: #F9F5FF; border-color: #E1D3F5; }
.org-box.kind-spoke { background: #EFFBFB; border-color: #C6ECEC; }
/* Hub/Spoke VNet boxes are already color-coded by their own fill (light
   purple vs. light teal), matching the Topology legend below the diagram —
   the little inline swatch square/dot (org-box-label::before) is redundant
   next to that, and next to the Subnet legend's own dot now that Subnets
   show inside the box (below). */
.org-box.kind-hub .org-box-label::before,
.org-box.kind-spoke .org-box-label::before { display: none; }
.org-box.auto-added { border-style: dashed; }
/* A VNet box that has its own Subnets listed inside it (org-box-subnets,
   below) grows to fit them instead of staying pinned to the diagram's
   normal fixed footprint — overflow:visible so the NSG/Route Table hover
   popover isn't clipped by the box's own edge. */
.org-box.has-extra {
  width: auto; min-width: 176px; max-width: 230px; height: auto; min-height: 68px;
  overflow: visible; padding-bottom: 8px;
}
/* Every .org-box already has its own z-index (see .org-box's base rule
   above), which makes it a stacking context of its own — so a Subnet's
   hover popover, even with its own high z-index, can never paint above a
   SIBLING VNet box that happens to sit later in the DOM (they're compared
   as whole stacking contexts, not element-by-element), and gets visually
   cut off wherever a neighboring box overlaps it. Raising the whole box's
   own z-index while it (or anything inside it, e.g. the badge) is hovered/
   focused lifts the popover above every sibling box at once. */
.org-box.has-extra:hover,
.org-box.has-extra:focus-within { z-index: 100; }
.org-box-subnets { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--c-border); width: 100%; text-align: left; }
.org-box-subnet-row { position: relative; display: flex; align-items: center; gap: 5px; padding: 2px 20px 2px 2px; font-size: 10.5px; }
.org-box-subnet-row + .org-box-subnet-row { margin-top: 2px; }
.org-box-subnet-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--c-primary); flex-shrink: 0; }
.org-box-subnet-name { color: var(--c-text); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.org-box-subnet-row > .subnet-badges { position: absolute; top: 1px; right: 0; }
.org-box-subnet-row .subnet-badge { width: 16px; height: 16px; }
.org-box-subnet-row .subnet-badge svg, .org-box-subnet-row .subnet-badge-icon { width: 10px; height: 10px; }
.org-box-subnet-row .subnet-badge-popover { top: 20px; }

/* Subnet's read-only NSG/Route Table hover badge — shared by the Canvas
   (builder.js's renderNode, positioned via .node > .subnet-badges above)
   and Solution Overview's Topology diagram (positioned via
   .org-box-subnet-row > .subnet-badges above, one per Subnet row). */
.subnet-badges { display: flex; gap: 4px; }
.subnet-badge {
  width: 22px; height: 22px; border-radius: 50%; background: var(--c-surface);
  border: 1.5px solid var(--c-border-strong); display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-2); position: relative; cursor: default;
}
.subnet-badge svg, .subnet-badge-icon { width: 13px; height: 13px; object-fit: contain; }
.subnet-badge-nsg { color: #038387; border-color: #038387; }
.subnet-badge-rt { color: #8764B8; border-color: #8764B8; }
/* Read-only hover popover — pure CSS reveal, no click/edit affordance
   anywhere inside it (matches the user's "not editable, just readonly"
   ask). :focus-within lets keyboard users (Tab to the badge) see it too,
   not just mouse hover. */
.subnet-badge-popover {
  display: none; position: absolute; top: 26px; right: 0; z-index: 50;
  width: 260px; max-height: 320px; overflow-y: auto;
  background: var(--c-surface); border: 1px solid var(--c-border-strong); border-radius: var(--radius);
  box-shadow: var(--shadow-8); padding: 10px 12px; text-align: left; white-space: normal;
  font-size: 11px; line-height: 1.5; cursor: default;
}
.subnet-badge:hover .subnet-badge-popover,
.subnet-badge:focus .subnet-badge-popover,
.subnet-badge:focus-within .subnet-badge-popover { display: block; }
.subnet-badge-popover-title { font-weight: 700; font-size: 11.5px; margin-bottom: 6px; color: var(--c-text); }
.subnet-badge-section + .subnet-badge-section { margin-top: 8px; }
.subnet-badge-section-title { font-size: 9.5px; text-transform: uppercase; letter-spacing: .3px; color: var(--c-text-tertiary); font-weight: 700; margin-bottom: 3px; }
.subnet-badge-empty { color: var(--c-text-tertiary); font-style: italic; }
.subnet-badge-rule { display: flex; justify-content: space-between; align-items: center; gap: 6px; margin-top: 4px; }
.subnet-badge-rule-name { font-weight: 600; color: var(--c-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.subnet-badge-rule-action { font-size: 9.5px; font-weight: 700; text-transform: uppercase; flex-shrink: 0; padding: 1px 5px; border-radius: 3px; }
.subnet-badge-rule-action.action-allow { color: var(--c-success); background: rgba(16,124,16,.1); }
.subnet-badge-rule-action.action-deny { color: var(--c-danger); background: rgba(209,52,56,.1); }
.subnet-badge-rule-detail { color: var(--c-text-tertiary); font-size: 10px; margin-top: 1px; }

.org-chart-legend { display: flex; gap: 22px; align-items: center; padding: 0 4px; flex-wrap: wrap; }
.org-chart-legend-item { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--c-text-secondary); }
.org-chart-legend-swatch { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }


/* ---------- Naming Convention drawer ---------- */

.drawer-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.25);
  opacity: 0; pointer-events: none; transition: opacity .18s ease; z-index: 190;
}
.drawer-overlay.open { opacity: 1; pointer-events: auto; }

.naming-drawer, .side-drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: 520px; max-width: 92vw;
  background: var(--c-surface); box-shadow: var(--shadow-16);
  transform: translateX(100%); transition: transform .2s ease;
  z-index: 200; display: flex; flex-direction: column;
}
.naming-drawer.open, .side-drawer.open { transform: translateX(0); }
.naming-drawer-header, .side-drawer-header {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  padding: 18px 20px; border-bottom: 1px solid var(--c-border);
}
.naming-drawer-header h2, .side-drawer-header h2 { font-size: 16px; font-weight: 600; margin: 0; }
.naming-drawer-body, .side-drawer-body { flex: 1; overflow-y: auto; padding: 20px; }

/* Grab handle for every slide-in drawer — a real, generously-sized button
   straddling the drawer's own left edge (assets/common.js's
   initDrawerResize appends one to any drawer as soon as it appears, so
   this works uniformly for every drawer regardless of which file created
   it, with no markup changes needed at each drawer's own creation site). */
.drawer-resize-handle {
  position: absolute; top: 50%; left: -10px; transform: translateY(-50%);
  width: 20px; height: 56px; border-radius: 8px;
  background: var(--c-surface); border: 1px solid var(--c-border-strong);
  box-shadow: var(--shadow-2);
  display: flex; align-items: center; justify-content: center;
  color: var(--c-text-secondary); cursor: ew-resize; z-index: 5;
}
.drawer-resize-handle svg { width: 8px; height: 24px; pointer-events: none; }
.drawer-resize-handle:hover,
.drawer-resize-handle.drawer-resize-active {
  background: var(--c-primary); border-color: var(--c-primary); color: #fff;
}
body.drawer-resizing { cursor: ew-resize !important; user-select: none; }
body.drawer-resizing iframe { pointer-events: none; }

/* ---------- Section drawer (Business Objectives / Foundation pages,
   pop out from the right like Naming Convention, over Solution Overview) --- */

.side-drawer.section-drawer { width: 920px; max-width: 96vw; }
.section-drawer-header-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.section-drawer-header-actions .btn { white-space: nowrap; }
.section-drawer-body.side-drawer-body { padding: 0; overflow: hidden; }
.section-drawer-iframe { display: block; width: 100%; height: 100%; border: 0; background: var(--c-bg); }

/* A page rendered inside the section drawer's iframe (?embed=1): hide its
   own topbar + sidebar, since the drawer chrome already supplies a title
   and close button — only the page's own content area should show. */
html.embed-mode .app-topbar,
html.embed-mode .app-sidebar {
  display: none;
}
html.embed-mode .app-body { display: block; height: 100vh; }
html.embed-mode .doc-page { height: 100vh; }
html.embed-mode .doc-content,
html.embed-mode .doc-content.doc-content-wide {
  max-width: none; padding: 22px 26px 60px;
}

.naming-stats {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 24px;
}
.naming-stat {
  background: var(--c-bg); border: 1px solid var(--c-border); border-radius: var(--radius);
  padding: 12px; text-align: center;
}
.naming-stat-value { font-size: 20px; font-weight: 700; color: var(--c-primary); }
.naming-stat-label { font-size: 10.5px; color: var(--c-text-tertiary); text-transform: uppercase; letter-spacing: .3px; margin-top: 2px; }

.naming-section { margin-bottom: 30px; }
.naming-section:last-child { margin-bottom: 6px; }
.naming-section h3 { font-size: 13.5px; font-weight: 700; margin: 0 0 6px; }
/* Networking's VNets/Subnets sections: heading and "+ Add" button share one
   row, button pinned to the top right, instead of the button sitting below
   the table like every other bespoke table's add button. */
.naming-section-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
.naming-section-header h3 { margin: 0; }
.naming-hint { font-size: 11.5px; color: var(--c-text-tertiary); line-height: 1.5; margin: 0 0 12px; }
.naming-section-header-row { display: flex; align-items: center; justify-content: space-between; }
.naming-section-header-row h3 { margin: 0; }

.pattern-preview {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px;
  background: var(--c-bg); border: 1px solid var(--c-border); border-radius: var(--radius);
  padding: 9px 12px; margin-bottom: 14px; color: var(--c-text); word-break: break-all;
}
.pattern-row-label { font-size: 10.5px; font-weight: 700; color: var(--c-text-tertiary); text-transform: uppercase; letter-spacing: .4px; margin: 0 0 6px; }
.pattern-tiles { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; min-height: 30px; }
.pattern-tile {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border-radius: 14px;
  font-size: 11.5px; font-weight: 600; cursor: pointer; border: 1px solid transparent; user-select: none;
}
.pattern-tile.in-pattern { background: var(--c-primary); color: #fff; cursor: grab; transition: opacity .12s ease, outline-color .12s ease; outline: 2px solid transparent; outline-offset: 2px; }
.pattern-tile.in-pattern:hover { background: var(--c-primary-dark); }
.pattern-tile.in-pattern.dragging { opacity: .4; cursor: grabbing; }
.pattern-tile.in-pattern.drag-over { outline-color: var(--c-primary-dark); }
.pattern-tile.available-tile { background: var(--c-primary-lighter); color: var(--c-primary-dark); border-color: var(--c-primary-light); }
.pattern-tile.available-tile:hover { background: var(--c-primary-light); }
.pattern-tile.literal { background: var(--c-bg); color: var(--c-text-secondary); border-color: var(--c-border-strong); }
.pattern-tile .tile-index { opacity: .7; font-weight: 700; font-size: 10px; }
.tile-delete {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; margin-left: 2px; padding: 0; border: none; border-radius: 50%;
  background: rgba(255,255,255,.25); color: inherit; font-size: 12px; line-height: 1; cursor: pointer;
}
.pattern-tile.available-tile .tile-delete { background: rgba(0,0,0,.08); }
.tile-delete:hover { background: var(--c-danger); color: #fff; }

.delimiter-field { margin-top: 4px; }
.delimiter-options { display: flex; gap: 14px; flex-wrap: wrap; }
.delimiter-options label { display: flex; align-items: center; gap: 5px; font-size: 12.5px; font-weight: 500; color: var(--c-text); cursor: pointer; }

.backend-options { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.backend-option {
  flex: 1; min-width: 120px; display: flex; align-items: center; gap: 7px; padding: 9px 12px;
  border: 1px solid var(--c-border-strong); border-radius: var(--radius); font-size: 12.5px; font-weight: 600;
  color: var(--c-text-secondary); cursor: pointer; background: var(--c-surface);
}
.backend-option input { margin: 0; }
.backend-option.active { border-color: var(--c-primary); background: var(--c-primary-lighter); color: var(--c-primary); }
.connection-status { font-size: 12px; margin-top: 10px; display: flex; align-items: center; gap: 6px; }
.connection-status.pending { color: var(--c-text-tertiary); }
.connection-status.success { color: var(--c-success); }
.connection-status.error { color: var(--c-danger); }

.naming-table { width: 100%; border-collapse: collapse; font-size: 12.5px; margin-bottom: 10px; }
.naming-table th {
  text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .3px;
  color: var(--c-text-tertiary); padding: 0 8px 6px; font-weight: 700;
}
.naming-table td { padding: 4px 8px 4px 0; vertical-align: middle; }
.naming-table tr + tr td { border-top: 1px solid var(--c-border); padding-top: 8px; }
.naming-table tr td { padding-bottom: 8px; }
.naming-table input, .naming-table select, .naming-table textarea {
  width: 100%; padding: 6px 8px; font-size: 12.5px; border: 1px solid var(--c-border-strong);
  border-radius: var(--radius); background: var(--c-surface); color: var(--c-text);
  box-sizing: border-box; font-family: inherit;
}
.naming-table textarea { resize: vertical; }
/* NSG rule Source/Destination Value cell when Source/Destination is "Any" —
   greyed out and non-interactive rather than an editable box implying a
   value is expected. */
.naming-table input:disabled { background: var(--c-bg); color: var(--c-text-tertiary); cursor: not-allowed; }
.naming-table .row-delete {
  background: none; border: none; color: var(--c-danger); cursor: pointer; padding: 4px; border-radius: var(--radius);
}
.naming-table .row-delete:hover { background: #FDF3F4; }
.naming-table code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; background: var(--c-bg); padding: 2px 5px; border-radius: 3px; cursor: pointer; }
.naming-table code:hover { background: var(--c-primary-lighter); color: var(--c-primary-dark); }

/* Resource Groups table: no row-separator line, tighter row spacing — this
   table can grow to a lot of rows (every generated "Resource group" name
   auto-adds one), so a clean, dense look matters more here than on the
   other naming-table-based pages. */
#rgTable tr + tr td { border-top: none; padding-top: 4px; }
#rgTable td { padding-bottom: 4px; }

/* Networking page: expandable per-NSG rule editor / per-Route-Table route
   editor (a full-width <tr><td colspan> under the row, toggled by the
   "N rules ▸" / "N routes ▸" button). Tinted background + tighter table so
   it reads as a nested detail panel rather than another top-level section. */
.rule-panel { background: var(--c-bg); border: 1px solid var(--c-border); border-radius: var(--radius); padding: 14px 16px; margin: 4px 0; }
.rule-block + .rule-block { margin-top: 16px; }
.rule-block h4 { font-size: 12.5px; font-weight: 700; margin: 0 0 8px; color: var(--c-text-secondary); }
.rule-table { font-size: 11.5px; }
.rule-table th { font-size: 9.5px; padding-bottom: 4px; }
.rule-table td { padding: 3px 6px 3px 0; }
.rule-table input, .rule-table select { padding: 4px 6px; font-size: 11.5px; }
.rule-table input[type="number"] { min-width: 54px; }
/* Azure's built-in default rules (AllowVNetInBound, DenyAllOutBound, etc.)
   always show below any custom rules — read-only (plain text cells, no
   inputs, no delete button) and visually muted so it's clear at a glance
   which rules are actually editable. */
.rule-table tr.rule-row-default { color: var(--c-text-tertiary); font-style: italic; }
.rule-table tr.rule-row-default td { padding: 5px 6px 5px 0; }

.naming-search {
  width: 100%; padding: 8px 10px; font-size: 12.5px; border: 1px solid var(--c-border-strong);
  border-radius: var(--radius); margin-bottom: 8px; background: var(--c-surface);
}
.resource-type-list {
  max-height: 220px; overflow-y: auto; border: 1px solid var(--c-border); border-radius: var(--radius);
  padding: 6px 4px; margin-bottom: 14px; background: var(--c-bg);
}
.resource-type-group-label {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .3px;
  color: var(--c-text-tertiary); padding: 6px 8px 4px;
}
.resource-type-row {
  display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: var(--radius);
  font-size: 12.5px; cursor: pointer;
}
.resource-type-row:hover { background: var(--c-primary-lighter); }
.resource-type-row input { margin: 0; }
.resource-type-row .rt-abbr { margin-left: auto; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; color: var(--c-text-tertiary); }

.quick-generate-overrides { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 4px; }

.region-add-row { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.region-add-row .field { flex: 0 1 320px; }
.add-region-btn,
.add-row-btn-icon {
  width: 36px; height: 36px; flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  background: transparent; border: none; border-radius: 50%;
  color: var(--c-success); cursor: pointer; padding: 0;
}
.add-region-btn:hover,
.add-row-btn-icon:hover { background: rgba(16,124,16,.12); }
.add-region-btn svg,
.add-row-btn-icon svg { width: 24px; height: 24px; }

.naming-empty { font-size: 12px; color: var(--c-text-tertiary); text-align: center; padding: 14px; }
.log-name-cell { display: flex; align-items: center; gap: 6px; }
.log-time { font-size: 11px; color: var(--c-text-tertiary); white-space: nowrap; }

@media (max-width: 900px) {
  .palette { width: 210px; }
  .detail-panel.open { width: 280px; }
  .detail-panel-inner { width: 280px; }
}

/* ================= MY JOURNEY (storyboard) ================= */
.journey-blocked-notice {
  position: fixed; top: 0; left: 0; right: 0; z-index: 500;
  background: #FFF4E5; color: #8A5300; border-bottom: 1px solid #F5A623;
  text-align: center; font-size: 12.5px; font-weight: 600; padding: 8px 16px;
}
.journey-wrap {
  flex: 1; display: flex; align-items: flex-start; justify-content: center;
  overflow-y: auto; padding: 48px 24px;
}
.journey-card {
  width: 100%; max-width: 720px; background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-4); padding: 36px 40px 28px;
  display: flex; flex-direction: column; min-height: 420px;
}
.journey-progress-label { font-size: 11.5px; font-weight: 600; color: var(--c-text-tertiary); text-transform: uppercase; letter-spacing: .4px; margin-bottom: 8px; }
.journey-progress-track { height: 4px; background: var(--c-bg); border-radius: 999px; overflow: hidden; margin-bottom: 28px; }
.journey-progress-fill { height: 100%; background: var(--c-primary); border-radius: 999px; transition: width .2s ease; }
.journey-stage { flex: 1; }
.journey-icon { font-size: 40px; line-height: 1; margin-bottom: 14px; }
.journey-stage h1 { font-size: 24px; font-weight: 600; margin: 0 0 14px; letter-spacing: -.2px; }
.journey-stage h2 { font-size: 19px; font-weight: 600; margin: 0 0 10px; letter-spacing: -.1px; }
.journey-eyebrow { font-size: 11.5px; font-weight: 700; color: var(--c-primary); text-transform: uppercase; letter-spacing: .5px; margin-bottom: 8px; }
.journey-lead { font-size: 14px; color: var(--c-text-secondary); line-height: 1.6; margin: 0 0 10px; }
.journey-lead-sub { color: var(--c-text-tertiary); font-size: 12.5px; }
.journey-hint { font-size: 12.5px; color: var(--c-text-tertiary); line-height: 1.55; margin: 0 0 18px; }
.journey-hint code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; background: var(--c-bg); padding: 1px 4px; border-radius: 4px; }
.journey-input {
  width: 100%; padding: 10px 12px; font-size: 15px; border: 1px solid var(--c-border-strong);
  border-radius: var(--radius); background: var(--c-surface); color: var(--c-text);
}
.journey-input:focus { outline: none; border-color: var(--c-primary); box-shadow: 0 0 0 1px var(--c-primary); }

.journey-choices { display: flex; flex-direction: column; gap: 10px; }
.journey-choice {
  display: flex; align-items: flex-start; gap: 10px; padding: 14px 16px; border: 1px solid var(--c-border);
  border-radius: var(--radius); cursor: pointer; transition: border-color .12s ease, background .12s ease;
}
.journey-choice:hover { border-color: var(--c-primary); background: var(--c-primary-lighter); }
.journey-choice.selected { border-color: var(--c-primary); background: var(--c-primary-lighter); box-shadow: 0 0 0 1px var(--c-primary); }
.journey-choice input { margin-top: 2px; flex-shrink: 0; }
.journey-choice-title { font-size: 13.5px; font-weight: 600; }
.journey-choice-desc { font-size: 12px; color: var(--c-text-tertiary); margin-top: 3px; line-height: 1.5; }
.journey-choice-check { align-items: center; padding: 11px 16px; }
.journey-choice-check .journey-choice-title { font-weight: 500; }

.journey-review-list { border: 1px solid var(--c-border); border-radius: var(--radius); overflow: hidden; margin-bottom: 14px; }
.journey-review-row { display: flex; gap: 14px; padding: 12px 16px; border-bottom: 1px solid var(--c-border); font-size: 13px; }
.journey-review-row:last-child { border-bottom: none; }
.journey-review-row:nth-child(odd) { background: var(--c-bg); }
.journey-review-label { flex: 0 0 130px; font-weight: 600; color: var(--c-text-secondary); }
.journey-review-value { color: var(--c-text); }
.journey-already { color: var(--c-primary-dark); background: var(--c-primary-lighter); padding: 10px 12px; border-radius: var(--radius); }

.journey-applied { margin-top: 18px; padding: 16px; border: 1px solid var(--c-success); background: #F1FAF1; border-radius: var(--radius); }
.journey-applied-title { font-size: 14px; font-weight: 700; color: var(--c-success); margin-bottom: 8px; }
.journey-applied-list { margin: 0 0 14px; padding-left: 18px; font-size: 12.5px; color: var(--c-text-secondary); line-height: 1.7; }
.journey-applied-links { display: flex; flex-wrap: wrap; gap: 8px; }

.journey-actions { display: flex; align-items: center; gap: 10px; margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--c-border); }
.journey-actions-spacer { flex: 1; }

.journey-stage .field textarea {
  width: 100%; padding: 8px 10px; font-size: 13.5px; border: 1px solid var(--c-border-strong);
  border-radius: var(--radius); background: var(--c-surface); color: var(--c-text); resize: vertical;
  font-family: inherit;
}
.journey-stage .field textarea:focus { outline: none; border-color: var(--c-primary); box-shadow: 0 0 0 1px var(--c-primary); }
.journey-preview-chart { border: 1px solid var(--c-border); border-radius: var(--radius); background: var(--c-bg); margin-bottom: 10px; }
.journey-legend-new { background: var(--c-surface); border: 1.5px dashed var(--c-text-tertiary); }
