﻿.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.loading-progress {
    position: absolute;
    display: block;
    width: 8rem;
    height: 8rem;
    inset: 20vh 0 auto 0;
    margin: 0 auto 0 auto;
}

    .loading-progress circle {
        fill: none;
        stroke: #e0e0e0;
        stroke-width: 0.6rem;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            stroke: #1b6ec2;
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.05s ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }

code {
    color: #c02d76;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}
/* Modular Patch Tools app */
/* Barlow (SIL Open Font License, see fonts/OFL.txt): a DIN-like face, as on module panels. Served with the app, so
   opening a patch asks nothing of any other site. The diagram's own text keeps the system face of the exports. */
@font-face { font-family: "Barlow"; font-weight: 400; font-display: swap; src: url("../fonts/barlow-400.woff2") format("woff2"); }
@font-face { font-family: "Barlow"; font-weight: 500; font-display: swap; src: url("../fonts/barlow-500.woff2") format("woff2"); }
@font-face { font-family: "Barlow"; font-weight: 600; font-display: swap; src: url("../fonts/barlow-600.woff2") format("woff2"); }
@font-face { font-family: "Barlow Semi Condensed"; font-weight: 500; font-display: swap; src: url("../fonts/barlow-semi-condensed-500.woff2") format("woff2"); }
@font-face { font-family: "Barlow Semi Condensed"; font-weight: 600; font-display: swap; src: url("../fonts/barlow-semi-condensed-600.woff2") format("woff2"); }

/* Our own light and dark themes: "only light" keeps a phone's forced dark mode off the light one (it would darken
   the page but leave the diagram's SVG fills light); in dark mode the page is dark already. */
:root { color-scheme: only light; }
@media (prefers-color-scheme: dark) { :root { color-scheme: dark; } }
html, body { margin: 0; }
body { background: #eef0f2; }
@media (prefers-color-scheme: dark) { body { background: #16171a; } }
/* The theme button overrides the system theme: the page around the diagram follows. */
body:has(.vpd-root[data-theme="light"]) { background: #eef0f2; color-scheme: light; }
body:has(.vpd-root[data-theme="dark"]) { background: #16171a; color-scheme: dark; }

.vpd-root.vpd-app {
  --ui-font: "Barlow", system-ui, -apple-system, "Segoe UI", sans-serif;
  --ui-condensed: "Barlow Semi Condensed", "Barlow", system-ui, sans-serif;
  /* The rail is the same metal in both themes. */
  --rail-top: #3d4148;
  --rail-bottom: #25282d;
  --rail-ink: #eceef1;
  --rail-muted: #a7acb4;
  --rail-alu: #c9ccd1;
  font-family: var(--ui-font);
  font-size: 15px;
  line-height: 1.4;
}
.vpd-app .vpd-toolbar, .vpd-app .vpd-panel, .vpd-app .vpd-menu .menu { font-family: var(--ui-font); }
.vpd-app :focus-visible { outline: 2px solid var(--vpd-gate); outline-offset: 2px; }
.vpd-app code { color: inherit; font-size: .92em; }

/* The rail */
.vpd-rail {
  position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 20px;
  padding: 7px 40px; min-height: 34px;
  color: var(--rail-ink);
  background:
    repeating-linear-gradient(180deg, rgb(255 255 255 / 3.5%) 0 1px, transparent 1px 3px),
    linear-gradient(180deg, var(--rail-top), var(--rail-bottom));
  border-top: 1px solid rgb(255 255 255 / 16%);
  border-bottom: 1px solid #101215;
  font-family: var(--ui-condensed);
}
/* The rail's mounting slots, one at each end. */
.vpd-rail::before, .vpd-rail::after {
  content: ""; position: absolute; top: 50%; width: 16px; height: 7px; margin-top: -4px; border-radius: 4px;
  background: #0e1012; box-shadow: inset 0 1px 2px rgb(0 0 0 / 70%), 0 1px 0 rgb(255 255 255 / 14%);
}
.vpd-rail::before { left: 14px; }
.vpd-rail::after { right: 14px; }
.rail-title { display: flex; align-items: center; gap: 12px; min-width: 0; }
.rail-title .name { font-size: 21px; font-weight: 600; letter-spacing: .01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rail-tabs { display: flex; gap: 2px; align-self: stretch; }
.rail-tabs button {
  font: inherit; font-size: 16px; font-weight: 500; color: var(--rail-muted); background: none; border: none; cursor: pointer;
  padding: 4px 12px; margin: -7px 0; border-bottom: 3px solid transparent;
}
.rail-tabs button:hover { color: var(--rail-ink); }
.rail-tabs button.active { color: var(--rail-ink); border-bottom-color: var(--rail-alu); }
.rail-end { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.rail-button {
  position: relative; display: inline-flex; align-items: center; font: inherit; font-size: 15px; font-weight: 500;
  color: var(--rail-ink); background: rgb(255 255 255 / 8%); border: 1px solid rgb(255 255 255 / 20%);
  border-radius: 5px; padding: 3px 11px; cursor: pointer; overflow: hidden;
}
.rail-button:hover { background: rgb(255 255 255 / 14%); }
/* The file input covers its button, invisible: click to choose, or drop a patch on it. */
.rail-button.file input, .vpd-drop input { position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; }
.rail-button.file input::file-selector-button, .vpd-drop input::file-selector-button { cursor: pointer; }

/* Drop-down menus (Options, Export, help): native <details>, closed by a click elsewhere (vpd.js). */
.vpd-menu { position: relative; }
.vpd-menu > summary { list-style: none; cursor: pointer; }
.vpd-menu > summary::-webkit-details-marker { display: none; }
.vpd-toolbar .vpd-menu > summary { padding: 4px 10px; border-radius: 5px; border: 1px solid var(--vpd-line); background: var(--vpd-panel); }
.vpd-toolbar .vpd-menu > summary::after { content: " ▾"; color: var(--vpd-muted); }
.vpd-toolbar .vpd-menu[open] > summary { border-color: var(--vpd-muted); }
.vpd-menu .menu {
  position: absolute; z-index: 30; top: calc(100% + 6px); left: 0; min-width: 200px;
  display: flex; flex-direction: column; gap: 8px; padding: 12px;
  background: var(--vpd-panel); color: var(--vpd-ink); border: 1px solid var(--vpd-line); border-radius: 8px;
  box-shadow: 0 8px 24px rgb(0 0 0 / 18%); font-size: 14px; white-space: nowrap;
}
.vpd-menu .menu label { display: flex; gap: 8px; align-items: center; cursor: pointer; }
.vpd-menu .menu select { font: inherit; margin-left: 4px; }
.vpd-menu .menu button { text-align: left; }
/* Help: short sections with room to breathe, not a block of text. */
.vpd-menu.help .menu { left: auto; right: 0; width: min(400px, calc(100vw - 32px)); white-space: normal; gap: 0; padding: 16px 18px; font-size: 14px; line-height: 1.6; }
.vpd-menu.help .menu h4 { margin: 18px 0 6px; font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--vpd-muted); }
.vpd-menu.help .menu h4:first-child { margin-top: 0; }
.vpd-menu.help .menu p { margin: 0; }
.vpd-menu.help .menu ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.vpd-menu.help .menu ul:not(.cable-legend) li { padding-left: 14px; position: relative; }
.vpd-menu.help .menu ul:not(.cable-legend) li::before { content: "•"; position: absolute; left: 0; color: var(--vpd-muted); }
.vpd-menu.help .menu b { font-weight: 600; }
.vpd-menu.help .cable-legend { gap: 6px; font-size: 13px; }
.vpd-menu.help .cable-legend li { display: flex; align-items: center; gap: 12px; }
.vpd-menu.help .cable-legend svg, .vpd-menu.help .insert-sample { flex: none; width: 32px; }
.vpd-menu.help .insert-sample { height: 12px; box-sizing: border-box; border: 1.5px dashed var(--vpd-muted); border-radius: 2px; }
.vpd-menu.help .menu p.private, .vpd-empty p.private {
  display: flex; gap: 10px; align-items: flex-start; margin: 0 0 18px; padding: 10px 12px; border-radius: 6px;
  background: color-mix(in srgb, var(--vpd-modulation) 14%, transparent); border: 1px solid color-mix(in srgb, var(--vpd-modulation) 45%, transparent);
}
.vpd-menu.help .menu p.private + h4 { margin-top: 0; }
.vpd-empty p.private { max-width: 640px; margin: 0 0 18px; font-size: 15px; }
.vpd-menu.help .menu p.private svg, .vpd-empty p.private svg { flex: none; margin-top: 2px; color: var(--vpd-modulation); }
/* The desktop or the touch wording, as everywhere else (the list display above would show both). */
@media (min-width: 701px) and (min-height: 501px) { .vpd-menu.help .menu ul.vpd-short { display: none; } }
@media (max-width: 700px), (max-height: 500px) { .vpd-menu.help .menu ul.vpd-long { display: none; } }
/* Narrow screens: the rail wraps, so the bubble is held to the screen edges rather than to its button. */
@media (max-width: 700px) { .vpd-menu.help .menu, .vpd-menu.about .menu { position: fixed; top: 64px; left: 16px; right: 16px; width: auto; max-height: calc(100dvh - 80px); overflow: auto; } }
/* The version button and its About menu: small, muted, out of the way. */
.rail-button.version { font-size: 12px; font-weight: 400; padding: 3px 7px; color: var(--rail-muted); }
.rail-button.version:hover { color: var(--rail-ink); }
.vpd-menu.about .menu { left: auto; right: 0; width: min(320px, calc(100vw - 32px)); white-space: normal; gap: 6px; }
.vpd-menu.about .menu p, .vpd-menu.about .menu ul { margin: 0; }
.vpd-menu.about .menu ul { padding-left: 18px; display: flex; flex-direction: column; gap: 4px; }
.vpd-menu.about .menu a { color: var(--vpd-gate); text-underline-offset: 3px; }
.vpd-menu.about .menu .muted { color: var(--vpd-muted); font-size: 13px; }
.vpd-menu.about .about-name { font-weight: 600; font-size: 15px; }
.vpd-menu.help > summary { padding: 3px 0; width: 28px; justify-content: center; font-weight: 600; }

/* Page */
.vpd-app .vpd-page { padding: 10px 12px; }
.vpd-error { color: var(--vpd-audio); margin: 0 0 10px; }
.vpd-link { background: none; border: none; color: var(--vpd-gate); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; font: inherit; padding: 0; }

/* Before a patch: what the tool does, and where to drop one. */
.vpd-empty { max-width: 620px; margin: 9vh auto 0; display: flex; flex-direction: column; align-items: flex-start; gap: 18px; }
.vpd-empty .lead { font-size: 19px; line-height: 1.45; margin: 0; }
.vpd-drop {
  position: relative; align-self: stretch; padding: 44px 20px; text-align: center; font-size: 16px; color: var(--vpd-muted);
  border: 2px dashed var(--vpd-line); border-radius: 10px; background: var(--vpd-panel);
}
.vpd-drop:hover, .vpd-drop:focus-within { border-color: var(--vpd-muted); color: var(--vpd-ink); }

/* One row of tools above the diagram: groups of quiet buttons, the layers as chips in their cable color. */
.vpd-app .vpd-toolbar { gap: 8px 18px; margin: 0 0 10px; font-size: 14px; }
.vpd-app .vpd-toolbar button { padding: 4px 10px; border-radius: 5px; }
.vpd-app .vpd-toolbar .group.zoom { margin-left: auto; }
.vpd-app .vpd-toolbar .group { min-width: 0; max-width: 100%; }
.vpd-toolbar .layers { gap: 4px; }
.vpd-toolbar button.layer { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px 3px 4px; border-radius: 14px; border-style: dashed; color: var(--vpd-muted); }
.vpd-toolbar button.layer .num {
  display: inline-grid; place-items: center; width: 19px; height: 19px; border-radius: 50%;
  font-family: var(--ui-condensed); font-size: 12px; font-weight: 600; border: 1.5px solid var(--c); color: var(--c);
}
.vpd-toolbar button.layer.on { border-style: solid; border-color: var(--c); color: var(--vpd-ink); background: color-mix(in srgb, var(--c) 12%, var(--vpd-panel)); }
.vpd-toolbar button.layer.on .num { background: var(--c); color: var(--vpd-panel); }

/* The diagram reads better with lane titles in plain case (the exports keep theirs). */
.vpd-app .vpd-band text { text-transform: none; letter-spacing: 0; font-size: 13px; }
/* Lane titles follow the scroll (vpd.js). Away from their place they pass over boxes and cables: a plate keeps them
   readable there, and lets clicks through to the boxes unless the title folds its lane back. */
.vpd-band-title { pointer-events: none; }
.vpd-band-title.unfolded { pointer-events: auto; }
.vpd-band.vpd-band-title .plate { stroke: var(--vpd-line); stroke-dasharray: none; opacity: 0; transition: opacity .12s; }
.vpd-band.vpd-band-title.stuck .plate { opacity: .94; }
@media (prefers-reduced-motion: reduce) { .vpd-band.vpd-band-title .plate { transition: none; } }
.vpd-edge { cursor: pointer; }
.vpd-edge.selected path:not(.hit) { stroke-width: 4; }

/* Cable intent and module details: a sheet docked at the bottom of the screen, on every screen size. Under the diagram,
   it would push the page down and take the top of the diagram out of view. */
.vpd-panel {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; max-height: 45dvh; overflow: auto; box-sizing: border-box;
  padding: 14px 18px; background: var(--vpd-panel); border-top: 1px solid var(--vpd-line);
  box-shadow: 0 -6px 20px rgb(0 0 0 / 18%); font-size: 14px;
  animation: vpd-sheet-in .16s ease-out;
}
@keyframes vpd-sheet-in { from { transform: translateY(16px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .vpd-panel { animation: none; } }
/* While the sheet is open and covers part of a diagram too tall for the room left above it, the diagram scrolls on past
   its bottom edge by just that much: every box can still be brought above the sheet. Set by vpd.js. */
.vpd-scroll::after { content: ""; display: block; height: var(--sheet-room, 0px); }
.vpd-panel input[type=text] { width: 100%; box-sizing: border-box; font: inherit; padding: 6px 8px; margin-top: 8px; border-radius: 6px; border: 1px solid var(--vpd-line); background: var(--vpd-bg); color: var(--vpd-ink); }
.vpd-panel .muted { color: var(--vpd-muted); }
.vpd-panel .close { float: right; margin: -6px -8px 0 8px; font: inherit; font-size: 22px; line-height: 1; padding: 4px 8px; border: none; background: none; color: var(--vpd-muted); cursor: pointer; }
.vpd-panel .close:hover { color: var(--vpd-ink); }
.vpd-panel .lib-link { display: inline-block; color: var(--vpd-gate); text-underline-offset: 3px; }
/* A module: its panel on the left, as in a rack, its name and ports on the right; the role color along the top. */
.vpd-panel.module { display: flex; align-items: flex-start; gap: 20px; border-top: 3px solid var(--role-color); }
.vpd-panel .panel-shot { flex: none; height: 200px; width: auto; border-radius: 3px; box-shadow: 0 1px 6px rgb(0 0 0 / 30%); }
.vpd-panel .sheet-body { flex: 1; min-width: 0; }
.vpd-panel h2 { margin: 0 0 10px; font-family: var(--ui-condensed); font-size: 21px; font-weight: 600; line-height: 1.2; }
.vpd-panel h2 .muted { font-family: var(--ui-font); font-size: 15px; font-weight: 400; margin-left: 4px; }
.vpd-panel .icon { fill: none; stroke: var(--role-color); stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; vertical-align: -2px; margin-right: 8px; }
.vpd-panel .ports { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 320px)); gap: 4px 24px; }
.vpd-panel h3 { margin: 0 0 4px; font-family: var(--ui-condensed); font-size: 14px; font-weight: 600; color: var(--vpd-muted); }
.vpd-panel ul { list-style: none; margin: 0 0 10px; padding: 0; }
.vpd-panel li { padding: 2px 0; }
.vpd-panel .sig { display: inline-block; width: 14px; height: 3px; border-radius: 2px; background: var(--c); margin-right: 8px; vertical-align: 4px; }
.vpd-panel p { margin: 0 0 8px; }
/* The panel shot is a button: a click shows it full height. */
.vpd-panel .panel-zoom { flex: none; padding: 0; border: none; background: none; cursor: zoom-in; border-radius: 3px; line-height: 0; }
.vpd-panel .panel-zoom:focus-visible { outline: 2px solid var(--vpd-gate); outline-offset: 3px; }
/* A module official Cardinal can't load: said under its name, with the color of how bad it is. */
.vpd-panel .cardinal-note { max-width: 70ch; padding: 2px 0 2px 10px; border-left: 3px solid var(--vpd-pitch); }
.vpd-panel .cardinal-note.missing { border-left-color: var(--vpd-audio); }
.vpd-panel .cardinal-note a { color: inherit; text-underline-offset: 3px; }
/* The panel enlarged: the module as if pulled out of the rack, its name on a strip under it. */
.vpd-zoom { padding: 0; border: none; background: none; overflow: visible; max-width: 92vw; max-height: 94dvh; }
.vpd-zoom::backdrop { background: rgb(10 11 13 / 72%); backdrop-filter: blur(3px); }
.vpd-zoom[open] { display: flex; flex-direction: column; align-items: center; gap: 10px; animation: vpd-zoom-in .18s ease-out; }
.vpd-zoom img { display: block; height: calc(94dvh - 46px); width: auto; max-width: 92vw; object-fit: contain; border-radius: 4px; box-shadow: 0 18px 50px rgb(0 0 0 / 55%), 0 2px 6px rgb(0 0 0 / 40%); }
.vpd-zoom .caption { display: flex; align-items: center; gap: 10px; margin: 0; color: #ececee; font-family: var(--ui-condensed); font-size: 18px; font-weight: 600; }
.vpd-zoom .close { font: inherit; font-size: 24px; line-height: 1; padding: 2px 8px; border: none; border-radius: 4px; background: none; color: #a7acb4; cursor: pointer; }
.vpd-zoom .close:hover, .vpd-zoom .close:focus-visible { color: #fff; }
.vpd-zoom .close:focus-visible { outline: 2px solid #5cb8ff; }
@keyframes vpd-zoom-in { from { transform: scale(.96); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .vpd-zoom[open] { animation: none; } }

.vpd-info dl { display: grid; grid-template-columns: max-content 1fr; gap: 4px 16px; margin: 0 0 12px; font-size: 14px; }
.vpd-info dt { color: var(--vpd-muted); }
.vpd-info dd { margin: 0; overflow-wrap: anywhere; }
.vpd-info dd ul.loops { margin: 0; padding: 0; list-style: none; }
.vpd-info .info-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 20px; margin: 0 0 8px; }
.vpd-info .library-all { font-size: 13px; text-underline-offset: 3px; }
.vpd-info button.instances { margin-left: 6px; padding: 0 6px; border: 1px solid var(--vpd-line); border-radius: 9px; background: none; color: var(--vpd-muted); font: inherit; font-size: 12px; cursor: pointer; }
.vpd-info button.instances:hover { color: var(--vpd-ink); }
.vpd-info tr.instance td { color: var(--vpd-muted); font-size: 13px; }
.vpd-info tr.instance td:first-child { padding-left: 34px; }
.vpd-info .info-option { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 13px; color: var(--vpd-muted); cursor: pointer; }
.vpd-info table { border-collapse: collapse; font-size: 14px; width: 100%; max-width: 960px; }
.vpd-info th, .vpd-info td { text-align: left; padding: 4px 10px 4px 0; border-bottom: 1px solid var(--vpd-line); }
.vpd-info th { color: var(--vpd-muted); font-weight: 600; }
.vpd-info .chip { display: inline-block; width: 10px; height: 10px; border-radius: 3px; background: var(--role-color); margin-right: 6px; vertical-align: -1px; }
.vpd-info a, .vpd-convert a { color: inherit; }
.vpd-convert { font-size: 14px; }
.vpd-convert .muted { color: var(--vpd-muted); }

/* Catalog tab: the user's own module descriptions */
.vpd-modules { font-size: 14px; max-width: 960px; }
.vpd-modules .lead { max-width: 760px; margin: 0 0 12px; }
.vpd-modules .muted { color: var(--vpd-muted); }
.vpd-modules h2 { font-family: var(--ui-condensed); font-size: 18px; margin: 18px 0 6px; }
.vpd-modules table { border-collapse: collapse; width: 100%; }
.vpd-modules th, .vpd-modules td { text-align: left; padding: 4px 10px 4px 0; border-bottom: 1px solid var(--vpd-line); vertical-align: top; }
.vpd-modules th { color: var(--vpd-muted); font-weight: 600; }
.vpd-modules td .muted { display: block; font-size: 12px; overflow-wrap: anywhere; }
.vpd-modules td .vpd-link + .vpd-link { margin-left: 10px; }
.vpd-modules tr.in-patch td:first-child { border-left: 3px solid var(--vpd-gate); padding-left: 6px; }
.vpd-modules .file-button { position: relative; display: inline-block; padding: 4px 10px; border-radius: 5px; border: 1px solid var(--vpd-line); background: var(--vpd-panel); cursor: pointer; }
.vpd-modules .file-button:hover { border-color: var(--vpd-muted); }
.vpd-modules .file-button input { position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; }
.vpd-modules .vpd-help { max-width: 760px; margin: 0 0 12px; }
.vpd-modules .vpd-help summary { cursor: pointer; color: var(--vpd-gate); }
.vpd-modules .vpd-help p { margin: 6px 0; }
.vpd-modules .vpd-notice.warn { border-left-color: var(--vpd-audio); }
.vpd-modules .vpd-notice summary { cursor: pointer; color: var(--vpd-muted); }
.module-editor { margin: 6px 0 14px; padding: 12px 14px; background: var(--vpd-panel); border: 1px solid var(--vpd-line); border-radius: 8px; }
.module-editor h2 { margin-top: 0; overflow-wrap: anywhere; }
.module-editor input[type=text], .module-editor select { font: inherit; padding: 4px 6px; border-radius: 5px; border: 1px solid var(--vpd-line); background: var(--vpd-bg); color: var(--vpd-ink); box-sizing: border-box; }
.module-editor .fields { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-bottom: 10px; }
.module-editor .fields label { display: flex; align-items: center; gap: 6px; }
.module-editor .fields input[type=text] { width: min(320px, 70vw); }
.module-editor .tags summary { cursor: pointer; margin-bottom: 6px; }
.module-editor .tag-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 2px 12px; margin-bottom: 10px; }
.module-editor .port-lists { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; }
.module-editor fieldset { border: 1px solid var(--vpd-line); border-radius: 6px; margin: 0; padding: 6px 10px 10px; min-width: 0; }
.module-editor fieldset .muted { margin: 0 0 6px; font-size: 12px; }
.module-editor ol { margin: 0 0 8px; padding-left: 2.2em; }
.module-editor ol li { margin: 2px 0; }
.module-editor ol input[type=text] { width: 100%; }
.module-editor button, .vpd-modules .vpd-help button { font: inherit; padding: 4px 10px; border-radius: 5px; border: 1px solid var(--vpd-line); background: var(--vpd-bg); color: var(--vpd-ink); cursor: pointer; }
.module-editor button:hover:not(:disabled), .vpd-modules .vpd-help button:hover { border-color: var(--vpd-muted); }
.module-editor button:disabled { opacity: .5; cursor: default; }
.module-editor .actions { display: flex; gap: 8px; margin-top: 12px; }
.module-editor .actions .primary { font-weight: 600; }
.vpd-panel .describe { display: block; margin: 0 0 8px; text-align: left; }
.vpd-notice { max-width: 760px; margin: 0 0 12px; padding: 8px 12px; border-left: 3px solid var(--vpd-pitch); background: var(--vpd-panel); border-radius: 0 6px 6px 0; }
.vpd-notice p { margin: 0 0 4px; }
.vpd-notice p:last-child { margin-bottom: 0; }
.vpd-notice .modules { color: var(--vpd-muted); overflow-wrap: anywhere; }
.vpd-notice.missing { border-left-color: var(--vpd-audio); }
.vpd-info td.cardinal-missing { color: var(--vpd-audio); }
.vpd-info td.cardinal-neilbgredition a { color: var(--vpd-pitch); text-underline-offset: 3px; }

/* The Diagram tab's notes: one line under the diagram, opened on demand, never taking more than a third of the window. */
.vpd-diag.notes { margin-top: 8px; }
.vpd-diag.notes summary { cursor: pointer; width: fit-content; }
.vpd-diag.notes summary:hover { color: var(--vpd-ink); }
.vpd-diag.notes ul { margin: 6px 0 0; padding-left: 20px; max-height: 33dvh; overflow: auto; }

@media (min-width: 701px) and (min-height: 501px) {
  .vpd-short { display: none; }
  /* Desktop: the Diagram tab fits the window under the rail, the diagram taking whatever height the toolbar leaves.
     The page itself doesn't scroll, so the top of the diagram never goes out of view. */
  .vpd-app:has(.vpd-scroll) { height: 100dvh; display: flex; flex-direction: column; }
  .vpd-app:has(.vpd-scroll) > .vpd-rail { flex: none; }
  .vpd-app:has(.vpd-scroll) > .vpd-page { flex: 1 1 auto; min-height: 0; box-sizing: border-box; display: flex; flex-direction: column; }
  .vpd-app .vpd-page > * { flex: none; }
  .vpd-app .vpd-page > .vpd-root.interactive { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
  .vpd-app .vpd-root.interactive > .vpd-scroll { flex: 1 1 auto; max-height: none; }
}
@media (max-width: 700px), (max-height: 500px) {
  .vpd-long { display: none; }
  .vpd-rail { padding: 6px 34px; gap: 4px 12px; }
  .vpd-rail::before { left: 10px; }
  .vpd-rail::after { right: 10px; }
  .rail-title .name { font-size: 18px; }
  .rail-tabs { order: 3; width: 100%; }
  .rail-tabs button { margin: 0; padding: 4px 10px; }
  .vpd-app .vpd-page { padding: 6px 8px; }
  .vpd-app .vpd-toolbar .group.zoom { margin-left: 0; }
  .vpd-app .vpd-toolbar { gap: 6px 10px; }
  .vpd-toolbar button.layer { padding-right: 8px; gap: 4px; }
  .vpd-empty { margin-top: 4vh; }
  .vpd-empty .lead { font-size: 17px; }
  .vpd-panel { padding: 12px 14px; }
  .vpd-panel.module { gap: 12px; }
  .vpd-panel .panel-shot { height: 140px; }
}
