/* Rack Live вЂ” Apple-like design system. Light and dark themes via [data-theme] on <html>. */
:root {
  --bg: #f2f2f7; --bg2: #ffffff; --card: rgba(255,255,255,.78); --card-solid: #fff; --elev: rgba(255,255,255,.92);
  --text: #1c1c1e; --text2: rgba(60,60,67,.72); --text3: rgba(60,60,67,.45);
  --line: rgba(60,60,67,.12); --line2: rgba(60,60,67,.2); --fill: rgba(120,120,128,.12); --fill2: rgba(120,120,128,.2);
  --accent: #007aff; --green: #34c759; --yellow: #ffcc00; --orange: #ff9500; --red: #ff3b30; --purple: #af52de; --teal: #30b0c7; --indigo: #5856d6;
  --shadow: 0 1px 2px rgba(0,0,0,.04), 0 8px 28px rgba(0,0,0,.06); --shadow-lg: 0 20px 60px rgba(0,0,0,.18);
  --rack: #1c1c1e; --rack-rail: #2c2c2e; --unit: #2a2a2d; --unit-text: #f5f5f7;
  --r: 14px; --r-lg: 20px;
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: "SF Mono", ui-monospace, Menlo, Consolas, monospace;
  color-scheme: light;
}
[data-theme="dark"] {
  --bg: #000; --bg2: #1c1c1e; --card: rgba(28,28,30,.78); --card-solid: #1c1c1e; --elev: rgba(44,44,46,.94);
  --text: #f5f5f7; --text2: rgba(235,235,245,.66); --text3: rgba(235,235,245,.38);
  --line: rgba(84,84,88,.45); --line2: rgba(84,84,88,.7); --fill: rgba(118,118,128,.22); --fill2: rgba(118,118,128,.32);
  --accent: #0a84ff; --green: #30d158; --yellow: #ffd60a; --orange: #ff9f0a; --red: #ff453a; --purple: #bf5af2; --teal: #40c8e0; --indigo: #5e5ce6;
  --shadow: 0 1px 2px rgba(0,0,0,.3), 0 8px 28px rgba(0,0,0,.35); --shadow-lg: 0 24px 70px rgba(0,0,0,.6);
  --rack: #0b0b0c; --rack-rail: #1c1c1e; --unit: #1f1f22; --unit-text: #f5f5f7;
  color-scheme: dark;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--text); font-family: var(--font); font-size: 15px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: 100%; }
html, body { height: auto; }
body { min-height: 100dvh; overscroll-behavior-y: none; }
#root { min-height: 100dvh; }
:root { --dock: rgba(242,242,247,.86); } [data-theme="dark"] { --dock: rgba(22,22,26,.86); }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent); text-decoration: none; }
::selection { background: color-mix(in srgb, var(--accent) 30%, transparent); }
.mono { font-family: var(--mono); font-size: .92em; }
.dim { color: var(--text2); } .dim3 { color: var(--text3); }
.row { display: flex; align-items: center; gap: 8px; } .col { display: flex; flex-direction: column; gap: 8px; }
.grow { flex: 1; min-width: 0; } .wrap { flex-wrap: wrap; } .center { justify-content: center; } .between { justify-content: space-between; }
.ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hide-sm { } @media (max-width: 760px) { .hide-sm { display: none !important; } }
.only-sm { display: none !important; } @media (max-width: 760px) { .only-sm { display: flex !important; } }

/* в”Ђв”Ђ app shell в”Ђв”Ђ */
.app-bg { position: fixed; inset: 0; z-index: -1; background:
  radial-gradient(1100px 600px at 10% -10%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 60%),
  radial-gradient(900px 500px at 100% 0%, color-mix(in srgb, var(--purple) 10%, transparent), transparent 60%), var(--bg); }
/* Floating docks (same look as the other home apps): fixed header capsule + floating tab bar */
/* The blur lives on a ::before layer, never on the element that holds text/buttons:
   iOS Safari otherwise smears the header's own content (especially with animations inside). */
.topbar { position: fixed; top: 0; left: 0; right: 0; z-index: 50; display: flex; align-items: center; gap: 14px; isolation: isolate;
  padding: calc(env(safe-area-inset-top) + 10px) calc(env(safe-area-inset-right) + 18px) 10px calc(env(safe-area-inset-left) + 18px); }
.topbar::before, .bottombar::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background: var(--dock); backdrop-filter: blur(32px) saturate(180%); -webkit-backdrop-filter: blur(32px) saturate(180%);
  border: .5px solid var(--line); box-shadow: 0 8px 30px rgba(0,0,0,.18); }
.topbar { border-radius: 0 0 24px 24px; } .topbar::before { border-top: 0; }
.brand { display: flex; align-items: center; gap: 10px; min-width: 34px; flex: 0 1 auto; max-width: 260px; }
.brand-text { min-width: 0; overflow: hidden; }            /* the title gives way (ellipsis), the icon never gets covered */
.topbar .tabs, .topbar .hdr-tools { flex-shrink: 0; }
/* narrower PC windows: tabs become icons (the open one keeps its name), then the view/edit switch too */
@media (max-width: 1180px) and (min-width: 761px) { .topbar .tab:not(.on) .tab-label { display: none; } .topbar .tab { padding: 7px 11px; } }
@media (max-width: 1060px) and (min-width: 761px) { .topbar .hdr-tools .seg-label { display: none; } }
@media (max-width: 900px) and (min-width: 761px) { .topbar .tab .tab-label { display: none; } .topbar .brand .live { display: none; } }
.brand-logo { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; background: linear-gradient(145deg, var(--accent), var(--indigo));
  box-shadow: 0 6px 16px color-mix(in srgb, var(--accent) 35%, transparent); flex-shrink: 0; }
.brand-title { font-weight: 700; font-size: 17px; letter-spacing: -.3px; }
.live { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; letter-spacing: .6px; text-transform: uppercase; color: var(--green); }
.live i { width: 7px; height: 7px; border-radius: 50%; background: currentColor; box-shadow: 0 0 6px currentColor; }
.live.stale { color: var(--orange); } .live.stale i { animation: none; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 60%, transparent); } 70% { box-shadow: 0 0 0 7px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
.tabs { display: flex; gap: 2px; padding: 3px; border-radius: 12px; background: var(--fill); }
.tab { border: 0; background: transparent; padding: 7px 14px; border-radius: 9px; font-size: 14px; font-weight: 500; color: var(--text2); cursor: pointer; display: flex; align-items: center; gap: 6px; transition: all .2s; white-space: nowrap; }
.tab:hover { color: var(--text); }
.tab.on { background: var(--card-solid); color: var(--text); box-shadow: 0 1px 3px rgba(0,0,0,.12); }
.tab .count { font-size: 11px; padding: 1px 6px; border-radius: 10px; background: var(--red); color: #fff; font-weight: 600; }
.bottombar { position: fixed; left: calc(env(safe-area-inset-left) + 12px); right: calc(env(safe-area-inset-right) + 12px); bottom: 0;
  margin-bottom: calc(env(safe-area-inset-bottom) + 8px); z-index: 50; display: none; gap: 4px; padding: 7px; border-radius: 28px; isolation: isolate; }
.bottombar button { flex: 1 1 0; min-width: 0; overflow: hidden; white-space: nowrap; border: 0; background: transparent; border-radius: 22px; display: flex; flex-direction: column; align-items: center; gap: 3px;
  font-size: 11px; font-weight: 600; color: var(--text2); padding: 9px 2px 7px; cursor: pointer; position: relative; transition: transform .15s, background .2s; }
.bottombar button:active { transform: scale(.9); }
.bottombar button.on { color: var(--accent); background: var(--fill); }
.bottombar button.on svg { filter: drop-shadow(0 0 7px var(--accent)); }
.bottombar .count { position: absolute; top: 3px; left: calc(50% + 7px); font-size: 10px; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px; background: var(--red); color: #fff; display: grid; place-items: center; font-weight: 700; }
main.page { min-height: calc(100lvh + 1px); padding: calc(env(safe-area-inset-top) + 82px) calc(env(safe-area-inset-right) + 20px) 32px calc(env(safe-area-inset-left) + 20px); max-width: 1500px; margin: 0 auto; }
.seg-label { display: inline; }
@media (max-width: 760px) {
  .bottombar { display: flex; } .topbar .tabs { display: none; }
  .topbar { gap: 8px; padding-left: calc(env(safe-area-inset-left) + 14px); padding-right: calc(env(safe-area-inset-right) + 12px); }
  .topbar .seg-label, .topbar .btn .btn-label { display: none; }
  .topbar .seg button { padding: 9px 13px; } .topbar .seg button svg { width: 19px; height: 19px; }
  .topbar .btn { min-width: 42px; min-height: 40px; padding: 9px 11px; border-radius: 12px; }
  .topbar .btn svg { width: 20px; height: 20px; }
  .brand-title { font-size: 16px; } .brand-logo { width: 32px; height: 32px; }
  main.page { padding: calc(env(safe-area-inset-top) + 76px) calc(env(safe-area-inset-right) + 14px) calc(env(safe-area-inset-bottom) + 108px) calc(env(safe-area-inset-left) + 14px); }
  .page-title { font-size: 26px; }
}
.page-title { font-size: 28px; font-weight: 700; letter-spacing: -.6px; margin: 4px 0 2px; }
.page-sub { color: var(--text2); font-size: 14px; margin-bottom: 18px; }

/* в”Ђв”Ђ controls в”Ђв”Ђ */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 7px; border: 0; border-radius: 11px; padding: 9px 15px; font-size: 14px; font-weight: 600;
  background: var(--fill); color: var(--text); cursor: pointer; transition: transform .12s, background .2s, opacity .2s; white-space: nowrap; }
.btn:hover { background: var(--fill2); } .btn:active { transform: scale(.97); }
.btn.primary { background: var(--accent); color: #fff; } .btn.primary:hover { background: color-mix(in srgb, var(--accent) 88%, #000); }
.btn.danger { background: color-mix(in srgb, var(--red) 14%, transparent); color: var(--red); }
.btn.ghost { background: transparent; color: var(--accent); }
.btn.sm { padding: 6px 11px; font-size: 13px; border-radius: 9px; } .btn.icon { padding: 8px; border-radius: 10px; }
.btn:disabled { opacity: .45; pointer-events: none; }
.btn.busy { pointer-events: none; opacity: .8; }
.btn.busy::after { content: ""; width: 14px; height: 14px; border-radius: 50%; border: 2px solid currentColor; border-top-color: transparent; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.seg { display: inline-flex; padding: 2px; border-radius: 10px; background: var(--fill); }
.seg button { border: 0; background: transparent; padding: 6px 12px; border-radius: 8px; font-size: 13px; font-weight: 600; color: var(--text2); cursor: pointer; display: flex; align-items: center; gap: 5px; }
.seg button.on { background: var(--card-solid); color: var(--text); box-shadow: 0 1px 3px rgba(0,0,0,.12); }
.seg.edit button.on.editing { background: var(--orange); color: #fff; }
.input, .select, .textarea { width: 100%; border: .5px solid var(--line2); background: var(--bg2); border-radius: 11px; padding: 10px 12px; outline: none; transition: border .2s, box-shadow .2s; }
.input:focus, .select:focus, .textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 18%, transparent); }
.textarea { min-height: 90px; resize: vertical; font-family: var(--mono); font-size: 13px; }
.field { display: flex; flex-direction: column; gap: 6px; } .field > label { font-size: 12.5px; font-weight: 600; color: var(--text2); }
.field .hint { font-size: 12px; color: var(--text3); }
.switch { position: relative; width: 46px; height: 28px; flex-shrink: 0; border-radius: 14px; background: var(--fill2); border: 0; cursor: pointer; transition: background .2s; }
.switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 24px; height: 24px; border-radius: 50%; background: #fff; box-shadow: 0 2px 6px rgba(0,0,0,.25); transition: transform .22s cubic-bezier(.3,1.4,.6,1); }
.switch.on { background: var(--green); } .switch.on::after { transform: translateX(18px); }
.search { position: relative; } .search .input { padding-left: 34px; } .search svg { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); opacity: .5; }

/* в”Ђв”Ђ cards в”Ђв”Ђ */
.card { background: var(--card); border: .5px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow); backdrop-filter: saturate(180%) blur(20px); -webkit-backdrop-filter: saturate(180%) blur(20px); }
.card.pad { padding: 16px 18px; }
.card-title { font-size: 13px; font-weight: 700; color: var(--text2); text-transform: uppercase; letter-spacing: .5px; margin-bottom: 10px; display: flex; align-items: center; gap: 8px; }
.grid { display: grid; gap: 14px; }
.grid.cards { grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); }
.stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; }
.stat { background: var(--fill); border-radius: 14px; padding: 11px 13px; position: relative; overflow: hidden; }
.stat .k { font-size: 12px; color: var(--text2); font-weight: 500; }
.stat .v { font-size: 22px; font-weight: 700; letter-spacing: -.4px; margin-top: 2px; }
.stat .v small { font-size: 13px; font-weight: 600; color: var(--text2); margin-left: 2px; }
.stat.warn .v { color: var(--orange); } .stat.bad .v { color: var(--red); }
/* a bare <Sparkline> (the Internet widget) has no size of its own otherwise — the browser falls back to its default SVG box (300×150), way
   oversized for the card. Its own fill has flat, square corners — round them, so a plain rectangle doesn't visually clash sitting this close
   to the card's rounded corner (that was the "square cut" look, not actual overflow — the rectangle never left the card at all). */
svg.spark { display: block; width: 100%; height: 56px; border-radius: 10px; }
.stat svg.spark { position: absolute; right: 0; bottom: 0; height: 34px; opacity: .55; border-radius: 0; }
.kv { display: grid; grid-template-columns: minmax(110px, 40%) 1fr; gap: 0; font-size: 14px; }
.kv > div { padding: 9px 0; border-bottom: .5px solid var(--line); } .kv > div:nth-last-child(-n+2) { border-bottom: 0; }
.kv > div:nth-child(odd) { color: var(--text2); } .kv > div:nth-child(even) { text-align: right; word-break: break-word; }
.badge { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: 20px; background: var(--fill); color: var(--text2); white-space: nowrap; }
.badge.online { background: color-mix(in srgb, var(--green) 16%, transparent); color: var(--green); }
.badge.warning { background: color-mix(in srgb, var(--orange) 16%, transparent); color: var(--orange); }
.badge.offline { background: color-mix(in srgb, var(--red) 15%, transparent); color: var(--red); }
.badge.info { background: color-mix(in srgb, var(--accent) 15%, transparent); color: var(--accent); }
.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex-shrink: 0; background: var(--text3); }
.dot.online { background: var(--green); box-shadow: 0 0 8px color-mix(in srgb, var(--green) 70%, transparent); }
.dot.warning { background: var(--orange); box-shadow: 0 0 8px color-mix(in srgb, var(--orange) 70%, transparent); }
.dot.offline { background: var(--red); box-shadow: 0 0 8px color-mix(in srgb, var(--red) 70%, transparent); }
.bar { height: 7px; border-radius: 4px; background: var(--fill2); overflow: hidden; } .bar > i { display: block; height: 100%; border-radius: 4px; background: var(--accent); transition: width .5s; }
.bar.warn > i { background: var(--orange); } .bar.bad > i { background: var(--red); }
.empty { text-align: center; color: var(--text3); padding: 36px 16px; font-size: 14px; }
.list { display: flex; flex-direction: column; } .list > .li { display: flex; align-items: center; gap: 12px; padding: 10px 2px; border-bottom: .5px solid var(--line); } .list > .li:last-child { border-bottom: 0; }
.ico-circle { width: 36px; height: 36px; border-radius: 10px; display: grid; place-items: center; flex-shrink: 0; background: var(--fill); }
.table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.table th { text-align: left; font-size: 12px; color: var(--text2); font-weight: 600; padding: 8px 10px; border-bottom: .5px solid var(--line2); position: sticky; top: 0; background: var(--elev); }
.table td { padding: 9px 10px; border-bottom: .5px solid var(--line); vertical-align: middle; }
.table tr:hover td { background: var(--fill); }

/* в”Ђв”Ђ modal / sheet в”Ђв”Ђ */
.overlay { position: fixed; inset: 0; z-index: 100; background: rgba(0,0,0,.36); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); animation: fade .2s; display: flex; }
@keyframes fade { from { opacity: 0; } }
.modal { margin: auto; width: min(560px, calc(100vw - 24px)); max-height: calc(100vh - 40px); overflow: auto; background: var(--elev); border-radius: 22px; box-shadow: var(--shadow-lg); border: .5px solid var(--line); animation: pop .28s cubic-bezier(.2,1.2,.4,1); backdrop-filter: blur(30px); -webkit-backdrop-filter: blur(30px); }
.modal.wide { width: min(820px, calc(100vw - 24px)); }
@keyframes pop { from { opacity: 0; transform: translateY(14px) scale(.97); } }
.modal-head { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; gap: 12px; padding: 16px 18px 12px; background: var(--elev); border-bottom: .5px solid var(--line); }
.modal-head h3 { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -.3px; flex: 1; }
.modal-body { padding: 16px 18px 20px; display: flex; flex-direction: column; gap: 14px; }
.modal-foot { position: sticky; bottom: 0; display: flex; gap: 10px; justify-content: flex-end; padding: 12px 18px; background: var(--elev); border-top: .5px solid var(--line); }
.sheet { position: fixed; top: 0; right: 0; bottom: 0; width: min(620px, 100vw); overflow: auto; overscroll-behavior: contain; padding-bottom: env(safe-area-inset-bottom); background: var(--elev); box-shadow: var(--shadow-lg); border-left: .5px solid var(--line); animation: slide .32s cubic-bezier(.2,1,.3,1); backdrop-filter: blur(30px); -webkit-backdrop-filter: blur(30px); }
@keyframes slide { from { transform: translateX(40px); opacity: 0; } }
.overlay:has(> .sheet.popup) { z-index: 110; }          /* a device opened from inside the rack window of the plan lies above that window */
/* the same card as a window in the middle (opened from the plan, like the speed test): the plan stays visible behind */
.sheet.popup { position: relative; top: auto; right: auto; bottom: auto; left: auto; margin: auto; width: min(760px, calc(100vw - 24px)); max-height: calc(100vh - 40px); border-radius: 22px; border: .5px solid var(--line); animation: pop .28s cubic-bezier(.2,1.2,.4,1); }
@media (max-width: 760px) { .overlay:has(> .sheet.popup) { align-items: flex-end; } .sheet.popup { top: auto; width: 100%; margin: auto 0 0; max-height: calc(100dvh - env(safe-area-inset-top) - 12px); border-radius: 22px 22px 0 0; border-left: 0; border-right: 0; border-bottom: 0; animation: up .3s cubic-bezier(.2,1,.3,1); } }
@media (max-width: 760px) { .sheet { left: 0; width: auto; top: calc(env(safe-area-inset-top) + 8px); border-radius: 22px 22px 0 0; border-left: 0; animation: up .32s cubic-bezier(.2,1,.3,1); } @keyframes up { from { transform: translateY(60px); opacity: 0; } } }
.sheet-head { position: sticky; top: 0; z-index: 3; padding: 16px 18px 0; background: var(--elev); }
.sheet-tabs { display: flex; flex-wrap: wrap; gap: 0 4px; padding: 12px 0 0; border-bottom: .5px solid var(--line); }   /* wrap: every tab stays visible */
.sheet-tabs button { border: 0; background: none; padding: 8px 12px 10px; font-size: 14px; font-weight: 600; color: var(--text2); cursor: pointer; border-bottom: 2px solid transparent; white-space: nowrap; }
.sheet-tabs button.on { color: var(--accent); border-bottom-color: var(--accent); }
.sheet-body { padding: 16px 18px 40px; display: flex; flex-direction: column; gap: 14px; }
.toast-wrap { position: fixed; left: 50%; bottom: calc(env(safe-area-inset-bottom) + 90px); transform: translateX(-50%); z-index: 300; display: flex; flex-direction: column; gap: 8px; align-items: center; pointer-events: none; }
.toast { background: var(--elev); color: var(--text); border: .5px solid var(--line); box-shadow: var(--shadow-lg); border-radius: 14px; padding: 11px 16px; font-size: 14px; font-weight: 500; animation: pop .3s; display: flex; align-items: center; gap: 8px; backdrop-filter: blur(30px); }
.toast.err { color: var(--red); }

/* в”Ђв”Ђ rack в”Ђв”Ђ */
.rack-layout { display: grid; grid-template-columns: minmax(320px, 560px) 1fr; gap: 20px; align-items: start; }
@media (max-width: 1000px) { .rack-layout { grid-template-columns: 1fr; } }
.rack { background: linear-gradient(180deg, #2c2c2e, #1c1c1e); border-radius: 18px; padding: 14px 12px; box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255,255,255,.08); position: relative; }
[data-theme="light"] .rack { background: linear-gradient(180deg, #3a3a3c, #232325); }
.rack-top { display: flex; align-items: center; justify-content: space-between; padding: 0 6px 10px; color: #f5f5f7; }
.rack-top .title { font-weight: 700; font-size: 15px; } .rack-top .meta { font-size: 12px; color: rgba(235,235,245,.6); }
.rack-body { display: grid; grid-template-columns: 26px 1fr 26px; background: #0b0b0c; border-radius: 10px; padding: 6px 0; }
.rack-rail { display: flex; flex-direction: column; }
.rack-rail div { height: var(--u); display: flex; align-items: center; justify-content: center; font-size: 10px; color: rgba(235,235,245,.28); font-family: var(--mono); position: relative; }
.rack-rail div::before { content: ""; width: 5px; height: 5px; border-radius: 1px; background: #2c2c2e; position: absolute; top: 4px; }
.rack-slots { position: relative; }
.rack-slot { height: var(--u); border-top: .5px dashed rgba(255,255,255,.04); }
.rack-slot.drop { background: color-mix(in srgb, var(--accent) 25%, transparent); outline: 1.5px dashed var(--accent); }
.rack-slot.addable { cursor: pointer; } .rack-slot.addable:hover { background: rgba(255,255,255,.04); }
.unit { position: absolute; left: 3px; right: 3px; border-radius: 6px; padding: 0 10px 0 14px; display: flex; align-items: center; gap: 10px; cursor: pointer;
  background: linear-gradient(180deg, #2f2f33, #232326); color: var(--unit-text); box-shadow: inset 0 1px 0 rgba(255,255,255,.07), 0 1px 2px rgba(0,0,0,.5); overflow: hidden; transition: transform .15s, box-shadow .2s; user-select: none; }
.unit:hover { box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 0 0 1.5px color-mix(in srgb, var(--accent) 70%, transparent); }
.unit.dragging { opacity: .5; }
.unit .strip { position: absolute; left: 0; top: 0; bottom: 0; width: 4px; }
.unit .uicon { width: 28px; height: 28px; border-radius: 8px; display: grid; place-items: center; background: rgba(255,255,255,.07); flex-shrink: 0; }
.unit .uname { font-size: 13.5px; font-weight: 600; } .unit .umeta { font-size: 11.5px; color: rgba(235,235,245,.6); }
.unit .leds { display: grid; grid-auto-flow: column; grid-template-rows: repeat(2, 7px); gap: 2px; margin-left: auto; flex-shrink: 0; }
.unit .leds i { width: 7px; height: 7px; border-radius: 2px; background: #3a3a3c; }
.unit .leds i.g { background: var(--green); box-shadow: 0 0 4px var(--green); } .unit .leds i.y { background: #ffd60a; box-shadow: 0 0 4px #ffd60a; } .unit .leds i.o { background: #ff9f0a; }
.unit .leds i.off { background: #4b1c1a; }
.unit .leds i.r { background: var(--red); box-shadow: 0 0 5px var(--red); }                 /* outlet block: red = something is plugged in */
.unit .leds.round { grid-template-rows: 9px !important; gap: 4px; } .unit .leds.round i { width: 9px; height: 9px; border-radius: 50%; }
.unit.passive { background: repeating-linear-gradient(90deg, #252527 0 6px, #202022 6px 12px); }
.unit.blank { background: #171718; cursor: default; }
.side-stack { display: flex; flex-direction: column; gap: 14px; }
.side-stack > .stats { grid-template-columns: repeat(4, 1fr); } @media (max-width: 520px) { .side-stack > .stats { grid-template-columns: repeat(2, 1fr); } }

/* в”Ђв”Ђ ports faceplate в”Ђв”Ђ */
.faceplate { background: var(--faceplate-bg, linear-gradient(180deg, #2c2c2e, #1f1f21)); border-radius: var(--faceplate-radius, 12px); padding: 12px; overflow-x: auto; }
.ports { display: grid; grid-auto-flow: column; grid-template-rows: repeat(2, auto); gap: 6px; width: max-content; }
.ports.one { grid-template-rows: auto; }
.port { width: var(--port-w, 38px); height: var(--port-h, 34px); border-radius: var(--port-radius, 6px); background: var(--port-bg, #3a3a3c); border: 1.5px solid var(--port-border, #48484a); cursor: pointer; position: relative; display: grid; place-items: center;
  font-size: 10px; font-weight: 700; color: var(--port-text, rgba(255,255,255,.5)); font-family: var(--mono); transition: transform .12s; }
.port:hover { transform: translateY(-1px); } .port.sel { outline: 2px solid var(--port-sel, var(--accent)); outline-offset: 2px; }
.port.g { background: color-mix(in srgb, var(--port-g, var(--green)) 30%, var(--port-base, #1c1c1e)); border-color: var(--port-g, var(--green)); color: var(--port-link-text, #fff); }
.port.y { background: color-mix(in srgb, var(--port-y, #ffd60a) 26%, var(--port-base, #1c1c1e)); border-color: var(--port-y, #ffd60a); color: var(--port-link-text, #fff); }
.port.o { background: color-mix(in srgb, var(--port-o, #ff9f0a) 26%, var(--port-base, #1c1c1e)); border-color: var(--port-o, #ff9f0a); color: var(--port-link-text, #fff); }
.port.dis { background: var(--port-dis-bg, #3a1513); border-color: var(--port-dis, #ff453a); }
.port.sfp { border-radius: var(--port-sfp-radius, 3px); width: var(--port-sfp-w, 44px); }
.port.wan { border-color: var(--port-wan, var(--purple)); }
.port .poe { position: absolute; top: -6px; right: -5px; width: 14px; height: 14px; border-radius: 50%; background: var(--poe-badge, #ffd60a); display: grid; place-items: center; box-shadow: 0 0 6px var(--poe-badge, #ffd60a); }
.port .vl { position: absolute; left: 3px; right: 3px; bottom: 2px; height: 3px; border-radius: 2px; display: flex; gap: 1px; overflow: hidden; }
.port .vl b { flex: 1; }
.legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12px; color: var(--text2); }
.legend span { display: inline-flex; align-items: center; gap: 6px; } .legend i { width: 14px; height: 4px; border-radius: 2px; display: inline-block; }

/* в”Ђв”Ђ map в”Ђв”Ђ */
.map-wrap { position: relative; height: calc(100vh - 230px); min-height: 480px; border-radius: var(--r-lg); overflow: hidden; background:
  radial-gradient(circle at 1px 1px, var(--line) 1px, transparent 0) 0 0 / 22px 22px, var(--bg2); border: .5px solid var(--line); box-shadow: var(--shadow); }
.map-wrap > svg { touch-action: none; }      /* only the map canvas; panels over it must scroll */
@media (max-width: 760px) { .map-wrap { height: calc(100dvh - 300px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); min-height: 380px; } }
.zoom-btns { position: absolute; right: 12px; bottom: 12px; z-index: 2; display: flex; flex-direction: column; gap: 6px; }
.zoom-btns .btn { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 14px; background: var(--elev); border: .5px solid var(--line); box-shadow: var(--shadow); font-size: 22px; font-weight: 500; padding: 0; }
@media (max-width: 760px) { .map-legend { display: none; } }
.node-info { position: absolute; right: 68px; bottom: 12px; width: 320px; z-index: 3; max-height: calc(100% - 80px); overflow: auto; touch-action: pan-y; overscroll-behavior: contain; }
@media (max-width: 760px) { .node-info { left: 10px; right: 64px; width: auto; } }
.spin-dot { width: 10px; height: 10px; border-radius: 50%; border: 2px solid currentColor; border-top-color: transparent; animation: spin .8s linear infinite; display: inline-block; }
.chart { width: 100%; height: 150px; display: block; }
.chart text { font-size: 10px; fill: var(--text3); font-family: var(--mono); }
.map-wrap > svg { width: 100%; height: 100%; display: block; cursor: grab; } .map-wrap > svg.panning { cursor: grabbing; }
.map-tools { position: absolute; top: 12px; left: 12px; right: 12px; display: flex; gap: 8px; align-items: flex-start; pointer-events: none; z-index: 2; }
.map-tools > * { pointer-events: auto; }
.map-panel { background: var(--elev); border: .5px solid var(--line); border-radius: 14px; box-shadow: var(--shadow); padding: 6px; display: flex; gap: 4px; backdrop-filter: blur(20px); }
.map-legend { position: absolute; left: 12px; bottom: 12px; z-index: 2; background: var(--elev); border: .5px solid var(--line); border-radius: 12px; padding: 8px 12px; box-shadow: var(--shadow); }
.edge { fill: none; stroke-width: 2.2; stroke-linecap: round; transition: opacity .2s, stroke-width .2s; }
.edge.flow { stroke-dasharray: 2 9; animation: flow 1.1s linear infinite; stroke-width: 2.6; }
.edge.wifi { stroke-dasharray: 5 6; animation: flow 1.6s linear infinite; }
.edge.dashed { stroke-dasharray: 7 7; }
/* лёгкая карта: бегущие штрихи на десятках линий перерисовывали всю схему каждый кадр — на телефоне и пока карту двигают они стоят; полупрозрачные панели без размытия фона */
@media (max-width: 760px) { .edge.flow, .edge.wifi { animation: none; } }
.map-wrap.moving .edge { animation: none !important; transition: none; }
.page-full .map-panel, .page-full .card, .page-full .plan-ctx, .page-full .plan-hint, .page-full .zoom-btns .btn, .page-full .health-panel, .page-full .node-info { backdrop-filter: none; -webkit-backdrop-filter: none; }
.newdev-row { display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px 14px; border: .5px solid var(--line); color: inherit; font: inherit; cursor: pointer; }
.newdev-ic { position: relative; width: 36px; height: 36px; border-radius: 10px; display: grid; place-items: center; background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); flex-shrink: 0; }
.newdev-ic .count { position: absolute; top: -6px; right: -7px; font-size: 10.5px; padding: 1px 5px; border-radius: 9px; background: var(--red); color: #fff; font-weight: 700; }
.view-switch { margin: 0 0 14px; } .view-switch .seg { display: inline-flex; }
.state-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
@media (max-width: 420px) { .state-tiles { grid-template-columns: 1fr; } }
.state-tile { display: flex; align-items: center; gap: 10px; min-width: 0; padding: 10px; border: 0; border-radius: 14px; background: var(--fill);
  color: inherit; font: inherit; text-align: left; cursor: pointer; transition: transform .15s; }
.state-tile:active { transform: scale(.98); }
.state-k { font-size: 11.5px; font-weight: 600; color: var(--text2); text-transform: uppercase; letter-spacing: .3px; }
.state-t { font-weight: 700; font-size: 13.5px; }
.found-type { font-size: 11px; font-weight: 600; padding: 1px 7px; border-radius: 7px; background: var(--fill); color: var(--text2); white-space: nowrap; }
/* Frank full access */
.ai-cmd { margin: 6px 0 0; padding: 7px 9px; border-radius: 9px; background: var(--fill); font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  white-space: pre-wrap; word-break: break-word; max-height: 220px; overflow: auto; }
.ai-cmd.out { color: var(--text2); background: transparent; border: .5px solid var(--line); }
.ai-ops { margin-top: 8px; border: .5px solid var(--line); border-radius: 12px; overflow: hidden; }
.ai-ops-head { display: flex; align-items: center; gap: 6px; width: 100%; padding: 8px 10px; border: 0; background: var(--fill); color: var(--text2);
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; text-align: left; }
.ai-op { padding: 8px 10px; border-top: .5px solid var(--line); } .ai-op.bad .ai-cmd.out { color: var(--red); }
.ai-badge { font-size: 10.5px; font-weight: 700; padding: 1px 6px; border-radius: 6px; background: var(--orange); color: #fff; vertical-align: 1px; }
.ai-admin-warn { margin-top: 6px; font-size: 12.5px; line-height: 1.4; padding: 8px 10px; border-radius: 10px;
  background: color-mix(in srgb, var(--orange) 14%, transparent); color: var(--text); }
/* availability: one bar per day */
.up-bars { display: flex; gap: 2px; height: 18px; margin: 5px 0 4px; }
.up-bars i { flex: 1; min-width: 2px; border-radius: 2px; opacity: .9; }
.up-row { align-items: flex-start; }
.wan-setup { margin-top: 12px; padding-top: 10px; border-top: .5px solid var(--line); }
.wan-setup .seg { display: flex; width: 100%; } .wan-setup .seg button { flex: 1; padding-left: 4px; padding-right: 4px; font-size: 12.5px; white-space: nowrap; }
.edge.isp { stroke-width: 4.5; opacity: .85; }           /* provider line (fibre / DSL) into the ONT / modem — thicker */
@keyframes flow { to { stroke-dashoffset: -22; } }
.edge-hit { fill: none; stroke: transparent; stroke-width: 14; cursor: pointer; }
.node { cursor: pointer; } .node rect.box { fill: var(--card-solid); stroke: var(--line2); stroke-width: 1; transition: stroke .2s; }      /* без drop-shadow: SVG-фильтр на каждой карточке тормозил прокрутку карты */
.node:hover rect.box, .node.sel rect.box { stroke: var(--accent); stroke-width: 2; }
.node .lbl { font-size: 13px; font-weight: 600; fill: var(--text); } .node .sub { font-size: 11px; fill: var(--text2); font-family: var(--mono); }
.node.client rect.box { fill: var(--bg2); }
.node.group rect.box { fill: var(--fill); stroke-dasharray: 4 4; }
.dim-out { opacity: .18; }
.port-pill rect { fill: var(--bg2); stroke: var(--line2); } .port-pill text { font-size: 10px; font-weight: 700; fill: var(--text2); font-family: var(--mono); }
.rackbox rect.frame { fill: #1c1c1e; stroke: #3a3a3c; }
[data-theme="light"] .rackbox rect.frame { fill: #2c2c2e; }
.rackbox .u rect { fill: #2a2a2d; stroke: rgba(255,255,255,.06); }
.rackbox .u:hover rect { stroke: var(--accent); stroke-width: 1.5; }
.rackbox text { fill: #f5f5f7; } .rackbox .usub { fill: rgba(235,235,245,.55); font-size: 10.5px; }

/* в”Ђв”Ђ auth screens в”Ђв”Ђ */
.auth { position: fixed; inset: 0; overflow-y: auto; display: grid; place-items: center; padding: calc(env(safe-area-inset-top) + 20px) 20px calc(env(safe-area-inset-bottom) + 20px); }
.auth .card { width: min(400px, 100%); padding: 28px 24px; text-align: center; animation: pop .4s cubic-bezier(.2,1.2,.4,1); }
.auth h1 { font-size: 26px; letter-spacing: -.5px; margin: 16px 0 6px; }
.auth .col { text-align: left; margin-top: 18px; }
.driver-pick { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.driver-pick button { text-align: left; border: .5px solid var(--line2); background: var(--bg2); border-radius: 14px; padding: 12px; cursor: pointer; display: flex; gap: 10px; align-items: flex-start; transition: border .2s, transform .12s; }
.driver-pick button:hover { border-color: var(--accent); transform: translateY(-1px); }
.driver-pick b { display: block; font-size: 14px; margin-bottom: 2px; } .driver-pick small { color: var(--text2); font-size: 12px; line-height: 1.35; display: block; }
.dev-card { padding: 14px 16px; cursor: pointer; transition: transform .15s, box-shadow .2s; }
.dev-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.code { font-family: var(--mono); font-size: 12.5px; background: var(--fill); border-radius: 10px; padding: 10px 12px; word-break: break-all; white-space: pre-wrap; user-select: all; }
.ev { display: flex; gap: 12px; padding: 10px 0; border-bottom: .5px solid var(--line); align-items: flex-start; } .ev:last-child { border-bottom: 0; }
.chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 20px; background: var(--fill); font-size: 13px; font-weight: 500; cursor: pointer; border: 0; color: var(--text2); }
.chip.on { background: var(--accent); color: #fff; }
.fade-in { animation: pop .35s cubic-bezier(.2,1.1,.4,1) both; }

/* cable test */
.cable { display: flex; flex-direction: column; gap: 12px; background: var(--fill); border-radius: 14px; padding: 14px; }
.cable-pairs { display: grid; gap: 9px; }
.cable-pair { display: grid; grid-template-columns: 58px 1fr 150px; gap: 12px; align-items: center; font-size: 13px; }
.cp-name { display: flex; gap: 6px; align-items: baseline; } .cp-name b { font-size: 14px; } .cp-name span { color: var(--text3); font-size: 11px; }
.cp-wire { position: relative; height: 10px; border-radius: 6px; background: var(--line); }
.cp-wire i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 6px; transition: width .6s cubic-bezier(.2,.9,.3,1);
  background: repeating-linear-gradient(115deg, var(--c) 0 9px, rgba(255,255,255,.85) 9px 13px); box-shadow: 0 0 10px color-mix(in srgb, var(--c) 45%, transparent); }
.cp-wire i.broken { border-radius: 6px 0 0 6px; }
.cp-x { position: absolute; top: 50%; width: 18px; height: 18px; margin: -9px 0 0 -9px; border-radius: 50%; background: var(--red); box-shadow: 0 0 0 3px var(--card, var(--bg)), 0 0 12px var(--red); }
.cp-x.warning { background: var(--orange); box-shadow: 0 0 0 3px var(--card, var(--bg)), 0 0 12px var(--orange); }
.cp-x::before, .cp-x::after { content: ''; position: absolute; left: 4px; right: 4px; top: 8px; height: 2px; background: #fff; border-radius: 2px; transform: rotate(45deg); }
.cp-x::after { transform: rotate(-45deg); }
.cp-st { display: flex; gap: 6px; align-items: center; white-space: nowrap; }
.cp-ruler { font-size: 10.5px; color: var(--text3); margin-top: -4px; }
.cable-details { margin: 0; padding-left: 18px; font-size: 13.5px; line-height: 1.5; }
@media (max-width: 560px) { .cable-pair { grid-template-columns: 44px 1fr 108px; gap: 8px; } .cp-name span { display: none; } }

/* network health */
.health { display: flex; flex-direction: column; gap: 16px; }
.score-ring { position: relative; flex-shrink: 0; }
.score-ring > div { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1; }
.score-ring b { font-weight: 800; letter-spacing: -.5px; } .score-ring small { font-size: 9.5px; color: var(--text3); margin-top: 2px; }
.check-item { align-items: flex-start; } .check-item.click { cursor: pointer; } .check-item.click:hover { background: var(--fill); }
.check-ic { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; flex-shrink: 0; }
.spof { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.spof-row { display: flex; gap: 10px; align-items: flex-start; padding: 10px; border-radius: 12px; background: var(--fill); }
.spof-row.click { cursor: pointer; } .spof-row.click:hover { background: color-mix(in srgb, var(--accent) 10%, var(--fill)); }
.spof-bar { height: 5px; border-radius: 3px; background: var(--line); margin-top: 6px; overflow: hidden; }
.spof-bar i { display: block; height: 100%; border-radius: 3px; background: linear-gradient(90deg, var(--orange), var(--red)); }
.link-btn { border: 0; background: none; color: var(--accent); font: inherit; font-size: 14px; font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; padding: 4px 0; }
.link-btn svg { transition: transform .2s; }
.topo-types { display: grid; gap: 8px; margin-top: 8px; }
.topo-type { display: flex; gap: 12px; align-items: center; padding: 8px 10px; border-radius: 12px; border: 1px solid transparent; }
.topo-type.on { border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.topo-type svg { flex-shrink: 0; } .topo-type b { font-size: 14px; }
.health-panel { position: absolute; left: 12px; top: 64px; width: 400px; max-height: calc(100% - 80px); overflow: auto; z-index: 3; touch-action: pan-y; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
@media (max-width: 760px) { .health-panel { left: 10px; right: 10px; width: auto; top: 60px; max-height: calc(100% - 140px); } .spof { grid-template-columns: 1fr; } }
.spof-mark { fill: none; stroke: var(--orange); stroke-width: 2; stroke-dasharray: 6 4; animation: spofdash 1.2s linear infinite; }
@keyframes spofdash { to { stroke-dashoffset: -20; } }

/* multiple racks */
.rack-tabs .chip { gap: 5px; }
.icon-link { border: 0; background: none; padding: 2px 4px; margin-left: 6px; color: var(--text3); cursor: pointer; vertical-align: middle; border-radius: 6px; }
.icon-link:hover { color: var(--accent); background: var(--fill); }

/* rack quick-jump on the map */
.rack-jump { position: absolute; left: 12px; top: 64px; z-index: 2; flex-direction: column; align-items: stretch; gap: 2px; max-width: 200px; max-height: calc(100% - 150px); overflow: auto; }
.rack-jump-title { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--text3); padding: 2px 8px 4px; }
.rack-jump-btn { display: flex; align-items: center; gap: 7px; padding: 7px 10px; border: 0; border-radius: 9px; background: none; color: var(--text2); font-size: 13px; font-weight: 500; cursor: pointer; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rack-jump-btn:hover { background: var(--fill); color: var(--text); }
@media (max-width: 760px) { .rack-jump { max-width: 150px; } }

/* places: box / room tile view + type picker */
.tilebox { background: var(--card); border: .5px solid var(--line); border-radius: 18px; padding: 16px; backdrop-filter: blur(20px); }
.tile { position: relative; display: flex; flex-direction: column; justify-content: center; gap: 8px; min-height: 64px; padding: 12px 14px 12px 18px; border-radius: 13px; background: var(--bg2); border: .5px solid var(--line); cursor: pointer; overflow: hidden; transition: transform .14s, box-shadow .2s; }
.tile:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.tile .strip { position: absolute; left: 0; top: 0; bottom: 0; width: 5px; }
.tile.passive { opacity: .82; }
.place-pick { display: flex; flex-direction: column; gap: 8px; }
.place-opt { display: flex; align-items: center; gap: 12px; text-align: left; padding: 12px 14px; border-radius: 13px; border: 1.5px solid var(--line); background: var(--bg2); cursor: pointer; color: var(--text); }
.place-opt.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.place-opt b { display: block; font-size: 14.5px; } .place-opt small { color: var(--text2); font-size: 12.5px; }

/* draggable box tiles */
.tiles-canvas { position: relative; margin-top: 14px; border-radius: 12px; min-height: 120px; }
.tiles-canvas.editing { background-image: radial-gradient(circle at 1px 1px, var(--line) 1px, transparent 0); background-size: 226px 76px; }
.tiles-canvas.editing .tile.free { cursor: grab; }
.tile.free { position: absolute; margin: 0; touch-action: none; user-select: none; transition: box-shadow .15s; }
.tile.free.grabbing { cursor: grabbing; box-shadow: var(--shadow-lg); z-index: 5; opacity: .95; transition: none; }

/* floor plan */
.plan-tools { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; overflow-x: auto; }
.plan-palette { margin-bottom: 10px; }
.plan-canvas { position: relative; height: calc(100vh - 290px); min-height: 440px; border-radius: var(--r-lg); overflow: hidden; border: .5px solid var(--line); background: var(--bg2); box-shadow: var(--shadow); touch-action: none; }
.plan-canvas.crosshair { cursor: none; }                    /* PlanCursor draws a visible snap marker instead */
.plan-canvas > svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.plan-open { position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 3; display: inline-flex; align-items: center; gap: 7px;
  max-width: calc(100% - 140px); white-space: nowrap; padding: 11px 16px 11px 14px; border-radius: 999px; border: 0; background: var(--accent); color: #fff;
  font: inherit; font-size: 15px; font-weight: 600; box-shadow: 0 6px 20px rgba(0,0,0,.28); cursor: pointer; animation: planOpenIn .18s ease-out; }
@keyframes planOpenIn { from { opacity: 0; transform: translate(-50%, 8px); } }
.plan-edit-dock { position: absolute; right: 12px; bottom: calc(220px + env(safe-area-inset-bottom, 0px)); z-index: 5; display: flex; flex-direction: column; align-items: flex-end; }
.plan-edit-fab { width: 48px; height: 48px; display: grid; place-items: center; border-radius: 16px; color: #fff; background: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 70%, white); box-shadow: 0 5px 18px rgba(0,0,0,.25); cursor: pointer; transition: transform .16s, background .16s; }
.plan-edit-fab:hover { transform: translateY(-2px); }
.plan-edit-fab.on { background: var(--text2); }
.plan-edit-panel { position: absolute; right: 0; bottom: 58px; width: min(360px, calc(100vw - 32px)); max-height: min(62vh, 560px); overflow: auto; padding: 13px; border: 1px solid var(--line); box-shadow: var(--shadow-lg); background: var(--card-solid); }
.plan-edit-panel > .row:first-child { margin-bottom: 7px; }
.plan-check { display: flex; align-items: center; gap: 9px; padding: 8px 2px; font-size: 13px; cursor: pointer; }
.plan-check input { accent-color: var(--accent); width: 16px; height: 16px; margin: 0; }
.plan-tool-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; margin-top: 7px; }
.plan-tool-grid .chip { justify-content: flex-start; min-height: 36px; }
.plan-tool-status { display: flex; align-items: center; gap: 6px; margin-top: 8px; padding: 7px 9px; border-radius: 10px; color: var(--accent); background: color-mix(in srgb, var(--accent) 13%, var(--card-solid)); border: 1px solid color-mix(in srgb, var(--accent) 50%, transparent); font-size: 12px; font-weight: 700; }
.plan-equip-list { margin-top: 7px; padding-top: 6px; border-top: 1px solid var(--line); }
.plan-equip-search { width: 100%; margin-bottom: 5px; }
.plan-equip-option { display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px; border: 0; border-radius: 9px; background: transparent; color: var(--text); text-align: left; font: inherit; font-size: 12.5px; cursor: pointer; }
.plan-equip-option > svg { flex: none; color: var(--accent); }
.plan-equip-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.plan-equip-copy b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-equip-copy small { color: var(--text3); font-size: 10.5px; }
.plan-equip-option:hover, .plan-equip-option.on { background: var(--fill); color: var(--accent); }
.plan-iso-ground { fill: color-mix(in srgb, var(--accent) 8%, var(--bg2)); stroke: color-mix(in srgb, var(--accent) 24%, transparent); stroke-width: 2; }
.plan-iso-slab { fill: var(--card-solid); stroke: var(--line2); stroke-width: 2; }
.plan-iso-slab-side { fill: var(--fill2); stroke: var(--line2); stroke-width: 1.5; }
.plan-iso-level.active .plan-iso-slab { fill: color-mix(in srgb, var(--accent) 17%, var(--card-solid)); stroke: var(--accent); stroke-width: 3.5; }
.plan-iso-level.active .plan-iso-slab-side { fill: color-mix(in srgb, var(--accent) 30%, var(--fill2)); stroke: color-mix(in srgb, var(--accent) 72%, white); stroke-width: 2; }
.plan-iso-room .pr-fill { stroke-width: 2; }
.plan-iso-room.sel .pr-fill { stroke-width: 4; }
.plan-room-selection-ring { fill: color-mix(in srgb, var(--orange) 12%, transparent); stroke: var(--orange); stroke-linejoin: round; animation: plan-room-selected-pulse 1.6s ease-in-out infinite; }
.plan-room-resize-handle { cursor: nwse-resize; touch-action: none; }
.plan-room-resize-dot { fill: var(--orange); stroke: var(--card-solid); filter: drop-shadow(0 2px 3px rgba(0,0,0,.35)); }
@keyframes plan-room-selected-pulse { 0%,100% { stroke-opacity: 1; } 50% { stroke-opacity: .5; } }
@media (prefers-reduced-motion: reduce) { .plan-room-selection-ring { animation: none; } }
.plan-placement-prompt { position: absolute; z-index: 4; left: 12px; bottom: 12px; max-width: calc(100% - 95px); display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 14px; border: 1px solid var(--accent); background: var(--card-solid); color: var(--text); box-shadow: var(--shadow); font-size: 13px; }
.plan-placement-prompt .btn { flex: none; }
.plan-iso-label { fill: var(--text); font-size: 12px; font-weight: 700; paint-order: stroke; stroke: var(--bg2); stroke-width: 3px; pointer-events: none; }
.plan-iso-level-name { fill: var(--text2); font-size: 12px; font-weight: 700; paint-order: stroke; stroke: var(--bg2); stroke-width: 4px; }
.plan-iso-level.active .plan-iso-level-name { fill: var(--accent); font-size: 14px; }
.plan-iso-wall-face { fill: color-mix(in srgb, var(--card-solid) 76%, var(--text2)); stroke: var(--line2); stroke-width: 1; }
.plan-iso-wall-top { stroke: var(--text2); stroke-width: 5; stroke-linecap: round; }
.plan-iso-wall-base { stroke: var(--line2); stroke-width: 2; }
.plan-iso-scene { --plan-wall-active: #ccd4de; --plan-wall-shade: #9ba8b8; --plan-wall-edge: #73849a; --plan-wall-cap: #edf2f8; }
[data-theme="light"] .plan-iso-scene { --plan-wall-active: #64717f; --plan-wall-shade: #46525f; --plan-wall-edge: #35414f; --plan-wall-cap: #95a3b1; }
.plan-iso-level.active .plan-iso-wall-face { fill: url(#plan-wall-matte); stroke: var(--plan-wall-edge); stroke-width: 1; stroke-linejoin: round; filter: drop-shadow(0 3px 3px rgba(0,0,0,.16)); }
.plan-iso-level.active .plan-iso-wall[data-wall-side="y"] .plan-iso-wall-face { fill: url(#plan-wall-matte-side); }
.plan-iso-level.active .plan-iso-wall-top { stroke: var(--plan-wall-cap); stroke-width: 7; }
.plan-iso-level.active .plan-iso-wall-base { stroke: var(--plan-wall-edge); opacity: .65; }
.plan-iso-wall.selected .plan-iso-wall-face { fill: color-mix(in srgb, var(--orange) 52%, var(--card-solid)); stroke: var(--orange); stroke-width: 3; }
.plan-iso-level.active .plan-iso-wall.selected[data-wall-side] .plan-iso-wall-face { fill: color-mix(in srgb, var(--orange) 52%, var(--card-solid)); stroke: var(--orange); }
.plan-iso-wall.selected .plan-iso-wall-top { stroke: var(--orange); stroke-width: 9; }
.plan-floor-handle { fill: var(--accent); stroke: white; stroke-width: 3; filter: drop-shadow(0 2px 4px rgba(0,0,0,.5)); cursor: nwse-resize; touch-action: none; }
.plan-floor-resize { cursor: nwse-resize; touch-action: none; }
.plan-equipment-size { padding: 8px; flex-wrap: wrap; }
.plan-equipment-size b { min-width: 44px; text-align: center; font-size: 13px; }
.plan-building-facade { fill: url(#plan-wall-matte); stroke: var(--plan-wall-edge); stroke-width: 2; opacity: .85; }
.plan-building-facade.side-1 { fill: url(#plan-wall-matte-side); }
.plan-building-seam { stroke: var(--plan-wall-cap); stroke-width: 3; opacity: .7; }
.plan-iso-scene.overview .plan-iso-slab { fill: color-mix(in srgb, var(--accent) 9%, var(--card-solid)); stroke: var(--line2); stroke-width: 2; }
.plan-iso-scene.overview .plan-iso-wall-face { fill: url(#plan-wall-matte); stroke: var(--plan-wall-edge); stroke-width: 1; }
.plan-iso-scene.overview .plan-iso-wall[data-wall-side="y"] .plan-iso-wall-face { fill: url(#plan-wall-matte-side); }
.plan-iso-scene.overview .plan-iso-wall-top { stroke: var(--plan-wall-cap); stroke-width: 5; }
.plan-wall { stroke: var(--text2); stroke-width: 6; stroke-linecap: round; }
.plan-wall.draft { stroke: var(--accent); stroke-dasharray: 6 6; opacity: .8; }
.plan-item .pi-bg { fill: var(--card-solid); stroke: var(--line2); stroke-width: 1.5; }
.plan-item .pi-core { stroke: none; }
.plan-item.sel .pi-bg { stroke: var(--accent); stroke-width: 3.5; }
.plan-item.outdoor .pi-bg { stroke: var(--accent) !important; stroke-dasharray: 4 2; }
.plan-item .pi-label { font-size: 12.5px; font-weight: 650; fill: var(--text); stroke: none; }
.plan-item .pi-type { font-size: 10.5px; font-family: var(--mono); fill: var(--text2); pointer-events: none; }
.plan-item .pi-outdoor { font-size: 9px; font-weight: 700; letter-spacing: .08em; fill: var(--accent); paint-order: stroke; stroke: var(--bg2); stroke-width: 3.5px; }
.plan-label text { font-size: 13px; font-weight: 700; fill: var(--text2); paint-order: stroke; stroke: var(--bg2); stroke-width: 4px; }
.plan-label text.sel { fill: var(--accent); }
.plan-hint { position: absolute; left: 12px; bottom: 12px; font-size: 12px; color: var(--text2); background: var(--elev); padding: 6px 11px; border-radius: 20px; border: .5px solid var(--line); backdrop-filter: blur(10px); }
.plan-empty { text-align: center; display: flex; flex-direction: column; align-items: center; padding: 50px 24px; }

/* territory + rooms + ghost + mobile */
.plan-yard { fill: color-mix(in srgb, var(--green) 14%, transparent); stroke: color-mix(in srgb, var(--green) 40%, transparent); stroke-width: 1.5; }
.plan-building .pi-card { fill: var(--card-solid); stroke: var(--line); stroke-width: 1; }
.plan-building.sel .pi-card { stroke: var(--accent); stroke-width: 2.5; }
.pb-name { font-size: 16px; font-weight: 750; fill: var(--text); }
.pb-sub { font-size: 12px; fill: var(--text2); }
.pb-hint { font-size: 10.5px; fill: var(--text3); }
.plan-link { stroke: var(--accent); stroke-width: 3; stroke-dasharray: 8 5; cursor: pointer; }
.plan-link-label { font-size: 11.5px; font-weight: 600; fill: var(--accent); paint-order: stroke; stroke: var(--bg2); stroke-width: 4px; }
.plan-room.sel rect { stroke-width: 2.5 !important; }
.plan-room-draft { fill: color-mix(in srgb, var(--accent) 10%, transparent); stroke: var(--accent); stroke-dasharray: 5 5; }
.ghost { opacity: .32; pointer-events: none; }
.plan-wall.ghost { stroke-width: 4; stroke-dasharray: 4 6; }
.plan-room-ghost { fill: none; stroke: var(--text3); stroke-dasharray: 4 5; }
.plan-item-ghost { fill: none; stroke: var(--text3); stroke-width: 1.5; }
@media (max-width: 760px) {
  .plan-canvas { height: calc(100dvh - 300px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); min-height: 360px; }   /* same as the network map */
  .plan-canvas .zoom-btns { bottom: 14px; }
  .plan-hint { display: none; }
}

/* plan cursor + finished rooms + erase selection */
.plan-cursor { fill: color-mix(in srgb, var(--accent) 30%, transparent); stroke: var(--accent); stroke-width: 1.5; }
.plan-cursor-x { stroke: var(--accent); stroke-width: 1.5; }
.pr-fill { stroke-width: 2.5; }
.plan-room.sel .pr-fill { stroke-width: 4; }
.pr-tag { font-size: 11px; font-weight: 700; fill: #fff; }
.plan-erase-draft { fill: color-mix(in srgb, var(--red) 12%, transparent); stroke: var(--red); stroke-dasharray: 5 5; }

/* poles on the territory */
.pole-bg { fill: var(--card-solid); stroke: var(--accent); stroke-width: 1.8; }
.plan-pole.sel .pole-bg { stroke-width: 3.5; }
.pole-mast { stroke: var(--text2); stroke-width: 2.2; stroke-linecap: round; }
.pole-ins { fill: var(--accent); }

/* device picker, UPS card, patch / cross port map */
.dev-pick { display: flex; flex-wrap: wrap; gap: 6px; max-height: 190px; overflow: auto; padding: 2px; }
.ups-big { font-size: 28px; font-weight: 800; letter-spacing: -.6px; line-height: 1.1; }
.ups-big small { font-size: 14px; font-weight: 600; color: var(--text2); }
.pm { display: flex; flex-direction: column; gap: 10px; margin-top: 4px; }
.pm-grid { display: grid; grid-template-columns: repeat(var(--cols), minmax(26px, 1fr)); gap: 5px; padding: 10px; border-radius: 12px; background: #1c1c1e; overflow-x: auto; }
.pm-port { position: relative; height: 30px; min-width: 26px; border-radius: 6px; border: 1px solid #3a3a3c; background: #2c2c2e; color: #aeaeb2; font: 600 10.5px var(--mono); cursor: pointer; overflow: hidden; }
.pm-port.set { border-color: #636366; color: #fff; }
.pm-port.down { border-color: #636366; color: #fff; box-shadow: inset 0 -3px 0 #48484a; }
.pm-port.g { border-color: var(--green); color: #fff; box-shadow: inset 0 -3px 0 var(--green); }
.pm-port.y { border-color: #ffd60a; color: #fff; box-shadow: inset 0 -3px 0 #ffd60a; }
.pm-port.sel { outline: 2px solid var(--accent); outline-offset: 1px; }
.pm-fiber { position: absolute; left: 0; top: 0; right: 0; height: 5px; }
.pm-lg { display: inline-block; width: 10px; height: 10px; border-radius: 3px; background: #48484a; }
.pm-lg.g { background: var(--green); } .pm-lg.y { background: #ffd60a; }
.pm-detail { background: var(--fill); border-radius: 12px; padding: 10px 12px; font-size: 14px; display: flex; flex-direction: column; gap: 3px; }
.pm-num { font: 700 12px var(--mono); min-width: 30px; height: 26px; padding: 0 6px; display: grid; place-items: center; border-radius: 7px; background: var(--fill); }
.pm-table-wrap { overflow: auto; max-height: 60vh; margin: 0 -4px; }
.pm-table td { padding: 4px 4px; } .pm-table th { position: sticky; top: 0; background: var(--card-solid); z-index: 1; }
.pm-in { height: 32px; padding: 4px 8px; font-size: 13px; min-width: 90px; }
.pm-sel { height: 32px; padding: 2px 6px; font-size: 13px; min-width: 70px; }
.pm-port.pm-empty { opacity: .45; border-style: dashed; }

/* modem sockets, swap highlight, unit hint */
.pm-grid.named { grid-template-columns: repeat(var(--cols), minmax(52px, 1fr)); }
.pm-port.named { font-size: 10px; padding: 0 4px; }
.unit.swap { outline: 2px dashed var(--accent); outline-offset: -2px; opacity: .75; }
.unit-grip { position: absolute; right: 0; top: 0; bottom: 0; width: 46px; display: grid; place-items: center; font-size: 22px; line-height: 1; color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); border-radius: 0 6px 6px 0; touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab; z-index: 2; }
.unit.dragging { z-index: 5; box-shadow: 0 8px 22px rgba(0,0,0,.45); }
/* «Что ставим?» — first step of a unit: your devices or plain equipment */
.up-sec { font-weight: 650; font-size: 14px; margin: 4px 2px -2px; } .up-sec small { color: var(--text2); font-weight: 400; margin-left: 6px; }
.unit-pick { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 8px; }
.up-opt { display: flex; align-items: center; gap: 10px; text-align: left; padding: 9px 11px; border-radius: 13px; border: 1.5px solid var(--line);
  background: var(--bg2); color: var(--text); cursor: pointer; min-width: 0; }
.up-opt > div { min-width: 0; } .up-opt b { display: block; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.up-opt small { display: block; color: var(--text2); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.up-opt:hover { border-color: color-mix(in srgb, var(--accent) 50%, var(--line)); }
.up-opt.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.up-opt.placed { opacity: .6; }
.up-opt.add { border-style: dashed; } .up-plus { width: 32px; height: 32px; border-radius: 9px; display: grid; place-items: center; flex: none;
  background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }
.up-what { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 14px; background: var(--fill); }
.up-what b { display: block; font-size: 15px; } .up-what small { display: flex; align-items: center; gap: 6px; color: var(--text2); font-size: 12.5px; }
.move-lbl { font-size: 13px; margin-left: 4px; }
.ont-setup { display: flex; flex-direction: column; gap: 10px; padding: 12px; border-radius: 14px; background: var(--fill); }
.ont-lans { display: flex; flex-direction: column; gap: 8px; }
.ups-curve { margin-top: 12px; } .ups-curve svg { width: 100%; height: 72px; display: block; }
.ups-curve .line { fill: none; stroke: var(--green); stroke-width: 2; vector-effect: non-scaling-stroke; }
.ups-curve .area { fill: color-mix(in srgb, var(--green) 14%, transparent); }
.loads { display: flex; flex-direction: column; gap: 6px; }
.hint-box .tips { margin: 4px 0 0; padding-left: 16px; display: flex; flex-direction: column; gap: 3px; font-size: 12.5px; line-height: 1.4; }
.hint-box .tips li::marker { color: var(--accent); }
.upsw-list { display: flex; flex-direction: column; gap: 12px; } .upsw { cursor: pointer; padding: 14px; }
.wg .upsw { border: 0; box-shadow: none; background: transparent; padding: 4px; } .wg .upsw + .upsw { border-top: .5px solid var(--line); border-radius: 0; padding-top: 14px; }
.upsw-main { display: flex; align-items: center; gap: 14px; margin: 12px 0 8px; } .upsw-bat { width: 112px; flex: none; }
.upsw-feeds { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.upsw-chip { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; padding: 4px 9px; border-radius: 999px; background: var(--fill); font-size: 12px; }
.upsw-chip .ellipsis { max-width: 120px; } .upsw-chip b { font-weight: 650; color: var(--text2); } .upsw-chip.more { color: var(--text3); }
.login-alts { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px; }
.login-alt { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 16px; border: 1.5px solid var(--line); background: var(--bg2); color: var(--text); font: inherit; text-align: left; cursor: pointer; min-width: 0; transition: border-color .15s, transform .1s; }
.login-alt:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); } .login-alt:active { transform: scale(.98); } .login-alt:disabled { opacity: .6; }
.login-alt .mi { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; flex: none; }
.login-alt b { display: block; font-size: 13.5px; } .login-alt small { display: block; color: var(--text2); font-size: 11.5px; }
.mfa-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.mfa-tile { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 16px; border: 1.5px solid var(--line); background: var(--bg2); color: var(--text); font: inherit; text-align: left; cursor: pointer; min-width: 0; transition: border-color .15s, box-shadow .15s, transform .1s; }
.mfa-tile:active { transform: scale(.98); }
.mfa-tile .mi { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; flex: none; }
.mfa-tile b { display: block; font-size: 13.5px; } .mfa-tile small { display: block; color: var(--text2); font-size: 11.5px; max-width: 100%; }
.mfa-tile.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, transparent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 13%, transparent); }
.otp { position: relative; display: flex; gap: 8px; justify-content: center; }
.otp-box { width: 46px; height: 56px; border-radius: 14px; background: var(--fill); border: 1.5px solid transparent; display: grid; place-items: center; font-size: 26px; font-weight: 650; font-variant-numeric: tabular-nums; transition: border-color .12s, box-shadow .12s; }
.otp-box.fill { background: var(--bg2); border-color: var(--line); }
.otp-box.cur { border-color: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 18%, transparent); }
.otp-in { position: absolute; inset: 0; width: 100%; opacity: 0; font-size: 16px; border: 0; background: none; color: transparent; }
.mfa-remember { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 14px; background: var(--fill); cursor: pointer; }
.mfa-err { padding: 10px 12px; border-radius: 12px; font-size: 13.5px; color: var(--red); background: color-mix(in srgb, var(--red) 10%, transparent); text-align: center; }
@media (max-width: 380px) { .otp-box { width: 40px; height: 52px; font-size: 24px; } .otp { gap: 6px; } }
.mfa-methods { display: flex; flex-wrap: wrap; gap: 6px; }
.mfa-m { display: inline-flex; align-items: center; gap: 6px; padding: 8px 12px; border-radius: 999px; border: 1.5px solid var(--line); background: var(--bg2); color: var(--text); font: inherit; font-size: 13px; cursor: pointer; }
.mfa-m.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); font-weight: 600; }
.mfa-wait { display: flex; align-items: center; gap: 14px; padding: 12px; border-radius: 14px; background: var(--fill); }
.mfa-spin { width: 26px; height: 26px; border-radius: 50%; border: 3px solid var(--fill2); border-top-color: var(--accent); animation: mfaSpin 1s linear infinite; flex: none; }
@keyframes mfaSpin { to { transform: rotate(360deg); } }
.mfa-row { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 14px; background: var(--fill); }
.rc-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; } .rc-grid code { padding: 9px 10px; border-radius: 10px; background: var(--fill); font-size: 15px; text-align: center; letter-spacing: 1px; }
.dev-sess { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: .5px solid var(--line); } .dev-sess:last-child { border-bottom: 0; }
.dev-loc { margin-bottom: 12px; } .dev-loc .seg { width: 100%; } .dev-loc .seg button { flex: 1; justify-content: center; }
.modal-back { width: 30px; height: 30px; border-radius: 50%; border: 0; background: var(--fill); color: var(--text); display: grid; place-items: center; cursor: pointer; flex: none; margin-right: 2px; }
.modal-back:hover { background: var(--fill2); }
.dev-cat { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 10px; }
.dev-cat-grp, .dev-cat-item { text-align: left; display: flex; align-items: center; gap: 12px; padding: 13px 14px; border-radius: 16px; border: .5px solid var(--line2); background: var(--bg2); color: var(--text); cursor: pointer; font: inherit; }
.dev-cat-grp:hover, .dev-cat-item:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--line2)); }
.dev-cat-grp > div:nth-child(2), .dev-cat-item > div:last-child { flex: 1; min-width: 0; } .dev-cat-item > :first-child, .dev-cat-grp > :first-child { flex: none; } .dev-cat-grp b, .dev-cat-item b { font-size: 15px; display: block; }
.dev-cat-grp small, .dev-cat-item small { display: block; color: var(--text2); font-size: 12.5px; line-height: 1.4; margin-top: 2px; }
.dev-cat-list { display: flex; flex-direction: column; gap: 8px; } .dev-cat-item { align-items: flex-start; }
.dev-cat-proof { display: inline-block; margin: 3px 0 0; padding: 1px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; color: var(--green);
  background: color-mix(in srgb, var(--green) 13%, transparent); }
.steps { margin: 8px 0 8px; padding-left: 20px; display: flex; flex-direction: column; gap: 5px; font-size: 13.5px; line-height: 1.45; }
/* Приветственное обучение (95_tour.jsx) */
.tour-layer { position: fixed; inset: 0; z-index: 100000; pointer-events: none; animation: tourIn .55s ease both; }
.tour-layer { --tour-a1: .88; --tour-a2: .86; --tour-a3: .9; }
/* a computer: the same glassy look as on a phone — the page stays visible through a lighter tint and is softly blurred (the lit-up part stays sharp: the four blocks leave it out) */
@media (min-width: 900px) { .tour-layer { --tour-a1: .5; --tour-a2: .46; --tour-a3: .52; } .tour-block { backdrop-filter: blur(8px) saturate(1.2); -webkit-backdrop-filter: blur(8px) saturate(1.2); } }
@keyframes tourIn { from { opacity: 0; } to { opacity: 1; } }
.tour-dim { position: absolute; inset: 0; }
.tour-block { position: absolute; pointer-events: auto; background: transparent; backdrop-filter: blur(2.5px); -webkit-backdrop-filter: blur(2.5px); }
.tour-ring { position: absolute; pointer-events: none; border: 2px solid rgba(255,255,255,.92); animation: tourPulse 1.7s ease-out infinite; }
@keyframes tourPulse { 0% { box-shadow: 0 0 0 0 rgba(10,132,255,.75), 0 0 22px 3px rgba(10,132,255,.5); } 70% { box-shadow: 0 0 0 16px rgba(10,132,255,0), 0 0 34px 8px rgba(10,132,255,.25); } 100% { box-shadow: 0 0 0 0 rgba(10,132,255,0), 0 0 22px 3px rgba(10,132,255,.5); } }
.tour-skip { position: absolute; top: max(14px, env(safe-area-inset-top)); right: 14px; pointer-events: auto; display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; border-radius: 999px;
  border: .5px solid rgba(255,255,255,.28); background: rgba(255,255,255,.12); color: #fff; font: inherit; font-size: 13.5px; cursor: pointer; backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
.tour-skip:hover { background: rgba(255,255,255,.2); }
@media (max-width: 760px) { .tour-skip { right: auto; left: 50%; transform: translateX(-50%); white-space: nowrap; padding: 7px 13px; font-size: 13px; } }      /* a phone: the «⋯» button of the header lives in the top right corner */
.tour-card { position: absolute; left: 0; top: 0; width: min(460px, calc(100vw - 24px)); display: flex; align-items: flex-start; gap: 6px; pointer-events: auto; will-change: transform; }
.tour-card.big { width: min(520px, calc(100vw - 24px)); }
.tour-frank-wrap { flex: none; position: relative; } .tour-frank svg { display: block; }
.tf-bob { animation: tfBob 3.4s ease-in-out infinite; } @keyframes tfBob { 50% { transform: translateY(-2.5px); } }
.tf-lid { transform-box: fill-box; transform-origin: 50% 0; transform: scaleY(0); animation: tfBlink 4.8s infinite; }
@keyframes tfBlink { 0%, 92%, 100% { transform: scaleY(0); } 94.5%, 96% { transform: scaleY(1); } }
.tf-wave { transform-box: view-box; transform-origin: 0 0; animation: tfWave 1.1s ease-in-out infinite; } @keyframes tfWave { 0%, 100% { transform: rotate(-16deg); } 50% { transform: rotate(18deg); } }
.tour-bubble { flex: 1; min-width: 0; position: relative; margin-top: 8px; padding: 14px 16px; border-radius: 20px; color: #fff; background: rgba(28,30,46,.86); border: .5px solid rgba(255,255,255,.2);
  box-shadow: 0 18px 50px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.12); backdrop-filter: blur(24px) saturate(1.4); -webkit-backdrop-filter: blur(24px) saturate(1.4); animation: tourPop .38s cubic-bezier(.2,.9,.3,1.2) both; }
.tour-bubble::before { content: ''; position: absolute; left: -5px; top: 26px; width: 10px; height: 10px; transform: rotate(45deg); background: rgba(28,30,46,.95); border-left: .5px solid rgba(255,255,255,.2); border-bottom: .5px solid rgba(255,255,255,.2); }
@keyframes tourPop { from { opacity: 0; transform: translateX(-8px) scale(.96); } to { opacity: 1; transform: none; } }
.tour-title { display: block; font-size: 17px; margin-bottom: 4px; letter-spacing: -.2px; } .tour-text { font-size: 14px; line-height: 1.5; color: rgba(255,255,255,.86); }
.tour-hint { display: flex; align-items: center; gap: 9px; margin-top: 11px; font-size: 13px; font-weight: 650; color: #7cc8ff; }
.tour-hint i { width: 9px; height: 9px; border-radius: 50%; background: #0a84ff; animation: tourDot 1.4s ease-out infinite; } @keyframes tourDot { 0% { box-shadow: 0 0 0 0 rgba(10,132,255,.85); } 80%, 100% { box-shadow: 0 0 0 9px rgba(10,132,255,0); } }
.tour-actions { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.tour-actions { flex-wrap: wrap; row-gap: 10px; } .tour-actions .grow { flex: 1 1 0; min-width: 0; } .tour-link, .tour-next { white-space: nowrap; flex: none; }
@media (max-width: 560px) { .tour-dots { flex: 1 1 100%; } }                          /* a phone: the dots take their own line, the buttons stay inside the bubble */
.tour-dots { display: flex; gap: 4px; } .tour-dots i { width: 6px; height: 6px; border-radius: 3px; background: rgba(255,255,255,.25); transition: all .25s; } .tour-dots i.done { background: rgba(255,255,255,.55); } .tour-dots i.on { width: 16px; background: #0a84ff; }
.tour-link { background: none; border: 0; color: rgba(255,255,255,.7); font: inherit; font-size: 13.5px; cursor: pointer; padding: 8px 6px; } .tour-link:hover { color: #fff; }
.tour-next { border: 0; border-radius: 999px; padding: 10px 18px; font: inherit; font-weight: 650; font-size: 14px; color: #fff; background: linear-gradient(135deg, #2b9bff, #0a6cff); box-shadow: 0 6px 18px rgba(10,108,255,.5); cursor: pointer; }
.tour-next:active { transform: scale(.97); }
.tour-card-eye { width: 64px; height: 64px; border-radius: 18px; flex: none; display: grid; place-items: center; background: linear-gradient(135deg, #0e1430, #1a1038); overflow: hidden; }
.tour-card-eye .tour-frank svg { overflow: visible; }
.tour-fast, .tour-fast * { animation: none !important; }
@media (prefers-reduced-motion: reduce) { .tf-bob, .tf-lid, .tf-wave, .tour-ring, .tour-hint i, .tour-bubble, .tour-layer { animation: none; } }
.loop-alarm { display: flex; gap: 10px; align-items: flex-start; padding: 11px 13px; border-radius: 14px; margin-bottom: 10px; font-size: 13.5px; line-height: 1.45;
  color: var(--red); background: color-mix(in srgb, var(--red) 11%, transparent); border: 1px solid color-mix(in srgb, var(--red) 35%, transparent); } .loop-alarm > svg { flex: none; margin-top: 2px; } .loop-alarm b { display: block; font-size: 14.5px; }
.advice { display: flex; gap: 10px; padding: 10px 0; border-top: 1px solid var(--line); } .advice:first-child { border-top: 0; }
.advice-ic { width: 28px; height: 28px; border-radius: 9px; flex: none; display: grid; place-items: center; background: var(--fill); }
.advice-t { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; font-size: 14px; } .advice-k { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.arrange-sw { display: inline-flex; align-items: center; gap: 8px; padding: 0 4px 0 10px; height: 34px; border-radius: 12px; background: var(--fill); font-size: 13px; font-weight: 600; white-space: nowrap; cursor: pointer; }
@media (max-width: 1320px) { .arrange-sw span { display: none; } .arrange-sw { padding: 0 6px; } }
.codebox { display: flex; flex-direction: column; gap: 8px; align-items: stretch; } .codebox .btn { align-self: flex-end; }
.load-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; } .load-row .select.grow { min-width: 150px; flex: 1 1 170px; }
.spec { display: inline-flex; align-items: center; gap: 5px; flex: none; } .spec .input { width: 58px; padding-left: 8px; padding-right: 8px; text-align: center; }
.spec i { font-style: normal; color: var(--text3); } .spec b { font-weight: 600; color: var(--text2); font-size: 13px; }
.ptree { border-left: 2px solid var(--line); padding-left: 8px; } .ptree .li { gap: 8px; }
.pt-out { min-width: 22px; height: 22px; border-radius: 7px; display: inline-grid; place-items: center; flex: none; font-size: 11.5px; font-weight: 700;
  background: color-mix(in srgb, var(--orange) 16%, transparent); color: var(--orange); margin-right: 2px; }
.ups-found { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }

/* notifications */
.notify-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 22px; align-items: start; }
.notify-ch { padding: 12px 14px; border-radius: 13px; background: var(--fill); }
.notify-rule { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: .5px solid var(--line); }
.notify-rule:last-of-type { border-bottom: 0; }

/* step-by-step guides in settings */
.guide { background: color-mix(in srgb, var(--accent) 7%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 20%, transparent); border-radius: 12px; padding: 8px 12px; font-size: 13px; line-height: 1.5; }
.guide summary { cursor: pointer; font-weight: 650; color: var(--accent); }
.guide ol, .guide ul { margin: 8px 0 4px; padding-left: 20px; } .guide li { margin-bottom: 5px; }
.guide code { font-family: var(--mono); font-size: 12px; background: var(--fill); padding: 1px 5px; border-radius: 5px; }

/* Telegram login / link */
.tg-flow { display: flex; flex-direction: column; gap: 10px; align-items: stretch; padding: 12px; border-radius: 13px; background: color-mix(in srgb, #229ed9 10%, transparent); border: 1px solid color-mix(in srgb, #229ed9 30%, transparent); font-size: 14px; }
.btn.tg-btn { background: #229ed9; color: #fff; justify-content: center; gap: 8px; text-decoration: none; }
.btn.tg-btn:hover { background: #1b8bc0; }
.or-line { display: flex; align-items: center; gap: 10px; color: var(--text3); font-size: 12.5px; margin: 2px 0; }
.or-line::before, .or-line::after { content: ''; flex: 1; height: .5px; background: var(--line); }
.tg-linked { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; border-radius: 12px; background: var(--bg2); border: .5px solid var(--line); }

/* ── hints ── */
.hint-box { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; margin-bottom: 14px; border-radius: 14px; font-size: 13.5px; line-height: 1.45;
  background: var(--hint-bg, color-mix(in srgb, var(--yellow) 11%, var(--card))); border: .5px solid var(--hint-line, color-mix(in srgb, var(--yellow) 45%, transparent)); color: var(--hint-text, inherit); border-radius: var(--hint-radius, 14px); }
.hint-box b { display: block; margin-bottom: 2px; }
.hint-ico { width: 28px; height: 28px; border-radius: 9px; display: grid; place-items: center; flex-shrink: 0; color: var(--hint-ico, #b58900); background: var(--hint-ico-bg, color-mix(in srgb, var(--yellow) 26%, transparent)); }
[data-theme="dark"] .hint-ico { color: var(--hint-ico, var(--yellow)); }
.hint-close { border: 0; background: var(--hint-close-bg, var(--fill)); color: var(--hint-close-text, var(--text2)); font-size: 12.5px; font-weight: 600; padding: 5px 10px; border-radius: 9px; cursor: pointer; flex-shrink: 0; }
.hint-close:hover { background: var(--fill2); }
.modal-body .hint-box, .sheet-body .hint-box { margin-bottom: 0; }
.linkbtn { border: 0; background: none; padding: 4px 0 0; color: var(--accent); font-size: 12.5px; cursor: pointer; text-align: left; }

/* ── speed test ── */
.gauge { position: relative; width: 100%; max-width: 300px; margin: 0 auto; }
.gauge svg { width: 100%; display: block; }
.gauge-tick { font-size: 9px; fill: var(--text3); }
.gauge-val { position: absolute; left: 0; right: 0; top: 46%; text-align: center; }
.gauge-val b { display: block; font-size: 40px; font-weight: 750; letter-spacing: -1px; line-height: 1; font-variant-numeric: tabular-nums; }
.gauge-val span { font-size: 12.5px; color: var(--text2); }
.gauge-phase { text-align: center; font-size: 13px; font-weight: 600; color: var(--text2); min-height: 18px; }
.gauge-bar { height: 3px; border-radius: 2px; background: var(--fill); margin: 8px auto 0; max-width: 220px; overflow: hidden; }
.gauge-bar i { display: block; height: 100%; background: var(--accent); transition: width .2s linear; }
.who { display: flex; align-items: flex-start; gap: 8px; font-size: 13.5px; padding: 9px 12px; border-radius: 12px; background: var(--fill); line-height: 1.4; }
.who svg { flex-shrink: 0; margin-top: 1px; color: var(--accent); }
.who.warn svg { color: var(--orange); }
.who code { font-family: var(--mono); font-size: 12px; }
.speed-verdict { border-left: 3px solid; padding: 4px 0 4px 12px; font-size: 13.5px; line-height: 1.5; display: flex; flex-direction: column; gap: 4px; }
.speed-dot { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; flex-shrink: 0; }
.err-note { margin-top: 12px; padding: 10px 12px; border-radius: 12px; font-size: 13px; line-height: 1.45;
  background: color-mix(in srgb, var(--orange) 10%, transparent); border: .5px solid color-mix(in srgb, var(--orange) 40%, transparent); }
.pin-banner { display: flex; align-items: center; gap: 10px; padding: 10px 12px; margin-bottom: 10px; border-radius: 14px; font-weight: 600; font-size: 14px;
  background: color-mix(in srgb, var(--accent) 12%, var(--card)); border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); color: var(--accent); }
.cov-pin { cursor: pointer; }
.cov-pin rect { stroke: var(--card-solid); stroke-width: 2; }
.cov-pin.sel rect { stroke: var(--text); }
.cov-txt { font-size: 11px; font-weight: 750; fill: #101820; font-variant-numeric: tabular-nums; pointer-events:none; }
.cov-pin .cov-hit { fill:transparent; stroke:none; pointer-events:all; }
@media (max-width: 760px) {
  .topbar .brand { flex: 1 1 auto; max-width: none; }     /* phones: the brand takes the row, «⋯» stays at the right edge */ .topbar > .grow { display: none; }
  .live { max-width: 100%; overflow: hidden; white-space: nowrap; }
}
@media (max-width: 400px) {
  .topbar { gap: 6px; } .topbar .seg button { padding: 9px 10px; } .topbar .btn { min-width: 38px; padding: 9px 9px; }
}
.card-toggle { display: inline-flex; align-items: center; gap: 6px; border: 0; background: none; padding: 0; font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit; cursor: pointer; }

/* ── plugins ── */
.plugin { padding: 0; overflow: hidden; }
.plugin-head { display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px 16px; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; }
.plugin-head:hover { background: var(--fill); }
.plugin-body { display: flex; flex-direction: column; gap: 12px; padding: 4px 16px 16px; border-top: .5px solid var(--line); padding-top: 14px; }
.checks { display: flex; flex-direction: column; gap: 6px; }
.check { display: flex; align-items: center; gap: 9px; font-size: 13.5px; }
.check-ico { width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; flex-shrink: 0; color: #fff; background: var(--red); }
.check.ok .check-ico { background: var(--green); } .check.opt .check-ico { background: var(--fill2); color: var(--text2); }
.steps { margin: 0; padding-left: 20px; font-size: 13.5px; line-height: 1.5; display: flex; flex-direction: column; gap: 7px; }
.steps code, .plugin-body code { font-family: var(--mono); font-size: 12px; background: var(--fill); padding: 1px 5px; border-radius: 5px; }
.awg-form { display: flex; flex-direction: column; gap: 12px; padding: 14px; border-radius: 14px; background: var(--bg2); border: .5px solid var(--line); }
.awg-form textarea { resize: vertical; min-height: 70px; }
.awg-prev { padding: 4px 12px; border-radius: 12px; background: var(--fill); }
.awg-suggest { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border-radius: 12px; font-size: 13px; line-height: 1.45;
  background: color-mix(in srgb, var(--accent) 9%, transparent); border: .5px solid color-mix(in srgb, var(--accent) 35%, transparent); }
.awg-suggest svg { color: var(--accent); flex-shrink: 0; margin-top: 1px; }
.plugin-result { padding: 12px 14px; border-radius: 14px; font-size: 13.5px; line-height: 1.45;
  background: color-mix(in srgb, var(--green) 10%, transparent); border: .5px solid color-mix(in srgb, var(--green) 40%, transparent); }
.plugin-result svg { color: var(--green); flex-shrink: 0; }
.plugin-result.warn { background: color-mix(in srgb, var(--orange) 10%, transparent); border-color: color-mix(in srgb, var(--orange) 40%, transparent); } .plugin-result.warn svg { color: var(--orange); }
.plugin-result.bad { background: color-mix(in srgb, var(--red) 10%, transparent); border-color: color-mix(in srgb, var(--red) 40%, transparent); } .plugin-result.bad svg { color: var(--red); }
.plugin-log { margin-top: 8px; max-height: 220px; overflow: auto; font-size: 11.5px; line-height: 1.5; padding: 8px 10px; border-radius: 10px; background: var(--fill); white-space: pre-wrap; word-break: break-all; }
.plugin-log .bad { color: var(--red); }
.modem-opt.sug { background: color-mix(in srgb, var(--accent) 7%, transparent); border-radius: 12px; padding-left: 8px; padding-right: 8px; }
.detect { display: flex; flex-direction: column; gap: 10px; padding: 14px; border-radius: 16px; background: color-mix(in srgb, var(--accent) 6%, var(--bg2)); border: .5px solid color-mix(in srgb, var(--accent) 30%, transparent); }
.detect-hit { width: 100%; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; border-radius: 12px; padding: 8px; }
.detect-hit:hover { background: var(--fill); } .detect-hit.best { background: color-mix(in srgb, var(--green) 10%, transparent); }
.copy-row { display: flex; align-items: center; gap: 10px; font-size: 13px; min-width: 0; }
.copy-row > .dim { width: 120px; flex-shrink: 0; font-size: 12.5px; }
.job { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-radius: 14px; background: color-mix(in srgb, var(--accent) 9%, transparent); border: .5px solid color-mix(in srgb, var(--accent) 35%, transparent); font-size: 13.5px; }
@media (max-width: 560px) { .copy-row > .dim { width: 80px; } }
.sec-item { align-items: flex-start; } .sec-item.hidden { opacity: .6; }
.sec-title { display: flex; align-items: center; gap: 8px; width: 100%; border: 0; background: none; color: inherit; font: inherit; font-weight: 650; font-size: 14px; padding: 0; text-align: left; cursor: pointer; }
.inet-big { font-size: 26px; font-weight: 750; letter-spacing: -.5px; line-height: 1.05; font-variant-numeric: tabular-nums; }
.inet-big small { font-size: 13px; color: var(--text2); font-weight: 600; }
.backup-grid { display: grid; grid-template-columns: 220px 1fr; gap: 12px; align-items: start; }
@media (max-width: 700px) { .backup-grid { grid-template-columns: 1fr; } .backup-list { max-height: 220px; } }
.backup-list { max-height: 520px; overflow: auto; }
.backup-v { width: 100%; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; border-radius: 10px; padding: 8px; }
.backup-v.on { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.diff { font-size: 11.5px; line-height: 1.5; background: var(--fill); border-radius: 12px; padding: 10px 12px; max-height: 520px; overflow: auto; white-space: pre; }
.diff .add { color: var(--green); background: color-mix(in srgb, var(--green) 10%, transparent); }
.diff .del { color: var(--red); background: color-mix(in srgb, var(--red) 10%, transparent); }
.diff .hunk { color: var(--accent); margin-top: 6px; }

/* AI assistant panel */
.ai-overlay { z-index: 150; }
.ai-panel { position: fixed; top: 0; right: 0; bottom: 0; width: min(460px, 100vw); display: flex; flex-direction: column; background: var(--elev); box-shadow: var(--shadow-lg); border-left: .5px solid var(--line); animation: slide .32s cubic-bezier(.2,1,.3,1); backdrop-filter: blur(30px); -webkit-backdrop-filter: blur(30px); }
@media (max-width: 760px) { .ai-panel { left: 0; width: auto; top: calc(env(safe-area-inset-top) + 8px); border-radius: 22px 22px 0 0; border-left: 0; } }
.ai-head { display: flex; align-items: center; gap: 10px; padding: 14px 16px 12px; border-bottom: .5px solid var(--line); }
.ai-logo { width: 34px; height: 34px; border-radius: 11px; display: grid; place-items: center; flex-shrink: 0; background: linear-gradient(135deg, var(--indigo), var(--purple) 60%, #ff6fb5); }
.ai-logo.big { width: 60px; height: 60px; border-radius: 18px; }
.ai-list { flex: 1; overflow: auto; overscroll-behavior: contain; padding: 14px 14px 8px; display: flex; flex-direction: column; gap: 10px; }
.ai-empty { margin: auto 0; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 12px; padding: 10px 8px 20px; }
.ai-suggest { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
.ai-suggest .chip { white-space: normal; text-align: left; }
.ai-msg { display: flex; } .ai-msg.user { justify-content: flex-end; }
.ai-bubble { max-width: 92%; padding: 10px 13px; border-radius: 18px; font-size: 14.5px; line-height: 1.45; background: var(--fill); overflow-wrap: anywhere; }
.ai-msg.user .ai-bubble { background: var(--accent); color: #fff; border-bottom-right-radius: 6px; white-space: pre-wrap; max-width: 85%; }
.ai-msg.assistant .ai-bubble { border-bottom-left-radius: 6px; }
.ai-msg.err .ai-bubble { background: color-mix(in srgb, var(--red) 12%, transparent); }
.ai-busy { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--text2); }
.ai-tools { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; width: 100%; }
.ai-tools span { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; color: var(--text3); background: var(--fill); border-radius: 8px; padding: 2px 7px; }
.ai-text p { margin: 0 0 6px; } .ai-text p:last-child { margin-bottom: 0; }
.ai-text ul, .ai-text ol { margin: 2px 0 8px; padding-left: 20px; } .ai-text li { margin: 2px 0; }
.ai-text .ai-h { font-weight: 700; margin: 8px 0 4px; }
.ai-text code { font-family: var(--mono); font-size: 12.5px; background: var(--fill2); border-radius: 5px; padding: 1px 5px; }
.ai-text pre { font-family: var(--mono); font-size: 12px; background: var(--fill2); border-radius: 10px; padding: 8px 10px; overflow: auto; margin: 4px 0 8px; }
.ai-foot { display: flex; gap: 8px; align-items: flex-end; padding: 10px 14px 6px; border-top: .5px solid var(--line); }
.ai-foot textarea { resize: none; min-height: 42px; max-height: 140px; field-sizing: content; font: inherit; color: inherit; }
.ai-foot .btn { height: 42px; width: 42px; padding: 0; justify-content: center; flex-shrink: 0; }
.ai-note { font-size: 11px; color: var(--text3); padding: 0 14px calc(env(safe-area-inset-bottom) + 10px); line-height: 1.35; }
@media (max-width: 760px) { .ai-foot textarea { font-size: 16px; } }

/* Frank — the assistant's eye avatar */
.frank { display: grid; place-items: center; flex-shrink: 0; overflow: hidden; background: var(--frank-bg, var(--fill)); }
.frank > img.frank-img { width: 84%; height: 84%; object-fit: contain; display: block; }
.frank svg { display: block; overflow: visible; }
.frank .frank-eye { transform-box: view-box; transform-origin: 20px 20px; animation: frank-blink 5.5s infinite; }
.frank .frank-iris { animation: frank-look 9s ease-in-out infinite; }
.frank.busy .frank-iris { animation: frank-scan 1.4s ease-in-out infinite; }
@keyframes frank-blink { 0%, 92%, 100% { transform: scaleY(1); } 95% { transform: scaleY(.08); } }
@keyframes frank-look { 0%, 18% { transform: translate(0, 0); } 26%, 40% { transform: translate(-4.5px, 1px); } 48%, 62% { transform: translate(4.5px, -1px); } 70%, 100% { transform: translate(0, 0); } }
@keyframes frank-scan { 0%, 100% { transform: translate(-5px, 0); } 50% { transform: translate(5px, 0); } }
@media (prefers-reduced-motion: reduce) { .frank .frank-eye, .frank .frank-iris { animation: none; } }
.frank-btn { padding: 3px !important; } .frank-btn .frank, .frank-ask .frank { background: transparent; }
.ai-chat-item { cursor: pointer; } .ai-chat-item:hover { background: var(--fill); } .ai-chat-item.on { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.frank-ask { display: inline-flex; align-items: center; gap: 7px; }

/* Frank's mood while thinking: m1 calm blue · m2 straining yellow (squints) · m3 heavy red (frowns, glows, trembles) */
.frank stop { transition: stop-color .8s; }
.frank .s0 { stop-color: var(--frank-iris-0, #7cf0ff); } .frank .s1 { stop-color: var(--frank-iris-1, #1fb6e8); } .frank .s2 { stop-color: var(--frank-iris-2, #0b5f9e); }
.frank.m2 .s0 { stop-color: var(--frank-m2-0, #fff3a6); } .frank.m2 .s1 { stop-color: var(--frank-m2-1, #ffc21a); } .frank.m2 .s2 { stop-color: var(--frank-m2-2, #b86e00); }
.frank.m3 .s0 { stop-color: var(--frank-m3-0, #ffb3a8); } .frank.m3 .s1 { stop-color: var(--frank-m3-1, #ff3b30); } .frank.m3 .s2 { stop-color: var(--frank-m3-2, #8a0f0a); }
.frank .frank-lid { transform: translateY(-14px); transition: transform .6s cubic-bezier(.3,1.3,.5,1); }
.frank.m2 .frank-lid { transform: translateY(-2.5px); }
.frank.m3 .frank-lid { transform: translateY(2.5px); }
.frank .frank-pupil { transform-box: fill-box; transform-origin: center; transition: transform .6s; }
.frank.m2 .frank-pupil { transform: scale(.85); } .frank.m3 .frank-pupil { transform: scale(.7); }
.frank .frank-brow { stroke: #ff453a; opacity: 0; transform: translateY(-4px) rotate(-6deg); transform-box: fill-box; transform-origin: center; transition: opacity .4s, transform .5s; }
.frank.m3 .frank-brow { opacity: 1; transform: none; }
.frank.m2 .frank-iris { animation: frank-scan 1s ease-in-out infinite; }
.frank.m3 .frank-iris { animation: frank-scan .55s ease-in-out infinite; }
.frank.m3 .frank-body { animation: frank-shake .32s linear infinite; transform-box: view-box; transform-origin: 20px 20px; }
.frank svg { transition: filter .6s; }
.frank.m2 svg, .frank.m2 img { filter: drop-shadow(0 0 3px rgba(255, 194, 26, .55)); }
.frank.m3 svg, .frank.m3 img { filter: drop-shadow(0 0 4px rgba(255, 59, 48, .8)); }
@keyframes frank-shake { 0%, 100% { transform: translate(0, 0); } 25% { transform: translate(-.6px, .3px) rotate(-1deg); } 50% { transform: translate(.5px, -.3px); } 75% { transform: translate(.6px, .4px) rotate(1deg); } }
@media (prefers-reduced-motion: reduce) { .frank .frank-iris, .frank .frank-body { animation: none !important; } }
.frank-install { display: flex; gap: 12px; align-items: flex-start; background: var(--fill); border-radius: 14px; padding: 12px; }

/* /frank — Frank as a separate full-screen app */
.frank-app { position: fixed; inset: 0; }
.ai-panel.standalone { position: fixed; inset: 0; width: auto; border: 0; border-radius: 0; box-shadow: none; animation: none; background: var(--bg);
  padding-top: env(safe-area-inset-top); backdrop-filter: none; -webkit-backdrop-filter: none; }
.ai-panel.standalone .ai-head, .ai-panel.standalone .ai-list, .ai-panel.standalone .ai-foot, .ai-panel.standalone .ai-note { padding-left: max(14px, calc((100% - 820px) / 2)); padding-right: max(14px, calc((100% - 820px) / 2)); }
.ai-panel.standalone .ai-head { background: var(--elev); }
@media (max-width: 760px) { .ai-panel.standalone { top: 0; left: 0; border-radius: 0; } }

/* /frank feels like an app: no zoom, no rubber-band page, no long-press menus; header paints under the notch */
html.frank-mode, html.frank-mode body { height: 100%; overflow: hidden; overscroll-behavior: none; touch-action: manipulation;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: 100%; }
html.frank-mode .ai-bubble, html.frank-mode textarea { -webkit-user-select: text; user-select: text; }
html.frank-mode textarea, html.frank-mode input { font-size: 16px; }
html.frank-mode .ai-list { overscroll-behavior: contain; touch-action: pan-y; }
.ai-panel.standalone { padding-top: 0; }
.ai-panel.standalone .ai-head { padding-top: calc(env(safe-area-inset-top) + 12px); }

/* /frank — Apple-style floating chrome: glass circle buttons over a blurred fade, a floating input capsule at the bottom */
:root { --glass: rgba(255,255,255,.72); --glass-line: rgba(0,0,0,.08); --dock-glass: rgba(255,255,255,.84); }
[data-theme="dark"] { --glass: rgba(58,58,64,.55); --glass-line: rgba(255,255,255,.13); --dock-glass: rgba(24,26,26,.86); }
.ai-panel.standalone .ai-list { padding-top: calc(env(safe-area-inset-top) + 86px); padding-bottom: calc(max(8px, env(safe-area-inset-bottom) - 14px) + 140px); }
.fr-top { position: absolute; top: 0; left: 0; right: 0; z-index: 5; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px;
  padding: calc(env(safe-area-inset-top) + 8px) max(16px, calc((100% - 820px) / 2)) 16px; pointer-events: none; }
.fr-top > * { pointer-events: auto; }
/* the blurred fade lives in its own element BELOW the header: on iOS a masked backdrop-filter blurs whatever shares its layer (buttons, title) */
.fr-blur { position: absolute; top: 0; left: 0; right: 0; height: calc(env(safe-area-inset-top) + 96px); z-index: 4; pointer-events: none;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--bg) 88%, transparent), color-mix(in srgb, var(--bg) 55%, transparent) 65%, transparent);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent); mask-image: linear-gradient(to bottom, #000 62%, transparent); }
.fr-top { isolation: isolate; transform: translateZ(0); }
.fr-title, .fr-circle { transform: translateZ(0); }
.fr-side { display: flex; gap: 10px; align-items: center; } .fr-side.r { justify-content: flex-end; }
.fr-title { min-width: 0; max-width: 46vw; text-align: center; display: flex; flex-direction: column; line-height: 1.25; }
.fr-title b { font-size: 17px; font-weight: 700; letter-spacing: -.2px; }
.fr-title span { font-size: 13px; color: var(--text2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-circle { width: 46px; height: 46px; border-radius: 50%; flex-shrink: 0; display: grid; place-items: center; padding: 0; cursor: pointer; color: var(--text);
  background: var(--glass); border: .5px solid var(--glass-line); backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 6px 18px rgba(0,0,0,.22); transition: transform .15s; }
.fr-circle:active { transform: scale(.93); }
.fr-circle.eye { overflow: hidden; cursor: default; } .fr-circle.eye .frank { background: transparent; }
/* composer card like the Claude app: text on top, a row of round buttons below; sits low, just above the home indicator */
.fr-dock { position: absolute; z-index: 5; left: max(10px, calc((100% - 820px) / 2)); right: max(10px, calc((100% - 820px) / 2));
  bottom: max(8px, calc(env(safe-area-inset-bottom) - 14px));
  display: flex; flex-direction: column; gap: 8px; padding: 14px 12px 12px; border-radius: 32px; background: var(--dock-glass); border: .5px solid var(--glass-line);
  backdrop-filter: blur(24px) saturate(180%); -webkit-backdrop-filter: blur(24px) saturate(180%); box-shadow: 0 12px 34px rgba(0,0,0,.32), inset 0 1px 0 rgba(255,255,255,.07); }
.fr-dock textarea { width: 100%; border: 0; outline: 0; background: transparent; color: var(--text); font: inherit; font-size: 17px; line-height: 1.35;
  resize: none; padding: 4px 8px; min-height: 30px; max-height: 150px; field-sizing: content; }
.fr-dock-row { display: flex; align-items: center; gap: 8px; }
.fr-dbtn { width: 46px; height: 46px; border-radius: 50%; border: 0; padding: 0; flex-shrink: 0; display: grid; place-items: center; cursor: pointer;
  background: var(--fr-btn); color: var(--text); transition: background .2s, transform .15s, color .2s; }
.fr-dbtn:active { transform: scale(.93); } .fr-dbtn.on { background: var(--fill2); }
.fr-model { height: 46px; display: flex; align-items: center; gap: 7px; padding: 0 17px; border-radius: 23px; background: var(--fr-btn); min-width: 0; font-size: 15px; }
.fr-model b { font-weight: 600; } .fr-model span { color: var(--text3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-quick { position: absolute; left: 0; right: 0; bottom: calc(100% + 8px); display: flex; flex-direction: column; gap: 4px; padding: 8px; border-radius: 24px;
  background: var(--dock-glass); border: .5px solid var(--glass-line); backdrop-filter: blur(24px) saturate(180%); -webkit-backdrop-filter: blur(24px) saturate(180%);
  box-shadow: 0 12px 34px rgba(0,0,0,.32); animation: pop .22s cubic-bezier(.2,1.2,.4,1); }
.fr-quick button { text-align: left; border: 0; background: none; color: var(--text); font: inherit; font-size: 15px; padding: 11px 12px; border-radius: 14px; cursor: pointer; }
.fr-quick button:active, .fr-quick button:hover { background: var(--fill); }
:root { --fr-btn: rgba(120,120,128,.14); } [data-theme="dark"] { --fr-btn: rgba(255,255,255,.08); --dock-glass: rgba(48,48,50,.88); }
.fr-dock textarea::placeholder { color: var(--text3); }
.fr-send { width: 44px; height: 44px; border-radius: 50%; border: 0; flex-shrink: 0; display: grid; place-items: center; padding: 0; background: var(--fill2); color: var(--text3);
  transition: background .2s, color .2s, box-shadow .25s, transform .15s; }
.fr-send.on { background: var(--accent); color: #fff; cursor: pointer; box-shadow: 0 0 20px color-mix(in srgb, var(--accent) 50%, transparent); }
.fr-send:active { transform: scale(.93); }
html.frank-mode .ai-suggest .chip { background: var(--glass); border: .5px solid var(--glass-line); padding: 9px 14px; border-radius: 18px; color: var(--text); font-size: 14px; }
html.frank-mode .ai-panel.standalone { background: var(--bg); }

/* install banner inside the separate apps (until they run from the home screen) */
.inst-banner { display: flex; align-items: center; gap: 10px; padding: 12px 12px 12px 16px; border-radius: 20px; font-size: 13px; line-height: 1.4;
  background: var(--glass); border: .5px solid var(--glass-line); backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%); }
.inst-banner b { font-size: 14px; } .inst-banner > .grow > div { color: var(--text2); margin-top: 2px; }
.inst-go { border: 0; border-radius: 16px; padding: 9px 14px; background: var(--accent); color: #fff; font: inherit; font-weight: 650; cursor: pointer; flex-shrink: 0; }
.inst-x { border: 0; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: var(--fill); color: var(--text2); cursor: pointer; flex-shrink: 0; padding: 0; }
/* settings: apps card + install window */
.apps-addr { display: flex; flex-direction: column; gap: 6px; padding: 12px 14px; border-radius: 14px; background: var(--fill); }
.apps-router { display: flex; flex-direction: column; gap: 10px; padding: 14px; border-radius: 16px; border: .5px solid var(--line2); }
.app-row { display: flex; align-items: center; gap: 12px; padding: 8px 0; }
.inst-modal { display: grid; grid-template-columns: auto 1fr; gap: 18px; align-items: center; }
@media (max-width: 520px) { .inst-modal { grid-template-columns: 1fr; justify-items: center; } }
.qr { background: #fff; border-radius: 16px; padding: 8px; box-sizing: border-box; flex-shrink: 0; } .qr svg { display: block; width: 100%; height: 100%; }
.inst-url { font-size: 12.5px; padding: 8px 10px; border-radius: 10px; background: var(--fill); min-width: 0; flex: 1; }
.inst-steps { display: flex; flex-direction: column; gap: 6px; font-size: 13px; line-height: 1.45; padding: 12px 14px; border-radius: 14px; background: var(--fill); }
/* /speed — the speed test app */
.speed-app .sp-body { display: flex; flex-direction: column; gap: 14px; }
.speed-app .sp-body > * { width: 100%; max-width: 560px; margin-left: auto; margin-right: auto; }
.speed-app .gauge { max-width: 380px; }
.speed-app .sp-who { display: flex; justify-content: center; } .speed-app .sp-who .who { background: var(--glass); border: .5px solid var(--glass-line); border-radius: 18px; padding: 8px 14px; }
.speed-app .stats { grid-template-columns: repeat(2, 1fr); }
.speed-app .sp-glass { background: var(--glass); border: .5px solid var(--glass-line); border-radius: 20px; padding: 6px; }
.sp-note { border-radius: 16px; }
.sp-ind { transition: color .4s; } .sp-ind.on svg { animation: sp-pulse 1.6s ease-in-out infinite; }
@keyframes sp-pulse { 50% { opacity: .55; } }
.sp-dock { padding: 8px; }
.sp-start { width: 100%; height: 54px; border: 0; border-radius: 24px; background: var(--accent); color: #fff; font: inherit; font-size: 17px; font-weight: 700; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 10px; box-shadow: 0 0 22px color-mix(in srgb, var(--accent) 45%, transparent); transition: transform .15s, background .3s; }
.sp-start:active { transform: scale(.98); } .sp-start.busy { background: var(--fr-btn); color: var(--text); box-shadow: none; font-size: 15px; font-weight: 600; }
.speed-app .ai-list { padding-bottom: calc(max(8px, env(safe-area-inset-bottom) - 14px) + 96px); }

/* Settings: sections list (left) + one section (right); on the phone the list becomes a row of chips */
.set-layout { display: grid; grid-template-columns: 290px minmax(0, 1fr); gap: 18px; align-items: start; }
.set-nav { position: sticky; top: 96px; display: flex; flex-direction: column; gap: 2px; padding: 6px; border-radius: var(--r-lg); background: var(--card); border: .5px solid var(--line);
  box-shadow: var(--shadow); backdrop-filter: saturate(180%) blur(20px); -webkit-backdrop-filter: saturate(180%) blur(20px); }
.set-item { display: flex; align-items: center; gap: 11px; width: 100%; padding: 9px 10px; border: 0; border-radius: 13px; background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer; transition: background .15s; }
.set-item:hover { background: var(--fill); }
.set-item.on { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.set-ic { width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center; flex-shrink: 0; }
.set-nav-sep { height: .5px; background: var(--line); margin: 4px 8px; flex-shrink: 0; }
@media (max-width: 900px) { .set-nav-sep { display: none; } }
.set-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.set-txt b { font-size: 14.5px; font-weight: 600; } .set-txt small { font-size: 12px; color: var(--text3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.set-body { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.set-body > .card { grid-column: auto !important; }
/* phone: Settings like on iOS — a grouped list, a tap opens a section with «‹ Настройки» */
.set-layout.ios { display: block; } .set-layout.ios .set-head { display: none; } .ios-hidden { display: none !important; }
.ios-list { display: flex; flex-direction: column; gap: 24px; padding-bottom: 10px; animation: iosPop .26s ease both; }
.ios-group { border-radius: 16px; overflow: hidden; background: var(--card); border: .5px solid var(--line); }
.ios-cell { position: relative; display: flex; align-items: center; gap: 13px; width: 100%; min-height: 54px; padding: 10px 14px; border: 0; background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.ios-cell:active { background: var(--fill); }
.ios-cell.on { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.ios-cell + .ios-cell::before { content: ''; position: absolute; top: 0; left: 59px; right: 0; height: .5px; background: var(--line); }
.ios-ico { width: 32px; height: 32px; flex: none; display: grid; place-items: center; overflow: hidden; border-radius: 8px; } .ios-ico .set-ic { width: 32px; height: 32px; border-radius: 8px; }
html.set-detail main.page > .row:first-child, html.set-detail main.page > .hint-box { display: none; }
.ios-label { flex: 1; min-width: 0; font-size: 17px; } .ios-val { max-width: 46%; font-size: 15px; color: var(--text3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ios-nav { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; min-height: 40px; margin: 0 0 12px; }
.ios-back { justify-self: start; display: inline-flex; align-items: center; gap: 1px; border: 0; background: none; padding: 8px 6px 8px 0; margin-left: -6px; color: var(--accent); font: inherit; font-size: 17px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.ios-title { font-size: 17px; font-weight: 650; }
.ios-push { animation: iosPush .3s cubic-bezier(.2,.9,.3,1) both; }
@keyframes iosPush { from { opacity: 0; transform: translateX(34px); } to { opacity: 1; transform: none; } }
@keyframes iosPop { from { opacity: 0; transform: translateX(-18px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .ios-list, .ios-push { animation: none; } }
.set-head { display: flex; flex-direction: column; gap: 2px; padding: 2px 4px 2px; }
.set-head b { font-size: 22px; font-weight: 750; letter-spacing: -.4px; } .set-head span { font-size: 13.5px; color: var(--text2); }
@media (max-width: 900px) {
  .set-layout { grid-template-columns: 1fr; gap: 12px; }
  .set-nav { position: static; flex-direction: row; overflow-x: auto; scrollbar-width: none; padding: 5px; gap: 4px; border-radius: 18px; margin: 0 -4px; }
  .set-nav::-webkit-scrollbar { display: none; }
  .set-item { width: auto; flex-shrink: 0; padding: 7px 12px 7px 7px; gap: 8px; border-radius: 13px; }
  .set-item small, .set-item > svg:last-child { display: none; }
  .set-ic, .set-item .frank, .set-item > img { width: 26px !important; height: 26px !important; }
}

/* actions Frank proposes (run only on the admin's press) */
.ai-prop { margin-top: 10px; padding: 11px 12px; border-radius: 14px; background: var(--bg2); border: .5px solid var(--line2); font-size: 13.5px; }
.ai-prop b { font-size: 14px; } .ai-prop-text { font-size: 13px; line-height: 1.4; margin-top: 5px; color: var(--text2); }
.ai-prop-ic { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; flex-shrink: 0; background: color-mix(in srgb, var(--orange) 16%, transparent); color: var(--orange); }
.ai-prop.done .ai-prop-ic { background: color-mix(in srgb, var(--green) 16%, transparent); color: var(--green); }
.ai-prop.error .ai-prop-ic { background: color-mix(in srgb, var(--red) 16%, transparent); color: var(--red); }
.ai-prop.cancelled { opacity: .6; } .ai-prop.cancelled .ai-prop-ic { background: var(--fill); color: var(--text3); }
.ai-prop .btn .spin-dot { margin-right: 6px; }
/* Frank app: the menu behind the eye */
.fr-circle.eye { cursor: pointer; }
.fr-menu-wrap { position: absolute; inset: 0; z-index: 20; background: rgba(0,0,0,.25); animation: fade .2s; }
.fr-menu { position: absolute; top: calc(env(safe-area-inset-top) + 66px); right: max(12px, calc((100% - 820px) / 2)); width: min(380px, calc(100% - 24px));
  max-height: calc(100% - env(safe-area-inset-top) - 90px); overflow: auto; display: flex; flex-direction: column; gap: 10px; padding: 14px; border-radius: 26px;
  background: var(--dock-glass); border: .5px solid var(--glass-line); backdrop-filter: blur(28px) saturate(180%); -webkit-backdrop-filter: blur(28px) saturate(180%);
  box-shadow: 0 18px 50px rgba(0,0,0,.4); animation: pop .25s cubic-bezier(.2,1.2,.4,1); transform-origin: top right; }
.fr-bal { padding: 12px 14px; border-radius: 18px; background: var(--fr-btn); display: flex; flex-direction: column; }
.fr-bal b { font-size: 30px; font-weight: 750; letter-spacing: -.6px; line-height: 1.1; } .fr-bal span { font-size: 13px; color: var(--text2); }
.fr-menu-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--text3); margin: 4px 4px -4px; }
.fr-models { display: flex; flex-direction: column; gap: 4px; }
.fr-model-opt { display: flex; align-items: center; gap: 11px; width: 100%; text-align: left; padding: 10px 12px; border: 0; border-radius: 16px; background: none; color: var(--text); font: inherit; cursor: pointer; }
.fr-model-opt:hover { background: var(--fill); } .fr-model-opt.on { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.fr-model-opt b { display: block; font-size: 15px; } .fr-model-opt small { display: block; font-size: 12.5px; color: var(--text2); line-height: 1.35; margin-top: 1px; }
.fr-radio { width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0; display: grid; place-items: center; border: 1.5px solid var(--line2); color: #fff; }
.fr-model-opt.on .fr-radio { background: var(--accent); border-color: var(--accent); }
.fr-menu .seg { width: 100%; } .fr-menu .seg button { flex: 1; justify-content: center; }

/* device card: «Веб-интерфейс» — link, login and password with copy buttons */
.web-acc { display: flex; flex-direction: column; gap: 8px; }
.web-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 12px; background: var(--fill); min-width: 0; }
.web-row .mono { font-size: 13.5px; } .web-k { width: 62px; flex-shrink: 0; font-size: 12.5px; color: var(--text2); }

/* Devices → «Роутеры в сети» */
.router-row { align-items: flex-start; gap: 12px; }
.router-st { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; margin-top: 5px; flex-wrap: wrap; }
.router-st.ok { color: var(--green); } .router-st.warn { color: var(--orange); }
.router-st .link-btn { font-size: 12.5px; padding: 0; margin-left: 4px; }

/* phones: modals are bottom sheets that fit the screen; a swipe scrolls the sheet, never the page behind it */
html.modal-open, html.modal-open body { overflow: hidden; }
.overlay { overscroll-behavior: contain; touch-action: none; }
.modal, .sheet, .sheet-body { overscroll-behavior: contain; touch-action: pan-y; -webkit-overflow-scrolling: touch; }
.modal-body textarea, .modal-body select, .modal-body input { touch-action: auto; }
@media (max-width: 760px) {
  .overlay:has(> .modal) { align-items: flex-end; }
  .modal, .modal.wide { width: 100%; margin: auto 0 0; max-height: calc(100dvh - env(safe-area-inset-top) - 12px); border-radius: 22px 22px 0 0;
    border-left: 0; border-right: 0; border-bottom: 0; animation: up .3s cubic-bezier(.2,1,.3,1); }
  .modal-foot { padding-bottom: calc(12px + env(safe-area-inset-bottom)); }
  .modal-body { padding: 14px 16px 18px; }
  /* 16px+ in inputs: smaller text makes iPhone zoom the whole page in when a field is tapped */
  .input, .select, .textarea, input, select, textarea { font-size: 16px; }
}
@media (max-width: 520px) { .driver-pick { grid-template-columns: 1fr !important; } }

/* header: desktop tools in a row; on phones one «⋯» button with an iOS-style menu */
.hdr-tools { display: flex; align-items: center; gap: 10px; }
.hdr-more { width: 40px; height: 40px; border-radius: 50%; border: 0; padding: 0; place-items: center; cursor: pointer; color: var(--text);
  background: var(--fill); position: relative; flex-shrink: 0; display: none; }
.hdr-more.editing::after { content: ""; position: absolute; top: 4px; right: 4px; width: 9px; height: 9px; border-radius: 50%; background: var(--orange); box-shadow: 0 0 0 2px var(--bg); }
@media (max-width: 760px) { .hdr-more.only-sm { display: grid !important; } }
.hdr-menu-wrap { position: fixed; inset: 0; z-index: 120; background: rgba(0,0,0,.18); animation: fade .15s; }
.hdr-menu { position: absolute; top: calc(env(safe-area-inset-top) + 64px); right: 12px; width: min(330px, calc(100vw - 24px)); padding: 10px; border-radius: 28px;
  display: flex; flex-direction: column; gap: 2px; background: var(--dock-glass, var(--elev)); border: .5px solid var(--glass-line, var(--line));
  backdrop-filter: blur(28px) saturate(180%); -webkit-backdrop-filter: blur(28px) saturate(180%); box-shadow: 0 18px 50px rgba(0,0,0,.35);
  animation: pop .25s cubic-bezier(.2,1.2,.4,1); transform-origin: top right; }
.hdr-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding-bottom: 8px; margin-bottom: 4px; border-bottom: .5px solid var(--line); }
.hdr-tiles button { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 4px 8px; border: 0; border-radius: 18px; background: none;
  color: var(--text); font: inherit; font-size: 13px; cursor: pointer; text-align: center; line-height: 1.2; }
.hdr-tiles button:active, .hdr-tiles button:hover { background: var(--fill); }
.hdr-tiles .frank { background: transparent; }
.hdr-row { display: flex; align-items: center; gap: 14px; width: 100%; min-height: 50px; padding: 6px 12px; border: 0; border-radius: 16px; background: none;
  color: var(--text); font: inherit; font-size: 16px; text-align: left; cursor: pointer; }
button.hdr-row:active, button.hdr-row:hover { background: var(--fill); }
.hdr-row > svg:first-child { color: var(--text2); flex-shrink: 0; }
.hdr-row .seg button { padding: 6px 9px; font-size: 12.5px; }

/* ── rack colours follow the theme: a dark cabinet in the dark theme, a light «aluminium» one in the light theme ── */
:root, [data-theme="dark"] {
  --rack-bg: linear-gradient(180deg, #2c2c2e, #1c1c1e); --rack-text: #f5f5f7; --rack-meta: rgba(235,235,245,.62); --rack-body: #0b0b0c;
  --rack-rail: rgba(235,235,245,.32); --rack-hole: #2c2c2e; --rack-slot: rgba(255,255,255,.04);
  --unit-bg: linear-gradient(180deg, #2f2f33, #232326); --unit-text: #f5f5f7; --unit-meta: rgba(235,235,245,.62); --unit-icon-bg: rgba(255,255,255,.08);
  --rack-icon: #f5f5f7; --unit-shadow: inset 0 1px 0 rgba(255,255,255,.07), 0 1px 2px rgba(0,0,0,.5);
  --led-off: #3a3a3c; --led-dead: #4b1c1a; --unit-passive: repeating-linear-gradient(90deg, #252527 0 6px, #202022 6px 12px); --unit-blank: #171718;
  --rack-seg-bg: rgba(0,0,0,.4); --rack-seg-text: rgba(235,235,245,.72); --rack-seg-on: rgba(255,255,255,.2); --rack-seg-on-text: #fff;
  --map-rack-frame: #1c1c1e; --map-rack-stroke: #3a3a3c; --map-unit: #2a2a2d; --map-unit-stroke: rgba(255,255,255,.06);
}
[data-theme="light"] {
  --rack-bg: linear-gradient(180deg, #fdfdfe, #e9e9ef); --rack-text: #1c1c1e; --rack-meta: rgba(60,60,67,.64); --rack-body: #d6d6dd;
  --rack-rail: rgba(60,60,67,.55); --rack-hole: #b4b4bc; --rack-slot: rgba(0,0,0,.07);
  --unit-bg: linear-gradient(180deg, #ffffff, #f2f2f6); --unit-text: #1c1c1e; --unit-meta: rgba(60,60,67,.66); --unit-icon-bg: rgba(0,0,0,.06);
  --rack-icon: #3a3a3c; --unit-shadow: inset 0 1px 0 #fff, 0 1px 2px rgba(0,0,0,.14);
  --led-off: #c9c9cf; --led-dead: #f2b8b3; --unit-passive: repeating-linear-gradient(90deg, #e6e6ec 0 6px, #dedee5 6px 12px); --unit-blank: #cdcdd4;
  --rack-seg-bg: rgba(0,0,0,.07); --rack-seg-text: rgba(60,60,67,.78); --rack-seg-on: #fff; --rack-seg-on-text: #1c1c1e;
  --map-rack-frame: #f4f4f7; --map-rack-stroke: #d1d1d8; --map-unit: #ffffff; --map-unit-stroke: rgba(0,0,0,.1);
}
.rack, [data-theme="light"] .rack { background: var(--rack-bg); box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255,255,255,.08); border: .5px solid var(--line); }
.rack-top { color: var(--rack-text); } .rack-top .meta { color: var(--rack-meta); }
.tilebox .rack-top { color: var(--text); } .tilebox .rack-top .meta { color: var(--text2); }     /* box / room: a normal card, normal text */
.rack-body { background: var(--rack-body); }
.rack-rail div { color: var(--rack-rail); } .rack-rail div::before { background: var(--rack-hole); }
.rack-slot { border-top-color: var(--rack-slot); } .rack-slot.addable:hover { background: var(--rack-slot); }
.unit { background: var(--unit-bg); color: var(--unit-text); box-shadow: var(--unit-shadow); }
.unit .uicon { background: var(--unit-icon-bg); color: var(--rack-icon); } .unit .umeta { color: var(--unit-meta); }
.unit .leds i { background: var(--led-off); } .unit .leds i.off { background: var(--led-dead); }
.unit.passive { background: var(--unit-passive); } .unit.blank { background: var(--unit-blank); }
.rack-top .seg { background: var(--rack-seg-bg); }
.rack-top .seg button { color: var(--rack-seg-text); }
.rack-top .seg button.on { background: var(--rack-seg-on); color: var(--rack-seg-on-text); box-shadow: 0 1px 3px rgba(0,0,0,.2); }
.tilebox .rack-top .seg { background: var(--fill); } .tilebox .rack-top .seg button { color: var(--text2); }
.tilebox .rack-top .seg button.on { background: var(--card-solid); color: var(--text); }
/* the map draws cabinets in SVG */
.rackbox rect.frame, [data-theme="light"] .rackbox rect.frame { fill: var(--map-rack-frame); stroke: var(--map-rack-stroke); }
.rackbox .u rect { fill: var(--map-unit); stroke: var(--map-unit-stroke); }
.rackbox text { fill: var(--unit-text); } .rackbox .usub { fill: var(--unit-meta); }
.rackbox .u-ic { color: var(--rack-icon); }

/* map: compact tools — a magnifier that opens the search, a cabinet button with a dropdown list of places */
.map-find { display: flex; align-items: center; gap: 6px; }
.map-search { width: min(230px, 52vw); }
.rack-jump { animation: pop .2s cubic-bezier(.2,1.2,.4,1); transform-origin: top left; min-width: 180px; }
@media (max-width: 760px) { .rack-jump { max-width: 240px !important; } }

/* phones / installed app: app-like — no selection or callout, no double-tap zoom (inputs stay selectable) */
html.app-touch { touch-action: manipulation; -webkit-text-size-adjust: 100%; }
html.app-touch body { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; }
html.app-touch input, html.app-touch textarea, html.app-touch [contenteditable], html.app-touch .ai-bubble, html.app-touch .ai-cmd { -webkit-user-select: text; user-select: text; -webkit-touch-callout: default; }
/* «Главная»: widgets — iOS-like: a rounded panel under every widget, content re-flows with the width (container queries) */
.dash { display: grid; grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr)); grid-auto-rows: 8px; column-gap: 14px; grid-auto-flow: row; }   /* no packing: the order is the layout, a lone square may stay alone */
.wg { position: relative; min-width: 0; padding-bottom: 14px; }
.wg-in { position: relative; box-sizing: border-box; display: flex; flex-direction: column; min-height: 0; padding: 14px; border-radius: 26px; overflow: hidden;
  background: var(--card-solid); border: .5px solid var(--line); box-shadow: var(--shadow); }
.wg.size-S .wg-in { aspect-ratio: 1 / 1; }            /* iOS small widget: a square */
.wg-body { min-width: 0; flex: 1; min-height: 0; display: flex; flex-direction: column; container-type: inline-size; }
.wg-body > * { margin: 0 !important; }
.wg-body > .card, .wg-full > .card { background: none; border: 0; box-shadow: none; padding: 0; border-radius: 0; backdrop-filter: none; -webkit-backdrop-filter: none; }
.wg-body > .newdev-row { padding: 0; }
.wg.view .wg-body > .wg-view { flex: 1; min-height: 0; }
.wg.wg-list:not(.size-S) .wg-body { max-height: 440px; overflow: auto; overscroll-behavior: contain; }   /* long lists scroll inside */
.wg-body .stats { margin: 0; }
@container (max-width: 560px) {
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  .state-tiles { grid-template-columns: 1fr; }
  .card .row { flex-wrap: wrap; }
}
@container (max-width: 300px) { .stats { grid-template-columns: 1fr !important; } .shortcuts { grid-template-columns: 1fr; } }

/* the compact tile (a squeezed widget) */
.wg-tile { display: flex; flex-direction: column; align-items: stretch; height: 100%; width: 100%; padding: 0; border: 0; background: none;
  color: inherit; font: inherit; text-align: left; cursor: pointer; min-width: 0; gap: 2px; }
.wg.size-S .wg-in { background: var(--tile-bg, radial-gradient(120% 90% at 100% 0%, color-mix(in srgb, var(--tc, var(--accent)) 16%, transparent), transparent 60%), var(--card-solid)); }
.wg-tile-art > img.tile-img { width: 100%; height: 100%; min-height: 36px; object-fit: contain; display: block; }
.wg-tile-top { display: flex; align-items: center; gap: 7px; min-width: 0; }
.wg-tile-ic { width: 24px; height: 24px; border-radius: 7px; display: grid; place-items: center; flex-shrink: 0; }
.wg-tile-name { font-size: 13px; font-weight: 650; color: var(--text2); min-width: 0; }
.wg-tile-art { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; padding: 6px 0 2px; overflow: hidden; }
.wg-tile-v { font-size: clamp(20px, 13cqw, 30px); font-weight: 750; letter-spacing: -.6px; line-height: 1.05; font-variant-numeric: tabular-nums; }
.wg-tile-s { font-size: 12px; color: var(--text2); }
/* the little pictures */
.mini-svg { max-width: 100%; max-height: 100%; width: auto; height: 100%; display: block; overflow: visible; }
.mini-svg.wide { width: 100%; height: auto; max-height: 100%; }
.mini-svg.fill { height: 100%; }
.mini-num { font-weight: 800; fill: var(--text); letter-spacing: -.5px; }
.mini-sub { font-size: 11px; font-weight: 600; fill: var(--text2); }
.mini-pair { display: flex; gap: 6px; width: 100%; height: 100%; justify-content: center; align-items: center; }
.mini-pair .mini-svg { width: 48%; height: auto; }
.mini-bars { display: flex; align-items: flex-end; gap: 2px; width: 100%; height: 70%; }
.mini-bars i { flex: 1; border-radius: 2px; min-width: 2px; }
.mini-dots { display: flex; flex-wrap: wrap; gap: clamp(5px, 3cqw, 9px); justify-content: center; align-content: center; width: 100%; }
.mini-dots i { width: clamp(12px, 10cqw, 26px); height: clamp(12px, 10cqw, 26px); border-radius: 50%; }
.mini-faces { display: flex; align-items: center; justify-content: center; }
.mini-faces span { width: clamp(34px, 22cqw, 64px); height: clamp(34px, 22cqw, 64px); border-radius: 50%; display: grid; place-items: center; margin-left: -10px; border: 3px solid var(--card-solid); }
.mini-faces span:first-child { margin-left: 0; } .mini-faces .more { background: var(--fill2); font-size: 12px; font-weight: 700; color: var(--text); }
.mini-events { display: flex; flex-direction: column; gap: 6px; width: 100%; align-self: center; }
.mini-events div { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--text2); min-width: 0; }
.mini-events i { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.mini-center { display: grid; place-items: center; width: 100%; height: 100%; }
.mini-grid4 { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(8px, 4cqw, 14px); }
.mini-grid4 span { width: clamp(34px, 22cqw, 62px); height: clamp(34px, 22cqw, 62px); border-radius: 28%; display: grid; place-items: center; }
.mini-note { width: 100%; height: 100%; padding: 8px 10px; border-radius: 12px; background: color-mix(in srgb, #ffd60a 22%, transparent);
  background-image: repeating-linear-gradient(transparent 0 19px, color-mix(in srgb, #ffd60a 35%, transparent) 19px 20px); font-size: 12px; line-height: 20px; color: var(--text); }
.mini-empty { font-size: 12px; color: var(--text3); }
/* «Требуют внимания» as a square: a soft gradient of the state colour, the picture in that colour */
.wg.tone-red { --tone: #ff453a; } .wg.tone-yellow { --tone: #ffb300; } .wg.tone-green { --tone: #30d158; }
.wg[class*="tone-"] .wg-in { background: linear-gradient(155deg, color-mix(in srgb, var(--tone) 38%, var(--card-solid)) 0%,
  color-mix(in srgb, var(--tone) 12%, var(--card-solid)) 60%, var(--card-solid) 100%); border-color: color-mix(in srgb, var(--tone) 35%, transparent); }
.wg[class*="tone-"] .wg-tile-ic { background: var(--tone) !important; }
.wg[class*="tone-"] .wg-tile-art { color: var(--tone); }
.wg[class*="tone-"] .wg-tile-s { color: color-mix(in srgb, var(--tone) 70%, var(--text)); font-weight: 600; }
.wg.tone-red .wg-tile-art, .wg.tone-yellow .wg-tile-art { animation: tonePulse 2s ease-in-out infinite; }
@keyframes tonePulse { 50% { transform: scale(1.05); } }
@media (prefers-reduced-motion: reduce) { .wg .wg-tile-art { animation: none !important; } }
/* Frank: the eye fills the square */
.mini-frank { width: 100%; height: 100%; display: grid; place-items: center; }
.mini-frank .frank { width: min(100%, 100cqh, 78cqw) !important; height: auto !important; aspect-ratio: 1; background: transparent !important; box-shadow: none !important; }
.mini-frank .frank svg { width: 100% !important; height: 100% !important; }
/* devices: icons tinted by status */
.mini-kinds { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(6px, 4cqw, 12px); width: 66%; }
.mini-kinds span { aspect-ratio: 1; border-radius: 28%; display: grid; place-items: center; }
.mini-kinds span svg { width: 52%; height: 52%; }
.mini-kinds .more { background: var(--fill2); color: var(--text); font-weight: 750; font-size: clamp(12px, 8cqw, 20px); }
/* arranging (edit mode + the «Расстановка» switch): jiggle, «−» top-left, the corner arc, the name below */
.wg.arranging { padding-bottom: 38px; }
.wg.arranging .wg-in { animation: wgJiggle .32s ease-in-out infinite alternate; }
.dash .wg.arranging:nth-child(2n) .wg-in { animation-delay: -.16s; } .dash .wg.arranging:nth-child(3n) .wg-in { animation-duration: .36s; }
@keyframes wgJiggle { from { transform: rotate(-.35deg); } to { transform: rotate(.35deg); } }
@media (prefers-reduced-motion: reduce) { .wg.arranging .wg-in { animation: none; } }
.wg-cover { position: absolute; inset: 0; z-index: 4; cursor: grab; touch-action: pan-y; border-radius: inherit; -webkit-touch-callout: none; }   /* a swipe scrolls; a long press lifts */
.wg.lifted { z-index: 6; } .wg.lifted .wg-in { animation: none; transform: scale(1.04); box-shadow: 0 22px 50px rgba(0,0,0,.4); transition: transform .18s; }
.wg.lifted .wg-cover { cursor: grabbing; }
.wg-x { position: absolute; top: -9px; left: -9px; z-index: 7; width: 28px; height: 28px; border-radius: 50%; border: .5px solid rgba(255,255,255,.25);
  background: color-mix(in srgb, var(--text3) 75%, var(--bg)); color: var(--text); display: grid; place-items: center; cursor: pointer; padding: 0;
  box-shadow: 0 3px 10px rgba(0,0,0,.3); }
.wg.lifted { pointer-events: none; }                      /* the finger «sees» the widgets under the lifted one */
.wg-size-btn { position: absolute; right: -9px; bottom: 29px; z-index: 7; width: 30px; height: 30px; border-radius: 50%; padding: 0; cursor: pointer;
  border: .5px solid rgba(255,255,255,.25); background: var(--accent); color: #fff; display: grid; place-items: center; box-shadow: 0 3px 10px rgba(0,0,0,.35); }
.wg-size-btn.on { background: var(--text); color: var(--bg); }
.wg-size-menu { position: absolute; right: 0; bottom: 66px; z-index: 9; min-width: 190px; padding: 6px; border-radius: 16px; background: var(--elev);
  border: .5px solid var(--line); box-shadow: 0 14px 40px rgba(0,0,0,.4); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  display: flex; flex-direction: column; gap: 2px; animation: wgMenu .16s ease-out; transform-origin: bottom right; }
@keyframes wgMenu { from { opacity: 0; transform: scale(.92); } }
.wg-size-opt { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border: 0; border-radius: 11px; background: none; color: var(--text);
  font: inherit; font-size: 14px; font-weight: 600; cursor: pointer; text-align: left; }
.wg-size-opt:hover:not(:disabled) { background: var(--fill); } .wg-size-opt.on { background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); }
.wg-size-opt:disabled { opacity: .35; cursor: default; }
.sz-ic { flex-shrink: 0; height: 16px; border-radius: 4px; border: 2px solid currentColor; }
.sz-S { width: 16px; } .sz-M { width: 26px; } .sz-L { width: 36px; }
.wg-label { position: absolute; left: 0; right: 0; bottom: 12px; text-align: center; font-size: 12.5px; font-weight: 500; color: var(--text2); }
.dash-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; padding: 12px 14px; border-radius: 18px; background: var(--card-solid); border: .5px solid var(--line); }

.wg-pick { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px; }
.wg-opt { display: flex; align-items: center; gap: 10px; padding: 10px; border-radius: 16px; border: .5px solid var(--line); background: var(--card-solid); color: inherit; font: inherit; text-align: left; cursor: pointer; }
.wg-opt:disabled { opacity: .45; cursor: default; }
.wg-opt b { display: block; font-size: 14px; } .wg-opt small { display: block; font-size: 12px; color: var(--text2); line-height: 1.35; }
.wg-opt-ic { width: 36px; height: 36px; border-radius: 10px; flex-shrink: 0; display: grid; place-items: center; }
.wg-view { display: flex; flex-direction: column; gap: 8px; height: 100%; min-height: 0; }
.wg-view-head { display: flex; align-items: center; justify-content: space-between; padding: 0 2px; }
.wg-view-body { flex: 1; min-height: 0; position: relative; }
.wg-view-body .map-wrap { height: 100%; min-height: 0; box-shadow: none; }
.wg-view-body .plan { height: 100%; display: flex; flex-direction: column; }
.wg-view-body .plan-canvas { flex: 1; height: auto; min-height: 160px; box-shadow: none; }
.shortcuts { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 6px; }
.shortcut { display: flex; align-items: center; gap: 8px; padding: 8px; border: 0; border-radius: 12px; background: var(--fill); color: inherit; font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer; min-width: 0; }

/* networks' roles, clients */
.net-roles { display: flex; flex-direction: column; gap: 8px; padding: 12px; border-radius: 16px; background: var(--fill); }
.net-role { padding: 10px 12px; border-radius: 12px; background: var(--card-solid); border: .5px solid var(--line); }
.net-role.todo { border-color: var(--orange); box-shadow: 0 0 0 1px color-mix(in srgb, var(--orange) 40%, transparent); }
.role-badge { display: inline-block; font-size: 10.5px; font-weight: 700; padding: 1px 7px; border-radius: 7px; color: #fff; white-space: nowrap; }
.role-badge.none { background: var(--fill2); color: var(--text2); }
.pending-ip { display: inline-flex; align-items: center; gap: 5px; margin-top: 3px; font-size: 11.5px; font-weight: 600; color: var(--orange);
  padding: 2px 8px; border-radius: 8px; background: color-mix(in srgb, var(--orange) 14%, transparent); width: fit-content; }
.pending-ip svg { animation: spin 2.4s linear infinite; }
.warn-box, .ok-box { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border-radius: 12px; font-size: 13px; line-height: 1.45; }
.warn-box { background: color-mix(in srgb, var(--orange) 14%, transparent); } .warn-box svg { color: var(--orange); flex-shrink: 0; margin-top: 2px; }
.ok-box { background: color-mix(in srgb, var(--green) 14%, transparent); color: var(--text); } .ok-box svg { color: var(--green); flex-shrink: 0; margin-top: 2px; }
.net-roles-row { display: flex; align-items: center; gap: 10px; width: 100%; padding: 11px 14px; border: 0; border-radius: 14px; background: var(--fill);
  color: inherit; font: inherit; font-size: 13.5px; text-align: left; cursor: pointer; }
/* «Устройства»: a magnifier, an iOS-style filter / sort button */
.dev-tools { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.round-btn { width: 40px; height: 40px; border-radius: 50%; border: .5px solid var(--line); background: var(--card-solid); color: var(--text);
  display: grid; place-items: center; cursor: pointer; box-shadow: var(--shadow); padding: 0; }
.round-btn.on { background: var(--accent); color: #fff; border-color: transparent; }
.dev-find { display: flex; align-items: center; gap: 6px; width: min(320px, 100%); }
.dev-find .search { flex: 1; }
.sort-menu { position: absolute; left: 0; top: 48px; z-index: 30; min-width: 230px; padding: 6px; border-radius: 16px; background: var(--elev);
  border: .5px solid var(--line); box-shadow: 0 14px 40px rgba(0,0,0,.4); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); animation: wgMenu .16s ease-out; transform-origin: top left; }
.sort-menu.right { left: auto; right: 0; max-width: calc(100vw - 32px); }
.sort-menu.right .sort-opt { white-space: normal; text-align: left; }
.sort-head { font-size: 11.5px; font-weight: 700; color: var(--text3); text-transform: uppercase; letter-spacing: .3px; padding: 8px 10px 4px; }
.sort-opt { display: flex; align-items: center; gap: 8px; width: 100%; padding: 9px 10px; border: 0; border-radius: 10px; background: none; color: var(--text);
  font: inherit; font-size: 14.5px; cursor: pointer; text-align: left; }
.sort-opt:hover { background: var(--fill); }
.sort-check { width: 16px; color: var(--accent); display: grid; place-items: center; }
/* a shelf with several devices */
.unit.shelf-multi { display: flex; gap: 4px; padding-left: 10px; padding-right: 6px; }
.shelf-cell { flex: 1; min-width: 0; display: flex; align-items: center; gap: 5px; padding: 0 7px; height: calc(100% - 8px); border-radius: 8px;
  background: var(--fill); font-size: 12px; font-weight: 600; cursor: pointer; }
.shelf-cell:hover { background: var(--fill2); }
.shelf-pick { display: flex; flex-wrap: wrap; gap: 6px; }
.shelf-pick .chip { cursor: pointer; display: inline-flex; align-items: center; gap: 5px; }
/* map: a room tag on nodes that stand in a room; a box (щиток) frame */
.room-tag { fill: color-mix(in srgb, var(--accent) 22%, var(--card-solid)); stroke: color-mix(in srgb, var(--accent) 45%, transparent); stroke-width: .6; }
.room-tag-t { font-size: 9.5px; font-weight: 700; fill: var(--accent); }
.rackbox.boxframe .frame { stroke-dasharray: none; }

/* ── Оформление (Настройки → Оформление): skin = data-skin on <html>, accent = data-accent; both are kept per device (localStorage rl_skin / rl_accent).
   «classic» is the default look above. «graphite» is flat: pure black, grey cards without blur, thin outlines, green accent. ── */
[data-skin="graphite"] { --r: 16px; --r-lg: 24px; --shadow: none; --shadow-lg: 0 24px 70px rgba(0,0,0,.28);
  --bg: #f4f4f2; --bg2: #ffffff; --card: #ffffff; --card-solid: #ffffff; --elev: #ffffff; --text: #111112; --text2: #66666b; --text3: #9a9a9f;
  --line: #e3e3df; --line2: #d2d2ce; --fill: #ececea; --fill2: #dcdcd8; --accent: #2f9e4f; --dock: #ffffff; --glass: #ffffff; --glass-line: #e3e3df; --dock-glass: #ffffff; --fr-btn: #ececea; }
[data-skin="graphite"][data-theme="dark"] { --shadow: none; --shadow-lg: 0 24px 70px rgba(0,0,0,.6);
  --bg: #000000; --bg2: #0d0d0d; --card: #242424; --card-solid: #242424; --elev: #171717; --text: #ffffff; --text2: #a0a0a5; --text3: #6b6b70;
  --line: #262628; --line2: #3a3a3d; --fill: #2c2c2e; --fill2: #3c3c3f; --accent: #4cb868; --dock: #0a0a0a; --glass: #141414; --glass-line: #262628; --dock-glass: #121212; --fr-btn: #2c2c2e; }
[data-skin="graphite"] .app-bg { background: var(--bg); }
[data-skin="graphite"] .topbar::before, [data-skin="graphite"] .bottombar::before { backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; background: var(--dock); border-color: var(--line); }
[data-skin="graphite"] .card { backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; background: var(--card-solid); border: 1px solid var(--line); }
[data-skin="graphite"] .modal, [data-skin="graphite"] .sheet { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--elev); border-color: var(--line2); }
[data-skin="graphite"] .overlay { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(0,0,0,.6); }
[data-skin="graphite"] .tab.on, [data-skin="graphite"] .seg button.on { box-shadow: none; }
[data-skin="graphite"] .switch.on { background: var(--accent); }
[data-skin="graphite"] .btn.primary { color: #fff; }
[data-skin="graphite"] .bottombar button.on svg { filter: none; }
[data-skin="graphite"] .wg-in { background: var(--bg); border: 1px solid var(--line2); box-shadow: none; }
[data-skin="graphite"] .wg.size-S .wg-in { background: var(--card-solid); border-color: var(--line); }
[data-skin="graphite"] .wg[class*="tone-"] .wg-in { background: color-mix(in srgb, var(--tone) 9%, var(--bg)); border-color: color-mix(in srgb, var(--tone) 55%, transparent); }
[data-skin="graphite"] .wg-tile-art, [data-skin="graphite"] .mini-svg { filter: none; }
[data-skin="graphite"] .ios-group { background: var(--card-solid); border: 1px solid var(--line); }
[data-skin="graphite"] .hdr-menu { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--elev); border-color: var(--line2); }
[data-skin="graphite"] .fr-dock, [data-skin="graphite"] .fr-top .fr-btn { backdrop-filter: none; -webkit-backdrop-filter: none; }

/* «net»: flat, like graphite, but bright controller-blue accent; no orange (replaced by yellow) and no purple (replaced by blue) anywhere, flat outline icons,
   no decorative pictures on widget tiles. ── */
[data-skin="net"] { --r: 14px; --r-lg: 20px; --shadow: none; --shadow-lg: 0 24px 70px rgba(0,0,0,.28);
  --bg: #f4f4f2; --bg2: #ffffff; --card: #ffffff; --card-solid: #ffffff; --elev: #ffffff; --text: #111112; --text2: #66666b; --text3: #9a9a9f;
  --line: #e3e3df; --line2: #d2d2ce; --fill: #ececea; --fill2: #dcdcd8; --accent: #0066ff; --dock: #ffffff; --glass: #ffffff; --glass-line: #e3e3df; --dock-glass: #ffffff; --fr-btn: #ececea;
  --orange: #ffcc00; --purple: #0066ff; --port-o: #ffcc00; --port-wan: var(--accent); --port-sel: var(--accent);
  --map-rack-frame: var(--card-solid); --map-rack-stroke: var(--line); --map-unit: var(--fill); --map-unit-stroke: var(--line2); }
[data-skin="net"][data-theme="dark"] { --shadow: none; --shadow-lg: 0 24px 70px rgba(0,0,0,.6);
  --bg: #000000; --bg2: #0d0d0d; --card: #1c1c1e; --card-solid: #1c1c1e; --elev: #171717; --text: #ffffff; --text2: #a0a0a5; --text3: #6b6b70;
  --line: #262628; --line2: #3a3a3d; --fill: #2c2c2e; --fill2: #3c3c3f; --accent: #2b8bff; --dock: #0a0a0a; --glass: #141414; --glass-line: #262628; --dock-glass: #121212; --fr-btn: #2c2c2e;
  --orange: #ffd60a; --purple: #2b8bff; --port-o: #ffd60a; --port-wan: var(--accent); --port-sel: var(--accent);
  --map-rack-frame: var(--card-solid); --map-rack-stroke: var(--line); --map-unit: var(--fill); --map-unit-stroke: var(--line2); }
[data-skin="net"] .app-bg { background: var(--bg); }
[data-skin="net"] .topbar::before, [data-skin="net"] .bottombar::before { backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; background: var(--dock); border-color: var(--line); }
/* «Контроллер» + liquid glass (on unless switched off: data-glass="off", Настройки → Оформление): a thin tint, strong blur, a light edge and a sheen on top */
[data-skin="net"] { --lg-tint: rgba(255,255,255,.42); --lg-edge: rgba(255,255,255,.75); --lg-hi: rgba(255,255,255,.9); --lg-sheen: rgba(255,255,255,.45); --lg-shadow: 0 10px 30px rgba(0,0,0,.12); }
[data-skin="net"][data-theme="dark"] { --lg-tint: rgba(28,28,32,.42); --lg-edge: rgba(255,255,255,.16); --lg-hi: rgba(255,255,255,.22); --lg-sheen: rgba(255,255,255,.09); --lg-shadow: 0 10px 34px rgba(0,0,0,.5); }
[data-skin="net"]:not([data-glass="off"]) .bottombar::before {
  background: linear-gradient(180deg, var(--lg-sheen), transparent 55%), var(--lg-tint);
  backdrop-filter: blur(22px) saturate(190%); -webkit-backdrop-filter: blur(22px) saturate(190%);
  border: .5px solid var(--lg-edge); box-shadow: inset 0 1px 0 var(--lg-hi), inset 0 0 14px rgba(255,255,255,.04), var(--lg-shadow); }[data-skin="net"] .card { backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; background: var(--card-solid); border: 1px solid var(--line); }
[data-skin="net"] .modal, [data-skin="net"] .sheet { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--elev); border-color: var(--line2); }
[data-skin="net"] .overlay { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(0,0,0,.6); }
[data-skin="net"] .tab.on, [data-skin="net"] .seg button.on { box-shadow: none; }
[data-skin="net"] .switch.on { background: var(--accent); }
[data-skin="net"] .seg.edit button.on.editing { background: var(--accent); }
[data-skin="net"] .btn.primary { color: #fff; }
[data-skin="net"] .bottombar button.on svg { filter: none; }
[data-skin="net"] .wg-in { background: var(--bg); border: 1px solid var(--line2); box-shadow: none; }
/* a skin's own .card look must not reach the card nested inside a widget — there it stays see-through, or it shows as a square block in the rounded widget */
[data-skin] .wg-body > .card, [data-skin] .wg-full > .card { background: none; border: 0; }
/* «Контроллер»: a grey inner panel nested in the black rim with a small gap — a sense of depth */
[data-skin="net"] .wg:not(.size-S) .wg-in { padding: 5px; }
[data-skin="net"] .wg:not(.size-S) .wg-body { background: var(--card-solid); border-radius: 20px; padding: 11px; }
/* only the widgets marked flat:true (92_dashboard.jsx WIDGETS) get this treatment — every other widget keeps its original look (picture, colour, gradient) */
[data-skin="net"] .wg.size-S.flat .wg-in { background: linear-gradient(155deg, color-mix(in srgb, var(--accent) 15%, var(--card-solid)) 0%, var(--card-solid) 62%); border-color: var(--line); }
[data-skin="net"] .wg.size-S.flat[class*="tone-"] .wg-in { background: linear-gradient(155deg, color-mix(in srgb, var(--tone) 28%, var(--card-solid)) 0%, var(--card-solid) 62%); border-color: color-mix(in srgb, var(--tone) 50%, var(--line)); }
[data-skin="net"] .wg.flat[class*="tone-"] .wg-in { background: color-mix(in srgb, var(--tone) 9%, var(--bg)); border-color: color-mix(in srgb, var(--tone) 55%, transparent); }
[data-skin="net"] .ios-group { background: var(--card-solid); border: 1px solid var(--line); }
[data-skin="net"] .hdr-menu { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--elev); border-color: var(--line2); }
[data-skin="net"] .fr-dock, [data-skin="net"] .fr-top .fr-btn { backdrop-filter: none; -webkit-backdrop-filter: none; }
[data-skin="net"] .stat, [data-skin="net"] .state-tile, [data-skin="net"] .shortcut { background: var(--fill); border: 0; }
[data-skin="net"] .tile, [data-skin="net"] .ios-cell { background: var(--card-solid); border: 1px solid var(--line); }
[data-skin="net"] .tile:hover { box-shadow: none; transform: none; }
[data-skin="net"] .mini-faces span { border-color: var(--card-solid); }
[data-skin="net"] .badge { border: 1px solid var(--line); background: transparent; }
[data-skin="net"] .chip { background: transparent; border: 1px solid var(--line2); } [data-skin="net"] .chip.on { background: var(--accent); color: #fff; border-color: var(--accent); }
/* the small coloured badge in the top-left corner of every square tile is gone — on every widget, not just the flattened ones */
[data-skin="net"] .wg.size-S .wg-tile-top .wg-tile-ic { display: none !important; }
/* no decorative pictures only on the flat:true tiles (Требуют внимания, Frank, Шкаф, Настройки, Новые в сети) — every other widget keeps its picture and colour */
[data-skin="net"] .wg.flat .wg-tile-art, [data-skin="net"] .wg.flat .tile-img { display: none !important; }
[data-skin="net"] .wg.flat .wg-tile-ic, [data-skin="net"] .set-ic, [data-skin="net"] .tool-ic, [data-skin="net"] .wg-opt-ic, [data-skin="net"] .mi, [data-skin="net"] .speed-dot, [data-skin="net"] .modal-head .wg-tile-ic { background: transparent !important; box-shadow: none !important; }
[data-skin="net"] .wg.flat .wg-tile-ic svg, [data-skin="net"] .set-ic svg, [data-skin="net"] .tool-ic svg, [data-skin="net"] .wg-opt-ic svg, [data-skin="net"] .mi svg, [data-skin="net"] .speed-dot svg, [data-skin="net"] .modal-head .wg-tile-ic svg { stroke: var(--accent) !important; }
[data-skin="net"] .wg.flat[class*="tone-"] .wg-tile-ic { background: transparent !important; }
[data-skin="net"] .wg.flat[class*="tone-"] .wg-tile-ic svg { stroke: var(--tone) !important; }
[data-skin="net"] .set-nav .set-ic, [data-skin="net"] .shortcuts .set-ic { display: none !important; }
/* device-kind badges (map, tools, device cards): flat outline like the settings icons, but keep each kind's own colour (no purple/orange — kindColor() already swaps those) */
[data-skin="net"] .kind-ic { background: transparent !important; }
/* «Советы Frank» is not flattened (not asked for) but its catalogue colour is still purple — just the badge colour changes */
[data-skin="net"] .wg.t-advice .wg-tile-ic { background: var(--accent) !important; }
[data-skin="net"] .wg.t-advice .wg-tile-ic svg { stroke: #fff !important; }
/* Frank's eye (header button, widget, chat): the calm-mood iris matches the controller-blue accent instead of the generic cyan */
[data-skin="net"] { --frank-iris-0: #bfe0ff; --frank-iris-1: var(--accent); --frank-iris-2: #0a3c80; }
[data-skin="net"][data-theme="dark"] { --frank-iris-0: #cfe8ff; --frank-iris-1: var(--accent); --frank-iris-2: #0d4a99; }
[data-skin="net"] .set-nav button, [data-skin="net"] .shortcut { gap: 10px; }

/* accent colours (the same for both looks); selectors are as specific as the skin rules and come after them */
[data-accent="blue"][data-theme] { --accent: #0a84ff; } [data-accent="green"][data-theme] { --accent: #30b455; } [data-accent="purple"][data-theme] { --accent: #a259e6; }
[data-accent="orange"][data-theme] { --accent: #f5870a; } [data-accent="red"][data-theme] { --accent: #f2453d; } [data-accent="teal"][data-theme] { --accent: #20b4cc; }
[data-accent="pink"][data-theme] { --accent: #ee3d73; }

/* the picker in Settings */
.look-skins { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.look-skin { display: flex; flex-direction: column; gap: 10px; text-align: left; padding: 10px; border-radius: 20px; border: 2px solid var(--line); background: var(--fill); cursor: pointer; color: inherit; font: inherit; }
.look-skin.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, var(--fill)); }
.look-skin b { font-size: 15px; } .look-skin small { color: var(--text2); font-size: 12.5px; line-height: 1.4; }
.look-prev { border-radius: 14px; padding: 10px; display: flex; flex-direction: column; gap: 6px; background: var(--bg); color: var(--text); border: 1px solid var(--line); pointer-events: none; }
.look-prev .lp-card { border-radius: 10px; padding: 8px 10px; background: var(--card-solid); border: 1px solid var(--line); display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 650; }
.look-prev .lp-card i { width: 18px; height: 18px; border-radius: 6px; background: var(--accent); display: block; flex: none; }
.look-prev .lp-card small { margin-left: auto; color: var(--text2); font-weight: 500; }
.look-prev .lp-ok { border-radius: 10px; padding: 8px 10px; font-size: 12px; font-weight: 650; background: color-mix(in srgb, #30d158 9%, var(--bg)); border: 1px solid color-mix(in srgb, #30d158 55%, transparent); color: #4cc364; }
.look-prev .lp-btn { align-self: flex-start; border-radius: 9px; padding: 5px 12px; font-size: 12px; font-weight: 700; background: var(--accent); color: #fff; }
.look-accents { display: flex; gap: 10px; flex-wrap: wrap; }
.look-dot { width: 38px; height: 38px; border-radius: 50%; border: 3px solid transparent; box-shadow: 0 0 0 1.5px var(--line2); cursor: pointer; padding: 0; display: grid; place-items: center; }
.look-dot.on { box-shadow: 0 0 0 2px var(--text); } .look-dot.def { background: conic-gradient(#0a84ff, #30d158, #ffd60a, #ff453a, #bf5af2, #0a84ff); }
@media (max-width: 520px) { .look-skins { grid-template-columns: 1fr; } }
/* graphite: icons are plain outlines (no coloured squares), tiles and small cards are flat grey with a hairline */
[data-skin="graphite"] .wg-tile-ic, [data-skin="graphite"] .set-ic { background: transparent !important; box-shadow: none !important; }
[data-skin="graphite"] .wg-tile-ic svg, [data-skin="graphite"] .set-ic svg { stroke: var(--text) !important; }
[data-skin="graphite"] .wg[class*="tone-"] .wg-tile-ic { background: transparent !important; } [data-skin="graphite"] .wg[class*="tone-"] .wg-tile-ic svg { stroke: var(--tone) !important; }
[data-skin="graphite"] .stat, [data-skin="graphite"] .state-tile, [data-skin="graphite"] .shortcut { background: var(--fill); border: 0; }
[data-skin="graphite"] .tile, [data-skin="graphite"] .ios-cell { background: var(--card-solid); border: 1px solid var(--line); }
[data-skin="graphite"] .tile:hover { box-shadow: none; transform: none; }
[data-skin="graphite"] .mini-faces span { border-color: var(--card-solid); }
[data-skin="graphite"] .wg-tile-v { font-weight: 800; }
[data-skin="graphite"] .badge { border: 1px solid var(--line); background: transparent; }
[data-skin="graphite"] .badge.online { color: #4cc364; border-color: color-mix(in srgb, #4cc364 50%, transparent); background: color-mix(in srgb, #4cc364 8%, transparent); }
[data-skin="graphite"] .chip { background: transparent; border: 1px solid var(--line2); } [data-skin="graphite"] .chip.on { background: var(--accent); color: #fff; border-color: var(--accent); }
/* the «Rack Live» preview keeps the original colours even while another look is active */
.look-prev[data-skin="classic"][data-theme="dark"] { --bg: #000; --card-solid: #1c1c1e; --text: #f5f5f7; --text2: rgba(235,235,245,.66); --line: rgba(84,84,88,.45); --accent: #0a84ff; --fill: rgba(118,118,128,.22); }
.look-prev[data-skin="classic"][data-theme="light"] { --bg: #f2f2f7; --card-solid: #fff; --text: #1c1c1e; --text2: rgba(60,60,67,.72); --line: rgba(60,60,67,.12); --accent: #007aff; --fill: rgba(120,120,128,.12); }
.look-prev[data-skin="classic"] .lp-card { border-radius: 14px; } .look-prev[data-skin="classic"] { border-radius: 18px; }
.look-prev[data-accent][data-theme] .lp-card i, .look-prev[data-accent][data-theme] .lp-btn { background: var(--accent); }

/* «Графит»: a tile is a big outline icon, the name, the value and a grey line — like the reference; the live picture is only in the original look */
.wg-tile-big, .wg-tile-v.gv { display: none; }
[data-skin="graphite"] .wg.size-S .wg-tile { align-items: center; text-align: center; justify-content: center; gap: 4px; }
[data-skin="graphite"] .wg.size-S .wg-tile-top { order: 2; justify-content: center; } [data-skin="graphite"] .wg.size-S .wg-tile-top .wg-tile-ic { display: none; }
[data-skin="graphite"] .wg.size-S .wg-tile-name { font-size: 15px; font-weight: 750; color: var(--text); text-align: center; }
[data-skin="graphite"] .wg.size-S .wg-tile-art { display: none; }
[data-skin="graphite"] .wg.size-S .wg-tile-big { order: 1; display: flex; flex: 1; align-items: center; justify-content: center; color: var(--text); min-height: 0; }
[data-skin="graphite"] .wg.size-S .wg-tile-big svg { width: clamp(30px, 30cqw, 52px); height: auto; stroke: currentColor !important; fill: none; }
[data-skin="graphite"] .wg.size-S .wg-tile-v, [data-skin="graphite"] .wg.size-S .wg-tile-v.gv { order: 3; display: block; font-size: clamp(18px, 11cqw, 26px); }
[data-skin="graphite"] .wg.size-S .wg-tile-s { order: 4; color: var(--text2); text-align: center; max-width: 100%; }
[data-skin="graphite"] .wg[class*="tone-"] .wg-tile-big { color: var(--tone); }
[data-skin="graphite"] .wg.size-S .wg-tile { padding-top: 6px; }
[data-skin="graphite"] .wg.size-S .wg-tile-big svg { width: clamp(38px, 38cqw, 72px); stroke-width: 1.4; }
/* «Контроллер»: the same flat big-outline-icon tile as «Графит», tinted with the controller-blue accent — every widget marked flat:true */
[data-skin="net"] .wg.size-S.flat .wg-tile { align-items: center; text-align: center; justify-content: center; gap: 4px; padding-top: 6px; }
[data-skin="net"] .wg.size-S.flat .wg-tile-top { order: 2; justify-content: center; }
[data-skin="net"] .wg.size-S.flat .wg-tile-top .wg-tile-ic { display: none; }
[data-skin="net"] .wg.size-S.flat .wg-tile-name { font-size: 15px; font-weight: 750; color: var(--text); text-align: center; }
[data-skin="net"] .wg.size-S.flat .wg-tile-art { display: none; }
[data-skin="net"] .wg.size-S.flat .wg-tile-big { order: 1; display: flex; flex: 1; align-items: center; justify-content: center; color: var(--accent); min-height: 0; }
[data-skin="net"] .wg.size-S.flat .wg-tile-big svg { width: clamp(38px, 38cqw, 72px); height: auto; stroke: currentColor !important; fill: none; stroke-width: 1.4; }
[data-skin="net"] .wg.size-S.flat .wg-tile-v, [data-skin="net"] .wg.size-S.flat .wg-tile-v.gv { order: 3; display: block; font-size: clamp(18px, 11cqw, 26px); }
[data-skin="net"] .wg.size-S.flat .wg-tile-s { order: 4; color: var(--text2); text-align: center; max-width: 100%; }
[data-skin="net"] .wg.flat[class*="tone-"] .wg-tile-big { color: var(--tone); }
/* Frank's tile: the plain flat blue outline eye (same family as every other flat tile), not the realistic gradient eye — but it blinks */
@keyframes flatBlink { 0%, 90%, 100% { transform: scaleY(1); } 94% { transform: scaleY(.08); } }
[data-skin="net"] .wg.size-S.t-frank .wg-tile-big svg { animation: flatBlink 4.5s ease-in-out infinite; transform-origin: center; transform-box: fill-box; }
@media (prefers-reduced-motion: reduce) { [data-skin="net"] .wg.size-S.t-frank .wg-tile-big svg { animation: none; } }
/* Rack's tile: the shelf stays still, but its four LED dots blink one after another like real equipment */
@keyframes rackLed { 0%, 70%, 100% { opacity: .22; } 78% { opacity: 1; } }
[data-skin="net"] .wg.size-S.t-rack .wg-tile-big svg circle { animation: rackLed 3.2s ease-in-out infinite; }
[data-skin="net"] .wg.size-S.t-rack .wg-tile-big svg circle:nth-of-type(1) { animation-delay: 0s; }
[data-skin="net"] .wg.size-S.t-rack .wg-tile-big svg circle:nth-of-type(2) { animation-delay: .5s; }
[data-skin="net"] .wg.size-S.t-rack .wg-tile-big svg circle:nth-of-type(3) { animation-delay: 1.1s; }
[data-skin="net"] .wg.size-S.t-rack .wg-tile-big svg circle:nth-of-type(4) { animation-delay: 1.7s; }
@media (prefers-reduced-motion: reduce) { [data-skin="net"] .wg.size-S.t-rack .wg-tile-big svg circle { animation: none; } }
.app-ic-g, .app-ic-n { display: none; }
[data-skin="graphite"] .app-ic-c { display: none !important; }
[data-skin="graphite"] .app-ic-g { display: block; }
/* «Контроллер» keeps the original gradient app icon (header, PWA) — it matched the style, the flat badge did not */

/* «Графит»: Frank, the speed test and the welcome tour — flat, no glass and no blue; the original look above is untouched */
[data-skin="graphite"] .ai-panel, [data-skin="graphite"] .ai-panel.standalone .ai-head { backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; }
[data-skin="graphite"] .ai-bubble { background: var(--card-solid); border: 1px solid var(--line); }
[data-skin="graphite"] .ai-msg.user .ai-bubble { background: var(--accent); border-color: var(--accent); color: #fff; }
[data-skin="graphite"] .ai-msg.err .ai-bubble { background: color-mix(in srgb, var(--red) 10%, var(--bg)); border-color: color-mix(in srgb, var(--red) 45%, transparent); }
[data-skin="graphite"] .ai-logo { background: var(--card-solid); border: 1px solid var(--line2); }
[data-skin="graphite"] .ai-tools span, [data-skin="graphite"] .ai-cmd, [data-skin="graphite"] .ai-ops-head { background: var(--fill); }
[data-skin="graphite"] .frank-install { background: var(--card-solid); border: 1px solid var(--line); }
[data-skin="graphite"] .fr-blur { backdrop-filter: none; -webkit-backdrop-filter: none; -webkit-mask-image: none; mask-image: none; background: linear-gradient(var(--bg) 55%, transparent); }
[data-skin="graphite"] .fr-circle, [data-skin="graphite"] .fr-dbtn, [data-skin="graphite"] .fr-model { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--fill); border: 1px solid var(--line); box-shadow: none; }
[data-skin="graphite"] .fr-dock { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--card-solid); border: 1px solid var(--line2); box-shadow: none; }
[data-skin="graphite"] .fr-send.on, [data-skin="graphite"] .fr-dbtn.on { background: var(--accent); box-shadow: none; color: #fff; }
[data-skin="graphite"] .ai-chat-item.on { background: var(--fill); }
/* speed test: the dial and the phases use the accent, the verdict is outlined */
[data-skin="graphite"] .gauge-bar i { background: var(--accent); }
[data-skin="graphite"] .speed-verdict { background: var(--card-solid); border: 1px solid var(--line); border-left-width: 3px; border-radius: 12px; padding: 10px 12px; }
[data-skin="graphite"] .speed-dot { background: transparent !important; border: 1px solid var(--line2); }
/* the welcome tour */
[data-skin="graphite"] .tour-bubble { background: #151516; border: 1px solid #3a3a3d; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
[data-skin="graphite"] .tour-bubble::before { background: #151516; border-color: #3a3a3d; }
[data-skin="graphite"] .tour-hint { color: var(--accent); } [data-skin="graphite"] .tour-hint i { background: var(--accent); animation: none; }
[data-skin="graphite"] .tour-dots i.on { background: var(--accent); }
[data-skin="graphite"] .tour-next { background: var(--accent); box-shadow: none; }
[data-skin="graphite"] .tour-skip { background: #1c1c1e; border: 1px solid #3a3a3d; backdrop-filter: none; -webkit-backdrop-filter: none; }
[data-skin="graphite"] .tour-card-eye { background: #1c1c1e; border: 1px solid #3a3a3d; }
[data-skin="graphite"] .tour-ring { border-color: var(--accent); }
[data-skin="graphite"] .tour-dim g rect:nth-child(2), [data-skin="graphite"] .tour-dim g rect:nth-child(3) { display: none; }
[data-skin="graphite"] .tour-dim g rect:nth-child(1) { fill: rgba(0,0,0,.84); }
.sys-log { font-size: 12px; line-height: 1.55; word-break: break-word; display: flex; flex-direction: column; gap: 5px; max-height: 60vh; overflow: auto; }
.sys-line b { font-weight: 650; }
.look-skin.off { opacity: .6; cursor: not-allowed; } .look-skin { cursor: pointer; }
.look-skin .look-prev img { max-height: 120px; object-fit: cover; }

/* a look that brings its own tile picture / colour wins over the built-in flat tile of «Графит» */
.wg-tile.has-color .wg-tile-big { color: var(--tc); }
[data-skin="graphite"] .wg.size-S .wg-tile.has-art .wg-tile-art { display: flex; order: 1; flex: 1; align-items: center; justify-content: center; min-height: 0; padding: 4px 0; color: var(--tc); }
[data-skin="graphite"] .wg.size-S .wg-tile.has-art .wg-tile-big { display: none; }

/* tab «Инструменты» */
.plug-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
.plug-card { display: flex; flex-direction: column; gap: 10px; }
.plug-devs { display: flex; flex-direction: column; gap: 4px; border-top: 1px solid var(--line, rgba(128,128,128,.2)); padding-top: 8px; }
.plug-dev { display: flex; align-items: center; gap: 8px; border: 0; background: var(--fill); color: inherit; border-radius: 11px; padding: 8px 11px; font: inherit; font-size: 13.5px; cursor: pointer; }
.plug-dev:hover { filter: brightness(1.08); }
.tool-card { display: flex; align-items: center; gap: 14px; cursor: pointer; text-align: left; font: inherit; color: inherit; width: 100%; }
.tool-card.soon { cursor: default; opacity: .7; }
.tool-ic { width: 48px; height: 48px; border-radius: 14px; display: grid; place-items: center; flex-shrink: 0; }
.cam-row { gap: 10px; }
.cam-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 12px; border: 0; background: transparent; color: inherit; font: inherit; cursor: pointer; padding: 0; }
.cam-box { display: flex; flex-direction: column; gap: 2px; }
.cam-box .kv { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; font-size: 13.5px; }
.cam-box .kv span { color: var(--text2, #8e8e93); }
.cam-shot { width: 100%; max-height: 360px; object-fit: contain; border-radius: 14px; background: #000; }
.cam-warn { border-radius: 14px; padding: 10px 13px; font-size: 13.5px; line-height: 1.45; background: color-mix(in srgb, var(--orange, #ff9f0a) 16%, transparent); border: 1px solid color-mix(in srgb, var(--orange, #ff9f0a) 45%, transparent); }
.cam-ok { border-radius: 12px; padding: 9px 12px; font-size: 13.5px; background: color-mix(in srgb, var(--green, #30d158) 16%, transparent); }
.cam-err { border-radius: 12px; padding: 9px 12px; font-size: 13.5px; background: color-mix(in srgb, var(--red, #ff453a) 16%, transparent); color: var(--text); }

@media (max-width: 480px) { .bottombar { gap: 1px; padding: 6px 5px; } .bottombar button { font-size: 9.5px; letter-spacing: -.1px; padding: 9px 0 7px; } }
.cam-box { padding: 12px 14px; }
.cam-main, .cam-row .grow, .plug-card .grow { min-width: 0; }

/* «где искать»: a small button with a drop-down */
.where { position: relative; display: inline-block; }
.where-btn { gap: 6px; }
.where-pop { position: absolute; top: calc(100% + 6px); left: 0; z-index: 30; width: min(380px, calc(100vw - 32px)); max-height: min(420px, calc(100vh - 160px)); overflow: auto; padding: 10px; box-shadow: 0 18px 50px rgba(0,0,0,.35); }
.where-pop.right { left: auto; right: 0; }
.where-row { display: flex; align-items: center; gap: 10px; width: 100%; border: 0; background: transparent; color: inherit; font: inherit; padding: 8px; border-radius: 11px; cursor: pointer; }
.where-row:hover { background: var(--fill); }
.where-row b { display: block; font-size: 13.5px; }
.where-row small { display: block; color: var(--text2, #8e8e93); font-size: 11.5px; line-height: 1.35; }
.where-dot { width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--text3, #8e8e93); flex-shrink: 0; position: relative; }
.where-dot.sq { border-radius: 6px; }
.where-row.on .where-dot { border-color: var(--accent); background: var(--accent); }
.where-row.on .where-dot::after { content: ''; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.where-link { display: inline-flex; align-items: center; gap: 6px; margin-top: 14px; border: 0; background: transparent; color: var(--text2, #8e8e93); font: inherit; font-size: 12.5px; cursor: pointer; padding: 0; }
/* cameras: ticks and the bar for «several at once» */
.cam-check { width: 20px; height: 20px; accent-color: var(--accent); flex-shrink: 0; cursor: pointer; }
.cam-row.picked { background: color-mix(in srgb, var(--accent) 9%, transparent); }
.cam-bar { position: sticky; bottom: 14px; z-index: 20; display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 14px; padding: 10px 12px 10px 16px; border-radius: 18px;
  background: var(--card-solid, #1c1c1e); border: 1px solid var(--line, rgba(128,128,128,.25)); box-shadow: 0 12px 36px rgba(0,0,0,.35); }
@media (max-width: 760px) { .cam-bar { bottom: calc(env(safe-area-inset-bottom) + 92px); } }
/* plugins by device */
.plug-list { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line, rgba(128,128,128,.2)); }
.plug-row { display: flex; align-items: center; gap: 10px; width: 100%; border: 0; background: var(--fill); color: inherit; font: inherit; border-radius: 13px; padding: 9px 12px; cursor: pointer; }
.plug-row b { display: block; font-size: 14px; }
.plug-row small { display: block; color: var(--text2, #8e8e93); font-size: 12px; line-height: 1.4; margin-top: 2px; }
.plug-row:hover { filter: brightness(1.08); }

/* Docker in detail */
.dk-sum { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 10px; }
.dk-sum > div { background: var(--fill); border-radius: 14px; padding: 9px 12px; display: flex; flex-direction: column; min-width: 0; }
.dk-sum b { font-size: 17px; } .dk-sum span { font-size: 11.5px; color: var(--text2, #8e8e93); }
.dk-card { padding: 0; overflow: hidden; }
.dk-head { display: flex; align-items: center; gap: 10px; width: 100%; border: 0; background: transparent; color: inherit; font: inherit; padding: 11px 14px; cursor: pointer; }
.dk-chips { display: flex; gap: 5px; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
.dk-body { padding: 0 14px 14px; border-top: 1px solid var(--line, rgba(128,128,128,.2)); }
.dk-desc { padding: 10px 0; font-size: 13.5px; line-height: 1.45; }
.dk-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 14px; }
.dk-h { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--text2, #8e8e93); margin-bottom: 5px; }
.dk-line { font-size: 13px; padding: 2px 0; display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline; }
.dk-bar { display: inline-block; flex: 1 1 60px; min-width: 60px; height: 5px; border-radius: 3px; background: var(--fill2, rgba(128,128,128,.25)); overflow: hidden; align-self: center; }
.dk-bar > i { display: block; height: 100%; }
@media (max-width: 480px) { .dk-sum { grid-template-columns: repeat(2, 1fr); } .dk-chips .badge:nth-child(n+3) { display: none; } }

.pick-label { display: inline-flex; align-items: center; gap: 6px; border: 0; background: transparent; color: var(--text2, #8e8e93); font: inherit; font-size: 13.5px; cursor: pointer; padding: 0; }

.dk-reason { font-size: 13px; line-height: 1.45; padding: 2px 0; }
.dk-attrs { display: flex; flex-direction: column; margin-top: 6px; font-size: 12.5px; }
.dk-attrs > div { display: grid; grid-template-columns: 34px 1fr auto 96px; gap: 8px; padding: 4px 0; border-top: 1px solid var(--line, rgba(128,128,128,.15)); }
.dk-attrs > div.bad { color: var(--red); }

/* terminal */
.term-bar { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.term-box { background: #0b0f14; border-radius: 14px; padding: 8px 6px 6px 10px; height: min(62vh, 560px); min-height: 280px; overflow: hidden; }
.term-box .xterm { height: 100%; } .term-box .xterm-viewport { background: transparent !important; }
.term-keys { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.term-keys.top { flex-wrap: nowrap; overflow-x: auto; margin: 0 0 8px; padding-bottom: 2px; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.term-keys.top::-webkit-scrollbar { display: none; }
.term-keys.top .btn { flex: 0 0 auto; }
.term-keys .btn { min-width: 40px; }
/* selecting text: the mouse works in xterm itself; on a touch screen the buffer is shown as plain text over the terminal */
.term-wrap { position: relative; }
.term-box, .term-box * { -webkit-user-select: text; user-select: text; }
.term-pick-wrap { position: absolute; inset: 0; display: flex; flex-direction: column; background: #0b0f14; border-radius: 14px; overflow: hidden; z-index: 3; }
.term-pick { flex: 1; margin: 0; padding: 10px 12px; overflow: auto; color: #d6deeb; white-space: pre-wrap; word-break: break-all; -webkit-user-select: text; user-select: text; -webkit-touch-callout: default; touch-action: pan-y; line-height: 1.35; }
.term-pick-bar { display: flex; align-items: center; gap: 8px; padding: 8px 10px; background: rgba(255,255,255,.07); }
html.app-touch .term-pick, html.app-touch .term-pick * { -webkit-user-select: text !important; user-select: text !important; }
/* the «Терминал» app: the whole screen */
.term-app { position: relative; z-index: 1; max-width: 1100px; margin: 0 auto; padding: calc(env(safe-area-inset-top, 0px) + 10px) 12px calc(env(safe-area-inset-bottom, 0px) + 10px); min-height: 100dvh; }
.term-app-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.term-app .term-box { height: calc(100dvh - 200px); min-height: 240px; }
html.term-mode, html.term-mode body { height: 100%; overflow: hidden; overscroll-behavior: none; touch-action: manipulation; }
html.term-mode input, html.term-mode select { font-size: 16px; }

/* «Режим разработчика»: a Wi-Fi network in the list of found ones */
.li.wifi-net { width: 100%; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; border-radius: 10px; padding: 8px 6px; }
.li.wifi-net:hover { background: var(--fill, rgba(120,120,128,.12)); }
.li.wifi-net.on { background: color-mix(in srgb, var(--accent) 14%, transparent); }

/* terminal: «Вставить» — a plain field that takes the system paste (xterm on a phone has none) */
.term-paste { display: flex; flex-direction: column; gap: 8px; margin: 8px 0; padding: 10px; border-radius: 12px; background: var(--fill, rgba(120,120,128,.12)); }
.term-paste textarea { width: 100%; resize: vertical; font-size: 16px; }

/* ── «Карточки» (/cards): a separate app — scan a QR sticker, get the device card ── */
.cards-app { max-width: 760px; margin: 0 auto; padding: calc(env(safe-area-inset-top) + 12px) 16px calc(env(safe-area-inset-bottom) + 40px); }
.cards-mode body, .cards-mode html { overscroll-behavior-y: none; }
.cd-top { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.cd-top h1 { flex: 1; margin: 0; font-size: 28px; font-weight: 750; letter-spacing: -.6px; }
.cd-scan { width: 100%; border: 0; border-radius: 24px; padding: 18px 20px; display: flex; align-items: center; gap: 16px; color: #fff; text-align: left; cursor: pointer; font: inherit;
  background: linear-gradient(135deg, #4aa3ff, #0a58e6); box-shadow: 0 12px 30px rgba(10,88,230,.35), inset 0 1px 0 rgba(255,255,255,.35); transition: transform .12s; }
.cd-scan:active { transform: scale(.985); }
.cd-scan-ic { width: 54px; height: 54px; border-radius: 17px; display: grid; place-items: center; background: rgba(255,255,255,.22); flex-shrink: 0; }
.cd-scan b { display: block; font-size: 19px; letter-spacing: -.3px; } .cd-scan small { display: block; margin-top: 2px; font-size: 13px; opacity: .9; }
.cd-h { margin: 20px 4px 8px; font-size: 13px; font-weight: 650; letter-spacing: .3px; text-transform: uppercase; color: var(--text2); }
.cd-row { cursor: pointer; padding: 10px 0; } .cd-row:active { opacity: .6; }
.cd-bar { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.cd-page { display: flex; flex-direction: column; gap: 12px; }
.cd-page > .card { margin: 0; }
/* the hero: big icon on a soft glow of the device's own colour */
.cd-hero { position: relative; overflow: hidden; border-radius: 28px; padding: 26px 20px 20px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--tc, var(--accent)) 30%, transparent), transparent 70%), var(--card); border: .5px solid var(--line); box-shadow: var(--shadow); }
.cd-hero h2 { margin: 8px 0 0; font-size: 26px; font-weight: 760; letter-spacing: -.6px; line-height: 1.15; word-break: break-word; }
.cd-sub { color: var(--text2); font-size: 14.5px; }
.cd-chips { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin-top: 8px; }
.cd-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.cd-facts:empty { display: none; }
.cd-fact { background: var(--card); border: .5px solid var(--line); border-radius: 16px; padding: 11px 14px; min-width: 0; }
.cd-fact.tap { cursor: pointer; } .cd-fact.tap:active { opacity: .6; }
.cd-fact .k { font-size: 11.5px; font-weight: 600; letter-spacing: .3px; text-transform: uppercase; color: var(--text3); }
.cd-fact .v { margin-top: 2px; font-size: 15.5px; font-weight: 600; overflow-wrap: anywhere; } .cd-fact .v.mono { font-size: 14px; }
.cd-port { margin-top: 12px; padding-top: 12px; border-top: .5px solid var(--line); }
.cd-pick .li input { width: 20px; height: 20px; accent-color: var(--accent); flex-shrink: 0; }
/* camera */
.cd-cam { position: fixed; inset: 0; z-index: 60; background: #000; color: #fff; }
.cd-cam video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cd-cam-top { position: absolute; left: 14px; right: 14px; top: calc(env(safe-area-inset-top) + 10px); display: flex; z-index: 2; }
.cd-pill { display: inline-flex; align-items: center; gap: 6px; height: 40px; padding: 0 16px; border: 0; border-radius: 20px; color: #fff; font: 600 14px/1 inherit; cursor: pointer;
  background: rgba(28,28,30,.62); -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px); }
.cd-pill.solid { background: #0a84ff; }
.cd-frame { position: absolute; left: 50%; top: 46%; width: min(64vw, 280px); aspect-ratio: 1; transform: translate(-50%, -50%); pointer-events: none; }
.cd-frame i { position: absolute; width: 34px; height: 34px; border: 4px solid #fff; border-radius: 10px; filter: drop-shadow(0 0 6px rgba(0,0,0,.5)); }
.cd-frame i:nth-child(1) { left: 0; top: 0; border-right: 0; border-bottom: 0; } .cd-frame i:nth-child(2) { right: 0; top: 0; border-left: 0; border-bottom: 0; }
.cd-frame i:nth-child(3) { left: 0; bottom: 0; border-right: 0; border-top: 0; } .cd-frame i:nth-child(4) { right: 0; bottom: 0; border-left: 0; border-top: 0; }
.cd-cam-hint { position: absolute; left: 20px; right: 20px; bottom: calc(env(safe-area-inset-bottom) + 36px); text-align: center; font-size: 15px; font-weight: 600; text-shadow: 0 1px 6px rgba(0,0,0,.7); }
.cd-cam-err { position: absolute; left: 24px; right: 24px; top: 50%; transform: translateY(-50%); text-align: center; padding: 22px; border-radius: 24px; background: rgba(28,28,30,.85); }
.cd-cam-err b { font-size: 18px; } .cd-cam-err p { margin: 8px 0; opacity: .85; line-height: 1.45; }
/* stickers: only the sheet is printed */
#cards-print { display: none; }
@media print {
  html.cards-print-mode, html.cards-print-mode body { background: #fff !important; height: auto !important; overflow: visible !important; }
  html.cards-print-mode body > *:not(#cards-print) { display: none !important; }
  html.cards-print-mode #cards-print { display: flex !important; flex-wrap: wrap; gap: 3mm; padding: 6mm; align-items: flex-start; }
  @page { margin: 8mm; }
}
/* sticker classes live only inside #cards-print: .cp-st is also the cable-test status column */
#cards-print .cp-st { background: #fff; color: #000; padding: 3mm; border: .2mm dashed #b8b8b8; text-align: center; break-inside: avoid; }
#cards-print .cp-qr { display: block; margin: 0 auto; } #cards-print .cp-qr svg { width: 100%; height: 100%; display: block; }
#cards-print .cp-cap { font: 7pt/1.15 Arial, sans-serif; margin-top: 1.2mm; max-width: 40mm; margin-left: auto; margin-right: auto; word-break: break-word; }
.cd-hero-ic { width: 86px; height: 86px; border-radius: 28px; display: grid; place-items: center; }
.cd-rows { display: flex; flex-direction: column; }
.cd-r { display: flex; justify-content: space-between; gap: 16px; padding: 10px 0; border-bottom: .5px solid var(--line); font-size: 14.5px; } .cd-r:last-child { border-bottom: 0; }
.cd-r span { color: var(--text2); flex-shrink: 0; } .cd-r b { text-align: right; font-weight: 600; overflow-wrap: anywhere; }
.cd-pls { display: flex; flex-direction: column; padding: 4px 12px; }
.cd-pl { display: flex; align-items: center; gap: 12px; padding: 9px 4px; border-bottom: .5px solid var(--line); cursor: pointer; border-radius: 10px; } .cd-pl:last-child { border-bottom: 0; }
.cd-pl.on { background: var(--fill); } .cd-pl b { font-size: 14.5px; font-weight: 600; } .cd-pl small { font-size: 12px; }
.cd-pn { width: 34px; height: 30px; border-radius: 8px; display: grid; place-items: center; font: 700 13px/1 var(--mono, ui-monospace, monospace); flex-shrink: 0; background: var(--fill2); color: var(--text2); }
.cd-pn.g { background: color-mix(in srgb, var(--green) 24%, transparent); color: var(--green); } .cd-pn.y { background: color-mix(in srgb, #ffd60a 26%, transparent); color: #b38f00; } .cd-pn.o { background: color-mix(in srgb, #ff9f0a 26%, transparent); color: #ff9f0a; }
.cd-ups-time { text-align: center; } .cd-ups-time .big { font-size: 40px; font-weight: 780; letter-spacing: -1px; line-height: 1.1; }
.cd-rings { display: flex; justify-content: center; gap: 22px; margin-top: 16px; flex-wrap: wrap; }
.cd-ring { position: relative; } .cd-ring svg { width: 100%; height: 100%; display: block; }
.cd-ring-in { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.cd-ring-in b { font-size: 21px; font-weight: 750; letter-spacing: -.4px; } .cd-ring-in small { font-size: 11.5px; color: var(--text2); margin-top: 1px; }
.cd-fit { width: 100%; overflow: hidden; } .cd-fit .faceplate { overflow: visible; }
.cd-pop { display: flex; align-items: center; gap: 12px; margin-top: 12px; padding: 10px 12px; border-radius: 18px; background: color-mix(in srgb, var(--pc, var(--accent)) 14%, var(--fill)); border: 1px solid color-mix(in srgb, var(--pc, var(--accent)) 38%, transparent); animation: cdpop .22s cubic-bezier(.2,.9,.3,1.2); }
.cd-pop-n { width: 44px; height: 44px; border-radius: 14px; display: grid; place-items: center; flex-shrink: 0; font: 750 19px/1 var(--mono, ui-monospace, monospace); color: #fff; background: var(--pc, var(--accent)); box-shadow: 0 6px 16px color-mix(in srgb, var(--pc, var(--accent)) 40%, transparent); }
.cd-pop b { display: block; font-size: 16px; font-weight: 700; letter-spacing: -.2px; } .cd-pop small { display: block; margin-top: 1px; font-size: 13px; color: var(--text2); }
.cd-pop-x { width: 30px; height: 30px; border: 0; border-radius: 50%; display: grid; place-items: center; background: var(--fill); color: var(--text2); cursor: pointer; flex-shrink: 0; }
@keyframes cdpop { from { opacity: 0; transform: translateY(6px) scale(.97); } to { opacity: 1; transform: none; } }
/* the card in the colour of its device: one hue for the hero, the chips and the tapped port (the switch is green, the NAS is cyan…) */
.cd-hero { border: 1px solid color-mix(in srgb, var(--tc, var(--accent)) 24%, var(--line)); border-radius: 30px; padding: 28px 20px 22px; gap: 4px;
  background: radial-gradient(130% 100% at 50% -10%, color-mix(in srgb, var(--tc, var(--accent)) 34%, transparent), transparent 68%), linear-gradient(180deg, color-mix(in srgb, var(--tc, var(--accent)) 7%, var(--card)), var(--card));
  box-shadow: 0 22px 44px -22px color-mix(in srgb, var(--tc, var(--accent)) 60%, transparent), inset 0 1px 0 rgba(255,255,255,.08); }
.cd-hero-ic { width: 92px; height: 92px; border-radius: 30px; background: linear-gradient(150deg, color-mix(in srgb, var(--tc, var(--accent)) 38%, transparent), color-mix(in srgb, var(--tc, var(--accent)) 12%, transparent)) !important;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--tc, var(--accent)) 40%, transparent), 0 14px 34px -6px color-mix(in srgb, var(--tc, var(--accent)) 48%, transparent), inset 0 1px 0 rgba(255,255,255,.28) !important; }
.cd-hero h2 { font-size: 28px; margin-top: 12px; letter-spacing: -.8px; }
.cd-chip { display: inline-flex; align-items: center; gap: 5px; padding: 4px 11px; border-radius: 999px; font-size: 12.5px; font-weight: 650; color: var(--tc, var(--accent)); background: color-mix(in srgb, var(--tc, var(--accent)) 15%, transparent); border: 1px solid color-mix(in srgb, var(--tc, var(--accent)) 26%, transparent); }
.cd-chip.neutral { color: var(--text2); background: var(--fill); border-color: transparent; } .cd-chip.mono { font-family: var(--mono, ui-monospace, monospace); font-size: 12px; }
.cd-page > .card { border-radius: 26px; }
.cd-page .card-title { color: var(--text2); letter-spacing: .5px; }
.cd-pop { border-radius: 22px; padding: 12px 14px; background: linear-gradient(135deg, color-mix(in srgb, var(--pc, var(--accent)) 22%, var(--card)), color-mix(in srgb, var(--pc, var(--accent)) 8%, var(--card))); border-color: color-mix(in srgb, var(--pc, var(--accent)) 34%, transparent);
  box-shadow: 0 14px 30px -16px color-mix(in srgb, var(--pc, var(--accent)) 70%, transparent); }
.cd-pop-n { width: 48px; height: 48px; border-radius: 16px; background: linear-gradient(150deg, color-mix(in srgb, var(--pc, var(--accent)) 100%, #fff 18%), var(--pc, var(--accent))); }
.cd-pop b { font-size: 17px; }
.cd-scan { border-radius: 26px; padding: 20px 22px; } .cd-top h1 { font-size: 30px; }
/* liquid glass + a thin neon line in the colour of the card */
.cards-app { position: relative; z-index: 1; }
.cd-glow { position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(70% 38% at 18% 2%, color-mix(in srgb, var(--tc) 34%, transparent), transparent 72%), radial-gradient(55% 34% at 92% 22%, color-mix(in srgb, var(--tc) 20%, transparent), transparent 72%), radial-gradient(60% 30% at 40% 100%, color-mix(in srgb, var(--tc) 14%, transparent), transparent 75%); }
.cd-page > .card, .cd-hero, .cd-pop {
  background: linear-gradient(160deg, rgba(255,255,255,.16), rgba(255,255,255,.04) 45%, color-mix(in srgb, var(--tc, var(--pc, var(--accent))) 9%, rgba(255,255,255,.03)));
  -webkit-backdrop-filter: blur(26px) saturate(1.9); backdrop-filter: blur(26px) saturate(1.9);
  border: 1px solid color-mix(in srgb, var(--tc, var(--pc, var(--accent))) 38%, rgba(255,255,255,.14));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.42), inset 0 -1px 0 rgba(255,255,255,.06), 0 0 0 .5px color-mix(in srgb, var(--tc, var(--pc, var(--accent))) 40%, transparent),
    0 0 16px -5px color-mix(in srgb, var(--tc, var(--pc, var(--accent))) 70%, transparent), 0 18px 36px -22px rgba(0,0,0,.55); }
[data-theme="light"] .cd-page > .card, [data-theme="light"] .cd-hero, [data-theme="light"] .cd-pop {
  background: linear-gradient(160deg, rgba(255,255,255,.85), rgba(255,255,255,.55) 50%, color-mix(in srgb, var(--tc, var(--pc, var(--accent))) 8%, rgba(255,255,255,.5)));
  box-shadow: inset 0 1px 0 #fff, 0 0 0 .5px color-mix(in srgb, var(--tc, var(--pc, var(--accent))) 40%, transparent), 0 0 14px -6px color-mix(in srgb, var(--tc, var(--pc, var(--accent))) 65%, transparent), 0 14px 30px -20px rgba(0,0,0,.25); }
.cd-pop-n { box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 0 14px -2px color-mix(in srgb, var(--pc, var(--accent)) 80%, transparent); }
.cd-chip { box-shadow: 0 0 10px -4px color-mix(in srgb, var(--tc, var(--accent)) 80%, transparent); }
.cd-ring svg circle:nth-child(2) { filter: drop-shadow(0 0 5px color-mix(in srgb, var(--tc, var(--accent)) 60%, transparent)); }
.cd-hero-ic { box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 0 0 1px color-mix(in srgb, var(--tc) 50%, transparent), 0 0 22px -4px color-mix(in srgb, var(--tc) 70%, transparent) !important; }
/* two-tone cards (OpenWrt: yellow + green): the second colour is --tc2, the same as --tc for one-colour cards */
.cd-glow { background: radial-gradient(70% 38% at 18% 2%, color-mix(in srgb, var(--tc) 34%, transparent), transparent 72%), radial-gradient(55% 34% at 92% 22%, color-mix(in srgb, var(--tc2, var(--tc)) 26%, transparent), transparent 72%), radial-gradient(60% 30% at 40% 100%, color-mix(in srgb, var(--tc2, var(--tc)) 16%, transparent), transparent 75%); }
.cd-hero-ic { background: linear-gradient(150deg, color-mix(in srgb, var(--tc) 40%, transparent), color-mix(in srgb, var(--tc2, var(--tc)) 30%, transparent)) !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 0 0 1px color-mix(in srgb, var(--tc2, var(--tc)) 50%, transparent), 0 0 22px -4px color-mix(in srgb, var(--tc) 70%, transparent), 0 8px 26px -8px color-mix(in srgb, var(--tc2, var(--tc)) 55%, transparent) !important; }
.cd-hero-ic svg { color: var(--tc); }
.cd-chip { color: var(--tc); background: linear-gradient(90deg, color-mix(in srgb, var(--tc) 16%, transparent), color-mix(in srgb, var(--tc2, var(--tc)) 16%, transparent)); border-color: color-mix(in srgb, var(--tc2, var(--tc)) 30%, transparent); }
.cd-chip.neutral { color: var(--text2); background: var(--fill); }
.cd-page > .card, .cd-hero { border-color: color-mix(in srgb, var(--tc) 36%, rgba(255,255,255,.14)); }
.cd-pop { background: linear-gradient(135deg, color-mix(in srgb, var(--pc, var(--accent)) 22%, var(--card)), color-mix(in srgb, var(--pc2, var(--pc, var(--accent))) 14%, var(--card))); }
.cd-pop-n { background: linear-gradient(150deg, var(--pc, var(--accent)), var(--pc2, var(--pc, var(--accent)))); }
/* the app is just the camera; a card slides up over it and can only be closed */
.cd-app { padding: 0; max-width: none; }
.cd-sheet { position: fixed; inset: 0; z-index: 70; overflow-y: auto; -webkit-overflow-scrolling: touch; background: var(--bg, #000); animation: cdsheet .32s cubic-bezier(.2,.9,.3,1); }
.cd-sheet .cards-app { padding-top: calc(env(safe-area-inset-top) + 10px); }
.cd-close { width: 42px; height: 42px; }
@keyframes cdsheet { from { transform: translateY(40px); opacity: 0; } to { transform: none; opacity: 1; } }
.cd-stk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; }
.cd-stk { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px; border-radius: 16px; background: var(--fill); }
.cd-stk-img { width: 100%; max-width: 180px; height: auto; border-radius: 6px; background: #fff; image-rendering: pixelated; -webkit-touch-callout: default; -webkit-user-select: auto; user-select: auto; }
.cd-stk small { font-size: 10.5px; color: var(--text3); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── «Витрина» (the Scanner's cards): studio white in the light theme, black aluminium in the dark one ── */
:root { --vt-bg: linear-gradient(180deg, #f3f4f6, #e4e6ea); --vt-solid: #eceef1; --vt-fg: #15171a; --vt-dim: #5b6168; --vt-line: #cfd3d9; --vt-card: rgba(255,255,255,.55);
  --s3-front: linear-gradient(180deg, #ffffff 0%, #eef0f2 30%, #dfe2e6 100%); --s3-top: linear-gradient(180deg, #fbfbfc, #e8eaee); --s3-side: linear-gradient(180deg, #e9ebee, #cfd3d8); --s3-back: #c9cdd2;
  --s3-port: #23262a; --s3-rim: #b9bec5; --s3-text: #5b6168; --s3-shadow: rgba(20,30,45,.42); --s3-led: #3d8bff; --s3-led2: #e2b93b; --s3-hl: rgba(255,255,255,.6); }
[data-theme="dark"] { --vt-bg: linear-gradient(180deg, #151619, #08090a); --vt-solid: #0d0e10; --vt-fg: #eceef1; --vt-dim: #8d949d; --vt-line: #2a2e34; --vt-card: rgba(255,255,255,.03);
  --s3-front: linear-gradient(180deg, #3a3d42 0%, #232528 28%, #16181a 100%); --s3-top: linear-gradient(180deg, #2e3135, #1c1e21); --s3-side: linear-gradient(180deg, #26292d, #121315); --s3-back: #0e0f10;
  --s3-port: #050506; --s3-rim: #454950; --s3-text: #a7adb5; --s3-shadow: rgba(0,0,0,.85); --s3-hl: rgba(255,255,255,.16); }

/* the bottom sheet over the camera */
.cd-dim { position: fixed; inset: 0; z-index: 69; background: rgba(0,0,0,.42); animation: cdfade .3s ease-out both; }
.cd-dim.out { opacity: 0; transition: opacity .26s; }
.cd-sheet2 { position: fixed; left: 0; right: 0; bottom: 0; top: calc(env(safe-area-inset-top, 0px) + 34px); z-index: 70; display: flex; flex-direction: column; border-radius: 26px 26px 0 0;
  background: var(--vt-bg); color: var(--vt-fg); box-shadow: 0 -12px 40px rgba(0,0,0,.35); animation: cdup .55s cubic-bezier(.16,.84,.24,1) both; transition: transform .26s ease-in; }
.cd-sheet2.out { transform: translateY(105%); }
@keyframes cdup { from { transform: translateY(100%); } to { transform: none; } }
@keyframes cdfade { from { opacity: 0; } }
.cd-sheet-top { flex: none; position: relative; height: 38px; touch-action: none; cursor: grab; }
.cd-grab { position: absolute; left: 50%; top: 9px; width: 38px; height: 5px; margin-left: -19px; border-radius: 3px; background: currentColor; opacity: .25; }
.cd-x { position: absolute; right: 14px; top: 8px; width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--vt-line); background: none; color: var(--vt-fg); display: grid; place-items: center; cursor: pointer; }
.cd-sheet-body { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 0 max(18px, env(safe-area-inset-left, 0px)) calc(env(safe-area-inset-bottom, 0px) + 28px); }
.cd-sheet-body > .vt { max-width: 720px; margin: 0 auto; }

/* the card */
.vt { display: flex; flex-direction: column; gap: 12px; color: var(--vt-fg); }
.vt-head { padding: 0 2px; }
.vt-k { font: 500 10.5px/1.3 var(--mono, ui-monospace, monospace); letter-spacing: .14em; text-transform: uppercase; color: var(--vt-dim); }
.vt-head h3 { margin: 6px 0 0; font-size: 23px; font-weight: 650; letter-spacing: -.02em; line-height: 1.15; }
.vt-m { margin-top: 4px; font-size: 13px; color: var(--vt-dim); }
.vt-state { display: inline-flex; align-items: center; gap: 7px; margin-top: 10px; font: 500 11px/1 var(--mono, ui-monospace, monospace); letter-spacing: .08em; text-transform: uppercase; }
.vt-state i { width: 7px; height: 7px; border-radius: 50%; background: var(--text3, #8e8e93); }
.vt-state.online i { background: var(--green); box-shadow: 0 0 8px var(--green); } .vt-state.warning i { background: var(--orange); box-shadow: 0 0 8px var(--orange); } .vt-state.offline i { background: var(--red); box-shadow: 0 0 8px var(--red); }
.vt-ico { height: 150px; display: grid; place-items: center; color: var(--vt-dim); }
.vt-facts { display: grid; grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--vt-line); border-bottom: 1px solid var(--vt-line); }
.vt-facts div { padding: 12px 0; text-align: center; font-variant-numeric: tabular-nums; min-width: 0; }
.vt-facts div + div { border-left: 1px solid var(--vt-line); }
.vt-facts b { display: block; font: 600 17px/1.1 var(--mono, ui-monospace, monospace); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vt-facts span { display: block; margin-top: 4px; font: 500 10px/1 var(--mono, ui-monospace, monospace); letter-spacing: .1em; text-transform: uppercase; color: var(--vt-dim); }
.vt-pop { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 3px 12px; align-items: center; min-height: 64px; padding: 12px 14px; border: 1px solid var(--vt-line); border-radius: 12px; animation: vtpop .22s ease-out; }
.vt-pop.empty { opacity: .55; animation: none; }
.vt-pop .n { grid-row: span 2; width: 40px; height: 40px; border-radius: 9px; display: grid; place-items: center; font: 600 16px/1 var(--mono, ui-monospace, monospace); background: var(--vt-fg); color: var(--vt-solid); }
.vt-pop b { font-size: 15px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vt-pop small { font: 400 12px/1.35 var(--mono, ui-monospace, monospace); color: var(--vt-dim); }
@keyframes vtpop { from { opacity: 0; transform: translateY(4px); } }
.vt .card { background: var(--vt-card); border: 1px solid var(--vt-line); box-shadow: none; border-radius: 14px; -webkit-backdrop-filter: none; backdrop-filter: none; margin: 0; }
.vt .card-title { color: var(--vt-dim); font-family: var(--mono, ui-monospace, monospace); font-size: 10.5px; letter-spacing: .12em; }

/* the device standing up in 3D */
.s3-stage { position: relative; height: 210px; perspective: 1000px; perspective-origin: 50% 30%; touch-action: pan-y; cursor: grab; user-select: none; -webkit-user-select: none; }
.s3-floor { position: absolute; left: 50%; top: 50%; transform-style: preserve-3d; }
.s3-float { transform-style: preserve-3d; animation: s3float 5s ease-in-out 2.2s infinite; }
@keyframes s3float { 50% { transform: translateY(-5px); } }
.s3-box { position: absolute; left: 0; top: 0; transform-style: preserve-3d; transform: rotateX(var(--rx)) rotateY(var(--ry)); transition: transform .9s cubic-bezier(.2,.8,.2,1); }
.s3-box.drag { transition: none; }
.s3-box.rise { animation: s3rise 1.25s cubic-bezier(.18,.82,.22,1) .25s both; }
@keyframes s3rise { 0% { transform: translateY(70px) rotateX(-82deg) rotateY(-4deg) scale(.82); } 100% { transform: rotateX(var(--rx)) rotateY(var(--ry)); } }
.s3-f { position: absolute; left: 0; top: 0; backface-visibility: hidden; }
.s3-front { width: var(--w); height: var(--h); transform: translate(-50%, -50%) translateZ(calc(var(--d) / 2)); display: grid; align-items: center; padding: 0 2.2%; gap: 2.4%;
  background: var(--s3-front); box-shadow: inset 0 1px 0 var(--s3-hl), inset 0 -1px 0 rgba(0,0,0,.25); color: var(--s3-text); overflow: hidden; }
.s3-back { width: var(--w); height: var(--h); transform: translate(-50%, -50%) rotateY(180deg) translateZ(calc(var(--d) / 2)); background: var(--s3-back); }
.s3-top { width: var(--w); height: var(--d); transform: translate(-50%, -50%) rotateX(90deg) translateZ(calc(var(--h) / 2)); background: var(--s3-top); }
.s3-bottom { width: var(--w); height: var(--d); transform: translate(-50%, -50%) rotateX(-90deg) translateZ(calc(var(--h) / 2)); background: var(--s3-back); }
.s3-left { width: var(--d); height: var(--h); transform: translate(-50%, -50%) rotateY(-90deg) translateZ(calc(var(--w) / 2)); background: var(--s3-side); }
.s3-right { width: var(--d); height: var(--h); transform: translate(-50%, -50%) rotateY(90deg) translateZ(calc(var(--w) / 2)); background: var(--s3-side); }
.s3-brand { font: 600 calc(var(--h) * .15)/1.15 var(--mono, ui-monospace, monospace); letter-spacing: .04em; white-space: nowrap; overflow: hidden; }
.s3-brand small { display: block; font-weight: 400; opacity: .65; font-size: .8em; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; }
.s3-ports { display: grid; grid-auto-flow: column; gap: calc(var(--h) * .07) 2.2%; height: 70%; }
.s3-sfp { display: grid; grid-template-columns: repeat(2, 1fr); grid-template-rows: repeat(2, 1fr); grid-auto-flow: column; gap: calc(var(--h) * .07) 6%; height: 62%; }
.s3-p { position: relative; border-radius: 2px; cursor: pointer; padding: 0; border: 0; background: var(--s3-port); box-shadow: inset 0 2px 3px rgba(0,0,0,.8), 0 0 0 1px var(--s3-rim); }
.s3-p::after { content: ""; position: absolute; top: 9%; left: 14%; width: 22%; height: 14%; border-radius: 1px; background: var(--led, transparent); box-shadow: 0 0 6px var(--led, transparent);
  opacity: 0; animation: s3led .35s ease-out forwards; animation-delay: calc(1.3s + var(--i) * 32ms); }
.s3-p.sel { outline: 1.5px solid var(--s3-led); outline-offset: 1px; box-shadow: inset 0 2px 3px rgba(0,0,0,.8), 0 0 10px var(--s3-led); }
@keyframes s3led { to { opacity: 1; } }
.s3-leds { display: grid; gap: calc(var(--h) * .1); justify-items: center; }
.s3-leds i { width: calc(var(--h) * .07); height: calc(var(--h) * .07); border-radius: 50%; background: var(--s3-led); box-shadow: 0 0 6px var(--s3-led); }
.s3-sweep { position: absolute; inset: 0; pointer-events: none; background: linear-gradient(105deg, transparent 35%, var(--s3-hl) 50%, transparent 65%); background-size: 260% 100%; background-position: 160% 0; }
.s3-box.rise .s3-sweep { animation: s3sweep 1.6s 1.35s ease-in-out both; }
@keyframes s3sweep { to { background-position: -60% 0; } }
.s3-shadow { position: absolute; left: 0; top: 0; width: calc(var(--w) * 1.05); height: calc(var(--d) * .9); transform: translate(-50%, -50%) rotateX(90deg) translateZ(calc(var(--h) / -2 - 2px));
  border-radius: 50%; background: var(--s3-shadow); filter: blur(18px); animation: cdfade 1s .8s both; }
.s3-hint { position: absolute; left: 0; right: 0; bottom: 4px; text-align: center; font: 500 10px/1 var(--mono, ui-monospace, monospace); letter-spacing: .12em; text-transform: uppercase; color: var(--vt-dim); opacity: .7; }

/* the device's own photo with invisible port buttons */
.ph-stage { display: flex; justify-content: center; padding: 14px 0 6px; }
.ph-wrap { position: relative; display: inline-block; max-width: 100%; animation: phrise .9s cubic-bezier(.18,.82,.22,1) .15s both; }
.ph-wrap img { display: block; max-width: 100%; max-height: 42vh; filter: drop-shadow(0 18px 22px var(--s3-shadow)); -webkit-user-select: none; user-select: none; }
@keyframes phrise { from { opacity: 0; transform: translateY(40px) scale(.94); } }
.ph-spot { position: absolute; border: 0; padding: 0; background: transparent; border-radius: 4px; cursor: pointer; animation: phhint 2.2s 1s ease-out both; }
@keyframes phhint { 0% { box-shadow: inset 0 0 0 1.5px transparent; } 30% { box-shadow: inset 0 0 0 1.5px var(--s3-led); } 100% { box-shadow: inset 0 0 0 1.5px transparent; } }
.ph-spot.sel { animation: none; background: color-mix(in srgb, var(--s3-led) 20%, transparent); box-shadow: 0 0 0 2px var(--s3-led), 0 0 14px var(--s3-led); }

/* the editor in Rack Live */
.pe-drop { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 34px 16px; border: 1.5px dashed var(--line2); border-radius: 16px; background: var(--fill); color: var(--text); font: inherit; cursor: pointer; text-align: center; }
.pe-drop b { font-size: 16px; } .pe-drop small { color: var(--text2); font-size: 12.5px; max-width: 46ch; line-height: 1.45; }
.pe-stage { display: flex; justify-content: center; padding: 22px 8px 10px; border-radius: 14px; background: repeating-conic-gradient(var(--fill) 0% 25%, transparent 0% 50%) 50% / 18px 18px; }
.pe-wrap { position: relative; display: inline-block; max-width: 100%; cursor: crosshair; touch-action: none; }
.pe-wrap img { display: block; max-width: 100%; max-height: 55vh; -webkit-user-select: none; user-select: none; pointer-events: none; }
.pe-spot { position: absolute; padding: 0; border: 2px solid var(--accent); border-radius: 4px; background: color-mix(in srgb, var(--accent) 18%, transparent); cursor: move; touch-action: none; }
.pe-spot span { position: absolute; left: 50%; bottom: calc(100% + 3px); transform: translateX(-50%); font: 600 10.5px/1 var(--mono, ui-monospace, monospace); background: var(--accent); color: #fff; padding: 2px 5px; border-radius: 6px; pointer-events: none; }
.pe-spot.on { border-color: #fff; box-shadow: 0 0 0 2px var(--accent), 0 0 12px var(--accent); }
.pe-bar { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }
.pe-sel { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; } .pe-sel .input { flex: 1; min-width: 180px; }
@media (prefers-reduced-motion: reduce) { .s3-box.rise, .s3-p::after, .s3-float, .ph-wrap, .cd-sheet2, .ph-spot { animation-duration: .01s !important; animation-delay: 0s !important; } }
/* 3D models (rackd/models.py): faces, ports of one real size, LEDs, text, vents, extra blocks */
.m3-stage { --m3-slot: rgba(0,0,0,.32); }
.m3-f { position: absolute; left: 0; top: 0; backface-visibility: hidden; overflow: hidden; box-shadow: inset 0 1px 0 var(--s3-hl), inset 0 -1px 0 rgba(0,0,0,.18); }
.m3-f::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(180deg, rgba(255,255,255,.07), rgba(0,0,0,.07)); }
.m3-top::after { background: linear-gradient(180deg, rgba(255,255,255,.12), rgba(255,255,255,0)); } .m3-left::after, .m3-right::after { background: rgba(0,0,0,.1); } .m3-bottom::after, .m3-back::after { background: rgba(0,0,0,.08); }
.m3-port { position: absolute; padding: 0; border: 0; border-radius: 1.5px; background: var(--s3-port); box-shadow: inset 0 2px 3px rgba(0,0,0,.8), 0 0 0 1px var(--s3-rim); cursor: pointer; z-index: 1; }
.m3-port::after { content: ""; position: absolute; top: 9%; left: 12%; width: 22%; height: 15%; border-radius: 1px; background: var(--led, transparent); box-shadow: 0 0 6px var(--led, transparent);
  opacity: 0; animation: s3led .35s ease-out forwards; animation-delay: calc(1.3s + var(--i, 0) * 32ms); }
.m3-port.dead { cursor: default; } .m3-port.dead::after { display: none; } .m3-port.power, .m3-port.coax { border-radius: 50%; } .m3-port.usb { border-radius: 1px; }
.m3-port.sel { outline: 1.5px solid var(--s3-led); outline-offset: 1px; box-shadow: inset 0 2px 3px rgba(0,0,0,.8), 0 0 10px var(--s3-led); }
.m3-led { position: absolute; border-radius: 50%; background: color-mix(in srgb, var(--c) 22%, #000); z-index: 1; } .m3-led.on { background: var(--c); box-shadow: 0 0 6px var(--c); }
.m3-text { position: absolute; line-height: 1; white-space: nowrap; font-family: var(--mono, ui-monospace, monospace); color: var(--s3-text); letter-spacing: .03em; z-index: 1; }
.m3-rect { position: absolute; background: rgba(0,0,0,.15); } .m3-circle { position: absolute; border-radius: 50%; background: rgba(0,0,0,.22); box-shadow: inset 0 1px 1px rgba(255,255,255,.3); }
.m3-vent { position: absolute; }
.m3-part { position: absolute; left: 0; top: 0; transform-style: preserve-3d; }
.m3-tools { position: absolute; right: 2px; top: 2px; display: flex; gap: 6px; z-index: 3; }
.m3-tool { display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 10px; border-radius: 15px; border: 1px solid var(--vt-line); background: var(--vt-card); color: var(--vt-fg); font: 600 11.5px/1 var(--mono, ui-monospace, monospace); cursor: pointer; }
.m3-tool.pri { background: var(--vt-fg); color: var(--vt-solid); border-color: transparent; }
.m3-preview { border-radius: 14px; background: var(--vt-bg); color: var(--vt-fg); border: 1px solid var(--line); overflow: hidden; }
.m3-add { display: flex; flex-direction: column; gap: 10px; padding: 12px; border-radius: 14px; background: var(--fill); }
.m3-add textarea { font-size: 12.5px; min-height: 140px; }
.m3-guide { white-space: pre-wrap; word-break: break-word; font: 12px/1.5 var(--mono, ui-monospace, monospace); max-height: 52vh; overflow: auto; background: var(--fill); padding: 12px; border-radius: 10px; margin: 0; -webkit-user-select: text; user-select: text; }
.plug-row.on { box-shadow: inset 0 0 0 1.5px var(--accent); }
.m3-mark { position: absolute; padding: 0; border: 0; background: transparent; border-radius: 2px; cursor: pointer; z-index: 2; animation: phhint 2.2s 1.2s ease-out both; }
.m3-mark::after { content: ""; position: absolute; top: 9%; left: 12%; width: 22%; height: 15%; border-radius: 1px; background: var(--led, transparent); box-shadow: 0 0 6px var(--led, transparent); opacity: 0; animation: s3led .35s ease-out forwards; animation-delay: calc(1.3s + var(--i, 0) * 32ms); }
.m3-mark.sel { animation: none; box-shadow: 0 0 0 1.5px var(--s3-led), 0 0 10px var(--s3-led); }
.m3-flat-stage { display: flex; justify-content: center; padding: 24px 12px 12px; margin-top: 10px; border-radius: 14px; background: var(--vt-bg); overflow: hidden; }
.m3-face-flat { position: relative; flex: none; cursor: crosshair; touch-action: none; box-shadow: 0 14px 30px -12px rgba(0,0,0,.45), inset 0 1px 0 var(--s3-hl); }
/* the magnifier above the finger while placing a mark */
.lp { position: fixed; width: 132px; height: 132px; border-radius: 50%; overflow: hidden; z-index: 10000; pointer-events: none; border: 3px solid #fff; background: #0c0d0f;
  box-shadow: 0 10px 28px rgba(0,0,0,.55), 0 0 0 1px rgba(0,0,0,.2); }
.lp-in { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.lp-x { position: absolute; left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%; border: 1.5px solid var(--accent); box-shadow: 0 0 0 1px rgba(255,255,255,.6); }
.lp-x::before, .lp-x::after { content: ""; position: absolute; background: var(--accent); }
.lp-x::before { left: 50%; top: -7px; bottom: -7px; width: 1.5px; margin-left: -.75px; } .lp-x::after { top: 50%; left: -7px; right: -7px; height: 1.5px; margin-top: -.75px; }
.pe-spot { pointer-events: none; } .pe-spot.ghost { border-style: dashed; background: color-mix(in srgb, var(--accent) 30%, transparent); }
.pe-spot span { font-size: 11.5px; padding: 2px 6px; }
.pe-wrap, .m3-face-flat { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }

/* ══ «Test»: the «Витрина» language for the whole app (on top of «Контроллер»: <html data-skin="net" data-look="test">).
   Strict and flat: black aluminium in the dark theme, white aluminium in the light one; hairlines instead of shadows, mono uppercase labels,
   monochrome device icons, primary buttons and selected tabs inverted (text colour on the background colour). Accent only for focus, links, switches. ══ */
[data-look="test"] { --r: 12px; --r-lg: 16px;
  --bg: #e9ebee; --bg2: #f4f5f7; --card: #f7f8f9; --card-solid: #f7f8f9; --elev: #fbfbfc; --text: #15171a; --text2: #5b6168; --text3: #8d939b;
  --line: #d4d8de; --line2: #c3c8cf; --fill: #e2e5e9; --fill2: #d5d9de; --dock: #f4f5f7; --glass: #f7f8f9; --glass-line: #d4d8de; --dock-glass: #f4f5f7; --fr-btn: #e2e5e9;
  --t-inv: #f7f8f9; --t-hl: rgba(255,255,255,.9); --t-bg: linear-gradient(180deg, #f3f4f6 0%, #e4e6ea 100%);
  --orange: #e2a30b; --purple: #3d6fd8; --port-o: #e2b93b;
  --faceplate-bg: linear-gradient(180deg, #ffffff 0%, #eef0f2 30%, #dfe2e6 100%); --port-bg: #23262a; --port-border: #b9bec5; --port-base: #23262a;
  --rack-bg: linear-gradient(180deg, #fbfbfc, #e3e6ea); --rack-body: #cfd3d9; --unit-bg: linear-gradient(180deg, #ffffff 0%, #eef0f2 40%, #e2e5e9 100%); --unit-icon-bg: rgba(0,0,0,.05); --rack-icon: #3b4047;
  --unit-shadow: inset 0 1px 0 #fff, inset 0 -1px 0 rgba(0,0,0,.08), 0 0 0 1px #cfd3d9;
  --map-rack-frame: #f7f8f9; --map-rack-stroke: #c3c8cf; --map-unit: #e9ebee; --map-unit-stroke: #c3c8cf; }
[data-look="test"][data-theme="dark"] {
  --bg: #090a0b; --bg2: #101113; --card: #111214; --card-solid: #111214; --elev: #16171a; --text: #eceef1; --text2: #9aa1aa; --text3: #656c75;
  --line: #22252a; --line2: #30343a; --fill: #1a1c1f; --fill2: #25282c; --dock: #0d0e10; --glass: #111214; --glass-line: #22252a; --dock-glass: #0d0e10; --fr-btn: #1a1c1f;
  --t-inv: #0b0c0e; --t-hl: rgba(255,255,255,.05); --t-bg: linear-gradient(180deg, #141518 0%, #08090a 100%);
  --orange: #e2b93b; --purple: #3d8bff; --port-o: #e2b93b;
  --faceplate-bg: linear-gradient(180deg, #3a3d42 0%, #232528 28%, #16181a 100%); --port-bg: #050506; --port-border: #454950; --port-base: #050506;
  --rack-bg: linear-gradient(180deg, #2a2d31, #15171a); --rack-body: #08090a; --unit-bg: linear-gradient(180deg, #34373c 0%, #212327 30%, #17191b 100%); --unit-icon-bg: rgba(255,255,255,.06); --rack-icon: #c9ced5;
  --unit-shadow: inset 0 1px 0 rgba(255,255,255,.12), inset 0 -1px 0 rgba(0,0,0,.6), 0 0 0 1px #000;
  --map-rack-frame: #111214; --map-rack-stroke: #30343a; --map-unit: #1a1c1f; --map-unit-stroke: #30343a; }
[data-look="test"]:not([data-accent]) { --accent: #1f6feb; } [data-look="test"][data-theme="dark"]:not([data-accent]) { --accent: #3d8bff; }

/* the ground: a soft studio gradient instead of a flat fill */
[data-look="test"] .app-bg, [data-look="test"] body { background: var(--t-bg); background-attachment: fixed; }
/* panels: flat, a hairline and a faint top light — no blur, no drop shadows */
[data-look="test"] .card, [data-look="test"] .wg-in, [data-look="test"] .modal, [data-look="test"] .sheet { background: var(--card); border: 1px solid var(--line); box-shadow: inset 0 1px 0 var(--t-hl);
  -webkit-backdrop-filter: none; backdrop-filter: none; }
[data-look="test"] .wg.size-S .wg-in, [data-look="test"] .wg[class*="tone-"] .wg-in { background: var(--card); }
[data-look="test"] .wg-in { border-radius: 18px; }
[data-look="test"] .card { border-radius: 14px; }
[data-look="test"] .modal, [data-look="test"] .sheet { background: var(--elev); }
[data-look="test"] .overlay { background: rgba(0,0,0,.55); }
/* top bar and dock: solid, hairline, no glass */
[data-look="test"] .topbar::before, [data-look="test"] .bottombar::before, [data-look="test"]:not([data-glass="off"]) .bottombar::before { background: var(--dock); border: 1px solid var(--line);
  -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; }
[data-look="test"] .bottombar::after, [data-look="test"] .topbar::after { display: none; }
/* labels: mono, uppercase, wide tracking */
[data-look="test"] .card-title, [data-look="test"] .dim3[style*="uppercase"], [data-look="test"] .cd-h { font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: .14em; color: var(--text2); }
[data-look="test"] .badge { font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: .06em; text-transform: uppercase; border-radius: 6px; background: transparent; border: 1px solid var(--line2); }
[data-look="test"] .badge .dot { box-shadow: 0 0 6px currentColor; }
[data-look="test"] .page-title, [data-look="test"] h1, [data-look="test"] h2 { letter-spacing: -.02em; font-weight: 650; }
[data-look="test"] .stat .k, [data-look="test"] .kv > div:nth-child(odd) { font-family: var(--mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; }
[data-look="test"] .stat .v { font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
/* buttons, tabs, segments: strict; the primary one and the selected tab are inverted */
[data-look="test"] .btn { border-radius: 10px; background: transparent; border: 1px solid var(--line2); }
[data-look="test"] .btn:hover { background: var(--fill); }
[data-look="test"] .btn.primary { background: var(--text); color: var(--t-inv); border-color: var(--text); }
[data-look="test"] .btn.primary:hover { background: color-mix(in srgb, var(--text) 86%, var(--bg)); }
[data-look="test"] .btn.danger { background: transparent; border-color: color-mix(in srgb, var(--red) 45%, transparent); }
[data-look="test"] .btn.ghost { border-color: transparent; }
[data-look="test"] .seg, [data-look="test"] .tabs { background: var(--fill); border: 1px solid var(--line); border-radius: 11px; }
[data-look="test"] .seg button.on, [data-look="test"] .tab.on, [data-look="test"] .tabs button.on { background: var(--text); color: var(--t-inv); box-shadow: none; }
[data-look="test"] .bottombar button.on { background: var(--fill); color: var(--text); }
[data-look="test"] .round-btn, [data-look="test"] .hdr-more { background: transparent; border: 1px solid var(--line2); }
[data-look="test"] .input { border-radius: 10px; background: var(--bg2); border: 1px solid var(--line); }
[data-look="test"] .input:focus { border-color: var(--accent); }
/* lists and rows */
[data-look="test"] .plug-row, [data-look="test"] .plug-dev { background: transparent; border: 1px solid var(--line); border-radius: 12px; }
[data-look="test"] .plug-row:hover { background: var(--fill); }
[data-look="test"] .li { border-color: var(--line); }
/* icons: monochrome tiles (the settings list, the kind icons get their colour from kindColor) */
[data-look="test"] .set-ic { background: var(--fill2) !important; border: 1px solid var(--line2); }
[data-look="test"] .set-ic svg { stroke: var(--text); }
[data-look="test"] .kind-ic { box-shadow: inset 0 0 0 1px var(--line2); }
[data-look="test"] .ico-circle { background: transparent; border: 1px solid var(--line2); }
/* the rack: aluminium, units like the 3D models */
[data-look="test"] .rack { border: 1px solid var(--line2); box-shadow: inset 0 1px 0 var(--t-hl); }
[data-look="test"] .unit { border-radius: 4px; }
/* hints and toasts: plain */
[data-look="test"] .hint-box { background: var(--card); border: 1px solid var(--line); color: var(--text); }
[data-look="test"] .toast { background: var(--text); color: var(--t-inv); border-radius: 12px; }
/* the preview tile in Settings → Оформление */
.look-prev[data-look="test"] { background: var(--t-bg); }
.look-prev[data-look="test"] .lp-card { background: var(--card); border: 1px solid var(--line); box-shadow: none; }
.look-prev[data-look="test"] .lp-btn { background: var(--text); color: var(--t-inv); border-radius: 8px; }
/* «Test»: a card inside a widget is the widget itself — one frame, not two; the header tabs inverted like the rest */
[data-look="test"] .wg-body > .card, [data-look="test"] .wg-full > .card { background: none; border: 0; box-shadow: none; }
html[data-look="test"] .tabs .tab.on { background: var(--text); color: var(--t-inv); box-shadow: none; }
html[data-look="test"] .chip.on, html[data-look="test"] .place-opt.on, html[data-look="test"] .sheet-tabs button.on { background: var(--text); color: var(--t-inv); border-color: var(--text); }
html[data-look="test"] .chip { border: 1px solid var(--line2); background: transparent; }
.vt-inline { border-radius: 14px; background: var(--t-bg, var(--vt-bg)); border: 1px solid var(--line); margin-bottom: 10px; color: var(--text); }
/* «Test», everything in one language: no decorative colour — rack strips, widget tiles and miniatures, map lines, room tags, hints */
.vt-inline { position: relative; }
.vt-inline.empty { min-height: 0; }
.vt-look { position: absolute; left: 10px; top: 10px; z-index: 3; }
html[data-look="test"] .unit .strip { background: var(--line2) !important; }
html[data-look="test"] .wg { --tc: var(--text2); --tone: var(--text2); }
html[data-look="test"] .wg-tile-ic { background: var(--fill2) !important; border: 1px solid var(--line2); }
html[data-look="test"] .wg-tile-ic svg { stroke: var(--text) !important; }
html[data-look="test"] .wg-tile-art, html[data-look="test"] .wg-tile-big, html[data-look="test"] .mini-svg, html[data-look="test"] .mini-bars, html[data-look="test"] .mini-kinds,
html[data-look="test"] .mini-dots, html[data-look="test"] .mini-pair, html[data-look="test"] .mini-faces, html[data-look="test"] .mini-events { filter: grayscale(1) contrast(1.05); }
html[data-look="test"] .wg-tile-v, html[data-look="test"] .mini-num { font-family: var(--mono); letter-spacing: -.02em; }
html[data-look="test"] .edge:not(.flow) { stroke: color-mix(in srgb, var(--text) 42%, transparent); }
html[data-look="test"] .edge.isp { stroke: var(--text); }
html[data-look="test"] .room-tag { fill: var(--fill2); stroke: var(--line2); } html[data-look="test"] .room-tag-t { fill: var(--text); }
html[data-look="test"] .hint-ico { background: transparent !important; color: var(--text2) !important; border: 1px solid var(--line2); }
html[data-look="test"] .hint-box b { font-family: var(--mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; }
html[data-look="test"] .stat { background: var(--card); border: 1px solid var(--line); }
html[data-look="test"] .bar i { background: var(--text); }
html[data-look="test"] .bar.warn i { background: var(--orange); } html[data-look="test"] .bar.bad i { background: var(--red); }
html[data-look="test"] .faceplate { border: 1px solid var(--line2); box-shadow: inset 0 1px 0 var(--t-hl); }
html[data-look="test"] .legend i { filter: grayscale(.6); }
html[data-look="test"] .look-dot.on { box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--text); }
html[data-look="test"] .map-cross rect { fill: var(--text); } html[data-look="test"] .map-cross text { fill: var(--t-inv); }
html[data-look="test"] .map-poe rect { fill: var(--card); stroke: var(--line2); } html[data-look="test"] .map-poe text { fill: var(--text); font-family: var(--mono); }
html[data-look="test"] .port-pill rect { fill: var(--card); stroke: var(--line2); }
html[data-look="test"] .spark path { stroke: var(--text2); fill: var(--text2); }
html[data-look="test"] .stat.warn, html[data-look="test"] .stat.bad { border-color: color-mix(in srgb, var(--orange) 50%, var(--line)); }
/* «Test» — the shapes too: an instrument-panel look. Bars attached to the edges (no floating capsules), squared tiles, buttons with mono
   capitals, thin strokes, a strict toggle; the open tab of the dock is marked by a line at its top edge, like an indicator on a front panel */
html[data-look="test"] .topbar { border-radius: 0; }
html[data-look="test"] .topbar::before { border-radius: 0; border-width: 0 0 1px 0 !important; }
html[data-look="test"] .tabs { background: transparent; border: 0; gap: 4px; padding: 0; }
html[data-look="test"] .tab { border-radius: 7px; font-family: var(--mono); font-size: 11.5px; font-weight: 500; letter-spacing: .08em; text-transform: uppercase; padding: 8px 12px; }
html[data-look="test"] .tab .count, html[data-look="test"] .bottombar .count { border-radius: 4px; font-family: var(--mono); }
html[data-look="test"] .bottombar { left: 0; right: 0; margin-bottom: 0; border-radius: 0; gap: 0;
  padding: 0 calc(env(safe-area-inset-right) + 6px) calc(env(safe-area-inset-bottom) + 4px) calc(env(safe-area-inset-left) + 6px); }
html[data-look="test"] .bottombar::before, html[data-look="test"]:not([data-glass="off"]) .bottombar::before { border-radius: 0; border-width: 1px 0 0 0 !important; background: var(--dock) !important; }
html[data-look="test"] .bottombar button { border-radius: 0; font-family: var(--mono); font-size: 9.5px; font-weight: 500; letter-spacing: .08em; text-transform: uppercase; color: var(--text3); padding: 11px 0 7px; }
html[data-look="test"] .bottombar button.on { background: transparent; color: var(--text); }
html[data-look="test"] .bottombar button.on svg { filter: none; }
html[data-look="test"] .bottombar button.on::before { content: ""; position: absolute; top: 0; left: 26%; right: 26%; height: 2px; background: var(--text); }
html[data-look="test"] .bottombar button:active { transform: none; opacity: .55; }
@media (max-width: 760px) { html[data-look="test"] main.page { padding-bottom: calc(env(safe-area-inset-bottom) + 92px); } }
html[data-look="test"] .btn { border-radius: 8px; font-family: var(--mono); font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; padding: 9px 14px; }
html[data-look="test"] .btn.sm { font-size: 11px; padding: 6px 10px; border-radius: 7px; }
html[data-look="test"] .btn:active { transform: none; opacity: .7; }
html[data-look="test"] .seg, html[data-look="test"] .tabs.seg { border-radius: 8px; }
html[data-look="test"] .seg button { border-radius: 6px; font-family: var(--mono); font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; }
html[data-look="test"] .chip, html[data-look="test"] .place-opt { border-radius: 7px; font-family: var(--mono); font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; }
html[data-look="test"] .round-btn, html[data-look="test"] .hdr-more, html[data-look="test"] .cd-x, html[data-look="test"] .m3-tool { background: transparent; border: 1px solid var(--line2); box-shadow: none; }
html[data-look="test"] .round-btn.on { background: var(--text); color: var(--t-inv); border-color: var(--text); }
html[data-look="test"] .kind-ic, html[data-look="test"] .set-ic, html[data-look="test"] .ios-ico, html[data-look="test"] .ios-ico .set-ic, html[data-look="test"] .ico-circle, html[data-look="test"] .wg-tile-ic,
html[data-look="test"] .uicon, html[data-look="test"] .brand-logo { border-radius: 6px !important; }
html[data-look="test"] :is(.btn, .tab, .bottombar, .kind-ic, .set-ic, .ico-circle, .round-btn, .hdr-more, .wg-tile-ic, .seg, .chip, .uicon, .m3-tool) svg { stroke-width: 1.5px; }
html[data-look="test"] .switch { border-radius: 6px; width: 44px; height: 26px; background: var(--fill2); box-shadow: inset 0 0 0 1px var(--line2); }
html[data-look="test"] .switch::after { border-radius: 4px; width: 20px; height: 20px; top: 3px; left: 3px; box-shadow: 0 1px 2px rgba(0,0,0,.3); }
html[data-look="test"] .switch.on { background: var(--text); box-shadow: none; } html[data-look="test"] .switch.on::after { transform: translateX(18px); background: var(--t-inv); }
html[data-look="test"] .input, html[data-look="test"] select.input, html[data-look="test"] textarea.input { border-radius: 8px; }
html[data-look="test"] .modal { border-radius: 16px; } html[data-look="test"] .card { border-radius: 12px; } html[data-look="test"] .wg-in { border-radius: 14px; }
html[data-look="test"] .badge { border-radius: 4px; }
html[data-look="test"] .stat { border-radius: 10px; }
html[data-look="test"] .hint-box, html[data-look="test"] .hint-ico { border-radius: 8px; }
html[data-look="test"] .hint-close { border-radius: 7px; font-family: var(--mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; }
html[data-look="test"] .set-item, html[data-look="test"] .ios-cell { border-radius: 8px; }
html[data-look="test"] .set-item.on, html[data-look="test"] .ios-cell.on { background: var(--fill); box-shadow: inset 2px 0 0 var(--text); }

/* ══ «Test»: no dock, no top tabs — a menu button where the logo was, the side menu; the tools of the header live in the menu ══ */
html[data-look="test"] .bottombar, html[data-look="test"] .topbar .tabs, html[data-look="test"] .topbar .hdr-tools, html[data-look="test"] .topbar .hdr-more,
html[data-look="test"] .topbar .brand .app-ic-c, html[data-look="test"] .topbar .brand .app-ic-g, html[data-look="test"] .topbar .brand .app-ic-n,
html[data-look="test"] .topbar .brand > img { display: none !important; }
@media (max-width: 760px) { html[data-look="test"] main.page { padding-bottom: calc(env(safe-area-inset-bottom) + 32px); } }
.tl-burger { width: 40px; height: 40px; flex: none; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 4px; border: 1px solid var(--line2); border-radius: 8px;
  background: transparent; cursor: pointer; padding: 0; }
.tl-burger i { display: block; width: 16px; height: 1.6px; background: var(--text); transition: transform .2s; }
.tl-burger i:nth-child(2) { width: 11px; margin-right: 5px; }
.tl-burger:active { opacity: .6; }
.tl-nav-wrap { position: fixed; inset: 0; z-index: 400; background: rgba(0,0,0,.45); animation: tlfade .25s ease-out both; }
.tl-nav-wrap.out { opacity: 0; transition: opacity .22s; }
.tl-nav { position: absolute; left: 0; top: 0; bottom: 0; width: min(330px, 86vw); display: flex; flex-direction: column; gap: 4px; overflow-y: auto;
  padding: calc(env(safe-area-inset-top) + 14px) 14px calc(env(safe-area-inset-bottom) + 14px) calc(env(safe-area-inset-left) + 14px);
  background: var(--t-bg, var(--bg)); border-right: 1px solid var(--line2); box-shadow: 20px 0 60px rgba(0,0,0,.35); color: var(--text);
  animation: tlin .34s cubic-bezier(.16,.84,.24,1) both; transition: transform .22s ease-in; touch-action: pan-y; }
.tl-nav.out { transform: translateX(-105%); }
@keyframes tlin { from { transform: translateX(-100%); } } @keyframes tlfade { from { opacity: 0; } }
.tl-nav-head { display: flex; align-items: center; gap: 10px; padding: 4px 2px 14px; border-bottom: 1px solid var(--line); margin-bottom: 8px; }
.tl-nav-head b { font-size: 16px; font-weight: 650; letter-spacing: -.01em; }
.tl-x { width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--line2); background: none; color: var(--text); display: grid; place-items: center; cursor: pointer; flex: none; }
.tl-nav-k { font: 500 10px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--text3); padding: 12px 4px 6px; }
.tl-nav-list { display: flex; flex-direction: column; gap: 2px; }
.tl-nav-item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 13px 10px; border: 0; border-radius: 8px; background: transparent; color: var(--text2); cursor: pointer;
  font: 600 13px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; text-align: left; animation: tlitem .4s cubic-bezier(.16,.84,.24,1) both; animation-delay: calc(.08s + var(--i) * 45ms); }
@keyframes tlitem { from { opacity: 0; transform: translateX(-14px); } }
.tl-nav-item:hover { background: var(--fill); color: var(--text); }
.tl-nav-item.on { color: var(--text); background: var(--fill); box-shadow: inset 2px 0 0 var(--text); }
.tl-nav-item > svg:last-child { opacity: .35; }
.tl-led { width: 6px; height: 6px; border-radius: 50%; background: var(--fill2); box-shadow: inset 0 0 0 1px var(--line2); flex: none; }
.tl-nav-item.on .tl-led { background: var(--accent); box-shadow: 0 0 8px var(--accent); }
.tl-count { font: 600 10.5px/1 var(--mono); padding: 3px 6px; border-radius: 4px; background: var(--red); color: #fff; }
.tl-nav-pad { padding: 0 4px; } .tl-nav-pad .seg { width: 100%; } .tl-nav-pad .seg button { flex: 1; justify-content: center; }
.tl-nav-row { display: flex; align-items: center; gap: 10px; padding: 10px 6px; font-size: 14px; }
.tl-nav-tools { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding: 0 4px; }
.tl-nav-tools button { display: flex; align-items: center; gap: 10px; padding: 10px; border: 1px solid var(--line); border-radius: 8px; background: transparent; color: var(--text); cursor: pointer;
  font: 600 11px/1.2 var(--mono); letter-spacing: .06em; text-transform: uppercase; text-align: left; min-height: 50px; }
.tl-nav-tools button:hover { background: var(--fill); }
.tl-nav-foot { display: flex; align-items: center; justify-content: space-between; padding: 14px 4px 0; margin-top: 10px; border-top: 1px solid var(--line); }

/* ══ instruments ══ */
.dial { position: relative; display: inline-flex; flex-direction: column; align-items: center; flex: none; }
.dial svg { width: 100%; display: block; overflow: visible; }
.dial-track { fill: none; stroke: var(--fill2); stroke-width: 3; stroke-linecap: round; }
.dial-zone { fill: none; stroke-width: 1.6; opacity: .75; }
.dial-fill { fill: none; stroke: var(--text); stroke-width: 3; stroke-linecap: round; transition: stroke-dasharray 1.2s; }
.dial .tk { stroke: var(--text3); stroke-width: .8; } .dial .tk.big { stroke: var(--text2); stroke-width: 1.3; }
.dial-needle { transition: transform 1.3s cubic-bezier(.3,1.4,.4,1); } .dial-needle path { fill: var(--accent); filter: drop-shadow(0 0 3px color-mix(in srgb, var(--accent) 60%, transparent)); }
.dial-hub { fill: var(--card); stroke: var(--line2); stroke-width: 1.2; } .dial-hub2 { fill: var(--text); }
.dial-v { margin-top: -18%; font: 600 clamp(15px, 2.2vw, 22px)/1 var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.dial-v small { font-size: .5em; margin-left: 3px; color: var(--text2); font-weight: 500; }
.dial-k { margin-top: 6px; font: 500 10px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text2); }
.dial-s { margin-top: 3px; font: 400 10.5px/1 var(--mono); color: var(--text3); }
html[data-look="test"] .state-tile { flex-direction: column; text-align: center; align-items: center; gap: 2px; }
html[data-look="test"] .state-tile .dial-v { font-size: 18px; }
.inet-dials { display: flex; align-items: flex-end; justify-content: space-around; gap: 10px; flex-wrap: wrap; cursor: pointer; padding: 4px 0; }
.inet-ping { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; padding-bottom: 14px; }
.ro-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 8px; container-type: inline-size; }
.ro { padding: 12px 12px 11px; border: 1px solid var(--line); border-radius: 10px; background: var(--card); box-shadow: inset 0 1px 0 var(--t-hl, transparent); min-width: 0; }
.ro-k { font: 500 10px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text2); }
.ro-v { margin-top: 8px; font: 600 24px/1 var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -.03em; white-space: nowrap; }
.ro-v small { font-size: .5em; margin-left: 3px; color: var(--text2); font-weight: 500; }
.ro.warn .ro-v { color: var(--orange); }
.ro-seg { display: grid; grid-template-columns: repeat(10, 1fr); gap: 2px; margin-top: 10px; }
.ro-seg i { height: 5px; border-radius: 1px; background: var(--fill2); }
.ro-seg i.on { background: var(--text); animation: segon .3s ease-out both; animation-delay: calc(.2s + var(--i) * 50ms); }
.ro.warn .ro-seg i.on { background: var(--orange); box-shadow: 0 0 6px color-mix(in srgb, var(--orange) 60%, transparent); }
@keyframes segon { from { opacity: 0; transform: scaleY(.3); } }
.led-row { display: flex; gap: 3px; flex-wrap: nowrap; justify-content: space-between; }
.led-row i { flex: 1 1 0; max-width: 14px; aspect-ratio: 1; border-radius: 2px; background: var(--fill2); box-shadow: inset 0 0 0 1px var(--line); }
.led-row i.on { background: var(--c); box-shadow: 0 0 6px color-mix(in srgb, var(--c) 55%, transparent); animation: ledon .25s ease-out both; animation-delay: calc(.15s + var(--i) * 28ms); }
@keyframes ledon { from { opacity: 0; } 60% { opacity: 1; filter: brightness(1.8); } }
.up-leds { cursor: pointer; margin-bottom: 10px; }
.dev-matrix { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.dev-cell { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; background: transparent; color: var(--text); cursor: pointer;
  font: 500 12px/1.2 var(--mono); text-align: left; min-width: 0; animation: tlitem .35s ease-out both; animation-delay: calc(var(--i) * 30ms); }
.dev-cell:hover { background: var(--fill); }
.dev-led { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--c); }
.dev-led.on { box-shadow: 0 0 7px var(--c); }

/* ══ Frank: a lens in a metal ring; the pupil follows the finger, the iris glows by mood ══ */
.flens { position: relative; flex: none; perspective: 240px; }
.flens-body { position: absolute; inset: 0; transform-style: preserve-3d; transform: rotateX(calc(var(--py) * -16deg)) rotateY(calc(var(--px) * 16deg)); transition: transform .25s ease-out; }
.flens-ring { position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(from 210deg, #8d939b, #f4f6f8 18%, #6b7179 36%, #d9dde2 55%, #4c5157 72%, #c8ccd2 88%, #8d939b);
  box-shadow: 0 3px 8px rgba(0,0,0,.45), inset 0 0 0 1px rgba(0,0,0,.35); }
.flens-glass { position: absolute; inset: 13%; border-radius: 50%; overflow: hidden;
  background: radial-gradient(circle at 50% 50%, #0d1218 0 40%, #04070a 75%); box-shadow: inset 0 2px 6px rgba(0,0,0,.9), inset 0 0 0 1px rgba(255,255,255,.08); transform: translateZ(4px); }
.flens-iris { --ic: #3cc8ff; position: absolute; left: 50%; top: 50%; width: 58%; height: 58%; margin: -29% 0 0 -29%; border-radius: 50%;
  transform: translate(calc(var(--px) * 22%), calc(var(--py) * 22%)); transition: transform .18s ease-out;
  background: radial-gradient(circle, transparent 0 34%, color-mix(in srgb, var(--ic) 90%, #fff) 36%, var(--ic) 48%, color-mix(in srgb, var(--ic) 40%, #000) 70%, transparent 72%),
    repeating-conic-gradient(from 0deg, rgba(255,255,255,.12) 0 6deg, transparent 6deg 12deg);
  box-shadow: 0 0 calc(var(--glow, 6) * 1px) var(--ic); }
.flens-pupil { position: absolute; inset: 33%; border-radius: 50%; background: #000; box-shadow: 0 0 0 1px rgba(0,0,0,.6); }
.flens-hl { position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: radial-gradient(ellipse 45% 30% at 34% 24%, rgba(255,255,255,.55), transparent 70%), radial-gradient(circle at 70% 78%, rgba(255,255,255,.12), transparent 30%); }
.flens-lid { position: absolute; inset: 0; background: #0a0d11; transform-origin: top; transform: scaleY(0); animation: flblink 6s 2s infinite; }
@keyframes flblink { 0%, 94%, 100% { transform: scaleY(0); } 96.5% { transform: scaleY(1); } }
.flens.m1 .flens-iris { --ic: #4c9dff; --glow: 9; }
.flens.m2 .flens-iris { --ic: #f3b52c; --glow: 11; }
.flens.m3 .flens-iris { --ic: #ff4d45; --glow: 14; animation: flpulse .8s ease-in-out infinite; }
.flens.m3 .flens-body { animation: fltremble .25s linear infinite; }
@keyframes flpulse { 50% { filter: brightness(1.5); } } @keyframes fltremble { 50% { transform: translateX(.5px); } }
@media (prefers-reduced-motion: reduce) { .tl-nav, .tl-nav-item, .ro-seg i.on, .led-row i.on, .dev-cell, .flens-lid, .flens.m3 .flens-iris, .flens.m3 .flens-body { animation: none !important; } .dial-needle { transition: none; } }
html[data-look="test"] .state-tile > div:last-child { width: 100%; min-width: 0; }
html[data-look="test"] .state-tile .state-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html[data-look="test"] .state-tile .state-k { font-family: var(--mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--text2); }

/* ══ «Test» widgets, second take: no panels — a technical sheet on the studio background. Each widget is a section under a hairline,
   a mono label on the left; big thin numerals; linear rulers instead of round dials; colour only where something is wrong ══ */
html[data-look="test"] .wg-in, html[data-look="test"] .wg.size-S .wg-in, html[data-look="test"] .wg[class*="tone-"] .wg-in {
  background: transparent !important; border: 0; border-top: 1px solid var(--line2); border-radius: 0; box-shadow: none; padding: 14px 2px 6px; overflow: visible; }
html[data-look="test"] .wg.t-rack .wg-in { border-top: 0; padding-top: 0; }
html[data-look="test"] .wg-body > .card, html[data-look="test"] .wg-full > .card { padding: 0; }
html[data-look="test"] .wg .card-title { margin-bottom: 16px; }
html[data-look="test"] .wg-tile { background: transparent; }
html[data-look="test"] .wg-tile-v { font-weight: 300; font-size: 44px; letter-spacing: -.04em; }
/* «Сводка» */
.sp-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.sp-cell { padding: 2px 16px 4px; border-left: 1px solid var(--line); min-width: 0; } .sp-cell:first-child { border-left: 0; padding-left: 0; }
.sp-k { font: 500 10px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--text2); white-space: nowrap; }
.sp-v { margin-top: 10px; font: 300 42px/1 var(--font); letter-spacing: -.045em; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sp-v small { font: 400 13px/1 var(--mono); letter-spacing: 0; color: var(--text3); margin-left: 4px; }
.sp-cell.warn .sp-v { color: var(--orange); }
.sp-line { margin-top: 12px; height: 1px; background: var(--line2); position: relative; }
.sp-line i { position: absolute; left: 0; top: -.5px; height: 2px; background: var(--text); animation: spgrow 1s cubic-bezier(.2,.8,.2,1) both; }
.sp-cell.warn .sp-line i { background: var(--orange); }
@keyframes spgrow { from { width: 0 !important; } }
@container (max-width: 520px) { .sp-row { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 18px; } .sp-cell:nth-child(3) { border-left: 0; padding-left: 0; } }
@media (max-width: 560px) { .sp-row { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 18px; } .sp-cell:nth-child(3) { border-left: 0; padding-left: 0; } .sp-v { font-size: 36px; } }
/* readings with a ruler (state, internet) */
.sr-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 22px 28px; }
.sr-btn { display: block; width: 100%; padding: 0; border: 0; background: none; color: inherit; text-align: left; cursor: pointer; font: inherit; }
.sr { min-width: 0; }
.sr-v { margin: 10px 0 12px; font: 300 40px/1 var(--font); letter-spacing: -.045em; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sr-v small { font: 400 12px/1 var(--mono); letter-spacing: 0; color: var(--text3); margin-left: 5px; }
.sr-v.warn { color: var(--orange); }
.sr-t { margin-top: 12px; font: 400 11.5px/1.3 var(--mono); color: var(--text2); } .sr-t.warn { color: var(--orange); }
.inet-sr { cursor: pointer; }
.sc { position: relative; height: 26px; }
.sc-ticks { position: absolute; left: 0; right: 0; top: 0; height: 9px; }
.sc-ticks i { position: absolute; top: 0; width: 1px; height: 3px; background: var(--text3); transform: translateX(-.5px); }
.sc-ticks i.m { height: 5px; } .sc-ticks i.b { height: 9px; background: var(--text2); }
.sc-line { position: absolute; left: 0; right: 0; top: 13px; height: 1px; background: var(--line2); }
.sc-line i { position: absolute; left: 0; top: -1px; height: 3px; background: var(--text); transition: width 1.1s cubic-bezier(.2,.8,.2,1); }
.sc-mark { position: absolute; top: 4px; width: 2px; height: 19px; margin-left: -1px; background: var(--accent); box-shadow: 0 0 6px color-mix(in srgb, var(--accent) 60%, transparent); transition: left 1.1s cubic-bezier(.2,.8,.2,1); }
.sc-zones { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; }
.sc-zones i { position: absolute; top: 0; height: 2px; opacity: .55; }
.sc-marks span { position: absolute; top: 18px; transform: translateX(-50%); font: 400 9.5px/1 var(--mono); color: var(--text3); white-space: nowrap; }
.sc-marks span::before { content: ""; position: absolute; left: 50%; top: -14px; width: 1px; height: 11px; background: var(--text2); }
/* «Доступность» */
.dk { display: flex; align-items: flex-end; gap: 3px; height: 34px; }
.dk i { flex: 1 1 0; width: 2px; border-radius: 0; animation: dkup .5s cubic-bezier(.2,.8,.2,1) both; animation-delay: calc(var(--i) * 22ms); transform-origin: bottom; }
@keyframes dkup { from { transform: scaleY(0); } }
/* «Устройства» */
.dt { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); column-gap: 28px; }
.dt-row { display: flex; align-items: center; gap: 10px; padding: 9px 0; border: 0; border-bottom: 1px solid var(--line); background: none; color: var(--text); cursor: pointer; text-align: left; min-width: 0;
  animation: tlitem .35s ease-out both; animation-delay: calc(var(--i) * 25ms); }
.dt-row:hover .dt-n { text-decoration: underline; text-underline-offset: 3px; }
.dt-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--text3); flex: none; }
.dt-dot.online { background: var(--green); } .dt-dot.warning { background: var(--orange); box-shadow: 0 0 6px var(--orange); } .dt-dot.offline { background: var(--red); box-shadow: 0 0 6px var(--red); }
.dt-n { flex: 1; min-width: 0; font-size: 14px; font-weight: 500; }
.dt-a { font: 400 11.5px/1 var(--mono); color: var(--text3); flex: none; max-width: 45%; }
/* the other lists inside widgets: hairline rows, no tiles */
html[data-look="test"] .wg .li { padding-left: 0; padding-right: 0; }
html[data-look="test"] .wg .state-tile, html[data-look="test"] .wg .stat { background: transparent; border: 0; }
/* ══ Frank: the lens mark ══ */
.fmark { position: relative; flex: none; display: grid; place-items: center; border-radius: 8px; border: 1px solid var(--line2); background: var(--card); }
.fmark svg { width: 82%; height: 82%; overflow: visible; }
.fm-ring { fill: none; stroke: var(--text); stroke-width: 1.3; }
.fm-ticks line { stroke: var(--text2); stroke-width: .9; }
.fm-ticks { transform-origin: 20px 20px; }
.fm-iris { fill: none; stroke: var(--text); stroke-width: 1.3; }
.fm-pupil { fill: var(--text); }
.fm-led { position: absolute; right: 12%; top: 12%; width: 13%; height: 13%; min-width: 3px; min-height: 3px; border-radius: 50%; background: var(--text3); }
.fmark.m1 .fm-led { background: var(--accent); box-shadow: 0 0 5px var(--accent); } .fmark.m2 .fm-led { background: var(--orange); box-shadow: 0 0 5px var(--orange); }
.fmark.m3 .fm-led { background: var(--red); box-shadow: 0 0 6px var(--red); animation: flpulse .8s ease-in-out infinite; }
.fmark.m1 .fm-ticks, .fmark.m2 .fm-ticks, .fmark.m3 .fm-ticks { animation: fmspin 6s linear infinite; } .fmark.m2 .fm-ticks { animation-duration: 3s; } .fmark.m3 .fm-ticks { animation-duration: 1.5s; }
@keyframes fmspin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .sp-line i, .dk i, .dt-row, .fm-ticks { animation: none !important; } .sc-line i, .sc-mark { transition: none; } }
html[data-look="test"] .wg .card { background: transparent !important; border: 0 !important; box-shadow: none !important; padding: 0; }
.dk { justify-content: space-between; gap: 2px; } .dk i { flex: 1 1 0; min-width: 4px; max-width: 9px; border-radius: 1.5px 1.5px 0 0; }
html[data-look="test"] .wg:not(.size-S) .wg-body, html[data-look="test"] .wg .wg-body { background: transparent !important; border-radius: 0; padding: 0; }
/* ══ «Test» squares: a label, a mini-instrument in hairlines, the reading ══ */
.tt { position: relative; display: flex; flex-direction: column; width: 100%; height: 100%; padding: 2px 0 0; border: 0; background: none; color: var(--text); text-align: left; cursor: pointer; font: inherit; min-width: 0; }
.tt:active { opacity: .6; }
.tt-top { display: flex; align-items: center; gap: 8px; min-width: 0; }
.tt-k { flex: 1; min-width: 0; font: 500 10px/1.2 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--text2); }
.tt-led { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.tt-art { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: flex-start; color: var(--text2); padding: 8px 0; }
.tt-v { font: 300 clamp(26px, 9cqw, 44px)/1 var(--font); letter-spacing: -.045em; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tt-v.warn { color: var(--orange); }
.tt-s { margin-top: 5px; font: 400 10.5px/1.2 var(--mono); color: var(--text3); }
.tt-svg { width: 100%; height: 26px; overflow: visible; } .tt-svg.tall { height: 100%; max-height: 92px; width: auto; max-width: 100%; }
.tt-tk { stroke: var(--text3); stroke-width: 1; vector-effect: non-scaling-stroke; }
.tt-base { stroke: var(--line2); stroke-width: 1; vector-effect: non-scaling-stroke; }
.tt-fill { stroke: var(--text); stroke-width: 2.4; vector-effect: non-scaling-stroke; }
.tt-mark { stroke: var(--accent); stroke-width: 2; vector-effect: non-scaling-stroke; }
.tt-line { fill: none; stroke: var(--text); stroke-width: 1.4; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.tt-frame { fill: none; stroke: var(--text2); stroke-width: 1; vector-effect: non-scaling-stroke; }
.tt-unit { fill: var(--fill2); } .tt-unit.on { fill: var(--text); }
.tt-wire { fill: none; stroke: var(--text3); stroke-width: 1; vector-effect: non-scaling-stroke; }
.tt-node { fill: var(--bg); stroke: var(--text2); stroke-width: 1.2; vector-effect: non-scaling-stroke; } .tt-node.on { fill: var(--text); stroke: var(--text); }
.tt-dots { display: grid; gap: 5px; width: 100%; max-width: 150px; }
.tt-dots i { aspect-ratio: 1; border-radius: 50%; max-width: 9px; }
.tt-days { display: flex; align-items: flex-end; justify-content: space-between; gap: 1px; width: 100%; height: 30px; } .tt-days i { flex: 1 1 0; min-width: 0; max-width: 6px; width: auto; border-radius: 1px 1px 0 0; }
.tt-pair { display: grid; gap: 10px; width: 100%; }
.tt-pair > div { display: grid; grid-template-columns: 1fr auto; align-items: end; row-gap: 3px; } .tt-pair .tt-svg { grid-column: 1 / -1; height: 16px; }
.tt-pair span { font: 500 9.5px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text3); }
.tt-pair b { font: 300 24px/1 var(--font); letter-spacing: -.04em; color: var(--text); } .tt-pair b.warn { color: var(--orange); }
.tt-rows { display: flex; flex-direction: column; gap: 7px; width: 100%; min-width: 0; }
.tt-rows > div { display: flex; align-items: center; gap: 7px; min-width: 0; font: 400 11px/1.2 var(--mono); color: var(--text2); }
.tt-rows i { width: 5px; height: 5px; border-radius: 50%; flex: none; }
.tt-center { width: 100%; display: grid; place-items: center; }
.tt-glyphs { display: grid; grid-template-columns: repeat(2, 30px); gap: 8px; }
.tt-glyphs span { width: 30px; height: 30px; display: grid; place-items: center; border: 1px solid var(--line2); border-radius: 6px; color: var(--text); }
.tt-note { font: 400 11.5px/1.45 var(--mono); color: var(--text2); width: 100%; min-width: 0; }
html[data-look="test"] .wg.size-S .wg-in { padding: 12px 2px 4px; container-type: inline-size; }
.unit3d { margin-bottom: 10px; }
/* «Test», third pass: icon tiles everywhere (settings, tools, widget picker, «Новые в сети») — a hairline square with a plain icon */
html[data-look="test"] .set-ic, html[data-look="test"] .tool-ic, html[data-look="test"] .wg-opt-ic, html[data-look="test"] .mi, html[data-look="test"] .newdev-ic, html[data-look="test"] .wg-tile-ic,
html[data-look="test"] .modal-head .wg-tile-ic { background: transparent !important; border: 1px solid var(--line2); border-radius: 6px !important; box-shadow: none !important; color: var(--text) !important; }
html[data-look="test"] .set-ic svg, html[data-look="test"] .tool-ic svg, html[data-look="test"] .wg-opt-ic svg, html[data-look="test"] .mi svg, html[data-look="test"] .newdev-ic svg, html[data-look="test"] .wg-tile-ic svg { stroke: var(--text) !important; stroke-width: 1.5px; }
html[data-look="test"] .newdev-row, html[data-look="test"] .tool-card, html[data-look="test"] .dev-card { box-shadow: none; }
html[data-look="test"] .ios-list { border-radius: 10px; }
/* health: the state LED beside the label */
.sr-led { display: inline-block; width: 6px; height: 6px; border-radius: 50%; margin-left: 8px; vertical-align: 1px; }
/* squares: centred glyphs */
.tt-art { justify-content: center; }
.tt-glyph { height: 100%; max-height: 84px; width: auto; max-width: 100%; } .tt-glyph.wide { max-height: 60px; width: 100%; }
.tt-gnum { font: 300 34px var(--font); letter-spacing: -.04em; }
.tt-knob { fill: var(--bg); stroke: var(--text); stroke-width: 1.6; vector-effect: non-scaling-stroke; }
.tt-sweep { stroke: var(--accent); stroke-width: 1.4; vector-effect: non-scaling-stroke; transform-origin: 40px 40px; animation: ttsweep 4s linear infinite; }
@keyframes ttsweep { to { transform: rotate(360deg); } }
.tt-wall { fill: none; stroke: var(--text); stroke-width: 2.2; vector-effect: non-scaling-stroke; } .tt-wall.in { stroke: var(--text2); stroke-width: 1.4; }
.tt-wifi { fill: color-mix(in srgb, var(--accent) 14%, transparent); stroke: none; } .tt-wifi.far { fill: color-mix(in srgb, var(--accent) 6%, transparent); }
/* the map: fast wired links blue, slow ones orange, the rest stays grey */
html[data-look="test"] .edge.fast:not(.flow) { stroke: var(--accent); }
html[data-look="test"] .edge.slow { stroke: color-mix(in srgb, var(--orange) 80%, transparent); }
@media (prefers-reduced-motion: reduce) { .tt-sweep { animation: none; } }
/* «Test»: its own app icons (black aluminium) */
.app-ic-t { display: none; }
html[data-look="test"] .app-ic-c, html[data-look="test"] .app-ic-g, html[data-look="test"] .app-ic-n { display: none !important; }
html[data-look="test"] .app-ic-t { display: block !important; }
/* «Test»: icons everywhere like the side menu — a bare line icon, no tile, no frame, no colour */
html[data-look="test"] :is(.set-ic, .tool-ic, .wg-opt-ic, .mi, .newdev-ic, .kind-ic, .ios-ico .set-ic, .modal-head .wg-tile-ic) {
  background: none !important; border: 0 !important; box-shadow: none !important; border-radius: 0 !important; width: 22px !important; height: 22px !important; min-width: 22px; color: var(--text2) !important; }
html[data-look="test"] :is(.set-ic, .tool-ic, .wg-opt-ic, .mi, .newdev-ic, .kind-ic) svg { stroke: currentColor !important; stroke-width: 1.6px !important; width: 18px; height: 18px; }
html[data-look="test"] :is(.set-item, .ios-cell):hover :is(.set-ic, .kind-ic), html[data-look="test"] :is(.set-item.on, .ios-cell.on) .set-ic { color: var(--text) !important; }
html[data-look="test"] .ios-ico { width: 22px; height: 22px; background: none; }
/* lists as in the side menu: plain rows, a fill on hover, the open one with a left bar and a blue light */
html[data-look="test"] :is(.ios-list, .ios-group, .set-nav) { background: transparent !important; border: 0 !important; box-shadow: none !important; }
html[data-look="test"] .ios-group { border-top: 1px solid var(--line) !important; border-radius: 0 !important; padding-top: 6px; }
html[data-look="test"] .ios-group + .ios-group { margin-top: 10px; }
html[data-look="test"] :is(.ios-cell, .set-item) { background: transparent !important; border: 0 !important; border-radius: 8px; padding: 12px 10px; gap: 12px; color: var(--text2); }
html[data-look="test"] :is(.ios-cell, .set-item)::after, html[data-look="test"] :is(.ios-cell, .set-item)::before { display: none !important; }
html[data-look="test"] :is(.ios-cell, .set-item):hover { background: var(--fill) !important; color: var(--text); }
html[data-look="test"] .set-item.on { background: var(--fill) !important; color: var(--text); box-shadow: inset 2px 0 0 var(--text); }
html[data-look="test"] .ios-label, html[data-look="test"] .set-txt b { color: var(--text); font-weight: 500; }
/* the row titles as in the side menu: mono caps; the value/subtitle small grey mono; a light before the open one */
html[data-look="test"] .ios-label, html[data-look="test"] .set-txt b, html[data-look="test"] .set-item > b, html[data-look="test"] .set-txt > :first-child {
  font: 600 13px/1.2 var(--mono) !important; letter-spacing: .1em; text-transform: uppercase; color: var(--text2); }
html[data-look="test"] :is(.ios-cell, .set-item):hover :is(.ios-label, .set-txt b, .set-txt > :first-child), html[data-look="test"] .set-item.on :is(.set-txt b, .set-txt > :first-child) { color: var(--text); }
html[data-look="test"] .ios-val, html[data-look="test"] .set-txt small, html[data-look="test"] .set-txt > :not(:first-child) { font: 400 11px/1.3 var(--mono) !important; letter-spacing: .02em; color: var(--text3) !important; text-transform: none; }
html[data-look="test"] :is(.ios-cell, .set-item) > svg:last-child { opacity: .35; }
html[data-look="test"] .set-item { position: relative; padding-left: 26px !important; }
html[data-look="test"] .set-item::before { content: ""; display: block !important; position: absolute; left: 10px; top: 50%; width: 6px; height: 6px; margin-top: -3px; border-radius: 50%; background: var(--fill2); box-shadow: inset 0 0 0 1px var(--line2); }
html[data-look="test"] .set-item.on::before { background: var(--accent); box-shadow: 0 0 8px var(--accent); }
/* ══ «Test», fourth pass ══ */
/* Frank: the main look's eye, monochrome — white on the dark theme, black on the light one */
html[data-look="test"] .frank { --frank-bg: transparent; background: transparent !important; }
html[data-look="test"] { --frank-sclera: #15171a; --frank-iris-0: #9aa1aa; --frank-iris-1: #5b6168; --frank-iris-2: #33373c; --frank-pupil: #000; --frank-lid: #c3c8cf;
  --frank-m2-0: #9aa1aa; --frank-m2-1: #5b6168; --frank-m2-2: #33373c; --frank-m3-0: #9aa1aa; --frank-m3-1: #5b6168; --frank-m3-2: #33373c; }
html[data-look="test"][data-theme="dark"] { --frank-sclera: #f1f3f5; --frank-iris-0: #8d939b; --frank-iris-1: #3d4248; --frank-iris-2: #15171a; --frank-pupil: #000; --frank-lid: #25282c;
  --frank-m2-0: #8d939b; --frank-m2-1: #3d4248; --frank-m2-2: #15171a; --frank-m3-0: #8d939b; --frank-m3-1: #3d4248; --frank-m3-2: #15171a; }
html[data-look="test"] .frank.m2 svg, html[data-look="test"] .frank.m3 svg { filter: none; }
.tt-frank .frank { width: min(86px, 70cqw) !important; height: min(86px, 70cqw) !important; }
.tt-frank .frank svg { width: 100% !important; height: 100% !important; }
/* the header: LIVE in blue */
html[data-look="test"] .live:not(.stale) { color: var(--accent) !important; }
html[data-look="test"] .live:not(.stale) i { background: var(--accent) !important; box-shadow: 0 0 6px var(--accent); }
/* «Новые в сети»: a bigger radar, blue blips that come and go with a ring */
.t-newdev .tt-art { padding: 2px 0; }
.tt-radar { max-height: 128px !important; }
.tt-sweep-g { transform-origin: 40px 40px; transform-box: view-box; animation: ttsweep 4s linear infinite; }
.tt-sweep-g .tt-sweep { animation: none; }
.tt-sweep-fan { fill: color-mix(in srgb, var(--accent) 14%, transparent); }
.tt-blip { animation: ttblip 4s ease-in-out infinite; }
.tt-blip-dot { fill: var(--accent); filter: drop-shadow(0 0 3px var(--accent)); }
.tt-blip-ring { fill: none; stroke: var(--accent); stroke-width: .8; transform-box: fill-box; transform-origin: center; animation: ttring 4s ease-out infinite; animation-delay: inherit; }
@keyframes ttblip { 0%, 100% { opacity: .28; } 35%, 60% { opacity: 1; } }
@keyframes ttring { 0% { transform: scale(.4); opacity: .9; } 70%, 100% { transform: scale(1.6); opacity: 0; } }
/* «Советы Frank»: every point a blue glowing dot */
.tt-bdot { background: var(--accent) !important; box-shadow: 0 0 6px var(--accent); }
html[data-look="test"] .advice-ic { width: 10px; min-width: 10px; display: grid; place-items: center; padding-top: 6px; align-self: flex-start; }
html[data-look="test"] .advice-ic svg { display: none; }
html[data-look="test"] .advice-ic::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 7px var(--accent); }
html[data-look="test"] .advice-k { color: var(--text3) !important; font: 500 9.5px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; }
/* «Заметка»: a notepad — a faint warm sheet with ruled lines under the text */
html[data-look="test"] .note-pad, html[data-look="test"] .tt-note {
  --nl: 22px; line-height: var(--nl) !important; font-size: 14px; padding: 4px 12px 6px !important; border: 0 !important; border-radius: 4px !important; box-shadow: none !important;
  background: repeating-linear-gradient(180deg, transparent 0 calc(var(--nl) - 1px), color-mix(in srgb, var(--orange) 26%, transparent) calc(var(--nl) - 1px) var(--nl)) 0 4px / 100% var(--nl),
              color-mix(in srgb, var(--orange) 7%, transparent) !important; background-attachment: local !important; color: var(--text); }
html[data-look="test"] .tt-note { --nl: 19px; font: 400 12px/19px var(--mono); }
html[data-look="test"] .note-pad:focus { outline: none; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--orange) 35%, transparent) !important; }
/* «Состояние сети»: the firewall */
.fw { width: 100%; height: 100%; overflow: visible; }
.fw-b { fill: color-mix(in srgb, var(--fw) 16%, transparent); stroke: var(--fw); stroke-width: 1.1; vector-effect: non-scaling-stroke; animation: fwin .45s cubic-bezier(.2,.9,.3,1) both; }
.fw-gap { fill: none; stroke: var(--line2); stroke-width: .8; stroke-dasharray: 2 2; vector-effect: non-scaling-stroke; }
.fw-debris { fill: color-mix(in srgb, var(--fw) 40%, transparent); stroke: var(--fw); stroke-width: .8; vector-effect: non-scaling-stroke; }
.fw-crack { fill: none; stroke: var(--fw); stroke-width: 1.6; vector-effect: non-scaling-stroke; stroke-linejoin: bevel; }
.fw.broken { filter: drop-shadow(0 0 5px color-mix(in srgb, var(--red) 55%, transparent)); }
@keyframes fwin { from { opacity: 0; transform: translateY(-4px); } }
.tt-fw { width: 100%; height: 100%; max-height: 96px; display: grid; place-items: center; } .tt-fw .fw { max-width: 120px; max-height: 96px; }
.sr-fw { border: 0; background: none; padding: 0 4px 0 0; width: 92px; flex: none; cursor: pointer; align-self: center; }
html[data-look="test"] .sr-row { align-items: center; }
/* the speed test: a straight ruler */
.gauge.lin { width: 100%; max-width: 520px; margin: 0 auto; padding: 6px 4px 0; }
.lg-val { display: flex; align-items: baseline; gap: 8px; }
.lg-val b { font: 300 clamp(48px, 13vw, 76px)/1 var(--font); letter-spacing: -.05em; font-variant-numeric: tabular-nums; }
.lg-val span { font: 500 11px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text3); }
.lg-scale { position: relative; height: 54px; margin: 18px 0 6px; }
.lg-ticks i { position: absolute; top: 0; width: 1px; height: 6px; background: var(--text3); } .lg-ticks i.m { height: 10px; } .lg-ticks i.b { height: 14px; background: var(--text2); }
.lg-line { position: absolute; left: 0; right: 0; top: 22px; height: 3px; background: var(--fill2); border-radius: 2px; }
.lg-line i { display: block; height: 100%; border-radius: 2px; }
.lg-mark { position: absolute; top: 15px; width: 3px; height: 17px; margin-left: -1.5px; border-radius: 2px; }
.lg-nums span { position: absolute; top: 38px; transform: translateX(-50%); font: 500 10px/1 var(--mono); color: var(--text3); }
.lg-nums span:first-child { transform: none; } .lg-nums span:last-child { transform: translateX(-100%); }
@media (prefers-reduced-motion: reduce) { .tt-sweep-g, .tt-blip, .tt-blip-ring, .fw-b { animation: none !important; } }
/* ИБП and «Новые в сети» opened, «Test» */
.ui-list { display: grid; gap: 18px; }
.ui { cursor: pointer; border-top: 1px solid var(--line); padding-top: 12px; }
.ui-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ui-st { display: inline-flex; align-items: center; gap: 6px; font: 500 10px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; }
.ui-st i { width: 6px; height: 6px; border-radius: 50%; }
.ui-main { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-top: 8px; }
.ui-bat { position: relative; display: grid; grid-template-columns: repeat(10, 9px); gap: 3px; padding: 4px; border: 1px solid var(--text2); border-radius: 3px; height: 34px; }
.ui-bat i { background: var(--fill2); border-radius: 1px; } .ui-bat i.on { box-shadow: 0 0 6px currentColor; }
.ui-bat b { position: absolute; right: -6px; top: 10px; width: 4px; height: 12px; border: 1px solid var(--text2); border-left: 0; border-radius: 0 2px 2px 0; }
.ui-feeds { margin-top: 12px; display: grid; gap: 6px; }
.ui-feeds > div { display: flex; align-items: baseline; gap: 6px; font: 400 12px/1.3 var(--mono); color: var(--text2); min-width: 0; }
.ui-feeds > div > i { flex: 1; border-bottom: 1px dotted var(--line2); transform: translateY(-3px); min-width: 12px; }
.ui-feeds b { color: var(--text); font-weight: 500; white-space: nowrap; }
.nd-instr { display: flex; gap: 22px; align-items: flex-start; }
.nd-radar { width: 190px; flex: none; } .nd-radar .tt-radar { width: 100%; height: auto; max-height: none !important; }
@media (max-width: 600px) { .nd-instr { flex-direction: column; align-items: stretch; } .nd-radar { width: 70%; margin: 0 auto; } }
/* «Test»: the score ring as a hairline instrument, check icons bare, bars plain, stat tiles as readings with a thin trace */
html[data-look="test"] .score-ring circle { stroke-width: 2.5px; stroke-linecap: butt; }
html[data-look="test"] .score-ring circle:last-child { filter: drop-shadow(0 0 4px currentColor); }
html[data-look="test"] .score-ring b { font-weight: 300 !important; letter-spacing: -.04em; }
html[data-look="test"] .score-ring small { font: 500 8.5px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; }
html[data-look="test"] .check-ic { background: none !important; width: 22px !important; min-width: 22px; }
html[data-look="test"] .spof-bar { height: 2px; background: var(--fill2); border-radius: 0; }
html[data-look="test"] .spof-bar i { background: var(--text); border-radius: 0; }
html[data-look="test"] .stats { gap: 0 16px; }
html[data-look="test"] .stat { background: none !important; border: 0 !important; border-top: 1px solid var(--line) !important; border-radius: 0 !important; padding: 10px 0 8px !important; box-shadow: none !important; }
html[data-look="test"] .stat .k { font: 500 10px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--text3); }
html[data-look="test"] .stat .v { font: 300 28px/1.15 var(--font) !important; letter-spacing: -.04em; margin-top: 6px; font-variant-numeric: tabular-nums; }
html[data-look="test"] .stat .v small { font: 500 10px/1 var(--mono); color: var(--text3); letter-spacing: .1em; }
html[data-look="test"] .stat svg.spark { height: 22px; opacity: .8; }
html[data-look="test"] .stat svg.spark path:first-child { display: none; }
html[data-look="test"] .stat svg.spark path:last-child { stroke: var(--text2); stroke-width: 1px; vector-effect: non-scaling-stroke; }
html[data-look="test"] .ui-bat i.on { box-shadow: none; }
html[data-look="test"] .stat svg.spark path[opacity] { display: none !important; }
html[data-look="test"] .stat svg.spark path { fill: none !important; stroke: var(--text3) !important; stroke-width: 1px !important; vector-effect: non-scaling-stroke; }
html[data-look="test"] .stat svg.spark { opacity: 1 !important; }
/* ══ «Сводка»: a pilot lamp ══ */
.plamp { display: grid; justify-items: center; gap: 8px; }
.plamp-bezel { width: var(--ls, 78px); aspect-ratio: 1; border-radius: 50%; padding: 9%; box-sizing: border-box;
  background: conic-gradient(from 210deg, #5d6168, #1d1f23 25%, #8b9097 50%, #1b1d20 75%, #5d6168); box-shadow: 0 2px 6px rgba(0,0,0,.6), inset 0 0 0 1px rgba(255,255,255,.08); }
html[data-theme="light"] .plamp-bezel { background: conic-gradient(from 210deg, #c9cdd3, #8d939b 25%, #f4f5f7 50%, #9aa1aa 75%, #c9cdd3); box-shadow: 0 2px 5px rgba(0,0,0,.18); }
.plamp-lens { position: relative; width: 100%; height: 100%; border-radius: 50%; overflow: hidden;
  background: radial-gradient(circle at 50% 55%, color-mix(in srgb, #fff 55%, var(--lc)) 0%, var(--lc) 38%, color-mix(in srgb, var(--lc) 45%, #000) 100%);
  box-shadow: 0 0 18px var(--lc), 0 0 46px color-mix(in srgb, var(--lc) 45%, transparent), inset 0 -6px 12px rgba(0,0,0,.45); animation: plamp 3.2s ease-in-out infinite; }
.plamp-lens::before { content: ""; position: absolute; inset: 0; background: repeating-radial-gradient(circle at 50% 50%, transparent 0 3px, rgba(255,255,255,.07) 3px 4px); }
.plamp-glint { position: absolute; left: 22%; top: 14%; width: 34%; height: 22%; border-radius: 50%; background: radial-gradient(ellipse, rgba(255,255,255,.75), transparent 70%); transform: rotate(-20deg); }
.plamp.bad .plamp-lens { animation: plampbad 1.1s ease-in-out infinite; }
.plamp-w { font: 500 9.5px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text3); }
@keyframes plamp { 50% { filter: brightness(1.12); } }
@keyframes plampbad { 50% { filter: brightness(.55); box-shadow: 0 0 6px var(--lc); } }
.tt-lamp-wrap { width: 100%; display: grid; place-items: center; } .tt-lamp-wrap .plamp { --ls: min(84px, 46cqw); }
.sp-row.with-lamp { grid-template-columns: auto repeat(4, 1fr) !important; align-items: center; }
.sp-lamp { padding-right: 14px; } .sp-lamp .plamp { --ls: 58px; }
@container (max-width: 520px) { .sp-row.with-lamp { grid-template-columns: repeat(2, 1fr) !important; } .sp-lamp { grid-column: 1 / -1; justify-self: center; padding: 0 0 8px; } }
@media (prefers-reduced-motion: reduce) { .plamp-lens { animation: none !important; } }

/* ══ the rack in 3D («Test») ══ */
.r3-wrap { position: relative; display: grid; place-items: center; perspective: 2200px; perspective-origin: 50% 40%; touch-action: pan-y; cursor: grab; user-select: none; -webkit-user-select: none; overflow: hidden; margin-top: 4px; }
.r3-wrap:active { cursor: grabbing; }
.r3-stage { position: relative; width: 0; height: 0; transform-style: preserve-3d; margin-top: -20px; }
.r3-obj { position: absolute; left: 0; top: 0; transform-style: preserve-3d; transition: transform .14s ease-out; }
.rack-transition { position: relative; overflow: hidden; transition: height .72s cubic-bezier(.22,.7,.2,1); }
.rack-transition-3d, .rack-transition-flat { position: absolute; inset: 0 0 auto; width: 100%; transition: opacity .34s ease, visibility 0s linear .72s; }
.rack-transition .r3-obj { transition: transform .72s cubic-bezier(.22,.7,.2,1); }
.rack-transition .r3-dragging .r3-obj { transition-duration: .08s; }
.rack-transition-flat .rack-body { transition: transform .72s cubic-bezier(.22,.7,.2,1); transform-origin: 50% 42%; }
.rack-transition.is-3d .rack-transition-3d, .rack-transition.is-flat .rack-transition-flat { opacity: 1; visibility: visible; transition-delay: .25s, 0s; }
.rack-transition.is-flat .rack-transition-3d, .rack-transition.is-3d .rack-transition-flat { opacity: 0; visibility: hidden; pointer-events: none; }
.rack-transition.is-3d .rack-transition-flat .rack-body { transform: scale(.94); }
@media (prefers-reduced-motion: reduce) {
  .rack-transition, .rack-transition-3d, .rack-transition-flat, .rack-transition .r3-obj, .rack-transition-flat .rack-body { transition: none !important; }
}
.r3f { position: absolute; left: 0; top: 0; transform-origin: 0 0; backface-visibility: hidden; -webkit-backface-visibility: hidden; box-sizing: border-box; }
.r3-hint { position: absolute; bottom: 8px; left: 0; right: 0; text-align: center; font: 500 9.5px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text3); pointer-events: none; }
/* the cabinet skin */
.r3-wrap { --r3-skin: linear-gradient(180deg, #24262a, #121315); --r3-in: #060607; --r3-roof: linear-gradient(180deg, #2e3034, #1a1b1e); --r3-bezel: linear-gradient(180deg, #34373c 0%, #1b1d20 22%, #111214 100%);
  --r3-ub: linear-gradient(180deg, #2e3135 0%, #1c1e21 35%, #131416 100%); --r3-us: #0f1012; --r3-ut: #1d1f22; --r3-num: #6d737b; --r3-edge: rgba(255,255,255,.07); }
html[data-theme="light"] .r3-wrap { --r3-skin: linear-gradient(180deg, #eef0f2, #d3d7dc); --r3-in: #aeb4bb; --r3-roof: linear-gradient(180deg, #f7f8f9, #e3e6ea); --r3-bezel: linear-gradient(180deg, #ffffff 0%, #eceef1 30%, #dadde2 100%);
  --r3-ub: linear-gradient(180deg, #ffffff 0%, #eef0f2 40%, #e0e3e7 100%); --r3-us: #c4c9cf; --r3-ut: #e6e8eb; --r3-num: #8d939b; --r3-edge: rgba(0,0,0,.08); }
.r3-shell.side, .r3-shell.rear { background: var(--r3-skin); box-shadow: inset 0 0 0 1px var(--r3-edge); }
.r3-shell.side::after { content: ""; position: absolute; inset: 12% 18%; background: repeating-linear-gradient(180deg, transparent 0 calc(var(--k) * 10px), color-mix(in srgb, var(--r3-in) 70%, transparent) calc(var(--k) * 10px) calc(var(--k) * 13px)); opacity: .55; border-radius: 2px; }
.r3-shell.inside { background: var(--r3-in); } .r3-shell.inside.wall { background: linear-gradient(180deg, var(--r3-in), color-mix(in srgb, var(--r3-in) 80%, #000)); }
.r3-shell.roof { background: var(--r3-roof); box-shadow: inset 0 0 0 1px var(--r3-edge); }
.r3-vents { position: absolute; left: 25%; right: 25%; top: 30%; bottom: 30%; background: repeating-linear-gradient(90deg, transparent 0 calc(var(--k) * 9px), color-mix(in srgb, var(--r3-in) 85%, transparent) calc(var(--k) * 9px) calc(var(--k) * 13px)); border-radius: 3px; }
.r3-shell.floor { background: #000; }
.r3-shell.bezel { background: var(--r3-bezel); box-shadow: inset 0 1px 0 rgba(255,255,255,.12), inset 0 0 0 1px var(--r3-edge); display: flex; align-items: center; }
.r3-shell.head { padding: 0 calc(var(--k) * 24px); justify-content: space-between; }
.r3-name { font: 600 calc(var(--k) * 13px)/1 var(--mono); letter-spacing: .18em; text-transform: uppercase; color: var(--text2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.r3-pwr { width: calc(var(--k) * 7px); height: calc(var(--k) * 7px); border-radius: 50%; background: var(--accent); box-shadow: 0 0 8px var(--accent); flex: none; }
.r3-grille { position: absolute; left: 14%; right: 14%; top: 30%; bottom: 30%; background: repeating-linear-gradient(90deg, color-mix(in srgb, var(--r3-in) 85%, transparent) 0 calc(var(--k) * 4px), transparent calc(var(--k) * 4px) calc(var(--k) * 8px)); border-radius: 2px; }
.r3-shell.stile { justify-content: flex-end; }
.r3-shell.stile.r { justify-content: flex-start; }
.r3-rail { width: 46%; height: 100%; display: flex; flex-direction: column; background: color-mix(in srgb, var(--r3-in) 55%, transparent); }
.r3-rail span { display: flex; align-items: center; justify-content: center; font: 500 calc(var(--k) * 9px)/1 var(--mono); color: var(--r3-num); border-bottom: 1px solid color-mix(in srgb, var(--r3-edge) 60%, transparent); box-sizing: border-box; position: relative; }
.r3-rail span::before, .r3-rail span::after { content: ""; position: absolute; left: 50%; width: calc(var(--k) * 4px); height: calc(var(--k) * 4px); margin-left: calc(var(--k) * -2px); background: #000; border-radius: 1px; opacity: .55; }
.r3-rail span::before { top: 14%; } .r3-rail span::after { bottom: 14%; }
/* units */
.r3-unit.front { background: var(--r3-ub); border-radius: 2px; box-shadow: inset 0 1px 0 rgba(255,255,255,.1), inset 0 -1px 0 rgba(0,0,0,.5), 0 0 0 .5px rgba(0,0,0,.6); cursor: pointer; transition: box-shadow .15s; }
.r3-unit.front:hover { box-shadow: inset 0 0 0 1.5px var(--accent), 0 0 14px color-mix(in srgb, var(--accent) 40%, transparent); }
.r3-unit.side, .r3-unit.back, .r3-unit.bottom { background: var(--r3-us); }
.r3-unit.top { background: var(--r3-ut); }
.r3u { position: relative; height: 100%; display: flex; align-items: center; gap: calc(var(--k) * 12px); padding: 0 calc(var(--k) * 30px); box-sizing: border-box; min-width: 0; }
.r3-ear { position: absolute; top: 0; bottom: 0; width: calc(var(--k) * 16px); }
.r3-ear.l { left: 0; border-right: 1px solid var(--r3-edge); } .r3-ear.r { right: 0; border-left: 1px solid var(--r3-edge); }
.r3-ear::before { content: ""; position: absolute; left: 50%; top: 50%; width: calc(var(--k) * 6px); height: calc(var(--k) * 6px); margin: calc(var(--k) * -3px); border-radius: 50%; background: radial-gradient(circle at 40% 35%, #9aa1aa, #3a3e44); }
.r3u-id { display: flex; align-items: center; gap: calc(var(--k) * 7px); min-width: 0; flex: 1; font: 600 calc(var(--k) * 12.5px)/1.1 var(--font); color: var(--text); }
.r3u-led { width: calc(var(--k) * 6px); height: calc(var(--k) * 6px); border-radius: 50%; flex: none; background: var(--text3); }
.r3u-led.online { background: var(--accent); box-shadow: 0 0 6px var(--accent); } .r3u-led.warning { background: var(--orange); box-shadow: 0 0 6px var(--orange); } .r3u-led.offline { background: var(--red); box-shadow: 0 0 6px var(--red); }
.r3u .leds { flex: none; display: grid; grid-auto-flow: column; grid-template-rows: repeat(2, calc(var(--k) * 9px)); gap: calc(var(--k) * 2.5px); }
.r3u .leds i { width: calc(var(--k) * 10px); height: calc(var(--k) * 9px); border-radius: 1px; background: #050506; box-shadow: inset 0 0 0 1px #3a3e44; }
html[data-theme="light"] .r3u .leds i { background: #23262a; box-shadow: inset 0 0 0 1px #8d939b; }
.r3u .leds i.g, .r3u .leds i.y, .r3u .leds i.o { background: #050506; box-shadow: inset 0 0 0 1px #3a3e44, inset 0 calc(var(--k) * -2.5px) 0 var(--green); }
.r3u .leds i.y, .r3u .leds i.o { box-shadow: inset 0 0 0 1px #3a3e44, inset 0 calc(var(--k) * -2.5px) 0 var(--orange); }
.r3u .leds i.off { background: #2a0d0c; }
.r3u .leds i.r { background: var(--red); box-shadow: 0 0 5px var(--red); }
.r3u .leds.round { grid-template-rows: calc(var(--k) * 10px) !important; gap: calc(var(--k) * 5px); } .r3u .leds.round i { width: calc(var(--k) * 10px); height: calc(var(--k) * 10px); border-radius: 50%; }
.r3u-vent { flex: none; width: 22%; height: 34%; background: repeating-linear-gradient(90deg, color-mix(in srgb, #000 55%, transparent) 0 calc(var(--k) * 3px), transparent calc(var(--k) * 3px) calc(var(--k) * 6px)); border-radius: 1px; opacity: .7; }
.r3u.blank { background: repeating-linear-gradient(180deg, transparent 0 calc(var(--k) * 5px), rgba(0,0,0,.25) calc(var(--k) * 5px) calc(var(--k) * 6px)); }
.cord-surface { position: relative; }
.rack-cords { position: absolute; inset: 0; overflow: visible; pointer-events: none; z-index: 4; }
.r3-cord-plane { pointer-events: none; background: none !important; }
.rack-cord path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.cord-shadow { stroke: #06090e; opacity: .82; }
.cord-body { stroke: var(--cord); }
.cord-light { stroke: #fff; opacity: .38; }
.cord-hit { stroke: transparent; pointer-events: stroke; cursor: pointer; }
.rack-cord:hover .cord-body { filter: drop-shadow(0 0 3px var(--cord)); }
.r3-shelf-ports { display: flex; gap: calc(var(--k) * 10px); flex: none; }
.cord-list { display: flex; flex-direction: column; gap: 7px; margin-top: 16px; max-height: 42vh; overflow: auto; }
.cord-row { display: flex; align-items: center; gap: 10px; border: 1px solid var(--line); background: var(--bg2); border-radius: 12px; padding: 11px; }
.cord-row.selected { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.cord-row b { font-size: 13px; display: block; overflow-wrap: anywhere; }
.cord-row small { display: block; font-size: 12px; color: var(--text2); margin-top: 4px; overflow-wrap: anywhere; }
.cord-row input[type="color"] { appearance: none; -webkit-appearance: none; width: 34px; height: 34px; border-radius: 9px; padding: 3px; border: 1px solid var(--line); background: transparent; flex-shrink: 0; cursor: pointer; }
.cord-swatch { width: 5px; height: 32px; border-radius: 4px; flex: none; }
.cord-empty { padding: 24px 8px; color: var(--text3); text-align: center; font-size: 13px; }
.cord-palette { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 7px; }
.cord-palette button { width: 24px; height: 24px; border: 1px solid transparent; border-radius: 50%; padding: 4px; background: var(--swatch); background-clip: content-box; cursor: pointer; }
.cord-palette button.on { border-color: var(--text2); }
html[data-look="test"] .rack-top { flex-wrap: wrap; gap: 8px; }
/* «Test»: the welcome tour — a neutral dim, a strict panel, mono controls */
html[data-look="test"] .tour-ring { border: 1.5px solid var(--accent); border-radius: 8px !important; box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 22%, transparent), 0 0 24px color-mix(in srgb, var(--accent) 45%, transparent); }
html[data-look="test"] .tour-skip { border-radius: 8px; background: rgba(20,21,24,.85); border: 1px solid #30343a; font: 500 11px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: #c9ced5; padding: 10px 14px; }
html[data-look="test"] .tour-bubble { border-radius: 10px; background: rgba(13,14,16,.94); border: 1px solid #30343a; box-shadow: 0 18px 50px rgba(0,0,0,.55); color: #eceef1; padding: 16px 18px; }
html[data-look="test"] .tour-bubble::before { background: rgba(13,14,16,.98); border-left: 1px solid #30343a; border-bottom: 1px solid #30343a; }
.tour-step { font: 500 9.5px/1 var(--mono); letter-spacing: .18em; text-transform: uppercase; color: #656c75; margin-bottom: 9px; }
html[data-look="test"] .tour-title { font-size: 18px; font-weight: 600; letter-spacing: -.02em; }
html[data-look="test"] .tour-text { color: #9aa1aa; }
html[data-look="test"] .tour-hint { color: var(--accent); font: 500 11px/1.3 var(--mono); letter-spacing: .1em; text-transform: uppercase; }
html[data-look="test"] .tour-hint i { background: var(--accent); }
html[data-look="test"] .tour-dots { gap: 3px; } html[data-look="test"] .tour-dots i { width: 10px; height: 2px; border-radius: 0; background: #30343a; }
html[data-look="test"] .tour-dots i.done { background: #9aa1aa; } html[data-look="test"] .tour-dots i.on { width: 18px; background: var(--accent); box-shadow: 0 0 6px var(--accent); }
html[data-look="test"] .tour-link { font: 500 11px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: #9aa1aa; }
html[data-look="test"] .tour-next { border-radius: 8px; background: #eceef1; color: #0b0c0e; box-shadow: none; font: 600 11px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; padding: 12px 18px; }
html[data-look="test"] .tour-card-eye { background: #0d0e10; border: 1px solid #30343a; border-radius: 10px; }
html[data-look="test"] .tour-layer { --tour-a1: .9; --tour-a3: .92; }
@media (min-width: 900px) { html[data-look="test"] .tour-layer { --tour-a1: .62; --tour-a3: .66; } }
@media (max-width: 600px) { .tour-bubble { max-width: calc(100vw - 132px); } .tour-card.big .tour-bubble { max-width: calc(100vw - 150px); } }
html.tour-on .tl-nav-wrap { z-index: 99990; }
/* «Test»: the scanner camera — a dimmed surround, thin square corners, a blue scan line, mono captions */
html[data-look="test"] .cd-frame { box-shadow: 0 0 0 100vmax rgba(0,0,0,.42); border-radius: 2px; }
html[data-look="test"] .cd-frame i { width: 26px; height: 26px; border-width: 2px; border-radius: 0; border-color: #f1f3f5; }
html[data-look="test"] .cd-frame::before { content: ""; position: absolute; left: 6%; right: 6%; height: 2px; top: 8%; background: var(--accent); box-shadow: 0 0 12px var(--accent), 0 0 2px var(--accent); animation: cdscan 2.4s ease-in-out infinite alternate; }
html[data-look="test"] .cd-frame::after { content: ""; position: absolute; left: 50%; top: 50%; width: 14px; height: 14px; margin: -7px; opacity: .55;
  background: linear-gradient(#f1f3f5, #f1f3f5) center / 1px 100% no-repeat, linear-gradient(#f1f3f5, #f1f3f5) center / 100% 1px no-repeat; }
@keyframes cdscan { to { top: 92%; } }
html[data-look="test"] .cd-cam-hint { font: 500 11px/1.4 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: #c9ced5; }
html[data-look="test"] .cd-pill { border-radius: 8px; background: rgba(13,14,16,.8); border: 1px solid #30343a; font: 600 11px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; }
html[data-look="test"] .cd-pill.solid { background: #eceef1; color: #0b0c0e; border-color: #eceef1; }
html[data-look="test"] .cd-cam-err { border-radius: 10px; background: rgba(13,14,16,.94); border: 1px solid #30343a; }
@media (prefers-reduced-motion: reduce) { html[data-look="test"] .cd-frame::before { animation: none; top: 50%; } }
/* «Сводка»: the bulb */
.bulb { width: var(--ls, 78px); height: auto; overflow: visible; }
.bulb-glow { fill: var(--lc); opacity: .16; filter: blur(9px); animation: bulb 3.2s ease-in-out infinite; }
.bulb-glass { fill: color-mix(in srgb, var(--lc) 7%, transparent); stroke: var(--text); stroke-width: 1.6; }
.bulb-wire { fill: none; stroke: var(--text3); stroke-width: 1.2; }
.bulb-fil { fill: none; stroke: var(--lc); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 0 3px var(--lc)) drop-shadow(0 0 7px var(--lc)); }
.bulb-base { fill: none; stroke: var(--text2); stroke-width: 2.2; stroke-linecap: round; }
.bulb-hl { fill: none; stroke: var(--text); stroke-width: 1.4; stroke-linecap: round; opacity: .45; }
.plamp.bad .bulb-fil, .plamp.bad .bulb-glow { animation: bulbbad 1.1s ease-in-out infinite; }
@keyframes bulb { 50% { opacity: .26; } }
@keyframes bulbbad { 50% { opacity: .25; } }
.tt-lamp-wrap .plamp { --ls: min(64px, 34cqw); } .sp-lamp .plamp { --ls: 40px; }
@media (prefers-reduced-motion: reduce) { .bulb-glow, .bulb-fil { animation: none !important; } }
/* «Test»: the smart zoom on the port block */
.s3-zoom { transform-style: preserve-3d; transition: transform .7s cubic-bezier(.2,.85,.25,1); }
.s3-stage { transition: height .5s cubic-bezier(.2,.85,.25,1); }
.s3-stage.zoomed { overflow: hidden; cursor: default; }
.s3-stage.zoomed .s3-float { animation: none; }
.s3-stage.zoomed .s3-shadow { opacity: 0; transition: opacity .3s; }
.ph-stage { position: relative; overflow: hidden; }
/* the zoom lives on its own layer: the photo's rise animation (.ph-wrap) is never switched off, so it does not replay when zooming out */
.ph-zoom { display: inline-block; max-width: 100%; transition: transform .7s cubic-bezier(.2,.85,.25,1); }
.m3-tool.zoom { gap: 6px; }
.zn-box { position: absolute; border: 1.5px dashed var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); pointer-events: none; border-radius: 2px; z-index: 2; }
.zn-box.draft { border-style: solid; }
.zn-box i { position: absolute; left: 0; top: -15px; font: 500 9px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--accent); font-style: normal; white-space: nowrap; }
.zoning { cursor: crosshair !important; }
.zn-bar { display: flex; align-items: center; gap: 8px; padding-top: 10px; border-top: 1px solid var(--line); flex-wrap: wrap; }
.zn-bar b { display: block; font-size: 13.5px; } .zn-bar small { display: block; font-size: 12px; color: var(--text3); }
.s3-stage { transition: height .5s cubic-bezier(.2,.85,.25,1), perspective .7s cubic-bezier(.2,.85,.25,1), perspective-origin .7s; }
.s3-stage .m3-tools { z-index: 5; }
.s3-stage.zoomed .s3-hint { color: var(--accent); opacity: 1; }
.s3-stage .m3-tools, .ph-stage .m3-tools { z-index: 20; transform: translateZ(0); }
.m3-tool.zoom { background: var(--card-solid, #111214) !important; color: var(--text) !important; border: 1px solid var(--line2) !important; opacity: 1 !important; }
.m3-tool.zoom.pri { background: var(--text) !important; color: var(--bg) !important; border-color: var(--text) !important; }
/* «Магазин моделей» */
.st-thumb { width: 56px; height: 36px; flex: none; border-radius: 7px; overflow: hidden; display: flex; align-items: center; justify-content: center; color: var(--text3);
  background: repeating-conic-gradient(var(--line) 0 25%, transparent 0 50%) 0 0 / 10px 10px; }
.st-thumb img { max-width: 100%; max-height: 100%; object-fit: contain; }
.st-badge { font-size: 12px; font-weight: 600; } .st-badge.ok { color: var(--green); } .st-badge.bad { color: var(--red); } .st-badge.wait { color: var(--text3); }
a.btn.sm { text-decoration: none; display: inline-flex; align-items: center; }

/* ── «Test»: the preview picture in Настройки → Оформление. A miniature of the look itself (mono captions, hairlines, aluminium units with ports and LEDs,
   a tabular number and a linear gauge) drawn with the look's own tokens, so the card always shows the real thing — in both themes and with any accent. ── */
.look-prev[data-look="test"] { padding: 12px; border-radius: 12px; }
.tp { display: flex; flex-direction: column; gap: 9px; }
.tp-h { display: flex; align-items: baseline; justify-content: space-between; gap: 6px; font: 500 9px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--text3); }
.tp-h span:first-child { color: var(--text2); }
.tp-rack { position: relative; display: flex; flex-direction: column; gap: 3px; padding: 5px 8px; border: 1px solid var(--line2); border-radius: 6px; background: var(--card);
  box-shadow: inset 0 1px 0 var(--t-hl); }
/* rack rails: two dashed strips inside the frame, like the uprights of a real cabinet */
.tp-rack::before, .tp-rack::after { content: ""; position: absolute; top: 5px; bottom: 5px; width: 2px; border-radius: 1px;
  background: repeating-linear-gradient(180deg, var(--line2) 0 2px, transparent 2px 5px); }
.tp-rack::before { left: 2px; } .tp-rack::after { right: 2px; }
.tp-u { display: flex; align-items: center; gap: 4px; height: 9px; padding: 0 4px; border-radius: 2px; border: 1px solid var(--line); overflow: hidden;
  background: linear-gradient(180deg, color-mix(in srgb, var(--fill2) 86%, #fff 14%), var(--fill2)); }
.tp-u.hi { height: 13px; }
.tp-name { font: 500 6.5px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--text2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tp-led { width: 3px; height: 3px; border-radius: 50%; flex: none; background: var(--green); box-shadow: 0 0 5px var(--green); }
.tp-ports { display: flex; gap: 2px; margin-left: auto; flex: none; }
.tp-ports i { display: block; width: 6px; height: 5px; border-radius: 1px; border: 1px solid color-mix(in srgb, var(--line2) 70%, var(--text3)); background: var(--port-bg, #1a1c1e); }
.tp-nums { display: flex; align-items: flex-end; gap: 7px; }
.tp-v { font: 600 24px/.9 var(--mono); letter-spacing: -.04em; font-variant-numeric: tabular-nums; color: var(--text); }
.tp-v small { font-size: 11px; font-weight: 500; letter-spacing: 0; color: var(--text3); }
.tp-k { font: 500 8.5px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text2); padding-bottom: 3px; }
.tp-side { margin-left: auto; font: 500 8.5px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text3); padding-bottom: 3px; white-space: nowrap; }
.tp-scale { position: relative; height: 13px; border-bottom: 1px solid var(--line2); }
.tp-scale::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 5px;
  background-image: repeating-linear-gradient(90deg, var(--line2) 0 1px, transparent 1px 7px); }
.tp-scale i { position: absolute; left: 0; bottom: 0; height: 2px; border-radius: 0 2px 2px 0; background: var(--text); }
.tp-scale b { position: absolute; bottom: -4px; width: 1.5px; height: 8px; margin-left: -.75px; background: var(--accent); box-shadow: 0 0 6px color-mix(in srgb, var(--accent) 65%, transparent); }
.tp-foot { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.tp-mono { font: 500 8.5px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--text2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tp-btn { flex: none; font: 600 8.5px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; padding: 5px 8px; border-radius: 5px;
  background: var(--text); color: var(--t-inv); border: 1px solid var(--text); }
@media (max-width: 520px) { .tp-v { font-size: 26px; } .look-prev[data-look="test"] { padding: 14px; } }
/* «Гостевой Wi-Fi с порталом» */
.pt-live { display: grid; gap: 4px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; margin: 4px 0 8px; }
.pt-sec { border-top: 1px solid var(--line); }
.pt-sec-h { display: flex; align-items: center; gap: 10px; width: 100%; padding: 12px 2px; border: 0; background: none; color: var(--text); font: inherit; cursor: pointer; text-align: left; }
.pt-sec-h b { flex: none; } .pt-sec-h span { flex: 1; min-width: 0; font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pt-sec-h svg { transition: transform .2s; } .pt-sec.open .pt-sec-h svg { transform: rotate(90deg); }
.pt-sec-b { display: grid; gap: 10px; padding: 0 2px 14px; }
.pt-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.pt-ports { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 8px; }
.pt-port { display: grid; gap: 6px; padding: 10px; border: 1px solid var(--line); border-radius: 10px; position: relative; }
.pt-port b { font: 600 12px/1 var(--mono); letter-spacing: .1em; }
.pt-port span { font-size: 11.5px; color: var(--text3); }
.pt-port .select { height: 32px; font-size: 13px; padding: 0 6px; }
.pt-port.wan { background: color-mix(in srgb, var(--accent) 8%, transparent); }
.pt-port.r-guest { border-color: color-mix(in srgb, var(--orange) 55%, var(--line)); }
.pt-port.r-trunk { border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); }
.pt-port.r-off { opacity: .55; }
.pt-led { position: absolute; right: 10px; top: 11px; width: 7px; height: 7px; border-radius: 50%; background: var(--fill2); }
.pt-led.on { background: var(--green); box-shadow: 0 0 6px var(--green); }
.pt-mg { color: var(--accent) !important; font-weight: 600; }
.pt-tpls { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.pt-tpl { display: grid; gap: 6px; padding: 8px; border: 1px solid var(--line); border-radius: 12px; cursor: pointer; min-width: 0; }
.pt-tpl.on { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.pt-thumb { height: 200px; overflow: hidden; border-radius: 8px; background: var(--fill); position: relative; }
.pt-thumb iframe { width: 390px; height: 800px; border: 0; transform: scale(.36); transform-origin: 0 0; pointer-events: none; position: absolute; left: 0; top: 0; }
.pt-tpl { overflow: hidden; }
.pt-thumb { width: 100%; contain: strict; }
.pt-thumb iframe { left: 50% !important; margin-left: -195px; transform-origin: 50% 0 !important; }
/* «Добавить» → a type: devices of this type found in the network */
.sft { display: grid; gap: 8px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; margin: 4px 0 10px; }
.sft-h { display: flex; align-items: center; gap: 8px; border: 0; background: none; color: var(--text); font: inherit; cursor: pointer; padding: 0; text-align: left; }
.sft-row { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border: 1px solid var(--line); border-radius: 10px; background: none; color: var(--text); font: inherit; cursor: pointer; min-width: 0; }
.sft-row:hover { background: var(--fill); } .sft-row.on { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.sft-row small { display: block; font-size: 11.5px; }
.sft-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--green); box-shadow: 0 0 6px var(--green); flex: none; }

/* «Test» — «Карта сети» и «План»: the same instrument-panel language as the rest. A flat field with a fine dot grid, hairline panels with no blur,
   squared cards and frames, mono captions, thin strokes. Colour stays only where it carries meaning (link speed, status, selection). */
html[data-look="test"] .map-wrap, html[data-look="test"] .plan-canvas { border-radius: 14px; border: 1px solid var(--line); box-shadow: none;
  background: radial-gradient(circle at 1px 1px, var(--line2) .7px, transparent 0) 0 0 / 24px 24px, var(--bg2); }
html[data-look="test"] .map-panel, html[data-look="test"] .map-legend, html[data-look="test"] .plan-hint { background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: inset 0 1px 0 var(--t-hl); -webkit-backdrop-filter: none; backdrop-filter: none; }
html[data-look="test"] .map-legend, html[data-look="test"] .plan-hint { font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em; }
html[data-look="test"] .zoom-btns .btn { border-radius: 10px; background: var(--card); border: 1px solid var(--line2); box-shadow: none; font-family: var(--mono); font-weight: 400; }
html[data-look="test"] .zoom-btns .btn:hover { background: var(--fill); }
html[data-look="test"] .plan-open { border-radius: 10px; box-shadow: none; }
/* map nodes: a flat card with a hairline, a mono caption; the icon sits on a neutral square */
html[data-look="test"] .node rect.box { rx: 6px; fill: var(--card-solid); stroke: var(--line2); stroke-width: 1; filter: none; }
html[data-look="test"] .node:hover rect.box { stroke: var(--text2); stroke-width: 1; }
html[data-look="test"] .node.sel rect.box { stroke: var(--accent); stroke-width: 1.5; }
html[data-look="test"] .node.client rect.box { fill: var(--bg2); }
html[data-look="test"] .node.group rect.box { fill: transparent; stroke-dasharray: 3 4; }
html[data-look="test"] .node > rect:not(.box):not(.room-tag):not(.spof-mark) { rx: 5px; fill: var(--fill2); opacity: 1; stroke: var(--line2); stroke-width: 1; }
html[data-look="test"] .node .lbl { font-size: 12.5px; font-weight: 600; letter-spacing: -.01em; }
html[data-look="test"] .node .sub { font-size: 10px; letter-spacing: .03em; }
html[data-look="test"] .room-tag { rx: 3px; }
html[data-look="test"] .spof-mark { rx: 9px; }
html[data-look="test"] .port-pill rect { rx: 3px; }
html[data-look="test"] .port-pill text { letter-spacing: .04em; }
/* links: thin, the provider line a touch heavier */
html[data-look="test"] .edge { stroke-width: 1.5; }
html[data-look="test"] .edge.flow { stroke-width: 2; }
html[data-look="test"] .edge.isp { stroke-width: 3; opacity: 1; }
/* the cabinet frames on the map: aluminium like the 3D rack; text follows the theme (the old rule forced light text) */
html[data-look="test"] .rackbox rect.frame { rx: 8px; fill: var(--map-rack-frame); stroke: var(--map-rack-stroke); stroke-width: 1; }
html[data-look="test"] .rackbox .u rect { rx: 4px; fill: var(--map-unit); stroke: var(--map-unit-stroke); }
html[data-look="test"] .rackbox .u rect[width="4"] { rx: 2px; fill: var(--text3); stroke: none; }
html[data-look="test"] .rackbox text { fill: var(--text); }
html[data-look="test"] .rackbox .usub { fill: var(--text3); font-family: var(--mono); letter-spacing: .05em; }
html[data-look="test"] .rackbox .u-ic { color: var(--text2); }
/* the plan: the yard is a dashed outline, buildings are flat cards, walls are plain strokes, rooms lose most of their colour */
html[data-look="test"] .plan-yard { fill: color-mix(in srgb, var(--text) 3%, transparent); stroke: var(--line2); stroke-width: 1; stroke-dasharray: 6 5; rx: 10px; }
html[data-look="test"] .plan-building .pi-card { rx: 8px; fill: var(--card-solid); stroke: var(--line2); stroke-width: 1; }
html[data-look="test"] .plan-building.sel .pi-card { stroke: var(--accent); stroke-width: 1.5; }
html[data-look="test"] .pb-name { font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
html[data-look="test"] .pb-sub { font-family: var(--mono); font-size: 10.5px; letter-spacing: .04em; }
html[data-look="test"] .pb-hint { font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase; }
html[data-look="test"] .plan-link { stroke: var(--text2); stroke-width: 1.5; }
html[data-look="test"] .plan-link-label { fill: var(--text); font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: .06em; }
html[data-look="test"] .plan-wall { stroke: var(--text); stroke-width: 4; stroke-linecap: square; }
html[data-look="test"] .plan-wall.ghost { stroke: var(--text3); }
html[data-look="test"] .plan-room { filter: saturate(.25); }
html[data-look="test"] .pr-tag { font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: .06em; }
html[data-look="test"] .plan-label text { font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; }
html[data-look="test"] .plan-item .pi-label { font-family: var(--mono); font-size: 11px; font-weight: 650; letter-spacing: .02em; }
html[data-look="test"] .plan-item .pi-bg, html[data-look="test"] .pole-bg { stroke-width: 1.5; }

/* the icon picker (Карта сети → узел → «Иконка») */
.ip-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(86px, 1fr)); gap: 8px; }
.ip-tile { position: relative; min-width: 0; }
.ip-btn { width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; padding: 12px 4px 8px; min-height: 76px; border: 1px solid var(--line); border-radius: 12px; background: var(--fill); color: var(--text); font: inherit; cursor: pointer; }
.ip-btn:hover { background: var(--fill2); }
.ip-btn:disabled { opacity: .6; cursor: default; }
.ip-tile.on .ip-btn { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.ip-cap { max-width: 100%; font-size: 10.5px; line-height: 1.2; color: var(--text2); text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ip-del { position: absolute; top: 4px; right: 4px; width: 20px; height: 20px; display: grid; place-items: center; padding: 0; border: 1px solid var(--line2); border-radius: 50%; background: var(--card-solid, var(--bg2)); color: var(--text2); cursor: pointer; }
.ip-del:hover { color: var(--red); border-color: var(--red); }
html[data-look="test"] .ip-btn { background: transparent; border-radius: 8px; }
html[data-look="test"] .ip-btn:hover { background: var(--fill); }
html[data-look="test"] .ip-cap { font-family: var(--mono); font-size: 9.5px; letter-spacing: .04em; }
/* Settings → О программе → Потребление */
.us-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
@media (max-width: 640px) { .us-tiles { grid-template-columns: 1fr 1fr; } }
.us-tiles > div { display: flex; flex-direction: column; gap: 1px; min-width: 0; padding: 10px 12px; border-radius: 12px; background: var(--fill); }
.us-tiles b { font-size: 18px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.us-tiles span { font-size: 12px; color: var(--text2); }
.us-tiles small { font-size: 11px; color: var(--text3); min-height: 14px; }
.us-charts { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 640px) { .us-charts { grid-template-columns: 1fr; } }
.us-rows { display: grid; gap: 9px; margin-bottom: 12px; }
html[data-look="test"] .us-tiles > div { background: transparent; border: 1px solid var(--line); border-radius: 8px; }
html[data-look="test"] .us-tiles b { font-family: var(--mono); font-weight: 500; }
html[data-look="test"] .us-tiles span { font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; }
/* the covers of the built-in looks (Настройки → Оформление) */
.look-cover { border-radius: 10px; overflow: hidden; line-height: 0; border: 1px solid var(--line); background: #000; }
.look-skin.on .look-cover { border-color: var(--accent); }
/* Frank: how full the window is, «/» commands, notes inside the chat */
.ai-ctx { padding: 6px 12px 2px; }
.fr-dock .ai-ctx { padding: 2px 4px 6px; }
.ai-ctx-bar { height: 3px; border-radius: 2px; background: var(--fill2); overflow: hidden; }
.ai-ctx-bar i { display: block; height: 100%; border-radius: 2px; transition: width .4s, background .3s; }
.ai-ctx-row { display: flex; align-items: center; gap: 8px; margin-top: 4px; font-size: 11.5px; color: var(--text3); font-variant-numeric: tabular-nums; }
.ai-ctx-row span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-ctx-btn { flex: none; border: 1px solid var(--line2); background: transparent; color: var(--text); border-radius: 8px; padding: 2px 9px; font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer; }
.ai-ctx-btn:hover { background: var(--fill); }
.ai-cmds { display: grid; gap: 2px; padding: 4px; margin: 0 8px 6px; border: 1px solid var(--line); border-radius: 12px; background: var(--card-solid, var(--bg2)); }
.fr-dock .ai-cmds { margin: 0 0 6px; }
.ai-cmds button { display: flex; align-items: baseline; gap: 10px; width: 100%; padding: 7px 10px; border: 0; border-radius: 8px; background: transparent; color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.ai-cmds button:hover { background: var(--fill); }
.ai-cmds b { font-family: var(--mono); font-size: 13px; font-weight: 600; flex: none; }
.ai-cmds span { font-size: 12.5px; color: var(--text2); min-width: 0; }
.ai-note-line { align-self: center; max-width: 92%; margin: 6px auto; padding: 6px 12px; border: 1px dashed var(--line2); border-radius: 10px; font-size: 12px; line-height: 1.45; color: var(--text2); text-align: center; white-space: pre-wrap; }
html[data-look="test"] .ai-ctx-row, html[data-look="test"] .ai-note-line { font-family: var(--mono); font-size: 10.5px; letter-spacing: .03em; }
/* Frank: attachments (files, photos) and the memory editor */
.ai-att { display: flex; gap: 6px; flex-wrap: wrap; padding: 0 12px 6px; }
.fr-dock .ai-att { padding: 0 2px 6px; }
.ai-att-chip { display: flex; align-items: center; gap: 6px; max-width: 220px; padding: 3px 4px 3px 3px; border: 1px solid var(--line2); border-radius: 10px; background: var(--fill); font-size: 12px; }
.ai-att-chip.busy { opacity: .6; }
.ai-att-chip img { width: 34px; height: 34px; object-fit: cover; border-radius: 7px; display: block; flex: none; }
.ai-att-ic { width: 34px; height: 34px; display: grid; place-items: center; border-radius: 7px; background: var(--fill2); flex: none; }
.ai-att-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-att-chip button { flex: none; width: 20px; height: 20px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--text2); cursor: pointer; }
.ai-att-chip button:hover { background: var(--fill2); color: var(--text); }
.ai-msg-files { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.ai-msg-files img { display: block; max-width: 220px; max-height: 200px; border-radius: 10px; object-fit: cover; }
.ai-file { display: inline-flex; align-items: center; gap: 6px; padding: 5px 9px; border-radius: 9px; background: rgba(255,255,255,.18); color: inherit; font-size: 12.5px; text-decoration: none; max-width: 240px; }
.ai-file small { opacity: .7; }
.ai-foot > .btn:first-of-type { flex: none; }
.ai-mem { width: 100%; min-height: 280px; font-size: 13px; line-height: 1.5; resize: vertical; }
.ai-note-line { text-align: left; }

/* ── мини-браузер Frank: скриншоты страниц прямо в ответе ─────────────────────────────────────────────────────────────────────────── */
.ai-shots { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 4px; }
.ai-shot { display: block; border-radius: 10px; overflow: hidden; border: 1px solid var(--line); background: var(--card); max-width: 100%; line-height: 0; }
.ai-shot img { display: block; width: auto; max-width: 100%; max-height: 340px; object-fit: contain; }
.ai-shot:hover { border-color: var(--line2); }
@media (max-width: 700px) { .ai-shot img { max-height: 260px; } }

/* «План»: контуры домов поверх карты, углы, подпись источника снимка */
.plan-outline { fill: color-mix(in srgb, var(--accent) 22%, transparent); stroke: var(--accent); stroke-width: 2.5; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.plan-outlined:hover .plan-outline { fill: color-mix(in srgb, var(--accent) 32%, transparent); }
.plan-outlined.sel .plan-outline { stroke-width: 4; fill: color-mix(in srgb, var(--accent) 34%, transparent); }
.plan-outline-name { font-size: 14px; font-weight: 750; fill: #fff; paint-order: stroke; stroke: rgba(0, 0, 0, .75); stroke-width: 3.5px; stroke-linejoin: round; pointer-events: none; }
.plan-outline-sub { font-size: 11.5px; font-weight: 600; fill: #fff; paint-order: stroke; stroke: rgba(0, 0, 0, .7); stroke-width: 3px; stroke-linejoin: round; pointer-events: none; }
.plan-vtx { fill: #fff; stroke: var(--accent); stroke-width: 2.5; cursor: grab; vector-effect: non-scaling-stroke; }
.plan-vtx.sel { fill: var(--accent); }
.plan-vtx.first { fill: var(--accent); stroke: #fff; }
.plan-vtx.ghost { fill: color-mix(in srgb, var(--accent) 35%, #fff); opacity: .75; }
.plan-draft-line { fill: color-mix(in srgb, var(--accent) 14%, transparent); stroke: var(--accent); stroke-width: 2.5; stroke-dasharray: 6 4; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.plan-attr { fill: #fff; paint-order: stroke; stroke: rgba(0, 0, 0, .7); stroke-width: 2.5px; pointer-events: none; }
.plan-attrib { position: absolute; left: 10px; bottom: 8px; font-size: 10.5px; color: #fff; text-shadow: 0 0 3px #000, 0 0 6px #000; pointer-events: none; max-width: 70%; }

/* «Живая карта (3D)» */
/* ── «Карта» и «План» на весь экран + выезжающее меню (38_workmenu.jsx) ── */
html[data-mapfull] body { overflow: hidden; }
main.page.page-full { min-height: 0; padding: 0; max-width: none; margin: 0; }
.page-full .map-wrap, .page-full .plan-canvas, .page-full .live-map { position: fixed; left: 0; right: 0; top: var(--tb-h, 62px); bottom: var(--bb-h, 0px); height: auto !important; min-height: 0;
  border-radius: 0 !important; border: 0 !important; box-shadow: none !important; z-index: 1; }
.page-full .plan { margin: 0; }
.wm-fab { position: fixed; z-index: 56; width: 40px; height: 40px; border-radius: 12px; border: 1px solid var(--line2); background: var(--card-solid); color: var(--text); display: grid; place-items: center; cursor: pointer;
  padding: 0; box-shadow: 0 4px 14px rgba(0, 0, 0, .22); top: calc(var(--tb-h, 62px) + 10px); right: calc(env(safe-area-inset-right, 0px) + 12px); transition: transform .12s; }
.wm-fab:active { transform: scale(.92); } .wm-fab.on { background: var(--accent); color: #fff; border-color: transparent; }
@media (max-width: 760px) { html:not([data-look="test"]) .wm-fab { top: calc(env(safe-area-inset-top, 0px) + 11px); right: calc(env(safe-area-inset-right, 0px) + 62px); } }
html[data-look="test"] .wm-fab { top: calc(env(safe-area-inset-top, 0px) + 11px); right: calc(env(safe-area-inset-right, 0px) + 12px); border-radius: 8px; box-shadow: none; }
.wm-wrap { position: fixed; inset: 0; z-index: 55; background: rgba(0, 0, 0, .28); animation: wmfade .15s; }
@keyframes wmfade { from { opacity: 0; } } @keyframes wmin { from { opacity: 0; transform: translateX(26px); } }
.wm-panel { position: absolute; right: calc(env(safe-area-inset-right, 0px) + 8px); top: calc(var(--tb-h, 62px) + 6px); width: min(94vw, 360px); display: flex; flex-direction: column;
  max-height: calc(100dvh - var(--tb-h, 62px) - env(safe-area-inset-bottom, 0px) - 18px); background: var(--card-solid); color: var(--text); border: 1px solid var(--line2); border-radius: 18px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .4); animation: wmin .22s cubic-bezier(.2, 1, .3, 1); overflow: hidden; }
@media (min-width: 761px) { html:not([data-look="test"]) .wm-panel { top: calc(var(--tb-h, 62px) + 58px); max-height: calc(100dvh - var(--tb-h, 62px) - 76px); } }
.wm-head { display: flex; align-items: center; padding: 12px 56px 4px 16px; font-size: 15px; }
.wm-body { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 4px 8px 12px; }
.wm-sec { padding: 6px 4px; } .wm-sec + .wm-sec { border-top: 1px solid var(--line); }
.wm-sec-t { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text3); padding: 6px 8px 4px; }
.wm-slots:empty { display: none; } .wm-slots { padding: 0; }
.wm-item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 11px 10px; border: 0; border-radius: 12px; background: transparent; color: var(--text); font: inherit; font-size: 15px; text-align: left; cursor: pointer; }
.wm-item:hover { background: var(--fill); } .wm-item:active { background: var(--fill2); }
.wm-item:disabled { opacity: .4; cursor: default; }
.wm-item.on { color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); } .wm-item.danger { color: var(--red); }
.wm-item.sw { cursor: default; } .wm-item.sw:hover { background: transparent; }
.wm-lbl { flex: 1; min-width: 0; display: flex; flex-direction: column; } .wm-lbl small { color: var(--text2); font-size: 12px; margin-top: 1px; }
.wm-choice { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 6px; padding: 2px 4px; }
.wm-choice button { display: flex; align-items: center; justify-content: center; gap: 7px; padding: 10px 8px; border: 0; border-radius: 12px; background: var(--fill); color: var(--text); font: inherit; font-size: 14px; font-weight: 600; cursor: pointer; }
.wm-choice button.on { background: var(--accent); color: #fff; }
.wm-colors { display: flex; flex-wrap: wrap; gap: 8px; padding: 6px 8px; }
.wm-colors button { width: 30px; height: 30px; border-radius: 50%; border: 2px solid var(--line2); padding: 0; cursor: pointer; }
.wm-colors button.auto { width: auto; padding: 0 12px; border-radius: 15px; font: inherit; font-size: 12.5px; font-weight: 600; background: var(--fill); color: var(--text); }
.wm-colors button.on { outline: 2.5px solid var(--accent); outline-offset: 2px; }
.wm-editpill { position: fixed; z-index: 6; left: 10px; top: calc(var(--tb-h, 62px) + 8px); display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 20px; font-size: 12.5px; font-weight: 700;
  background: color-mix(in srgb, var(--orange) 22%, var(--card-solid)); color: var(--orange); border: 1px solid color-mix(in srgb, var(--orange) 45%, transparent); pointer-events: none; }
.page-full .map-tools { padding-right: 62px; }
.live-map { position: relative; flex: 1; min-height: 0; }
.live-map .maplibregl-canvas { outline: none; touch-action: none; }
.live-map .maplibregl-canvas-container { touch-action: none; }
.live-msg { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 4; color: #fff; background: rgba(0, 0, 0, .65); padding: 10px 14px; border-radius: 12px; max-width: 80%; text-align: center; font-size: 14px; }
.live-msg.err { background: rgba(160, 30, 30, .85); }
.live-msg.hint { top: auto; bottom: 18px; transform: translateX(-50%); font-size: 13px; }
.live-loading-panel { position: absolute; top: 10px; left: 58px; z-index: 5; width: min(270px, calc(100% - 130px)); display: grid; gap: 6px; pointer-events: none; }
.live-loading-status, .live-loading-houses { background: var(--card-solid); color: var(--text); border: 1px solid var(--line2); border-radius: 12px; box-shadow: var(--shadow); padding: 8px 10px; }
.live-loading-heading { display: flex; justify-content: space-between; gap: 12px; font-size: 12px; font-weight: 650; }
.live-loading-heading b { color: var(--accent); font-variant-numeric: tabular-nums; }
.live-loading-track, .live-loading-indeterminate { height: 4px; border-radius: 9px; background: var(--fill2); overflow: hidden; margin-top: 6px; }
.live-loading-track i, .live-loading-indeterminate::after { display: block; height: 100%; border-radius: inherit; background: var(--accent); }
.live-loading-track i { transition: width .18s ease; }
.live-loading-indeterminate::after { content: ''; width: 35%; animation: live-loading 1.2s ease-in-out infinite alternate; }
@keyframes live-loading { from { transform: translateX(0); } to { transform: translateX(185%); } }
@media (prefers-reduced-motion: reduce) { .live-loading-indeterminate::after { animation: none; } }
.live-loading-status small { display: block; color: var(--text3); font-size: 10px; margin-top: 4px; }
.live-loading-houses { display: grid; gap: 5px; font-size: 11px; color: var(--text2); pointer-events: auto; }
.live-loading-houses .select { width: 100%; min-width: 0; font-size: 13px; }
.plan-settings { display: grid; gap: 12px; }
.plan-settings input[type="range"] { width: 100%; accent-color: var(--accent); }
.live-label { color: #fff; font: 700 13px/1 -apple-system, system-ui, sans-serif; padding: 5px 9px; border-radius: 9px; background: rgba(0, 0, 0, .58); border: 1px solid rgba(255, 255, 255, .28); white-space: nowrap; cursor: pointer; text-shadow: 0 1px 2px #000; }
.live-pole { width: 14px; height: 14px; border-radius: 50%; background: #0a84ff; border: 2px solid #fff; box-shadow: 0 0 6px #000; }
.live-root { display: contents; }
.live-find { position: absolute; top: 10px; left: 58px; right: 10px; z-index: 6; max-width: 460px; padding: 8px; border-radius: 14px; background: var(--card-solid); color: var(--text); border: 1px solid var(--line2); box-shadow: 0 8px 30px rgba(0, 0, 0, .4); }
.live-find .list { margin-top: 6px; max-height: 46vh; overflow: auto; }
.live-pole.sel { box-shadow: 0 0 0 4px #fff, 0 0 8px #000; }
.live-node { display: flex; align-items: center; gap: 6px; padding: 4px 9px 4px 6px; border-radius: 10px; background: rgba(0, 0, 0, .62); color: #fff; border: 1.5px solid rgba(255, 255, 255, .85); font: 600 12px/1 -apple-system, system-ui, sans-serif; white-space: nowrap; cursor: pointer; }
.live-node i { width: 11px; height: 11px; border-radius: 3px; background: #8e8e93; flex: none; }
.live-node.online i { background: #30d158; } .live-node.warning i { background: #ff9f0a; } .live-node.offline i { background: #ff453a; }
.live-node.sel { box-shadow: 0 0 0 3px #0a84ff; }
.live-card, .live-bar { position: absolute; left: 12px; right: 12px; margin: 0 auto; bottom: calc(env(safe-area-inset-bottom, 0px) + 14px); z-index: 5; max-width: 440px; padding: 12px; border-radius: 16px;
  background: var(--card-solid); color: var(--text); border: 1px solid var(--line2); box-shadow: 0 8px 30px rgba(0, 0, 0, .45); }
.live-card { max-height: 72%; overflow: auto; }
.live-bar { display: flex; flex-direction: column; gap: 8px; max-width: 520px; }
.live-bar-t { font-size: 13.5px; line-height: 1.35; } .live-bar-b { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
.live-label.sel { background: var(--accent); border-color: #fff; }
.live-vtx { width: 22px; height: 22px; border-radius: 50%; background: #fff; border: 3px solid #0a84ff; box-shadow: 0 1px 6px rgba(0, 0, 0, .5); cursor: grab; }
.live-vtx.sel { background: #ff9f0a; border-color: #fff; }
.live-mid { width: 18px; height: 18px; border-radius: 50%; background: rgba(10, 132, 255, .92); color: #fff; font: 700 14px/16px -apple-system, system-ui, sans-serif; text-align: center; cursor: pointer; border: 1.5px solid #fff; }
.live-move { width: 34px; height: 34px; border-radius: 50%; background: #0a84ff; color: #fff; font: 700 18px/31px -apple-system, system-ui, sans-serif; text-align: center; cursor: grab; border: 2px solid #fff; box-shadow: 0 2px 8px rgba(0, 0, 0, .5); }
.house-style { margin-top: 8px; border-top: 1px solid var(--line); padding-top: 6px; }
.plan-ctx { position: absolute; top: 10px; left: 10px; z-index: 3; display: flex; align-items: center; gap: 8px; max-width: calc(100% - 20px); padding: 5px 10px 5px 5px; border-radius: 14px;
  background: var(--elev); border: .5px solid var(--line); box-shadow: var(--shadow); backdrop-filter: blur(14px); font-size: 14px; }
.plan-ctx b { min-width: 0; flex: 1; }
.plan-ctx .btn { flex: none; }
.plan-floors { position: absolute; top: 58px; left: 10px; right: 70px; z-index: 3; display: flex; gap: 6px; overflow-x: auto; padding: 2px; }
.plan-floor-picker { display: inline-flex; align-items: center; gap: 8px; padding: 7px 11px; border-radius: 12px; border: 1px solid var(--line2); background: var(--elev); color: var(--text2); font-size: 12px; }
.plan-floor-picker select { min-width: 120px; max-width: 180px; padding: 4px 22px 4px 6px; border: 0; border-radius: 7px; font: inherit; font-weight: 650; color: var(--text); background-color: var(--card-solid); }
.plan-tool-current { position: absolute; top: 98px; right: 10px; z-index: 3; display: flex; align-items: center; gap: 6px; padding: 7px 10px; border: 1px solid color-mix(in srgb, var(--accent) 58%, transparent); border-radius: 999px; color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, var(--card-solid)); box-shadow: var(--shadow); backdrop-filter: blur(12px); font-size: 12px; font-weight: 700; pointer-events: none; }
.plan-palette { position: absolute; left: 10px; right: 70px; bottom: 12px; z-index: 3; max-height: 40%; overflow: auto; }
.plan-testcard { position: absolute; left: 10px; right: 70px; bottom: 12px; z-index: 3; max-height: 55%; overflow: auto; }
.plan-cov { position: absolute; left: 10px; bottom: 46px; z-index: 3; background: var(--elev); padding: 6px 10px; border-radius: 12px; border: .5px solid var(--line); }
.plan-cov { max-width: calc(100% - 76px); flex-wrap: wrap; gap: 5px 10px; font-size: 11px; pointer-events: none; }
.plan-coverage-settings { display: grid; gap: 8px; padding: 4px 10px 10px; }
.plan-coverage-settings label { display: grid; gap: 4px; color: var(--text2); font-size: 12px; min-width: 0; }
.plan-coverage-settings .select { width: 100%; min-width: 0; font-size: 13px; }
.plan-app-header { padding-right:68px !important; gap:6px; }
.plan-app-brand { display:flex; align-items:center; gap:9px; min-width:0; }
.plan-app-brand>div { display:grid; min-width:0; gap:2px; }
.plan-app-brand b { font-size:16px; }
.plan-app-brand small { font-size:10px; color:var(--text3); max-width:160px; }
html.plan-mode .wm-fab { top:calc(env(safe-area-inset-top,0px) + 11px); right:calc(env(safe-area-inset-right,0px) + 12px); }
@media(max-width:400px) { .plan-app-brand small { max-width:85px; } .plan-app-header .btn { min-width:32px; padding:8px; } }
.plan-survey-card { position:absolute; z-index:5; left:12px; bottom:14px; width:min(380px,calc(100% - 94px)); padding:14px; border:1px solid color-mix(in srgb,var(--accent) 30%,var(--line)); border-radius:18px; background:var(--elev); box-shadow:0 12px 36px #0003; box-sizing:border-box; max-height:44%; overflow:auto; touch-action:pan-y; overscroll-behavior:contain; }
.plan-survey-head { display:flex; align-items:center; gap:10px; }
.plan-survey-head .grow { min-width:0; }
.plan-survey-head small { display:block; font-size:9px; font-weight:700; letter-spacing:1px; color:var(--accent); margin-bottom:3px; }
.plan-survey-head b { display:block; font-size:15px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.plan-survey-badge { display:grid; place-items:center; width:36px; height:36px; border-radius:11px; color:var(--accent); background:color-mix(in srgb,var(--accent) 13%,transparent); flex:none; }
.plan-survey-progress { display:flex; gap:8px; margin:12px 0 8px; }
.plan-survey-progress button { display:grid; place-items:center; min-width:32px; height:32px; border:1px solid var(--line); border-radius:10px; color:var(--text2); background:var(--bg2); font:inherit; font-size:12px; font-weight:600; cursor:pointer; }
.plan-survey-close { display:grid; place-items:center; width:32px; height:32px; flex:none; border:0; border-radius:9px; color:var(--text2); background:transparent; cursor:pointer; }
.plan-survey-close:hover { background:color-mix(in srgb,var(--accent) 12%,transparent); color:var(--accent); }
.plan-survey-progress button.current { color:var(--accent); border-color:var(--accent); box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 12%,transparent); }
.plan-survey-progress button.done { color:var(--green); background:color-mix(in srgb,var(--green) 12%,var(--bg2)); }
.plan-survey-card p { color:var(--text2); font-size:12px; line-height:1.5; margin:10px 0; }
.plan-survey-card p b { color:var(--text); font-size:13px; }
.plan-survey-foot { margin-top:10px; font-size:10px; color:var(--text3); }
.plan-survey-end { display:block; padding:6px 0 0; border:0; background:none; color:var(--text3); font:inherit; text-decoration:underline; cursor:pointer; }
.plan-survey-warning,.plan-survey-note { padding:8px 10px; margin:8px 0; font-size:12px; line-height:1.45; border-radius:10px; background:color-mix(in srgb,var(--orange) 12%,var(--bg2)); color:var(--text); }
.plan-survey-note { background:color-mix(in srgb,var(--accent) 9%,var(--bg2)); color:var(--text2); }
.plan-survey-stop .plan-survey-dot { fill:var(--elev); stroke:var(--accent); stroke-width:2; }
.plan-survey-stop text { fill:var(--accent); font-size:12px; font-weight:700; }
.plan-survey-stop.current .plan-survey-dot { fill:var(--accent); }
.plan-survey-stop.current text { fill:#fff; }
.plan-survey-stop.done .plan-survey-dot { fill:var(--green); stroke:var(--green); }
.plan-survey-stop.done text { fill:#fff; }
.plan-survey-halo { fill:none; stroke:var(--accent); stroke-width:2; transform-box:fill-box; transform-origin:center; animation:survey-breathe 2s ease-in-out infinite; }
@keyframes survey-breathe { 0%,100% {opacity:.65;transform:scale(.85)} 50% {opacity:.15;transform:scale(1.2)} }
@media(prefers-reduced-motion:reduce) { .plan-survey-halo { animation:none; } }
.survey-intro { color:var(--text); line-height:1.5; font-size:14px; }
.survey-intro p { margin:6px 0 10px; color:var(--text2); }
.survey-intro .dim { font-size:12px; }
.survey-room-list { display:grid; gap:8px; margin-top:16px; }
.survey-room-choice { display:flex; align-items:center; gap:12px; width:100%; padding:14px; color:var(--text); background:var(--bg2); border:1px solid var(--line); border-radius:13px; text-align:left; cursor:pointer; font:inherit; }
.survey-room-choice:hover { border-color:var(--accent); }
.survey-room-choice>svg { color:var(--accent); flex:none; }
.survey-room-choice span { display:grid; gap:3px; flex:1; min-width:0; }
.survey-room-choice small { color:var(--text3); font-size:12px; }
.survey-measure-intro { display:grid; gap:4px; padding:12px; background:color-mix(in srgb,var(--accent) 9%,var(--bg2)); border-radius:12px; }
.survey-measure-intro span { color:var(--text2); font-size:12px; line-height:1.45; }
@media(max-width:400px) { .plan-survey-card { padding:11px; left:8px; width:calc(100% - 82px); } .plan-survey-progress { gap:6px; } }
.plan-open-g { position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 3; display: flex; gap: 8px; }
.plan-open-g .plan-open { position: static; transform: none; }
.page-full .zoom-btns { bottom: calc(env(safe-area-inset-bottom, 0px) + 12px); }
.page-full > .plan-empty, .page-full .plan > .plan-empty { margin: calc(var(--tb-h, 62px) + 16px) 14px 90px; }
.map-wrap.scoped .map-tools { top: 58px; }
.wm-fab.edit { border-color: var(--orange); }
.wm-fab.edit::after { content: ""; position: absolute; top: -3px; right: -3px; width: 10px; height: 10px; border-radius: 50%; background: var(--orange); border: 2px solid var(--card-solid); }


