:root {
  --bg: #0b0f14; --panel: #121821; --panel2: #18202b; --line: #243040; --text: #d7e1ea; --muted: #7d8fa1;
  --green: #39ff8a; --green-d: #1c7a45; --amber: #ffb020; --red: #ff4d5e; --blue: #4fb3ff; --violet: #b18cff;
  --port: #0d1218; --mono: 'JetBrains Mono', ui-monospace, Menlo, monospace; --sans: 'IBM Plex Sans', system-ui, sans-serif;
  color-scheme: dark;
}
* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--text); font: 15px/1.45 var(--sans); }
body { background-image: radial-gradient(circle at 50% -20%, #13202e 0, transparent 60%); min-height: 100vh; }
button, input, select { font: inherit; color: inherit; }
a { color: var(--blue); }
.wrap { max-width: 1100px; margin: 0 auto; padding: 14px 16px 60px; }
.mono { font-family: var(--mono); }
.muted { color: var(--muted); }
.small { font-size: 12.5px; }
h1, h2, h3 { margin: 0 0 8px; line-height: 1.15; }
h2 { font-size: 15px; font-family: var(--mono); text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
.panel { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 14px; margin-bottom: 14px; }
.row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 760px) { .grid2 { grid-template-columns: 1fr; } }

.btn { background: var(--panel2); border: 1px solid var(--line); border-radius: 7px; padding: 8px 13px; cursor: pointer; font-weight: 600; }
.btn:hover { border-color: #3a4d63; }
.btn.go { background: var(--green-d); border-color: var(--green); color: #eafff2; }
.btn.warn { background: #4a1b22; border-color: var(--red); }
.btn.on { outline: 2px solid var(--amber); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
input[type=text], input[type=password] { background: var(--port); border: 1px solid var(--line); border-radius: 7px; padding: 9px 11px; width: 100%; }
label { display: block; margin-bottom: 8px; }

/* header */
.top { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 14px; }
.brand { display: flex; align-items: center; gap: 10px; font-family: var(--mono); font-weight: 800; font-size: 20px; letter-spacing: .02em; }
.brand .nines { color: var(--green); }
.leds { display: inline-flex; gap: 3px; }
.leds i { width: 7px; height: 7px; border-radius: 2px; background: var(--green); box-shadow: 0 0 6px var(--green); animation: blink 1.4s infinite; }
.leds i:nth-child(2) { animation-delay: .3s; } .leds i:nth-child(3) { animation-delay: .7s; background: var(--amber); box-shadow: 0 0 6px var(--amber); }
@keyframes blink { 50% { opacity: .35; } }

/* avatars */
.av { width: 44px; height: 44px; display: block; }
.av.big { width: 76px; height: 76px; }
.av.sm { width: 28px; height: 28px; }
.mood-panic { animation: shake .3s 3; } .mood-cheer { animation: hop .6s infinite alternate; }
@keyframes shake { 25% { transform: translateX(-2px); } 75% { transform: translateX(2px); } }
@keyframes hop { to { transform: translateY(-4px); } }
.pick { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
.pick button { background: var(--panel2); border: 1px solid var(--line); border-radius: 8px; padding: 6px 4px; cursor: pointer; font-size: 11.5px; text-align: center; }
.pick button .av { margin: 0 auto; }
.pick button.on { border-color: var(--green); box-shadow: 0 0 0 1px var(--green); }
.pick button:disabled { opacity: .35; }

/* incidents */
.incs { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px; }
.inc { text-align: left; background: var(--panel2); border: 1px solid var(--line); border-radius: 8px; padding: 9px 11px; cursor: pointer; }
.inc.on { border-color: var(--amber); box-shadow: 0 0 0 1px var(--amber); }
.inc .id { font-family: var(--mono); font-size: 11.5px; color: var(--muted); }
.inc b { display: block; }
.sev { font-family: var(--mono); font-size: 10.5px; padding: 1px 5px; border-radius: 3px; margin-left: 6px; }
.sev1 { background: #5c1620; color: #ffb3bb; } .sev2 { background: #5a3a0c; color: #ffd48a; } .sev3 { background: #173a5c; color: #a8d8ff; } .sev4 { background: #1d3d2a; color: #a6f5c5; }
.won-mark { color: var(--green); font-family: var(--mono); font-size: 11px; float: right; }
.brief { border-left: 3px solid var(--amber); padding-left: 12px; }
.brief ul { margin: 6px 0 0; padding-left: 18px; }

/* status bar */
.status { display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: center; font-family: var(--mono); font-size: 13px; }
.status .k { color: var(--muted); }
.pips { display: inline-flex; gap: 3px; vertical-align: middle; }
.pips i { width: 10px; height: 14px; border-radius: 2px; background: var(--green); }
.pips i.off { background: #3a1820; }
.clock { color: var(--amber); font-weight: 800; }
.clock.hot { color: var(--red); animation: blink .8s infinite; }
.vlanboard { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 8px; }
.vb { font-family: var(--mono); font-size: 11px; border: 1px solid var(--line); border-radius: 4px; padding: 2px 5px; min-width: 42px; text-align: center; }
.vb.done { border-color: var(--green-d); color: var(--green); }
.vb.route { border-color: var(--amber); }
.vb.blocked { opacity: .45; }

/* rack + switches */
.rack { position: relative; padding: 10px 22px; margin-bottom: 14px; border-radius: 6px;
  background: #07090c; border: 1px solid #1d2632;
  background-image: repeating-linear-gradient(#0b0f14 0 10px, #07090c 10px 14px); }
.rack::before, .rack::after { content: ''; position: absolute; top: 0; bottom: 0; width: 16px;
  background: #2a323c repeating-linear-gradient(transparent 0 7px, #0b0e12 7px 12px, transparent 12px 21px) center / 6px 100% no-repeat; }
.rack::before { left: 3px; } .rack::after { right: 3px; }
.cables { position: absolute; inset: 0; pointer-events: none; z-index: 3; overflow: visible; }
.cable path { filter: drop-shadow(0 2px 2px rgba(0,0,0,.6)); }
.cable.fresh path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw .9s ease-out forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }

.switch { position: relative; display: flex; align-items: stretch; margin: 0 -12px 18px; }
.switch .ear { width: 16px; flex: none; background: linear-gradient(90deg, #8d969f, #c2c9cf 40%, #7c858e); border-radius: 2px; display: flex; flex-direction: column; justify-content: space-around; align-items: center; padding: 6px 0; }
.switch .ear i { width: 7px; height: 7px; border-radius: 50%; background: #1b1f24; box-shadow: inset 0 1px 1px #000, 0 1px 0 rgba(255,255,255,.4); }
.switch .face { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; padding: 9px 12px;
  background: linear-gradient(#2b333d, #1d242c 55%, #181e25); border-top: 1px solid #47525f; border-bottom: 2px solid #0a0d10; }
.switch.turn .face { box-shadow: inset 0 0 0 2px var(--amber), 0 0 22px rgba(255,176,32,.18); }
.switch.mine .face { background: linear-gradient(#2a3946, #1c2833 55%, #17212b); }
.switch.far { opacity: .45; }
.sw-meta { position: absolute; right: 22px; bottom: -15px; font-family: var(--mono); font-size: 10.5px; color: var(--muted); white-space: nowrap; }
.brandplate { display: flex; align-items: center; gap: 8px; min-width: 150px; }
.brandplate .model { font-family: var(--mono); font-weight: 800; font-size: 11px; color: #9fb0c2; letter-spacing: .08em; }
.brandplate .hostn { font-family: var(--mono); font-size: 13px; font-weight: 700; color: var(--text); }
.botb { background: #33415c; color: #b8ccff; border-radius: 3px; padding: 0 4px; font-size: 9.5px; letter-spacing: .05em; }
.sysleds { display: grid; grid-template-columns: 8px auto; gap: 1px 4px; align-items: center; font-family: var(--mono); font-size: 8.5px; color: #8796a6; margin-left: 4px; }
.sled { width: 6px; height: 6px; border-radius: 50%; background: var(--green); box-shadow: 0 0 5px var(--green); }
.sled.amber { background: var(--amber); box-shadow: 0 0 5px var(--amber); }
.sled.blink { animation: blink 1.6s infinite; }
.banks { display: flex; flex-wrap: wrap; gap: 10px; }
.bank { display: grid; grid-template-rows: repeat(2, auto); grid-auto-flow: column; gap: 4px 3px; padding: 5px; background: #12171d; border-radius: 3px; box-shadow: inset 0 1px 3px #000; }
.uplinks { display: flex; gap: 5px; align-items: center; margin-left: auto; }
.sfp { width: 20px; height: 14px; background: #0b0e12; border: 2px solid #8c949c; border-radius: 1px; }
.console { font-family: var(--mono); font-size: 8px; color: #7d8a97; border: 1px solid #4a5561; padding: 3px 4px; border-radius: 2px; background: #2a5d8a33; }

.port { position: relative; width: 34px; cursor: pointer; text-align: center; transition: transform .12s; }
.port .pnum { display: block; font-family: var(--mono); font-size: 8.5px; color: #7f8d9b; line-height: 10px; }
.port:nth-child(even) .pnum { position: absolute; bottom: -10px; left: 0; right: 0; }
.port .jack { position: relative; height: 24px; margin: 0 2px; background: #020304; border: 2px solid #3d4752; border-radius: 2px 2px 6px 6px; }
.port .jack::after { content: ''; position: absolute; left: 32%; right: 32%; bottom: -2px; height: 6px; background: #020304; border: 2px solid #3d4752; border-top: 0; border-radius: 0 0 2px 2px; }
.port .led { position: absolute; top: -6px; right: 1px; width: 6px; height: 3px; border-radius: 1px; background: #2a1d1d; }
.port .led.l2 { right: auto; left: 1px; }
.port .plug { position: absolute; inset: 3px 4px 1px; background: var(--c); border-radius: 2px; box-shadow: inset 0 -5px 0 rgba(0,0,0,.25), inset 0 2px 0 rgba(255,255,255,.35); z-index: 1; }
.port .vl { display: block; font-family: var(--mono); font-weight: 800; font-size: 14px; height: 18px; line-height: 18px; color: var(--text); }
.port:nth-child(odd) .vl { order: -1; }
.port .vl[style] { color: var(--c); }
.port.unknown .vl { color: #4a5868; }
.port.up .led { background: var(--green); box-shadow: 0 0 5px var(--green); }
.port.up .led.l2 { background: var(--amber); box-shadow: 0 0 5px var(--amber); animation: blink .7s infinite; }
.port.up .vl { opacity: .65; }
.port.loop .vl { color: var(--red); }
.port.loop .jack { border-color: #6b2a32; }
.port.shut { opacity: .45; }
.port.blind .vl { color: var(--violet); }
.port:hover .jack { border-color: #6c7a8a; }
.port.sel { transform: translateY(-3px); }
.port.sel .jack { border-color: var(--amber); box-shadow: 0 0 8px rgba(255,176,32,.6); }
.port .tagb { position: absolute; top: 12px; left: 50%; transform: translateX(-50%); z-index: 2; font-family: var(--mono); font-size: 10px; font-weight: 800; background: var(--amber); color: #1c1200; border-radius: 3px; padding: 0 3px; }
.port .tagb.loop { background: var(--red); color: #fff; font-size: 8px; }
.port .peek { position: absolute; top: -4px; right: -6px; z-index: 2; font-family: var(--mono); font-size: 10px; font-weight: 800; background: var(--violet); color: #12052e; border-radius: 3px; padding: 0 3px; }
.port .note { position: absolute; bottom: -2px; left: -4px; right: -4px; z-index: 2; font-family: var(--mono); font-size: 8px; color: #9fd4ff; background: #0d2236; border-radius: 2px; }
.port.flash-ok .jack { animation: okf .9s; } .port.flash-bad .jack { animation: badf .9s; }
@keyframes okf { 0%, 60% { background: #1c6b3a; } }
@keyframes badf { 0%, 60% { background: #8a1c2a; } }
@media (max-width: 560px) { .rack { padding: 8px 18px; } .brandplate { min-width: 0; } .uplinks { display: none; } .port { width: 31px; } }

/* action bar */
.actions { position: sticky; bottom: 0; z-index: 5; background: rgba(11,15,20,.96); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin-bottom: 14px; backdrop-filter: blur(6px); }
.actions .hint { font-family: var(--mono); font-size: 13px; margin-bottom: 8px; }
.vbtns { display: flex; flex-wrap: wrap; gap: 5px; }
.vbtns button { width: 36px; padding: 6px 0; font-family: var(--mono); font-weight: 800; }

/* syslog */
.log { font-family: var(--mono); font-size: 12px; max-height: 260px; overflow: auto; background: #070a0e; border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; }
.log div { white-space: pre-wrap; word-break: break-word; }
.log .good { color: var(--green); } .log .bad { color: #ff8c97; } .log .lose { color: var(--red); font-weight: 800; } .log .win { color: var(--green); font-weight: 800; }
.log .tool { color: var(--violet); } .log .sys { color: var(--amber); } .log .info { color: var(--blue); }
.log time { color: #4b5a6a; margin-right: 6px; }

/* end banner */
.banner { border-radius: 10px; padding: 16px; margin-bottom: 14px; text-align: center; font-family: var(--mono); }
.banner.won { background: #0f2a1a; border: 1px solid var(--green); }
.banner.lost { background: #2a0f14; border: 1px solid var(--red); }
.banner h1 { font-size: 26px; }
.storm-flash { animation: storm 1.4s; }
@keyframes storm { 0%, 20%, 40% { background: #5c0d18; } 10%, 30% { background: #fff; } }

/* curtain (one-device) */
.curtain { position: fixed; inset: 0; background: var(--bg); z-index: 50; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; text-align: center; padding: 16px; }

table.board { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.board td, table.board th { padding: 5px 6px; border-bottom: 1px solid var(--line); text-align: left; }
table.board th { color: var(--muted); font-weight: 500; font-family: var(--mono); font-size: 11.5px; }
.toast { position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); background: #2a1219; border: 1px solid var(--red); color: #ffd2d7; padding: 9px 14px; border-radius: 8px; z-index: 60; max-width: calc(100% - 32px); }
.code { font-family: var(--mono); font-weight: 800; font-size: 22px; letter-spacing: .2em; color: var(--amber); }

/* v3: STP, fiber, parts bin, dependencies, levels */
.stp { font-family: var(--mono); }
.stp.ok { color: var(--green); } .stp.warn { color: var(--amber); } .stp.hot { color: var(--red); font-weight: 800; animation: blink 1s infinite; } .stp.dead { color: var(--red); font-weight: 800; }
.sled.red { background: var(--red); box-shadow: 0 0 6px var(--red); }
.switch.dead .face { background: linear-gradient(#3a1a1f, #24100f); filter: saturate(.6); }
.switch.dead .port .led { background: #301010 !important; box-shadow: none !important; animation: none !important; }
.port.fiber .jack { height: 16px; margin: 4px 5px 4px; border-radius: 2px; border-color: #8c949c; background: #0a0d10; }
.port.fiber .jack::after { content: ''; left: 18%; right: 18%; bottom: auto; top: 4px; height: 4px; border: 1px solid #f2a33a; border-radius: 1px; background: #2a1e0c; }
.port.fiber .pnum { color: #f2a33a; }
.cable.bad path { filter: drop-shadow(0 0 4px rgba(255,60,80,.55)); }
.cable.bad.stuck path:last-child { animation: blink 1.2s infinite; }
.bin { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 10px; font-family: var(--mono); font-size: 12px; }
.bin .k, .deps .k { color: var(--muted); margin-right: 4px; }
.part { background: #1f1830; border: 1px solid #5b4a8a; color: #e2d8ff; border-radius: 6px; padding: 5px 9px; cursor: pointer; font-family: var(--mono); font-size: 12px; }
.part .pi { margin-right: 5px; }
.part.on { outline: 2px solid var(--violet); }
.part:disabled { opacity: .55; cursor: default; }
.deps { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin-top: 8px; font-family: var(--mono); font-size: 11.5px; }
.dep { border: 1px dashed #6b5a2a; border-radius: 4px; padding: 1px 6px; background: #1d1708; }
.dep.met { border-style: solid; border-color: var(--green-d); background: #0d2016; opacity: .7; }
.lvl-title { font-family: var(--mono); font-weight: 800; font-size: 20px; color: var(--green); }
.xpbar { height: 8px; border-radius: 4px; background: #1a222c; overflow: hidden; margin-top: 8px; }
.xpbar i { display: block; height: 100%; background: linear-gradient(90deg, var(--green-d), var(--green)); }
.awards { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.award { display: flex; flex-direction: column; gap: 1px; background: var(--panel2); border: 1px solid var(--line); border-radius: 8px; padding: 7px 9px; opacity: .45; filter: grayscale(1); }
.award.got { opacity: 1; filter: none; border-color: #3b6b4c; background: #12221a; }
.award .ai { font-size: 20px; line-height: 1; }
.award b { font-size: 13px; }
.award .small { font-size: 11px; line-height: 1.3; }

/* Home Games sign-in: guest warning */
.warn { color: var(--amber); font-size: 13px; }

/* v4: err-disabled, PoE, rogue DHCP */
.port.err .jack { border-color: var(--amber); box-shadow: inset 0 0 0 2px rgba(255,176,32,.25); }
.port.err .led { background: var(--amber) !important; box-shadow: 0 0 5px var(--amber); animation: blink .9s infinite; }
.port .errb { position: absolute; top: 14px; left: 50%; transform: translateX(-50%); z-index: 2; font-family: var(--mono); font-size: 8px; font-weight: 800; background: #4a3205; color: var(--amber); border: 1px solid var(--amber); border-radius: 2px; padding: 0 2px; }
.port .poeb { position: absolute; bottom: -2px; right: -6px; z-index: 2; font-family: var(--mono); font-size: 9px; font-weight: 800; background: #2d2a05; color: #fde047; border: 1px solid #a3940f; border-radius: 3px; padding: 0 2px; }
.port .poeb.on { background: #123d1f; color: var(--green); border-color: var(--green-d); }
.port.poe:not(.on) .jack { opacity: .55; }
.port.rogue .vl { color: #d07bff; }
.port .tagb.rogue { background: #7c2fbf; color: #fff; font-size: 8px; }
