/* MyVPN Manager — patch-bay styling on top of Bootstrap 5.3.
   Idea: a public name is "plugged" into a device. Rows draw that cable.
   No inline styles anywhere (strict CSP), so everything lives here. */

@font-face {
  font-family: "Manrope";
  src: url("../fonts/manrope-latin-wght-normal.woff2") format("woff2");
  font-weight: 200 800;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/jetbrains-mono-latin-wght-normal.woff2") format("woff2");
  font-weight: 100 800;
  font-display: swap;
}

:root {
  --font-ui: "Manrope", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --bg: #e8ecef;          /* rack grey */
  --surface: #f8fafb;     /* panel */
  --surface-2: #eef2f4;   /* recessed */
  --ink: #111c26;
  --muted: #55636f;
  --line: #cbd3d9;
  --cable: #1b5edb;
  --cable-soft: #dce8fb;
  --led: #1fa463;
  --amber: #b86e08;
  --danger: #c23b3b;
  --radius: 14px;
  --radius-sm: 9px;
  --shadow: 0 1px 0 rgba(17, 28, 38, .04), 0 8px 24px -14px rgba(17, 28, 38, .25);

  --bs-body-font-family: var(--font-ui);
  --bs-body-bg: var(--bg);
  --bs-body-color: var(--ink);
  --bs-secondary-color: var(--muted);
  --bs-border-color: var(--line);
  --bs-link-color: var(--cable);
  --bs-link-hover-color: var(--cable);
  --bs-focus-ring-color: color-mix(in srgb, var(--cable) 30%, transparent);
}

[data-bs-theme="dark"] {
  --bg: #0b1218;
  --surface: #131d26;
  --surface-2: #0f1820;
  --ink: #e6edf3;
  --muted: #93a1ad;
  --line: #263442;
  --cable: #6aa5ff;
  --cable-soft: #17293f;
  --led: #3dd68c;
  --amber: #e3a03a;
  --danger: #f27b82;
  --shadow: 0 1px 0 rgba(255, 255, 255, .03), 0 10px 28px -16px rgba(0, 0, 0, .8);
  --bs-body-bg: var(--bg);
  --bs-body-color: var(--ink);
  --bs-border-color: var(--line);
}

html { scroll-padding-top: 5rem; }
body {
  background: var(--bg);
  color: var(--ink);
  font-feature-settings: "ss01", "cv11";
  -webkit-font-smoothing: antialiased;
}
.mono, code { font-family: var(--font-mono); font-size: .92em; }
code { color: inherit; background: none; padding: 0; }
.flex-none { flex: none; }

/* Shared building blocks -------------------------------------------------- */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.icon { width: 1.15rem; height: 1.15rem; flex: none; }
:focus-visible { outline: 2px solid var(--cable); outline-offset: 2px; border-radius: 6px; }

.btn { --bs-btn-font-weight: 600; --bs-btn-border-radius: var(--radius-sm); display: inline-flex; align-items: center; justify-content: center; gap: .45rem; }
.btn-primary {
  --bs-btn-bg: var(--cable); --bs-btn-border-color: var(--cable); --bs-btn-color: #fff;
  --bs-btn-hover-bg: color-mix(in srgb, var(--cable) 88%, #000); --bs-btn-hover-border-color: color-mix(in srgb, var(--cable) 88%, #000); --bs-btn-hover-color: #fff;
  --bs-btn-active-bg: color-mix(in srgb, var(--cable) 80%, #000); --bs-btn-active-border-color: color-mix(in srgb, var(--cable) 80%, #000); --bs-btn-active-color: #fff;
  --bs-btn-disabled-bg: var(--cable); --bs-btn-disabled-border-color: var(--cable);
}
[data-bs-theme="dark"] .btn-primary { --bs-btn-color: #06121f; --bs-btn-hover-color: #06121f; --bs-btn-active-color: #06121f; }
.btn-outline-secondary {
  --bs-btn-color: var(--ink); --bs-btn-border-color: var(--line);
  --bs-btn-hover-bg: var(--surface-2); --bs-btn-hover-color: var(--ink); --bs-btn-hover-border-color: var(--muted);
  --bs-btn-active-bg: var(--surface-2); --bs-btn-active-color: var(--ink); --bs-btn-active-border-color: var(--muted);
}
.btn-ghost { --bs-btn-color: var(--ink); --bs-btn-hover-bg: color-mix(in srgb, var(--ink) 8%, transparent); --bs-btn-hover-color: var(--ink); --bs-btn-border-color: transparent; --bs-btn-hover-border-color: transparent; --bs-btn-active-bg: color-mix(in srgb, var(--ink) 12%, transparent); --bs-btn-active-color: var(--ink); --bs-btn-active-border-color: transparent; border: 1px solid transparent; }
.btn-icon { padding: .45rem; }

.form-control, .input-group-text {
  background-color: var(--surface); color: var(--ink); border-color: var(--line);
  border-radius: var(--radius-sm);
}
.form-control::placeholder { color: color-mix(in srgb, var(--muted) 70%, transparent); }
.form-control:focus { background-color: var(--surface); color: var(--ink); border-color: var(--cable); box-shadow: 0 0 0 .2rem var(--bs-focus-ring-color); }
.input-group > .form-control:not(:last-child) { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.input-group-text { background: var(--surface-2); color: var(--muted); }
.form-text { color: var(--muted); font-size: .8125rem; }
.invalid-feedback { color: var(--danger); font-size: .8125rem; }
.form-control.is-invalid { border-color: var(--danger); background-image: none; padding-right: .75rem; }
.alert { border-radius: var(--radius-sm); }

/* Top bar ----------------------------------------------------------------- */
.topbar { position: sticky; top: 0; z-index: 30; background: color-mix(in srgb, var(--bg) 88%, transparent); backdrop-filter: blur(10px); border-bottom: 1px solid var(--line); }
.topbar-inner { display: flex; align-items: center; gap: 1rem; min-height: 3.75rem; }
.brand { display: inline-flex; align-items: center; gap: .6rem; color: var(--ink); text-decoration: none; }
.brand-name { font-weight: 800; letter-spacing: -.02em; font-size: 1.15rem; }
.brand-mark { width: 2.4rem; height: 2.4rem; color: var(--ink); }
.brand-mark-sm { width: 1.9rem; height: 1.9rem; }
.topbar-domain { color: var(--muted); font-size: .85rem; padding: .2rem .55rem; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); }
.topbar-actions { margin-left: auto; display: flex; align-items: center; gap: .25rem; }
#themeToggle .icon-moon { display: none; }
[data-bs-theme="dark"] #themeToggle .icon-sun { display: none; }
[data-bs-theme="dark"] #themeToggle .icon-moon { display: block; }

/* Workspace layout -------------------------------------------------------- */
.workspace { padding-top: 1.5rem; padding-bottom: 4rem; }
.workspace-grid { display: grid; gap: 1.5rem; grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 992px) {
  .workspace-grid { grid-template-columns: minmax(320px, 400px) minmax(0, 1fr); gap: 2rem; }
  .form-shell { position: sticky; top: 5.25rem; }
}

.panel {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.25rem; box-shadow: var(--shadow);
}
.offcanvas-lg .offcanvas-body { padding: 0; }
@media (max-width: 991.98px) {
  .form-shell.offcanvas-bottom { height: auto; max-height: 92vh; background: var(--bg); border-top: 1px solid var(--line); border-radius: var(--radius) var(--radius) 0 0; --bs-offcanvas-bg: var(--bg); --bs-offcanvas-color: var(--ink); }
  .form-shell .offcanvas-body { padding: 0 1rem 1rem; }
  .form-shell .panel { border: 0; box-shadow: none; padding: .25rem 0 0; background: transparent; }
}
.panel-head { align-items: center; justify-content: space-between; margin-bottom: 1rem; }
.panel-title { font-size: 1.15rem; font-weight: 800; letter-spacing: -.01em; margin: 0; }
.panel.is-editing { border-color: var(--cable); box-shadow: 0 0 0 3px var(--cable-soft), var(--shadow); }

.field { margin: 0 0 1.15rem; padding: 0; border: 0; min-width: 0; }
.field-label { display: block; float: none; width: auto; padding: 0; margin: 0 0 .4rem; font-size: .875rem; font-weight: 700; color: var(--ink); }
.panel-actions { display: flex; gap: .6rem; margin-top: 1.5rem; }
.panel-actions .btn-primary { flex: 1; padding-top: .6rem; padding-bottom: .6rem; }
.form-error { margin-top: 1rem; margin-bottom: 0; font-size: .9rem; }

/* Segmented radio groups */
.segmented { display: grid; grid-template-columns: 1fr 1fr 1.5fr; gap: 3px; padding: 3px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 11px; }
.segmented-2 { grid-template-columns: 1fr 1fr; }
.segmented-eq { grid-template-columns: repeat(3, 1fr); }
.segment { text-align: center; padding: .5rem .4rem; border-radius: 8px; font-size: .875rem; font-weight: 600; color: var(--muted); cursor: pointer; user-select: none; transition: background-color .15s, color .15s; white-space: nowrap; }
.segment:hover { color: var(--ink); }
.btn-check:checked + .segment { background: var(--surface); color: var(--ink); box-shadow: 0 0 0 1px var(--line), 0 1px 3px rgba(17, 28, 38, .12); }
.btn-check:focus-visible + .segment { outline: 2px solid var(--cable); outline-offset: 1px; }

/* URL preview: the slug is the point, the domain recedes */
.preview { margin-top: .9rem; padding: .7rem .85rem; background: var(--cable-soft); border-radius: var(--radius-sm); }
.preview-label { display: block; font-size: .75rem; font-weight: 600; color: var(--muted); margin-bottom: .1rem; }
.preview-row { display: flex; align-items: center; gap: .25rem; }
.preview-url { flex: 1; min-width: 0; overflow-wrap: anywhere; font-size: .95rem; line-height: 1.45; color: var(--muted); }
.preview-url b { font-weight: 700; color: var(--ink); }
#regenerate.is-spinning .icon { animation: spin .5s linear; }
@keyframes spin { to { transform: rotate(360deg); } }

/* List -------------------------------------------------------------------- */
.list-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .75rem; margin-bottom: 1rem; }
.list-title { font-size: 1.15rem; font-weight: 800; letter-spacing: -.01em; margin: 0; display: flex; align-items: center; gap: .55rem; }
.count { font-size: .8rem; font-weight: 700; color: var(--muted); background: var(--surface); border: 1px solid var(--line); border-radius: 999px; padding: .05rem .55rem; }
.search { position: relative; flex: 1 1 14rem; max-width: 22rem; }
.search .icon { position: absolute; left: .7rem; top: 50%; transform: translateY(-50%); color: var(--muted); pointer-events: none; }
.search .form-control { padding-left: 2.2rem; }

.link-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .75rem; }
.link-row {
  --row-pad: 1rem;
  display: grid; grid-template-columns: minmax(0, 1.4fr) 3rem minmax(11rem, 1fr); align-items: center; column-gap: .25rem; row-gap: .6rem;
  padding: var(--row-pad) 1.1rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.link-row.is-fresh { animation: settle 1.6s ease-out; }
@keyframes settle { 0% { background: var(--cable-soft); border-color: var(--cable); } 100% { background: var(--surface); border-color: var(--line); } }
.link-row.is-invalid { border-color: color-mix(in srgb, var(--amber) 55%, var(--line)); }

.link-main { display: flex; align-items: center; gap: .7rem; min-width: 0; }
.led { width: .6rem; height: .6rem; border-radius: 50%; flex: none; background: var(--led); box-shadow: 0 0 0 3px color-mix(in srgb, var(--led) 22%, transparent); }
.is-invalid .led { background: var(--amber); box-shadow: 0 0 0 3px color-mix(in srgb, var(--amber) 22%, transparent); }
.link-url { min-width: 0; font-family: var(--font-mono); text-decoration: none; overflow-wrap: anywhere; color: var(--muted); line-height: 1.3; display: flex; flex-direction: column; }
.link-url .slug { color: var(--ink); font-weight: 700; font-size: 1.05rem; }
.link-url .domain { font-size: .8rem; }
.link-url:hover .slug { color: var(--cable); }

/* The cable: a line with round plugs joining name to device */
.link-cable { position: relative; height: 2px; background: var(--cable); border-radius: 2px; margin: 0 .1rem; opacity: .85; }
.link-cable::before, .link-cable::after { content: ""; position: absolute; top: 50%; width: .5rem; height: .5rem; margin-top: -.25rem; border-radius: 50%; background: var(--cable); }
.link-cable::before { left: -.25rem; }
.link-cable::after { right: -.25rem; }
.is-invalid .link-cable { background: repeating-linear-gradient(90deg, var(--amber) 0 5px, transparent 5px 9px); opacity: 1; }
.is-invalid .link-cable::before, .is-invalid .link-cable::after { background: var(--amber); }

.link-target { min-width: 0; display: flex; flex-direction: column; gap: .3rem; }
.target-addr { font-family: var(--font-mono); font-weight: 600; font-size: .95rem; white-space: nowrap; }
.target-addr .port { color: var(--muted); font-weight: 500; }
.chips { display: flex; flex-wrap: wrap; gap: .35rem; }
.chip { font-size: .75rem; font-weight: 600; padding: .1rem .5rem; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--line); color: var(--muted); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chip.chip-https { color: var(--cable); border-color: color-mix(in srgb, var(--cable) 40%, var(--line)); }
.link-problem { grid-column: 1 / -1; display: flex; gap: .5rem; align-items: flex-start; font-size: .85rem; color: var(--amber); }
.link-problem .icon { margin-top: .1rem; }

.link-actions { grid-column: 1 / -1; display: flex; gap: .25rem; justify-content: flex-end; padding-top: .55rem; border-top: 1px solid var(--line); }
@media (min-width: 1400px) {
  /* Wide screens have room for everything on one line. */
  .link-row { grid-template-columns: minmax(0, 1.4fr) 3rem minmax(11rem, 1fr) auto; }
  .link-actions { grid-column: auto; padding-top: 0; border-top: 0; }
}
.link-actions .btn { padding: .4rem .65rem; font-size: .875rem; }
.link-actions .btn-copy { --bs-btn-color: var(--cable); --bs-btn-hover-color: var(--cable); background: var(--cable-soft); }
.link-actions .btn-copy:hover { background: color-mix(in srgb, var(--cable) 22%, var(--surface)); }
.link-actions .btn-delete:hover { --bs-btn-hover-color: var(--danger); color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); }

@media (max-width: 767.98px) {
  .link-row { grid-template-columns: minmax(0, 1fr); row-gap: .5rem; }
  .link-cable { width: 2px; height: 1.1rem; margin: 0 0 0 .25rem; }
  .link-cable::before { left: 50%; top: -.2rem; margin: 0 0 0 -.25rem; }
  .link-cable::after { left: 50%; right: auto; top: auto; bottom: -.2rem; margin: 0 0 0 -.25rem; }
  .is-invalid .link-cable { background: repeating-linear-gradient(180deg, var(--amber) 0 5px, transparent 5px 9px); }
  .link-target { padding-left: 1.3rem; }
  .link-actions { justify-content: stretch; }
  .link-actions .btn { flex: 1; padding: .55rem .5rem; }
}

/* Empty state */
.empty { text-align: center; padding: 3rem 1rem; border: 1.5px dashed var(--line); border-radius: var(--radius); }
.empty-art { width: 9rem; height: auto; margin-bottom: .5rem; }
.empty-port { fill: var(--surface-2); stroke: var(--muted); stroke-width: 2; }
.empty-cable { fill: none; stroke: var(--cable); stroke-width: 3; stroke-linecap: round; }
.empty-cable-gap { stroke-dasharray: 2 8; }
.empty-title { font-size: 1.05rem; font-weight: 800; margin: 0 0 .25rem; }
.empty-text { color: var(--muted); margin: 0 auto 1rem; max-width: 28ch; }

/* Toast ------------------------------------------------------------------- */
.toast-holder { position: fixed; left: 0; right: 0; bottom: max(1rem, env(safe-area-inset-bottom)); display: flex; justify-content: center; pointer-events: none; z-index: 2000; padding: 0 1rem; }
.toast-msg { pointer-events: auto; background: var(--ink); color: var(--bg); padding: .6rem 1rem; border-radius: 999px; font-weight: 600; font-size: .9rem; box-shadow: 0 10px 30px -10px rgba(0, 0, 0, .5); }
.toast-msg.is-error { background: var(--danger); color: #fff; }

/* Modal */
.modal-content { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); }
.modal-content code { overflow-wrap: anywhere; }

/* Login / error pages ------------------------------------------------------ */
.auth-body { min-height: 100vh; background: var(--bg); background-image: radial-gradient(color-mix(in srgb, var(--ink) 9%, transparent) 1.2px, transparent 1.4px); background-size: 22px 22px; }
.auth { min-height: 100vh; display: grid; grid-template-columns: minmax(0, 1fr); align-items: center; max-width: 68rem; margin: 0 auto; padding: 1.5rem; gap: 2rem; }
.auth-single { max-width: 34rem; }
@media (min-width: 900px) { .auth:not(.auth-single) { grid-template-columns: minmax(0, 26rem) minmax(0, 1fr); gap: 4rem; } }
.auth-panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 2rem; box-shadow: var(--shadow); }
.auth-title { font-size: 1.6rem; font-weight: 800; letter-spacing: -.02em; margin: 1rem 0 .4rem; }
.auth-lede { color: var(--muted); margin-bottom: 1.5rem; overflow-wrap: anywhere; }
.auth-form .form-label { font-weight: 700; font-size: .875rem; }
.auth-art { display: none; }
@media (min-width: 900px) { .auth-art { display: block; } }
.patch-art { width: 100%; height: auto; max-height: 30rem; }
.patch-ports rect { fill: var(--surface); stroke: var(--line); stroke-width: 2; }
.patch-cables path { fill: none; stroke: var(--cable); stroke-width: 4; stroke-linecap: round; }
.patch-leds circle { fill: var(--led); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* Link lifetime ------------------------------------------------------------ */
.form-select { background-color: var(--surface); color: var(--ink); border-color: var(--line); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; max-width: 8.5rem; }
.form-select:focus { border-color: var(--cable); box-shadow: 0 0 0 .2rem var(--bs-focus-ring-color); }
.presets { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .6rem; }
.preset { border: 1px solid var(--line); background: var(--surface-2); color: var(--muted); border-radius: 999px; padding: .15rem .7rem; font-size: .8125rem; font-weight: 600; }
.preset:hover { color: var(--ink); border-color: var(--muted); }
.preset.is-active { color: var(--cable); border-color: var(--cable); background: var(--cable-soft); }
input[type="datetime-local"].form-control { font-family: var(--font-mono); font-size: .92rem; }

.chip.chip-expiry { color: var(--cable); border-color: color-mix(in srgb, var(--cable) 40%, var(--line)); }
.chip.chip-soon { color: var(--amber); border-color: color-mix(in srgb, var(--amber) 55%, var(--line)); background: color-mix(in srgb, var(--amber) 10%, var(--surface-2)); }
.chip.chip-expired { color: var(--muted); border-style: dashed; }
.link-row.is-expired .led { background: var(--muted); box-shadow: 0 0 0 3px color-mix(in srgb, var(--muted) 20%, transparent); }
.link-row.is-expired .link-url,
.link-row.is-expired .target-addr { opacity: .6; }
.link-row.is-expired .link-cable { background: repeating-linear-gradient(90deg, var(--muted) 0 3px, transparent 3px 8px); opacity: .8; }
.link-row.is-expired .link-cable::before,
.link-row.is-expired .link-cable::after { background: var(--muted); }
@media (max-width: 767.98px) {
  .link-row.is-expired .link-cable { background: repeating-linear-gradient(180deg, var(--muted) 0 3px, transparent 3px 8px); }
}
