@import '_content/Z.Blazor.Diagrams/Z.Blazor.Diagrams.ezdqu7jd9f.bundle.scp.css';

/* /Components/CommandPalette.razor.rz.scp.css */
/* ⌘K command palette (proposal 25) — design-system tokens only, IBM Plex Mono for data. */

.cp-backdrop[b-gpavlty1ib] {
    position: fixed;
    inset: 0;
    z-index: 900;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 14vh;
    background: rgba(0, 0, 0, .45);
}

.cp-ov[b-gpavlty1ib] {
    width: min(560px, 92vw);
    border: 1px solid var(--border3);
    border-radius: 10px;
    background: var(--surf1);
    overflow: hidden;
    box-shadow: 0 8px 30px rgba(0, 0, 0, .35);
}

.cp-search[b-gpavlty1ib] {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
}

.cp-search svg[b-gpavlty1ib] {
    width: 14px;
    height: 14px;
    color: var(--fg-faint);
    flex: none;
}

.cp-search input[b-gpavlty1ib] {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: var(--fg);
    font-family: var(--mono);
    font-size: 12.5px;
}

.cp-search input[b-gpavlty1ib]::placeholder { color: var(--fg-faint); }

.cp-search .esc[b-gpavlty1ib] {
    font-family: var(--mono);
    font-size: 9px;
    color: var(--fg-faint);
    padding: 2px 6px;
    border: 1px solid var(--border);
    border-radius: 4px;
    cursor: pointer;
}

.cp-list[b-gpavlty1ib] {
    max-height: 260px;
    overflow: auto;
}

.cp-empty[b-gpavlty1ib] {
    padding: 18px 14px;
    font-family: var(--mono);
    font-size: 11px;
    color: var(--fg-faint);
}

.cp-row[b-gpavlty1ib] {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 14px;
    cursor: pointer;
    border-bottom: 1px solid var(--border);
}

.cp-row:last-child[b-gpavlty1ib] { border-bottom: none; }
.cp-row:hover[b-gpavlty1ib],
.cp-row.sel[b-gpavlty1ib] { background: var(--hover); }
.cp-row.sel[b-gpavlty1ib] { box-shadow: inset 2px 0 0 var(--fg2); }

.cp-row .dot[b-gpavlty1ib] {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: none;
}

.cp-row .dot.up[b-gpavlty1ib] { background: var(--green); }
.cp-row .dot.slow[b-gpavlty1ib] { background: var(--yellow); }
.cp-row .dot.down[b-gpavlty1ib] { background: var(--red); }
.cp-row .dot.na[b-gpavlty1ib] { background: var(--fg-faint); }

.cp-row .n[b-gpavlty1ib] {
    font-family: var(--mono);
    font-size: 11.5px;
    color: var(--fg2);
}

.cp-row .kind[b-gpavlty1ib] {
    font-family: var(--mono);
    font-size: 9px;
    color: var(--fg-faint);
    padding: 1px 6px;
    border: 1px solid var(--border);
    border-radius: 4px;
}

.cp-row .u[b-gpavlty1ib] {
    margin-left: auto;
    font-family: var(--mono);
    font-size: 9.5px;
    color: var(--fg-faint);
}

.cp-acts[b-gpavlty1ib] {
    display: flex;
    gap: 7px;
    flex-wrap: wrap;
    padding: 11px 14px;
    border-top: 1px solid var(--border3);
    background: var(--surf0);
    align-items: center;
}

.cp-acts .lbl[b-gpavlty1ib] {
    font-family: var(--mono);
    font-size: 9.5px;
    color: var(--fg-faint);
    margin-right: 2px;
}

.cp-act[b-gpavlty1ib] {
    font-family: var(--mono);
    font-size: 10.5px;
    padding: 5px 11px;
    border: 1px solid var(--border);
    background: var(--panel);
    color: var(--fg2);
    border-radius: 5px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 5px;
}

.cp-act:hover[b-gpavlty1ib] { background: var(--hover); border-color: var(--border3); }
.cp-act.danger:hover[b-gpavlty1ib] { border-color: var(--red); color: var(--red); }

.cp-act:disabled[b-gpavlty1ib] {
    opacity: .45;
    cursor: not-allowed;
}

.cp-act:disabled:hover[b-gpavlty1ib] {
    background: var(--panel);
    border-color: var(--border);
    color: var(--fg2);
}

.cp-act .adm[b-gpavlty1ib] {
    font-size: 8px;
    color: var(--fg-faint);
}

.cp-toast[b-gpavlty1ib] {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 14px 12px;
    padding: 9px 13px;
    border: 1px solid var(--border3);
    border-radius: 8px;
    background: var(--panel);
    font-family: var(--mono);
    font-size: 10.5px;
    color: var(--fg2);
}

.cp-toast .sp[b-gpavlty1ib] {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: none;
    background: var(--green);
}

.cp-toast.err .sp[b-gpavlty1ib] { background: var(--red); }
.cp-toast .t[b-gpavlty1ib] { color: var(--fg-faint); }
/* /Components/Graph/ServiceGraph.razor.rz.scp.css */
/* Service-graph canvas — composes design-system tokens only, no new colors.
   Ported from proposal 04's scoped style block. ::deep reaches the diagram
   library's rendered markup (nodes/ports/links) so it can be re-skinned. */

/* Full-bleed canvas (proposal 10): edge-to-edge, no fixed height / margin.
   Parent (.miniframe graph column) is a flex column; .canvas flexes to fill it. */
.canvas[b-o6b0i2za67] {
    position: relative;
    flex: 1;
    min-height: 0;
    background: radial-gradient(circle at 1px 1px, var(--border) 1px, transparent 0) 0 0 / 24px 24px;
    overflow: hidden;
}

/* ── floating add-node FAB (proposal 10), n8n top-right ─────────────────────── */
.fab[b-o6b0i2za67] {
    position: absolute;
    top: 14px;
    right: 14px;
    z-index: 8;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--grad);
    color: var(--on-grad-ink);
    border: none;
    box-shadow: 0 0 10px var(--glow);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    line-height: 1;
    font-weight: 600;
    cursor: pointer;
    font-family: var(--mono);
}

/* add-zone FAB, sits under the add-node FAB (proposal 09) */
.fab.zonefab[b-o6b0i2za67] {
    top: 56px;
    background: var(--surf1);
    color: var(--fg-dim);
    border: 1px solid var(--border2);
    box-shadow: none;
    font-size: 15px;
}

/* sync-from-Coolify FAB, sits under the add-zone FAB (proposal 26) */
.fab.syncfab[b-o6b0i2za67] {
    top: 98px;
    background: var(--surf1);
    color: var(--fg-dim);
    border: 1px solid var(--border2);
    box-shadow: none;
    font-size: 16px;
}

/* backup/restore FAB, sits under the sync FAB (proposal 28) */
.fab.backupfab[b-o6b0i2za67] {
    top: 140px;
    background: var(--surf1);
    color: var(--fg-dim);
    border: 1px solid var(--border2);
    box-shadow: none;
    font-size: 16px;
}

/* ── zone chrome (proposal 09) — rendered in the diagram group layer, beneath nodes.
   ::deep reaches the group widget markup; the group container is sized/positioned
   inline by the diagram, so .zone just fills it. */
.canvas[b-o6b0i2za67]  .zone {
    position: absolute;
    inset: 0;
    border: 1px dashed var(--border4);
    border-radius: var(--r-menu);
    background: color-mix(in srgb, var(--fg-faint) 6%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fg-faint) 5%, transparent);
}

/* ── Edges under a group stay pickable (proposal 37) ─────────────────────────
   Edges routed under a group used to be un-clickable because the group's HTML
   rectangle painted ABOVE the SVG link layer and swallowed the click. This is now
   solved by LAYER ORDER (ServiceGraph.razor: LinksLayerOrder = 1), which raises the
   whole link layer above the node/group layer — the thin edge stroke (the library's
   .diagram-link is pointer-events:visiblePainted) sits on top and takes the click,
   while everything else falls through to the group beneath. So the group keeps the
   library default `.diagram-group { pointer-events: all; cursor: move }` and stays
   draggable by its WHOLE body. (The previous fix set pointer-events:none on the
   group, which broke body-dragging: a body press fell through to the canvas pan
   handler and panned the entire diagram.) The header cursor:move below just advertises
   the grip; no pointer-events override is needed on the group or its fill. */
.canvas[b-o6b0i2za67]  .zone.sel {
    border-style: solid;
    border-color: var(--fg-dim);
    box-shadow: inset 0 0 0 1px var(--fg-dim);
}

.canvas[b-o6b0i2za67]  .zone .zh {
    position: absolute;
    top: 8px;
    left: 10px;
    display: flex;
    align-items: center;
    gap: 7px;
    /* proposal 37: interior is now click-through, so the header IS the drag grip —
       pointer-events:auto makes it the group's move/select handle (events bubble to
       the wrapper's pointer handlers). cursor:move advertises it. */
    pointer-events: auto;
    cursor: move;
}

.canvas[b-o6b0i2za67]  .zone .zh .znm {
    font-family: var(--mono);
    font-size: 10.5px;
    font-weight: 600;
    color: var(--fg);
    letter-spacing: .3px;
}

.canvas[b-o6b0i2za67]  .zone .zh .zid {
    font-family: var(--mono);
    font-size: 8px;
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-xs);
    padding: 0 4px;
    line-height: 14px;
}

.canvas[b-o6b0i2za67]  .zone .zct {
    position: absolute;
    top: 8px;
    right: 10px;
    font-family: var(--mono);
    font-size: 8px;
    color: var(--fg-faint);
    /* proposal 37: keep the count interactive (part of the header chrome). */
    pointer-events: auto;
    cursor: move;
}

.canvas[b-o6b0i2za67]  .zone .rh {
    position: absolute;
    width: 12px;
    height: 12px;
    right: -1px;
    bottom: -1px;
    /* proposal 37: resize grip stays interactive over the click-through interior. */
    pointer-events: auto;
    cursor: nwse-resize;
    border-right: 2px solid var(--fg-dim);
    border-bottom: 2px solid var(--fg-dim);
    border-bottom-right-radius: var(--r-menu);
}

/* ── bottom-left zoom cluster (proposal 10) ─────────────────────────────────── */
.ctrls[b-o6b0i2za67] {
    position: absolute;
    left: 14px;
    bottom: 14px;
    z-index: 8;
    display: flex;
    gap: 6px;
}

.cbtn[b-o6b0i2za67] {
    font-family: var(--mono);
    font-size: 12px;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--surf1);
    border: 1px solid var(--border2);
    color: var(--fg-dim);
    border-radius: var(--r-sm);
    cursor: pointer;
}

.cbtn.txt[b-o6b0i2za67] {
    width: auto;
    padding: 0 9px;
    font-size: 10px;
}

/* zoom % readout, top-left */
.zread[b-o6b0i2za67] {
    position: absolute;
    left: 14px;
    top: 14px;
    z-index: 8;
    font-family: var(--mono);
    font-size: 9px;
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-xs);
    padding: 3px 7px;
    background: var(--surf1);
}

/* ── Diagram canvas host ─────────────────────────────────────────────────── */
.canvas[b-o6b0i2za67]  .diagram-canvas {
    width: 100%;
    height: 100%;
    background: transparent;
}

/* Node widget chrome */
.canvas[b-o6b0i2za67]  .gnode {
    /* positioning context for the edge-anchored ports (proposal 30) */
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 5px;
    background: var(--surf1);
    border: 1px solid var(--border2);
    border-radius: var(--r-menu);
    /* Extra L/R padding so the edge-anchored ports (proposal 30) straddle the
       border without clipping node text. */
    padding: 9px 16px 8px;
    min-width: 118px;
    transition: border-color .12s, box-shadow .12s;
}

.canvas[b-o6b0i2za67]  .gnode:hover {
    border-color: var(--border4);
    box-shadow: 0 4px 16px rgba(0, 0, 0, .35);
}

.canvas[b-o6b0i2za67]  .gnode.sel {
    border-color: var(--fg-dim);
    box-shadow: 0 0 0 1px var(--fg-dim);
}

.canvas[b-o6b0i2za67]  .gnode .gh {
    display: flex;
    align-items: center;
    gap: 6px;
}

.canvas[b-o6b0i2za67]  .gnode .gh .dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex: none;
    /* default when no live status yet; overridden by the state classes below (proposal 31) */
    background: var(--gray);
}

.canvas[b-o6b0i2za67]  .gnode .nm {
    font-family: var(--mono);
    font-size: 11px;
    color: var(--fg);
    font-weight: 500;
}

.canvas[b-o6b0i2za67]  .gnode .url {
    font-family: var(--mono);
    font-size: 8.5px;
    color: var(--fg-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 120px;
}

.canvas[b-o6b0i2za67]  .gnode .tags {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
}

.canvas[b-o6b0i2za67]  .gnode .tag {
    font-family: var(--mono);
    font-size: 8px;
    color: var(--fg-dim);
    border: 1px solid var(--border2);
    border-radius: var(--r-xs);
    padding: 0 4px;
    line-height: 14px;
}

.canvas[b-o6b0i2za67]  .gnode.off {
    opacity: .5;
}

/* ── Live node health layer (proposal 31) ──────────────────────────────────
   Each node wears its latest status: a status-tinted left bar + soft glow, a
   coloured header dot, and a labelled chip. Colour comes ONLY from the design-
   system status tokens (--green / --yellow / --red / --gray / --accent) — never
   a raw hex. Encoded by colour + shape + TEXT so it survives colour-blindness. */
.canvas[b-o6b0i2za67]  .gnode {
    border-left-width: 3px;
    border-left-style: solid;
    border-left-color: var(--border2);
}

.canvas[b-o6b0i2za67]  .gnode.up {
    border-left-color: var(--green);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--green) 55%, transparent), 0 6px 20px rgba(0, 0, 0, .30);
}
.canvas[b-o6b0i2za67]  .gnode.up .gh .dot { background: var(--green); }

.canvas[b-o6b0i2za67]  .gnode.slow {
    border-left-color: var(--yellow);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--yellow) 55%, transparent), 0 6px 20px rgba(0, 0, 0, .30);
}
.canvas[b-o6b0i2za67]  .gnode.slow .gh .dot { background: var(--yellow); }

.canvas[b-o6b0i2za67]  .gnode.down {
    border-left-color: var(--red);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--red) 60%, transparent), 0 6px 22px rgba(0, 0, 0, .30);
}
.canvas[b-o6b0i2za67]  .gnode.down .gh .dot { background: var(--red); }

.canvas[b-o6b0i2za67]  .gnode.probe { border-left-color: var(--accent); }
.canvas[b-o6b0i2za67]  .gnode.probe .gh .dot {
    background: var(--accent);
    animation: gnode-pulse-b-o6b0i2za67 1.15s ease-in-out infinite;
}

.canvas[b-o6b0i2za67]  .gnode.na {
    border-left-style: dashed;
    border-left-color: var(--gray);
    opacity: .72;
}
.canvas[b-o6b0i2za67]  .gnode.na .gh .dot {
    background: transparent;
    border: 1.5px solid var(--gray);
    box-sizing: border-box;
}

@keyframes gnode-pulse-b-o6b0i2za67 {
    0%, 100% { opacity: 1; }
    50% { opacity: .28; }
}

/* Labelled status chip — colour + shape + text. */
.canvas[b-o6b0i2za67]  .gnode .schip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    align-self: flex-start;
    font-family: var(--mono);
    font-size: 7.5px;
    font-weight: 600;
    line-height: 1;
    letter-spacing: .1em;
    text-transform: uppercase;
    border-radius: var(--r-xs);
    padding: 2px 5px;
    border: 1px solid var(--border2);
    color: var(--fg-faint);
}
.canvas[b-o6b0i2za67]  .gnode .schip .g {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex: none;
    background: var(--gray);
}

.canvas[b-o6b0i2za67]  .gnode.up .schip {
    color: var(--green);
    border-color: color-mix(in srgb, var(--green) 45%, var(--border2));
}
.canvas[b-o6b0i2za67]  .gnode.up .schip .g { background: var(--green); }

.canvas[b-o6b0i2za67]  .gnode.slow .schip {
    color: var(--yellow);
    border-color: color-mix(in srgb, var(--yellow) 45%, var(--border2));
}
.canvas[b-o6b0i2za67]  .gnode.slow .schip .g { background: var(--yellow); }

.canvas[b-o6b0i2za67]  .gnode.down .schip {
    color: var(--red);
    border-color: color-mix(in srgb, var(--red) 50%, var(--border2));
}
.canvas[b-o6b0i2za67]  .gnode.down .schip .g { background: var(--red); }

.canvas[b-o6b0i2za67]  .gnode.probe .schip { color: var(--accent); }
.canvas[b-o6b0i2za67]  .gnode.probe .schip .g { background: var(--accent); }

.canvas[b-o6b0i2za67]  .gnode.na .schip { color: var(--fg-faint); }
.canvas[b-o6b0i2za67]  .gnode.na .schip .g {
    background: transparent;
    border: 1px solid var(--gray);
    box-sizing: border-box;
}

/* Ports (connect/disconnect handles) — edge-anchored (proposal 30).
   The 9×9 dot IS the library's attach-point box (Z.Blazor.Diagrams derives link
   endpoints from getBoundingClientRect of the port element), so it stays a clean
   fixed-size circle; only its position moves. .l → left-edge midpoint (IN),
   .r → right-edge midpoint (OUT). Absolute against the relatively-positioned
   .gnode; translateY(-50%) centres it on the edge so wires land dead-centre. */
.canvas[b-o6b0i2za67]  .port {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--panel);
    border: 1.5px solid var(--border4);
    box-sizing: border-box;
    cursor: crosshair;
    z-index: 2;
}

.canvas[b-o6b0i2za67]  .port.l {
    left: -5px;
}

.canvas[b-o6b0i2za67]  .port.r {
    right: -5px;
}

.canvas[b-o6b0i2za67]  .port.has-links {
    background: var(--accent);
    border-color: var(--accent);
}

/* IN / OUT micro-label — a ::after on the port itself so the port's own box is
   never resized (keeps the library's attach-point measurement intact). Fades in
   on node hover, sits just outside its edge, non-interactive. */
.canvas[b-o6b0i2za67]  .port::after {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    font-family: var(--mono);
    font-size: 7px;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--fg-faint);
    background: var(--surf1);
    border: 1px solid var(--border2);
    border-radius: var(--r-xs);
    padding: 1px 3px;
    line-height: 1;
    opacity: 0;
    transition: opacity .12s;
    pointer-events: none;
    white-space: nowrap;
}

.canvas[b-o6b0i2za67]  .port.l::after {
    content: "in";
    right: calc(100% + 4px);
}

.canvas[b-o6b0i2za67]  .port.r::after {
    content: "out";
    left: calc(100% + 4px);
}

.canvas[b-o6b0i2za67]  .gnode:hover .port::after {
    opacity: 1;
}

/* Links — structural stroke-width/fill only (proposal 35). The resting stroke is
   NO LONGER forced here: a colored edge carries a per-link `stroke="…"` presentation
   attribute (set from ServiceEdge.Color via ApplyEdgeVisuals → link.Color), and a CSS
   `stroke:` declaration on this rule would always beat that attribute — which is why
   feature 27's colored wires stayed silver. So this base rule sets width/fill only and
   lets the per-link stroke attribute paint the resting color. */
.canvas[b-o6b0i2za67]  .diagram-link path {
    stroke-width: 2;
    fill: none;
}

/* Uncolored edges (link.Color null → Blazor omits the `stroke` attribute entirely)
   keep today's exact Basalt silver default. Scoped to :not([stroke]) so it only
   applies when the path has no per-link stroke attribute, and a colored edge's
   attribute stroke still wins. Token-driven, so it re-tints per theme. */
.canvas[b-o6b0i2za67]  .diagram-link path:not([stroke]) {
    stroke: var(--border4);
}

/* Interaction states win over BOTH the resting color and the null default: hover /
   selected always light to --accent (proposal 35 keeps this unchanged). */
.canvas[b-o6b0i2za67]  .diagram-link.selected path,
.canvas[b-o6b0i2za67]  .diagram-link:hover path {
    stroke: var(--accent);
}

/* ── Edit popover placement (proposal 10) ─────────────────────────────────────
   Floating overlay over the full canvas, top-right below the add-node FAB. */
.popwrap[b-o6b0i2za67] {
    position: absolute;
    top: 58px;
    right: 14px;
    z-index: 9;
    display: flex;
    justify-content: flex-end;
}

.ring[b-o6b0i2za67] {
    border-radius: var(--r-pop);
}

/* Popover chrome not already covered by app.css .pop */
[b-o6b0i2za67] .svcpop {
    width: 250px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .55);
}

[b-o6b0i2za67] .svcpop .idpill {
    margin-left: auto;
    font-size: 8.5px;
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-xs);
    padding: 1px 5px;
    text-transform: none;
    letter-spacing: 0;
}

[b-o6b0i2za67] .svcpop .tagedit {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    align-items: center;
    background: var(--surf0);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 5px 6px;
}

[b-o6b0i2za67] .svcpop .tagedit .tag {
    font-family: var(--mono);
    font-size: 9px;
    color: var(--fg-dim);
    border: 1px solid var(--border3);
    border-radius: var(--r-xs);
    padding: 1px 5px;
    display: flex;
    gap: 4px;
    align-items: center;
}

[b-o6b0i2za67] .svcpop .tagedit .tag .x {
    color: var(--fg-faint);
    cursor: pointer;
}

[b-o6b0i2za67] .svcpop .togline {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
}

[b-o6b0i2za67] .svcpop .togline .lab {
    font-family: var(--mono);
    font-size: 10px;
    color: var(--fg-dim);
}

/* Preview-page toggle (proposal 29): a stacked label + sub line above the switch. */
[b-o6b0i2za67] .svcpop .togline.preview {
    align-items: flex-start;
}

[b-o6b0i2za67] .svcpop .togline.preview .lab {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

[b-o6b0i2za67] .svcpop .togline.preview .lab .newpill {
    display: inline-block;
    font-family: var(--mono);
    font-size: 7.5px;
    letter-spacing: .5px;
    color: var(--on-grad-ink);
    background: var(--grad);
    border-radius: var(--r-xs);
    padding: 0 4px;
    line-height: 12px;
    vertical-align: middle;
}

[b-o6b0i2za67] .svcpop .togline.preview .lab .sub {
    font-family: var(--sans);
    font-size: 9px;
    color: var(--fg-faint);
}

[b-o6b0i2za67] .svcpop .switch {
    margin-left: auto;
    width: 32px;
    height: 18px;
    border-radius: 10px;
    background: var(--grad);
    position: relative;
    cursor: pointer;
    box-shadow: 0 0 8px var(--glow);
}

[b-o6b0i2za67] .svcpop .switch .knob {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--logo-ink);
}

[b-o6b0i2za67] .svcpop .switch.off {
    background: var(--border3);
    box-shadow: none;
}

[b-o6b0i2za67] .svcpop .switch.off .knob {
    left: 2px;
    right: auto;
    background: var(--fg-faint);
}

[b-o6b0i2za67] .svcpop .popbtns {
    display: flex;
    gap: 6px;
    margin-top: 2px;
}

[b-o6b0i2za67] .svcpop .popbtns .save {
    flex: 1;
    font-family: var(--mono);
    font-size: 11px;
    background: var(--grad);
    color: var(--on-grad-ink);
    border: none;
    border-radius: var(--r-sm);
    padding: 6px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 0 8px var(--glow);
}

[b-o6b0i2za67] .svcpop .popbtns .del {
    font-family: var(--mono);
    font-size: 11px;
    background: var(--surf1);
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 6px 10px;
    cursor: pointer;
}

/* ── Group picker (proposal 13) — explicit one-group-or-ungrouped select ─────── */
[b-o6b0i2za67] .svcpop .grpsel {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

[b-o6b0i2za67] .svcpop .grpsel .selrow {
    display: flex;
    align-items: center;
    gap: 8px;
}

[b-o6b0i2za67] .svcpop .grpsel select {
    flex: 1;
    appearance: none;
    background: var(--surf0);
    color: var(--fg);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 6px 9px;
    font-family: var(--mono);
    font-size: 11px;
    cursor: pointer;
}

[b-o6b0i2za67] .svcpop .grpsel select:focus {
    outline: none;
    border-color: var(--fg-dim);
}

[b-o6b0i2za67] .svcpop .grpsel .grpchip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: var(--mono);
    font-size: 9px;
    padding: 2px 7px;
    border-radius: 999px;
    border: 1px solid var(--border2);
    color: var(--fg-dim);
    background: var(--surf1);
    align-self: flex-start;
}

[b-o6b0i2za67] .svcpop .grpsel .grpchip .dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
}

[b-o6b0i2za67] .svcpop .grpsel .grpchip.none .dot {
    background: var(--fg-faint);
    opacity: .5;
}

/* ── Sync-from-Coolify popover (proposal 26) — shares .pop base + popbtns ── */
[b-o6b0i2za67] .syncpop {
    width: 250px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .55);
}

[b-o6b0i2za67] .syncpop .idpill {
    margin-left: auto;
    font-size: 8.5px;
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-xs);
    padding: 1px 5px;
    text-transform: none;
    letter-spacing: 0;
    font-family: var(--mono);
}

[b-o6b0i2za67] .syncpop .syncblurb {
    font-family: var(--sans);
    font-size: 11px;
    line-height: 1.5;
    color: var(--fg-dim);
    margin: 0 0 10px;
}

[b-o6b0i2za67] .syncpop .syncres {
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: var(--surf0);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 8px 10px;
    margin-bottom: 10px;
}

[b-o6b0i2za67] .syncpop .syncres .row {
    display: flex;
    align-items: center;
    font-family: var(--mono);
    font-size: 10px;
}

[b-o6b0i2za67] .syncpop .syncres .row .k {
    color: var(--fg-faint);
}

[b-o6b0i2za67] .syncpop .syncres .row .v {
    margin-left: auto;
    color: var(--fg);
}

[b-o6b0i2za67] .syncpop .syncres .row .v em {
    color: var(--fg-faint);
    font-style: normal;
}

[b-o6b0i2za67] .syncpop .popbtns {
    display: flex;
    gap: 6px;
    margin-top: 2px;
}

[b-o6b0i2za67] .syncpop .popbtns .save {
    flex: 1;
    font-family: var(--mono);
    font-size: 11px;
    background: var(--grad);
    color: var(--on-grad-ink);
    border: none;
    border-radius: var(--r-sm);
    padding: 6px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 0 8px var(--glow);
}

[b-o6b0i2za67] .syncpop .popbtns .save:disabled {
    opacity: .55;
    cursor: default;
    box-shadow: none;
}

[b-o6b0i2za67] .syncpop .popbtns .del {
    font-family: var(--mono);
    font-size: 11px;
    background: var(--surf1);
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 6px 10px;
    cursor: pointer;
}

/* ── Backup/restore popover (proposal 28) — shares .pop base + sync chrome ── */
[b-o6b0i2za67] .backuppop {
    width: 268px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .55);
}

[b-o6b0i2za67] .backuppop .idpill {
    margin-left: auto;
    font-size: 8.5px;
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-xs);
    padding: 1px 5px;
    text-transform: none;
    letter-spacing: 0;
    font-family: var(--mono);
}

[b-o6b0i2za67] .backuppop .backupblurb {
    font-family: var(--mono);
    font-size: 10px;
    line-height: 1.5;
    color: var(--fg-dim);
    margin: 0 0 10px;
}

[b-o6b0i2za67] .backuppop .backupres {
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: var(--surf0);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 8px 10px;
    margin-bottom: 10px;
}

[b-o6b0i2za67] .backuppop .backupres .row {
    display: flex;
    align-items: center;
    font-family: var(--mono);
    font-size: 10px;
}

[b-o6b0i2za67] .backuppop .backupres .row .k {
    color: var(--fg-faint);
}

[b-o6b0i2za67] .backuppop .backupres .row .v {
    margin-left: auto;
    color: var(--fg);
}

[b-o6b0i2za67] .backuppop .act {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    text-align: left;
    background: var(--surf1);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 9px 11px;
    margin-bottom: 8px;
    cursor: pointer;
    position: relative;
}

[b-o6b0i2za67] .backuppop .act.disabled {
    opacity: .55;
    cursor: default;
}

[b-o6b0i2za67] .backuppop .act .ico {
    font-family: var(--mono);
    font-size: 14px;
    color: var(--fg-dim);
    flex: none;
    width: 15px;
    text-align: center;
}

[b-o6b0i2za67] .backuppop .act .txt {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

[b-o6b0i2za67] .backuppop .act .lbl {
    font-family: var(--mono);
    font-size: 12px;
    color: var(--fg);
}

[b-o6b0i2za67] .backuppop .act .sub {
    font-family: var(--sans);
    font-size: 10px;
    color: var(--fg-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

[b-o6b0i2za67] .backuppop .act .go {
    margin-left: auto;
    font-family: var(--mono);
    font-size: 10.5px;
    padding: 4px 9px;
    border-radius: var(--r-xs);
    background: var(--grad);
    color: var(--on-grad-ink);
    font-weight: 600;
    flex: none;
}

/* Hide the raw file input; the styled .act label is the click target. */
[b-o6b0i2za67] .backuppop .filehide {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
}

[b-o6b0i2za67] .backuppop .warnrow {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin: 4px 0 10px;
    font-family: var(--sans);
    font-size: 10.5px;
    color: var(--warn);
    line-height: 1.45;
}

[b-o6b0i2za67] .backuppop .warnrow .warnico {
    font-family: var(--mono);
    font-weight: 700;
    flex: none;
    line-height: 1.35;
}

[b-o6b0i2za67] .backuppop .popbtns {
    display: flex;
    gap: 6px;
    margin-top: 2px;
}

[b-o6b0i2za67] .backuppop .popbtns .save {
    flex: 1;
    font-family: var(--mono);
    font-size: 11px;
    background: var(--grad);
    color: var(--on-grad-ink);
    border: none;
    border-radius: var(--r-sm);
    padding: 6px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 0 8px var(--glow);
}

[b-o6b0i2za67] .backuppop .popbtns .save:disabled {
    opacity: .55;
    cursor: default;
    box-shadow: none;
}

[b-o6b0i2za67] .backuppop .popbtns .del {
    font-family: var(--mono);
    font-size: 11px;
    background: var(--surf1);
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 6px 10px;
    cursor: pointer;
}

/* ── Zone edit popover (proposal 09) — shares .pop base + node popover buttons ── */
[b-o6b0i2za67] .zonepop {
    width: 250px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .55);
}

[b-o6b0i2za67] .zonepop .idpill {
    margin-left: auto;
    font-size: 8.5px;
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-xs);
    padding: 1px 5px;
    text-transform: none;
    letter-spacing: 0;
}

[b-o6b0i2za67] .zonepop .dims {
    display: flex;
    gap: 8px;
    font-family: var(--mono);
    font-size: 9px;
    color: var(--fg-faint);
    margin-bottom: 10px;
}

[b-o6b0i2za67] .zonepop .dims span {
    border: 1px solid var(--border2);
    border-radius: var(--r-xs);
    padding: 2px 6px;
}

[b-o6b0i2za67] .zonepop .popbtns {
    display: flex;
    gap: 6px;
    margin-top: 2px;
}

[b-o6b0i2za67] .zonepop .popbtns .save {
    flex: 1;
    font-family: var(--mono);
    font-size: 11px;
    background: var(--grad);
    color: var(--on-grad-ink);
    border: none;
    border-radius: var(--r-sm);
    padding: 6px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 0 8px var(--glow);
}

[b-o6b0i2za67] .zonepop .popbtns .del {
    font-family: var(--mono);
    font-size: 11px;
    background: var(--surf1);
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 6px 10px;
    cursor: pointer;
}

/* ── Edge edit popover (proposal 15) — shares .pop base + node popover buttons ── */
[b-o6b0i2za67] .edgepop {
    width: 250px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .55);
}

[b-o6b0i2za67] .edgepop .idpill {
    margin-left: auto;
    font-size: 8.5px;
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-xs);
    padding: 1px 5px;
    text-transform: none;
    letter-spacing: 0;
    font-family: var(--mono);
}

/* 3-way direction segment */
[b-o6b0i2za67] .edgepop .dirseg {
    display: flex;
    gap: 6px;
}

[b-o6b0i2za67] .edgepop .dirseg .opt {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 8px 4px;
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    background: var(--surf0);
    cursor: pointer;
    font-family: var(--mono);
    font-size: 8.5px;
    color: var(--fg-faint);
    text-align: center;
}

[b-o6b0i2za67] .edgepop .dirseg .opt .glyph {
    font-size: 15px;
    line-height: 1;
    color: var(--fg-dim);
}

[b-o6b0i2za67] .edgepop .dirseg .opt.sel {
    border-color: var(--accent);
    color: var(--fg);
}

[b-o6b0i2za67] .edgepop .dirseg .opt.sel .glyph {
    color: var(--fg);
}

[b-o6b0i2za67] .edgepop .popbtns {
    display: flex;
    gap: 6px;
    margin-top: 2px;
}

[b-o6b0i2za67] .edgepop .popbtns .save {
    flex: 1;
    font-family: var(--mono);
    font-size: 11px;
    background: var(--grad);
    color: var(--on-grad-ink);
    border: none;
    border-radius: var(--r-sm);
    padding: 6px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 0 8px var(--glow);
}

[b-o6b0i2za67] .edgepop .popbtns .del {
    font-family: var(--mono);
    font-size: 11px;
    background: var(--surf1);
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 6px 10px;
    cursor: pointer;
}

/* ── Edge color swatch grid (proposal 27) ────────────────────────────────────
   10×2 grid of the 20 curated "faded" hues. Structure is design-system tokens;
   each swatch's fill is the per-hue --c custom property set inline in the markup
   (the palette itself is defined once, in EdgeEditPopover's C# Palette array). */
[b-o6b0i2za67] .edgepop .swatches {
    display: grid;
    grid-template-columns: repeat(10, 1fr);
    gap: 5px;
}

[b-o6b0i2za67] .edgepop .swatches .sw {
    aspect-ratio: 1;
    border-radius: var(--r-xs);
    cursor: pointer;
    border: 1.5px solid transparent;
    background: var(--c);
    transition: transform .08s, border-color .08s;
}

[b-o6b0i2za67] .edgepop .swatches .sw:hover {
    transform: scale(1.12);
}

/* Selected swatch: a ring lifted off the swatch with a token-surface gap. */
[b-o6b0i2za67] .edgepop .swatches .sw.sel {
    border-color: var(--fg);
    box-shadow: 0 0 0 2px var(--surf1), 0 0 0 3px var(--c);
}

/* ── Mid-wire label pill (proposal 27) ───────────────────────────────────────
   Rendered by EdgeLabelWidget inside the library's foreignObject.diagram-link-label
   (which is 1×1 with overflow:visible, so the pill overflows and centers on the
   wire). Neutral chrome by default (token surfaces); when the edge carries a
   curated hue, the widget adds .tinted + inline --pc and the pill fills solid.
   Keeps the null-color default: an untinted pill matches today's silver stroke. */
.canvas[b-o6b0i2za67]  .diagram-link-label .edge-pill {
    transform: translate(-50%, -50%);
    display: inline-block;
    white-space: nowrap;
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .03em;
    line-height: 1;
    padding: 4px 9px;
    border-radius: 999px;
    color: var(--fg-dim);
    background: var(--surf1);
    border: 1px solid var(--border3);
    box-shadow: 0 1px 4px rgba(0, 0, 0, .35);
    pointer-events: none;
}

.canvas[b-o6b0i2za67]  .diagram-link-label .edge-pill.tinted {
    color: #fff;
    background: var(--pc);
    border-color: color-mix(in srgb, var(--pc) 70%, #000);
}

/* ── Right-click node context menu (proposal 29) ─────────────────────────────
   A full-canvas scrim captures the outside-click / re-right-click to dismiss;
   the menu itself is fixed-positioned at the pointer via inline left/top. */
.ctx-scrim[b-o6b0i2za67] {
    position: fixed;
    inset: 0;
    z-index: 20;
}

[b-o6b0i2za67] .ctxmenu {
    position: fixed;
    width: 176px;
    background: var(--surf1);
    border: 1px solid var(--border3);
    border-radius: var(--r-menu);
    padding: 5px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .55);
}

[b-o6b0i2za67] .ctxmenu .mi {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 9px;
    border-radius: var(--r-sm);
    font-family: var(--sans);
    font-size: 12px;
    color: var(--fg-dim);
    cursor: pointer;
}

[b-o6b0i2za67] .ctxmenu .mi:hover {
    background: var(--hover);
    color: var(--fg);
}

[b-o6b0i2za67] .ctxmenu .mi.primary {
    color: var(--fg);
}

[b-o6b0i2za67] .ctxmenu .mi svg {
    width: 14px;
    height: 14px;
    flex: none;
    color: var(--fg-faint);
}

[b-o6b0i2za67] .ctxmenu .mi.dis {
    opacity: .4;
    cursor: not-allowed;
}

[b-o6b0i2za67] .ctxmenu .mi.dis:hover {
    background: transparent;
    color: var(--fg-dim);
}

[b-o6b0i2za67] .ctxmenu .sep {
    height: 1px;
    background: var(--border);
    margin: 4px 2px;
}

/* ── Full-screen page preview modal (proposal 29) — mirrors .cp-backdrop ─────── */
[b-o6b0i2za67] .pv-backdrop {
    position: fixed;
    inset: 0;
    z-index: 40;
    display: flex;
    align-items: stretch;
    justify-content: stretch;
    padding: 18px;
    box-sizing: border-box;
    background: color-mix(in srgb, var(--surf0) 78%, transparent);
    backdrop-filter: blur(3px);
    outline: none;
}

[b-o6b0i2za67] .pv-browser {
    flex: 1;
    display: flex;
    flex-direction: column;
    background: var(--surf1);
    border: 1px solid var(--border3);
    border-radius: var(--r-pop);
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0, 0, 0, .6);
}

[b-o6b0i2za67] .pv-chrome {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    border-bottom: 1px solid var(--border);
    background: var(--surf0);
    flex: none;
}

[b-o6b0i2za67] .pv-chrome .st {
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 600;
    color: var(--fg2);
}

[b-o6b0i2za67] .pv-chrome .st .dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex: none;
}

[b-o6b0i2za67] .pv-chrome .st .dot.up { background: var(--green); }
[b-o6b0i2za67] .pv-chrome .st .dot.na { background: var(--fg-faint); }

[b-o6b0i2za67] .pv-chrome .addr {
    flex: 1;
    background: var(--surf1);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 6px 10px;
    font-family: var(--mono);
    font-size: 11px;
    color: var(--fg-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

[b-o6b0i2za67] .pv-chrome .ext,
[b-o6b0i2za67] .pv-chrome .x {
    width: 28px;
    height: 28px;
    border-radius: var(--r-sm);
    border: 1px solid var(--border2);
    background: var(--surf1);
    color: var(--fg-dim);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    font-family: var(--mono);
    font-size: 14px;
}

[b-o6b0i2za67] .pv-chrome .ext svg {
    width: 14px;
    height: 14px;
}

[b-o6b0i2za67] .pv-chrome .ext:hover,
[b-o6b0i2za67] .pv-chrome .x:hover {
    background: var(--hover);
    color: var(--fg);
}

[b-o6b0i2za67] .pv-body {
    flex: 1;
    position: relative;
    min-height: 0;
    background: var(--surf0);
}

[b-o6b0i2za67] .pv-body iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: none;
    background: var(--surf0);
}

/* Blocked-embed fallback sits behind the iframe; when the page refuses to frame,
   the transparent iframe reveals this open-in-new-tab notice. */
[b-o6b0i2za67] .pv-body .pv-fallback {
    position: absolute;
    inset: 0;
    z-index: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    text-align: center;
    padding: 24px;
    pointer-events: none;
}

[b-o6b0i2za67] .pv-body iframe {
    z-index: 1;
}

[b-o6b0i2za67] .pv-body .pv-fallback .fb-title {
    font-family: var(--mono);
    font-size: 12px;
    color: var(--fg2);
}

[b-o6b0i2za67] .pv-body .pv-fallback .fb-sub {
    font-family: var(--sans);
    font-size: 11px;
    line-height: 1.5;
    color: var(--fg-faint);
    max-width: 340px;
}

[b-o6b0i2za67] .pv-body .pv-fallback .fb-btn {
    pointer-events: auto;
    margin-top: 4px;
    font-family: var(--mono);
    font-size: 11px;
    background: var(--surf1);
    color: var(--fg-dim);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 6px 12px;
    cursor: pointer;
}

[b-o6b0i2za67] .pv-body .pv-fallback .fb-btn:hover {
    background: var(--hover);
    color: var(--fg);
}

/* ── Last-response viewer modal (proposal 32) — mirrors .pv-backdrop ─────────── */
[b-o6b0i2za67] .lr-backdrop {
    position: fixed;
    inset: 0;
    z-index: 41;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    box-sizing: border-box;
    background: color-mix(in srgb, var(--surf0) 78%, transparent);
    backdrop-filter: blur(3px);
    outline: none;
}

[b-o6b0i2za67] .lr-modal {
    width: min(760px, 100%);
    max-height: calc(100vh - 48px);
    display: flex;
    flex-direction: column;
    background: var(--surf0);
    border: 1px solid var(--border3);
    border-radius: var(--r-pop);
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0, 0, 0, .6);
}

[b-o6b0i2za67] .lr-head {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 10px 12px;
    background: var(--surf1);
    border-bottom: 1px solid var(--border3);
    flex: none;
}

[b-o6b0i2za67] .lr-head .lr-pill {
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .06em;
    padding: 4px 7px;
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    color: var(--fg-dim);
}

[b-o6b0i2za67] .lr-head .nm {
    font-family: var(--mono);
    font-size: 12px;
    color: var(--fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

[b-o6b0i2za67] .lr-head .code2 {
    margin-left: auto;
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 600;
}

[b-o6b0i2za67] .lr-head .code2.ok { color: var(--green); }
[b-o6b0i2za67] .lr-head .code2.bad { color: var(--red); }

[b-o6b0i2za67] .lr-head .x {
    width: 28px;
    height: 28px;
    flex: none;
    border-radius: var(--r-sm);
    border: 1px solid var(--border2);
    background: var(--surf1);
    color: var(--fg-dim);
    cursor: pointer;
    font-family: var(--mono);
    font-size: 13px;
}

[b-o6b0i2za67] .lr-head .x:hover {
    background: var(--hover);
    color: var(--fg);
}

[b-o6b0i2za67] .lr-meta {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 3px 14px;
    padding: 12px;
    margin: 0;
    font-family: var(--mono);
    font-size: 11.5px;
    line-height: 1.5;
    flex: none;
}

[b-o6b0i2za67] .lr-meta dt { color: var(--fg-faint); }
[b-o6b0i2za67] .lr-meta dd { color: var(--fg-dim); margin: 0; word-break: break-all; }
[b-o6b0i2za67] .lr-meta dd.ok { color: var(--green); }
[b-o6b0i2za67] .lr-meta dd.bad { color: var(--red); }

[b-o6b0i2za67] .lr-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 12px;
    padding: 6px 10px;
    border: 1px solid var(--border2);
    border-bottom: none;
    border-radius: var(--r-sm) var(--r-sm) 0 0;
    background: var(--surf2);
    font-family: var(--mono);
    font-size: 10.5px;
    color: var(--fg-faint);
    flex: none;
}

[b-o6b0i2za67] .lr-bar .trunc { color: var(--yellow); }

[b-o6b0i2za67] .lr-bar .btns {
    margin-left: auto;
    display: flex;
    gap: 6px;
}

[b-o6b0i2za67] .lr-bar .b {
    padding: 4px 8px;
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    background: var(--surf1);
    color: var(--fg-dim);
    cursor: pointer;
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 500;
}

[b-o6b0i2za67] .lr-bar .b:hover {
    color: var(--fg);
    border-color: var(--border3);
}

[b-o6b0i2za67] .lr-bar .b.on {
    color: var(--fg);
    border-color: var(--accent);
}

[b-o6b0i2za67] .lr-body {
    margin: 0 12px 12px;
    padding: 10px 12px;
    border: 1px solid var(--border2);
    border-radius: 0 0 var(--r-sm) var(--r-sm);
    background: var(--surf1);
    font-family: var(--mono);
    font-size: 11px;
    line-height: 1.5;
    color: var(--fg-dim);
    white-space: pre;
    max-height: 340px;
    overflow: auto;
    flex: 1 1 auto;
    min-height: 0;
}

[b-o6b0i2za67] .lr-empty {
    margin: 12px;
    padding: 24px 16px;
    border: 1px dashed var(--border2);
    border-radius: var(--r-sm);
    background: var(--surf1);
    text-align: center;
    font-family: var(--mono);
    font-size: 12px;
    color: var(--fg-faint);
}

/* ── Delete rows on the right-click context menus (proposal 33) ───────────────
   Reuses the shared .ctxmenu chrome (proposal 29); the destructive row keys off
   --red only, with a color-mix tint on hover. Applies to node / edge / zone menus. */
[b-o6b0i2za67] .ctxmenu .mi.danger {
    color: var(--red);
}

[b-o6b0i2za67] .ctxmenu .mi.danger svg {
    color: var(--red);
}

[b-o6b0i2za67] .ctxmenu .mi.danger:hover {
    background: color-mix(in srgb, var(--red) 14%, var(--surf1));
    color: var(--red);
}

/* ── Counted confirm dialog for the cascading group delete (proposal 33) ──────
   Centred modal over a dim backdrop; tokens-only, --red for the destructive act. */
.dlc-backdrop[b-o6b0i2za67] {
    position: fixed;
    inset: 0;
    z-index: 42;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, .5);
}

.dlc[b-o6b0i2za67] {
    width: 320px;
    max-width: calc(100vw - 32px);
    border: 1px solid var(--border2);
    border-radius: var(--r-md, 10px);
    overflow: hidden;
    background: var(--surf0);
    box-shadow: 0 20px 60px rgba(0, 0, 0, .5);
}

.dlc-head[b-o6b0i2za67] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 11px 13px;
    background: var(--surf1);
    border-bottom: 1px solid var(--border2);
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 600;
    color: var(--fg);
}

.dlc-head svg[b-o6b0i2za67] {
    width: 15px;
    height: 15px;
    flex: none;
    color: var(--red);
}

.dlc-body[b-o6b0i2za67] {
    padding: 13px;
    font-family: var(--mono);
    font-size: 11.5px;
    line-height: 1.55;
    color: var(--fg-dim);
}

.dlc-body strong[b-o6b0i2za67] {
    color: var(--fg);
}

.dlc-count[b-o6b0i2za67] {
    display: flex;
    gap: 7px;
    margin: 11px 0 3px;
    flex-wrap: wrap;
}

.dlc-pill[b-o6b0i2za67] {
    font-family: var(--mono);
    font-size: 10.5px;
    font-weight: 600;
    padding: 5px 8px;
    border-radius: var(--r-sm);
    border: 1px solid var(--border2);
    background: var(--surf1);
    color: var(--fg-dim);
}

.dlc-pill b[b-o6b0i2za67] {
    color: var(--red);
}

.dlc-err[b-o6b0i2za67] {
    margin-top: 10px;
    font-family: var(--mono);
    font-size: 11px;
    color: var(--red);
}

.dlc-foot[b-o6b0i2za67] {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 11px 13px;
    border-top: 1px solid var(--border2);
    background: var(--surf1);
}

.dlc-btn[b-o6b0i2za67] {
    padding: 6px 13px;
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    background: var(--surf0);
    color: var(--fg-dim);
    cursor: pointer;
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 500;
}

.dlc-btn:hover:not(:disabled)[b-o6b0i2za67] {
    color: var(--fg);
    border-color: var(--border3);
}

.dlc-btn:disabled[b-o6b0i2za67] {
    opacity: .55;
    cursor: default;
}

.dlc-btn.destroy[b-o6b0i2za67] {
    border-color: color-mix(in srgb, var(--red) 55%, var(--border2));
    color: var(--red);
}

.dlc-btn.destroy:hover:not(:disabled)[b-o6b0i2za67] {
    background: color-mix(in srgb, var(--red) 16%, var(--surf0));
    color: var(--red);
}

/* ── Add-iframe FAB (proposal 36) — sits under the backup FAB ────────────────── */
.fab.iframefab[b-o6b0i2za67] {
    top: 182px;
    background: var(--surf1);
    color: var(--fg-dim);
    border: 1px solid var(--border2);
    box-shadow: none;
    font-size: 16px;
}

/* ── Add-iframe URL prompt (proposal 36) — shares .pop base + sync chrome ────── */
[b-o6b0i2za67] .iframepop {
    width: 262px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .55);
}

[b-o6b0i2za67] .iframepop .idpill {
    margin-left: auto;
    font-size: 8.5px;
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-xs);
    padding: 1px 5px;
    text-transform: none;
    letter-spacing: 0;
    font-family: var(--mono);
}

[b-o6b0i2za67] .iframepop .syncblurb {
    font-family: var(--sans);
    font-size: 11px;
    line-height: 1.5;
    color: var(--fg-dim);
    margin: 0 0 10px;
}

[b-o6b0i2za67] .iframepop .iframeurl {
    width: 100%;
    box-sizing: border-box;
    background: var(--surf0);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    color: var(--fg);
    font-family: var(--mono);
    font-size: 12px;
    padding: 9px 10px;
    margin-bottom: 10px;
}

[b-o6b0i2za67] .iframepop .iframeurl:focus {
    outline: none;
    border-color: var(--accent);
}

/* Add block / Cancel buttons (proposal 38): the .iframepop block never scoped its
   .popbtns, so the buttons rendered as raw browser controls. Cloned from the shipped
   ::deep .syncpop .popbtns rules — silver-gradient primary + quiet secondary, tokens
   only, no new colors. */
[b-o6b0i2za67] .iframepop .popbtns {
    display: flex;
    gap: 6px;
    margin-top: 2px;
}

[b-o6b0i2za67] .iframepop .popbtns .save {
    flex: 1;
    font-family: var(--mono);
    font-size: 11px;
    background: var(--grad);
    color: var(--on-grad-ink);
    border: none;
    border-radius: var(--r-sm);
    padding: 6px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 0 8px var(--glow);
}

[b-o6b0i2za67] .iframepop .popbtns .save:disabled {
    opacity: .55;
    cursor: default;
    box-shadow: none;
}

[b-o6b0i2za67] .iframepop .popbtns .del {
    font-family: var(--mono);
    font-size: 11px;
    background: var(--surf1);
    color: var(--fg-faint);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 6px 10px;
    cursor: pointer;
}

/* ── Iframe block node (proposal 36) — a quiet browser frame; NO ports ───────── */
.canvas[b-o6b0i2za67]  .ifrnode {
    /* In-flow with an explicit size (set inline from the model) so the diagram's node
       wrapper measures a real box. An absolute/inset:0 root collapsed the wrapper to
       0×0, so every iframe block was persisted but painted nothing. */
    position: relative;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    background: var(--surf1);
    border: 1px solid var(--border3);
    border-radius: var(--r-menu);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
    overflow: hidden;
}

.canvas[b-o6b0i2za67]  .ifrnode.sel {
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent), 0 10px 30px rgba(0, 0, 0, .45);
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 9px;
    background: var(--surf2);
    border-bottom: 1px solid var(--border3);
    cursor: grab;
    flex: none;
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--fg-faint);
    flex: none;
}

/* Yellow while a load is pending; green once a genuine `load` actually fired. */
.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .dot.pending { background: var(--yellow); }
.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .dot.ok { background: var(--green); }

.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .ti {
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 600;
    color: var(--fg2);
    flex: none;
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .ad {
    flex: 1;
    min-width: 0;
    font-family: var(--mono);
    font-size: 10px;
    color: var(--fg-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: right;
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .rf,
.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .ext,
.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .x {
    width: 22px;
    height: 22px;
    border-radius: var(--r-xs);
    border: 1px solid var(--border2);
    background: var(--surf1);
    color: var(--fg-dim);
    cursor: pointer;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--mono);
    font-size: 12px;
    line-height: 1;
    padding: 0;
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .rf svg,
.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .ext svg {
    width: 12px;
    height: 12px;
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .rf:hover,
.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .ext:hover,
.canvas[b-o6b0i2za67]  .ifrnode .ifr-bar .x:hover {
    background: var(--hover);
    color: var(--fg);
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-pg {
    flex: 1;
    position: relative;
    min-height: 0;
    background: var(--surf0);
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-pg iframe {
    position: absolute;
    inset: 0;
    z-index: 1;
    width: 100%;
    height: 100%;
    border: none;
    background: var(--surf0);
}

/* Blocked-embed fallback. Behind the iframe by default (feature 29 pattern); promoted to a
   first-class FRONT state when the watchdog confirms the frame is blocked (.ifrnode.blocked). */
.canvas[b-o6b0i2za67]  .ifrnode .ifr-fallback {
    position: absolute;
    inset: 0;
    z-index: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    text-align: center;
    padding: 16px;
    pointer-events: none;
    background: var(--surf0);
}

/* Flip the card above the frame once detected-blocked, and let its buttons take clicks. */
.canvas[b-o6b0i2za67]  .ifrnode.blocked .ifr-fallback {
    z-index: 3;
    pointer-events: auto;
}

/* Classified failure-reason chip (proposal 40). A leading dot signals severity: --red for a
   hard fault (refused / unreachable / http error), --yellow for a soft timeout (.warn). */
.canvas[b-o6b0i2za67]  .ifrnode .ifr-fallback .fb-code {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: var(--mono);
    font-size: 9.5px;
    color: var(--fg-faint);
    background: var(--surf1);
    border: 1px solid var(--border2);
    border-radius: var(--r-xs);
    padding: 3px 6px;
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-fallback .fb-code::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--red);
    flex: none;
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-fallback .fb-code.warn::before { background: var(--yellow); }

.canvas[b-o6b0i2za67]  .ifrnode .ifr-fallback .fb-host {
    font-family: var(--mono);
    font-size: 10px;
    color: var(--fg-dim);
    max-width: 240px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-fallback .fb-title {
    font-family: var(--mono);
    font-size: 11px;
    color: var(--fg2);
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-fallback .fb-sub {
    font-family: var(--sans);
    font-size: 10px;
    line-height: 1.5;
    color: var(--fg-faint);
    max-width: 240px;
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-fallback .fb-btns {
    display: flex;
    gap: 6px;
    margin-top: 4px;
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-fallback .fb-btn {
    pointer-events: auto;
    font-family: var(--mono);
    font-size: 10px;
    background: var(--surf1);
    color: var(--fg-dim);
    border: 1px solid var(--border2);
    border-radius: var(--r-sm);
    padding: 5px 10px;
    cursor: pointer;
}

.canvas[b-o6b0i2za67]  .ifrnode .ifr-fallback .fb-btn.pri { color: var(--fg); }

.canvas[b-o6b0i2za67]  .ifrnode .ifr-fallback .fb-btn:hover {
    background: var(--hover);
    color: var(--fg);
}

/* Corner resize grip, bottom-right. */
.canvas[b-o6b0i2za67]  .ifrnode .ifr-grip {
    position: absolute;
    right: 2px;
    bottom: 2px;
    z-index: 2;
    width: 15px;
    height: 15px;
    cursor: nwse-resize;
    background: linear-gradient(135deg,
        transparent 0 46%, var(--border4) 46% 54%,
        transparent 54% 70%, var(--border4) 70% 78%, transparent 78%);
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-chpdfulsjd],
.components-reconnect-repeated-attempt-visible[b-chpdfulsjd],
.components-reconnect-failed-visible[b-chpdfulsjd],
.components-pause-visible[b-chpdfulsjd],
.components-resume-failed-visible[b-chpdfulsjd],
.components-rejoining-animation[b-chpdfulsjd] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-chpdfulsjd],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-chpdfulsjd],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-chpdfulsjd],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-chpdfulsjd],
#components-reconnect-modal.components-reconnect-retrying[b-chpdfulsjd],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-chpdfulsjd],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-chpdfulsjd],
#components-reconnect-modal.components-reconnect-failed[b-chpdfulsjd],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-chpdfulsjd] {
    display: block;
}


#components-reconnect-modal[b-chpdfulsjd] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-chpdfulsjd 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-chpdfulsjd 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-chpdfulsjd 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-chpdfulsjd]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-chpdfulsjd 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-chpdfulsjd {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-chpdfulsjd {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-chpdfulsjd {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-chpdfulsjd] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-chpdfulsjd] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-chpdfulsjd] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-chpdfulsjd] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-chpdfulsjd] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-chpdfulsjd] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-chpdfulsjd] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-chpdfulsjd 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-chpdfulsjd] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-chpdfulsjd {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
