/* Web Panel v6 beta: v6-glass.css (see web-src/v6/README.md)
   macOS-style frosted glass over a CSS-only wallpaper.  Dark glass is the default (no data-theme, any OS); light is the
   bright frosted-mist variant ([data-theme="light"], the design's toggle + localStorage 's1n-v5c-theme' keep working).
   Token contract for the other v6 files: --v6-wall --v6-glass --v6-glass-strong --v6-glass-soft --v6-stroke --v6-hi
   --v6-text --v6-muted --v6-accent --v6-accent-2 --v6-ok --v6-warn --v6-bad --v6-blur --v6-radius --v6-radius-sm --v6-shadow.
   This file runs after every design style, so the design's own tokens are remapped here and the whole panel turns glass;
   the rules below only add what tokens cannot (wallpaper, blur, pills, highlights).  Looks only: no layout, text or data. */

/* ================= 1. TOKENS ================= */
/* Colour family = the Sky1Net logo (design/brand/sky1net-logo-hero.webp, measured): base navy #000020 / #001030, deep navy #001850-#002050,
   royal blue #0030a8 / #003090 / #0048d8, electric blue #0060f0 / #0078f0 (the "1" and the swoosh), swoosh cyan-blue #16aef8, silver wordmark.
   Dark = navy base + royal / electric waves; light = pale blue mist + soft royal waves.  Semantic ok / warn / bad stay green / amber / red. */
html:root{
  --v6-blur:18px;--v6-radius:18px;--v6-radius-sm:12px;--v6-radius-lg:24px;
  --v6-bf:blur(var(--v6-blur)) saturate(140%);
  /* the dark wallpaper base (also used by the splash): ONE gradient, deep navy with a soft royal glow at the top fading to the base navy.
     Calm on purpose (owner 2026-10-02): the page is THREE layers, see section 2: this base + two slow, soft waves (the --v6-wave-* images). */
  --v6-wall-dark:radial-gradient(135% 80% at 50% -14%,#0b3496 0%,#082064 22%,#051443 44%,#040e30 66%,#030a24 86%,#02071b 100%);
}
/* dark glass: the default, with or without [data-theme="dark"], whatever the OS says */
html:root:not([data-theme="light"]){
  color-scheme:dark;
  --v6-base:#030a24;
  --v6-wall:var(--v6-wall-dark);
  --v6-wave-a:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 440' preserveAspectRatio='none'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='rgb(11,92,238)' stop-opacity='0.21'/%3E%3Cstop offset='0.5' stop-color='rgb(0,52,170)' stop-opacity='0.11'/%3E%3Cstop offset='1' stop-color='rgb(0,30,110)' stop-opacity='0'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M0 190 C 200 110,400 110,600 190 S 1000 270,1200 190 L1200 440 L0 440 Z' fill='url("/v6/%23g")' opacity='0.25' transform='translate(0,-30)'/%3E%3Cpath d='M0 190 C 200 110,400 110,600 190 S 1000 270,1200 190 L1200 440 L0 440 Z' fill='url("/v6/%23g")' opacity='0.5' transform='translate(0,-14)'/%3E%3Cpath d='M0 190 C 200 110,400 110,600 190 S 1000 270,1200 190 L1200 440 L0 440 Z' fill='url("/v6/%23g")'/%3E%3C/svg%3E");
  --v6-wave-b:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 340' preserveAspectRatio='none'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='rgb(74,152,255)' stop-opacity='0.15'/%3E%3Cstop offset='0.55' stop-color='rgb(11,92,238)' stop-opacity='0.09'/%3E%3Cstop offset='1' stop-color='rgb(0,60,200)' stop-opacity='0'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M0 150 C 220 215,420 215,600 150 S 1000 85,1200 150 L1200 340 L0 340 Z' fill='url("/v6/%23g")' opacity='0.25' transform='translate(0,-30)'/%3E%3Cpath d='M0 150 C 220 215,420 215,600 150 S 1000 85,1200 150 L1200 340 L0 340 Z' fill='url("/v6/%23g")' opacity='0.5' transform='translate(0,-14)'/%3E%3Cpath d='M0 150 C 220 215,420 215,600 150 S 1000 85,1200 150 L1200 340 L0 340 Z' fill='url("/v6/%23g")'/%3E%3Cpath d='M0 150 C 220 215,420 215,600 150 S 1000 85,1200 150' fill='none' stroke='rgb(150,208,255)' stroke-opacity='0.14' stroke-width='1.2' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
  --v6-glass:rgba(12,32,84,.58);
  --v6-glass-strong:rgba(6,18,54,.90);
  --v6-glass-soft:rgba(190,215,255,.08);
  --v6-glass-bar:rgba(4,12,40,.84);
  --v6-stroke:rgba(165,200,255,.20);
  --v6-hi:rgba(200,225,255,.22);
  --v6-text:#eef4ff;--v6-muted:#b6c7e4;
  --v6-accent:#4a98ff;--v6-accent-2:#7cc6ff;
  --v6-ok:#4be0a0;--v6-warn:#ffc857;--v6-bad:#ff8590;
  --v6-on-accent:#fff;
  --v6-grad-accent:linear-gradient(180deg,#1c72fa 0%,#0b5cee 42%,#0640c6 100%);
  --v6-shadow:0 14px 44px rgba(0,4,24,.46),0 2px 8px rgba(0,4,24,.28);
  --v6-well:inset 0 1px 3px rgba(0,4,24,.42);
  --v6-thumb:rgba(190,215,255,.18);
  /* the design's own tokens -> glass (dark) */
  --bg:#030a24;--surface:var(--v6-glass);--surface-2:rgba(170,200,255,.07);--surface-3:rgba(170,200,255,.13);
  --line:rgba(165,200,255,.15);--line-strong:rgba(165,200,255,.28);
  --ink:var(--v6-text);--ink-2:#d4dff2;--muted:var(--v6-muted);
  --brand:#3d8bff;--brand-strong:#2a74f0;--brand-hover:#63a5ff;--brand-ink:#86b9ff;--brand-soft:rgba(61,139,255,.18);--on-brand:#fff;
  --glow:#3db4fa;--grad-brand:linear-gradient(135deg,#3a9bff 0%,#0a5cf0 48%,#0636a8 100%);--grad-cta:linear-gradient(135deg,#1a73ff 0%,#0a55dd 55%,#0838a0 100%);
  --wmt-1:#eef3fa;--wmt-2:#aebbd0;--wmt-3:#5d6b82;--wmt-one:#2b8cff;--wmt-glow:#2b8cff8c;
  --band:#051a52;--band-2:#020a26;--band-ink:#f1f6ff;--band-muted:#b2c4e6;--band-line:rgba(165,200,255,.2);--band-star:#8cc4ff;--band-glass:rgba(190,215,255,.09);
  --map-ok:#4be0a0;--map-warn:#ffc857;--map-bad:#ff8590;--map-info:#9fd0ff;--map-idle:#8aa6d4;--map-node:#06194f;
  --ok:#4be0a0;--ok-soft:rgba(75,224,160,.15);--warn:#ffc857;--warn-soft:rgba(255,200,87,.15);--bad:#ff8590;--bad-soft:rgba(255,133,144,.16);
  --info:#7cc0ff;--info-soft:rgba(124,192,255,.15);--idle:#9fb2d4;--idle-soft:rgba(190,215,255,.09);
  --focus:#8fd0ff;
  --s-de:#4a94ff;--s-de2:#6f9fe8;--s-ruh1:#25b8f5;--s-ruh2:#8097bd;--s-ruh3:#9ccfff;--s-ruh4:#2a9fe6;
  --lease:#6f93c8;
  --spd-bg:rgba(74,152,255,.15);--spd-hot-bg:rgba(74,152,255,.24);--spd-ink:#b8d8ff;--spd-line:rgba(74,152,255,.38);--spd-dn:#6aa8ff;--spd-up:#3cc8ff;--spd-glow:rgba(74,152,255,.36);
  --scrim:rgba(1,6,26,.62);
  --shadow-1:0 8px 28px rgba(0,4,24,.3);--shadow-2:0 28px 80px rgba(0,3,18,.6);
  --r-6:8px;--r-8:12px;--r-12:var(--v6-radius);--r-16:var(--v6-radius-lg);
  /* conn-kit («متصل» column): its light tokens would win under an OS-light browser, so the dark ones are restated */
  --conn-hl:rgba(190,215,255,.06);--conn-warn-fill:#f2b447;--conn-radius:8px;--conn-radius-lg:14px;
  --conn-fam-xray:#b7a0ff;--conn-fam-xray-chip:rgba(183,160,255,.14);--conn-fam-xray-rim:#b7a0ff40;
  --conn-fam-tunnel:#2dc3f7;--conn-fam-tunnel-chip:rgba(45,195,247,.14);--conn-fam-tunnel-rim:#2dc3f740;
  --conn-fam-vpn:#f08bd2;--conn-fam-vpn-chip:rgba(240,139,210,.14);--conn-fam-vpn-rim:#f08bd240;
  --conn-fam-udp:#b5dc52;--conn-fam-udp-chip:rgba(181,220,82,.14);--conn-fam-udp-rim:#b5dc5240;
  --conn-fam-sky:#6ea2ff;--conn-fam-sky-chip:rgba(110,162,255,.14);--conn-fam-sky-rim:#6ea2ff55;
  --conn-fam-other:#a9b8ca;--conn-fam-other-chip:rgba(169,184,202,.13);--conn-fam-other-rim:#a9b8ca40;
  /* login.css tokens (the sign-in page has its own names) */
  --card:var(--v6-glass-strong);--bg2:#051a4a;--mute:var(--v6-muted);--brand2:#7cc6ff;
}
/* light glass: pale blue mist with soft royal-blue waves */
html:root[data-theme="light"]{
  color-scheme:light;
  --v6-base:#eaf1fc;
  --v6-wall:radial-gradient(135% 80% at 50% -14%,#ffffff 0%,#f1f6ff 26%,#e5edfc 52%,#d9e5fa 78%,#d0dff8 100%);
  --v6-wave-a:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 440' preserveAspectRatio='none'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='rgb(60,120,250)' stop-opacity='0.16'/%3E%3Cstop offset='0.55' stop-color='rgb(100,160,255)' stop-opacity='0.08'/%3E%3Cstop offset='1' stop-color='rgb(150,195,255)' stop-opacity='0'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M0 190 C 200 110,400 110,600 190 S 1000 270,1200 190 L1200 440 L0 440 Z' fill='url("/v6/%23g")' opacity='0.25' transform='translate(0,-30)'/%3E%3Cpath d='M0 190 C 200 110,400 110,600 190 S 1000 270,1200 190 L1200 440 L0 440 Z' fill='url("/v6/%23g")' opacity='0.5' transform='translate(0,-14)'/%3E%3Cpath d='M0 190 C 200 110,400 110,600 190 S 1000 270,1200 190 L1200 440 L0 440 Z' fill='url("/v6/%23g")'/%3E%3C/svg%3E");
  --v6-wave-b:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 340' preserveAspectRatio='none'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='rgb(255,255,255)' stop-opacity='0.5'/%3E%3Cstop offset='0.5' stop-color='rgb(120,170,255)' stop-opacity='0.14'/%3E%3Cstop offset='1' stop-color='rgb(100,160,255)' stop-opacity='0'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M0 150 C 220 215,420 215,600 150 S 1000 85,1200 150 L1200 340 L0 340 Z' fill='url("/v6/%23g")' opacity='0.25' transform='translate(0,-30)'/%3E%3Cpath d='M0 150 C 220 215,420 215,600 150 S 1000 85,1200 150 L1200 340 L0 340 Z' fill='url("/v6/%23g")' opacity='0.5' transform='translate(0,-14)'/%3E%3Cpath d='M0 150 C 220 215,420 215,600 150 S 1000 85,1200 150 L1200 340 L0 340 Z' fill='url("/v6/%23g")'/%3E%3Cpath d='M0 150 C 220 215,420 215,600 150 S 1000 85,1200 150' fill='none' stroke='rgb(255,255,255)' stroke-opacity='0.8' stroke-width='1.2' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
  --v6-glass:rgba(255,255,255,.56);
  --v6-glass-strong:rgba(255,255,255,.84);
  --v6-glass-soft:rgba(255,255,255,.66);
  --v6-glass-bar:rgba(255,255,255,.82);
  --v6-stroke:rgba(20,60,150,.15);
  --v6-hi:rgba(255,255,255,.96);
  --v6-text:#0a1a3a;--v6-muted:#445a82;
  --v6-accent:#0a4fd6;--v6-accent-2:#1a8cf0;
  --v6-ok:#086b42;--v6-warn:#7d4c00;--v6-bad:#a8202f;
  --v6-on-accent:#fff;
  --v6-grad-accent:linear-gradient(180deg,#1c72fa 0%,#0b5cee 42%,#0640c6 100%);
  --v6-shadow:0 12px 36px rgba(16,50,130,.14),0 1px 4px rgba(16,50,130,.08);
  --v6-well:inset 0 1px 2px rgba(16,50,130,.10);
  --v6-thumb:rgba(255,255,255,.96);
  --bg:#eaf1fc;--surface:var(--v6-glass);--surface-2:rgba(20,60,150,.045);--surface-3:rgba(20,60,150,.09);
  --line:rgba(20,60,150,.13);--line-strong:rgba(20,60,150,.26);
  --ink:var(--v6-text);--ink-2:#243a62;--muted:var(--v6-muted);
  --brand:#0a4fd6;--brand-strong:#1f66ea;--brand-hover:#1456d8;--brand-ink:#0a45bd;--brand-soft:rgba(10,79,214,.12);--on-brand:#fff;
  --glow:#1f7bf0;--grad-brand:linear-gradient(135deg,#3a9bff 0%,#0a5cf0 48%,#0636a8 100%);--grad-cta:linear-gradient(135deg,#1a73ff 0%,#0a55dd 55%,#0838a0 100%);
  --wmt-1:#6a7890;--wmt-2:#26354d;--wmt-3:#0f1b2e;--wmt-one:#0a58e0;--wmt-glow:#1f7bf033;
  --band:#051a52;--band-2:#020a26;--band-ink:#f1f6ff;--band-muted:#b2c4e6;--band-line:rgba(165,200,255,.22);--band-star:#8cc4ff;--band-glass:rgba(190,215,255,.1);
  --map-ok:#4be0a0;--map-warn:#ffc857;--map-bad:#ff9aa3;--map-info:#a9d2ff;--map-idle:#8fa8d0;--map-node:#06194f;
  --ok:#086b42;--ok-soft:rgba(8,107,66,.12);--warn:#7d4c00;--warn-soft:rgba(180,110,0,.14);--bad:#a8202f;--bad-soft:rgba(168,32,47,.11);
  --info:#0a4fb0;--info-soft:rgba(10,79,176,.11);--idle:#4a6082;--idle-soft:rgba(20,60,150,.08);
  --focus:#0a4fd6;
  --s-de:#1f6fff;--s-de2:#0b44a8;--s-ruh1:#0a95d8;--s-ruh2:#6b82a8;--s-ruh3:#3f90f0;--s-ruh4:#0a6aa8;
  --lease:#6f93c8;
  --spd-bg:rgba(10,79,214,.12);--spd-hot-bg:rgba(10,79,214,.2);--spd-ink:#0a3f9e;--spd-line:rgba(10,79,214,.34);--spd-dn:#0a4fd6;--spd-up:#076f9a;--spd-glow:rgba(10,79,214,.32);
  --scrim:rgba(6,24,70,.36);
  --shadow-1:0 6px 24px rgba(16,50,130,.10);--shadow-2:0 28px 70px rgba(10,40,110,.28);
  --r-6:8px;--r-8:12px;--r-12:var(--v6-radius);--r-16:var(--v6-radius-lg);
  --conn-hl:rgba(20,60,150,.06);--conn-warn-fill:#e2a21f;--conn-radius:8px;--conn-radius-lg:14px;
  --conn-fam-xray:#6a3fd4;--conn-fam-xray-chip:rgba(106,63,212,.11);--conn-fam-xray-rim:transparent;
  --conn-fam-tunnel:#0a6fa8;--conn-fam-tunnel-chip:rgba(10,111,168,.11);--conn-fam-tunnel-rim:transparent;
  --conn-fam-vpn:#a8237a;--conn-fam-vpn-chip:rgba(168,35,122,.10);--conn-fam-vpn-rim:transparent;
  --conn-fam-udp:#4f6b00;--conn-fam-udp-chip:rgba(79,107,0,.12);--conn-fam-udp-rim:transparent;
  --conn-fam-sky:#1a5fe0;--conn-fam-sky-chip:rgba(26,95,224,.10);--conn-fam-sky-rim:#1a5fe066;
  --conn-fam-other:#526174;--conn-fam-other-chip:rgba(82,97,116,.12);--conn-fam-other-rim:transparent;
  --card:var(--v6-glass-strong);--bg2:#dae6fb;--mute:var(--v6-muted);--brand2:#0a4fd6;
}
/* the dark brand moments (hero band, splash, sign-in) stay dark navy glass in both themes: their tokens above are the same */

/* ================= 2. WALLPAPER + BASE ================= */
/* THREE fixed full-viewport layers (owner 2026-10-02: calmer, readable, light on phones; was ~8 stacked gradients).  No image file, no SVG filter,
   no blur here, nothing on the main thread:
     1. html::before  the base: deep navy + one soft glow at the top, static (painted once)
     2. html::after   the back wave:  a wide, soft royal-blue wave, drifts a few percent very slowly (compositor-only transform)
     3. body::before  the front wave: a lighter, lower wave, drifts the other way, even slower
   The waves are low-contrast on purpose (no bright crest lines behind the text) and sit in the lower part of the screen.  They are wider than
   the viewport, so their edges never show while they drift.  The drift uses `steps()` on purpose: a smooth 60 fps drift measured 6-10x the idle CPU
   of a still page (every frame re-blurs everything behind the bars and panels), so each wave moves by a pixel or two every 3 s instead, and the two
   waves step on the SAME 3 s beat (150 s / 50 steps, 210 s / 70 steps) so the browser draws one frame per beat, not two.  Too slow and too small to
   see as steps, it reads as a slow tide.  prefers-reduced-motion: no animation at all (section 15). */
html{background:var(--v6-base);min-height:100%}
html::before,html::after,body::before{content:"";position:fixed;pointer-events:none;z-index:-1}
html::before{inset:0;background:var(--v6-wall);transform:translateZ(0)}
html::after,body::before{background-repeat:no-repeat;background-size:100% 100%;will-change:transform}
html::after{left:-15vw;width:130vw;bottom:-6vh;height:64vh;background-image:var(--v6-wave-a);
  animation:v6-wave-a 150s steps(50) infinite alternate}
body::before{left:-20vw;width:140vw;bottom:-8vh;height:42vh;background-image:var(--v6-wave-b);
  animation:v6-wave-b 210s steps(70) infinite alternate}
@keyframes v6-wave-a{from{transform:translate3d(-3%,0,0)}to{transform:translate3d(3%,-1.5%,0)}}
@keyframes v6-wave-b{from{transform:translate3d(3%,0,0)}to{transform:translate3d(-3%,1.5%,0)}}
body{background:transparent;color:var(--ink);min-height:100%}
::selection{background:color-mix(in srgb,var(--v6-accent) 38%,transparent);color:inherit}
*{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--v6-text) 28%,transparent) transparent}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--v6-text) 26%,transparent);border-radius:99px;border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-track,::-webkit-scrollbar-corner{background:transparent}
h1,h2,h3,h4{font-weight:500}
h1{letter-spacing:0}
h1[tabindex="-1"]:focus,h1[tabindex="-1"]:focus-visible{outline:0}
.muted,.hint,.small.muted{color:var(--muted)}
a{color:var(--brand-ink)}
/* thin icon grammar: one stroke for the whole set (contexts that set their own stroke, like .spd and .pillars, keep it) */
.ic{stroke-width:1.75}
/* big numbers: light, tabular */
.num,.tnum,.stat .v,.meter-big,.lv-fig .v,.lim .box .v,.fact .v,.plan .big,.skc-kpi b{font-variant-numeric:tabular-nums}
.stat .v{font-size:32px;font-weight:400;letter-spacing:-.01em}
.stat .v small{font-weight:400}
.meter-big{font-weight:400}
.lv-fig .v{font-weight:400;font-size:28px}
.lim .box .v{font-weight:400;font-size:24px}
.fact .v{font-weight:500}
.plan .big,.meter-pct{font-weight:500}
.stat .l,.fact .l,.kv dt{font-weight:400}

/* ================= 3. APP SHELL ================= */
.topbar{background:var(--v6-glass-bar);-webkit-backdrop-filter:var(--v6-bf);backdrop-filter:var(--v6-bf);border-block-end:1px solid var(--v6-stroke);box-shadow:inset 0 -1px 0 color-mix(in srgb,var(--v6-hi) 18%,transparent)}
.strip{background:transparent;border-block-end:1px solid var(--v6-stroke)}
.side{background:var(--v6-glass-strong);-webkit-backdrop-filter:var(--v6-bf);backdrop-filter:var(--v6-bf);border-inline-end:1px solid var(--v6-stroke)}
.side-brand{background:linear-gradient(140deg,rgba(8,40,112,.92),rgba(3,12,42,.94));color:#f1f6ff;border:1px solid rgba(190,215,255,.16);box-shadow:inset 0 1px 0 rgba(200,225,255,.18),0 6px 18px rgba(0,4,24,.22)}
.side-brand::after{border-block-start-color:rgba(130,190,255,.40);box-shadow:0 -4px 16px rgba(40,130,255,.30)}
.side-brand small{color:#b2c4e6}
.ng-t{font-weight:500;letter-spacing:.04em}
.nv{border-radius:var(--v6-radius-sm);font-weight:400;min-height:42px;transition:background var(--dur),color var(--dur)}
.nv .ic{opacity:.9}
.nv:hover{background:var(--v6-glass-soft);color:var(--ink)}
html:root .nv[aria-current="page"]{background:color-mix(in srgb,var(--v6-accent) 17%,transparent);color:var(--ink);font-weight:500;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--v6-accent) 34%,transparent),inset 0 1px 0 var(--v6-hi)}
.nv[aria-current="page"] .ic{color:var(--v6-accent);opacity:1}
html:root[data-theme="light"] .nv[aria-current="page"] .ic{color:var(--brand-ink)}
.nv .cnt{background:var(--surface-3);font-weight:500;font-variant-numeric:tabular-nums}
.nv.prot{color:var(--muted)}
.ver{background:var(--v6-glass-soft);color:var(--brand-ink);border:1px solid var(--v6-stroke);font-weight:500}
.live i{box-shadow:0 0 0 3px var(--ok-soft),0 0 10px var(--ok)}
.bbar,.rbar{background:var(--v6-glass-bar);-webkit-backdrop-filter:var(--v6-bf);backdrop-filter:var(--v6-bf);border-block-start:1px solid var(--v6-stroke);box-shadow:inset 0 1px 0 color-mix(in srgb,var(--v6-hi) 16%,transparent);border-start-start-radius:20px;border-start-end-radius:20px}
.rb{font-weight:500}
.rb[aria-current="page"]{color:var(--brand-ink)}
.rb[aria-current="page"] .ic{color:var(--v6-accent)}
.rb.plus .ic{background:var(--v6-grad-accent);color:var(--v6-on-accent);box-shadow:0 0 0 4px color-mix(in srgb,var(--v6-glass-strong) 90%,transparent),0 6px 16px color-mix(in srgb,var(--v6-accent) 40%,transparent)}
.scrim{-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}

/* ================= 4. GLASS SURFACES ================= */
/* big containers: translucent fill + hairline + soft top highlight (+ blur where it is cheap, see the phone block) */
.panel,.stat,.fact,.srv,.plan,.rs,.al-list,.tbl-wrap,.bi-card,.spec,.sky-card,.fc,.cg,.sky-plan,.sky-logc,.infra,.ucard{border-color:var(--v6-stroke)}
.panel,.stat,.fact,.srv,.plan,.rs,.al-list,.tbl-wrap,.bi-card,.ucard,.sky-card,.sky-logc,.spec{box-shadow:var(--v6-shadow),inset 0 1px 0 var(--v6-hi)}
.panel,.stat,.srv,.plan,.rs,.tbl-wrap,.al-list,.bi-card,.spec{-webkit-backdrop-filter:var(--v6-bf);backdrop-filter:var(--v6-bf)}
.panel{padding:20px}
/* nested containers sit on the parent glass: a lighter tint, no extra blur / shadow */
.panel .tbl-wrap,.panel .al-list,.panel .fc-s,.panel .ucard,.panel .srv,.panel .plan,.panel .sky-card,.panel .sky-logc,.panel .bi-card,.panel .spec,.panel .fact,.panel .stat,.srv .tbl-wrap,.plan .tbl-wrap,.rs .tbl-wrap{
  background:var(--surface-2);box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none}
.stat.alert{border-color:color-mix(in srgb,var(--warn) 50%,var(--v6-stroke))}
.plan.def{border-color:color-mix(in srgb,var(--v6-accent) 70%,transparent);box-shadow:var(--v6-shadow),inset 0 1px 0 var(--v6-hi),0 0 0 1px color-mix(in srgb,var(--v6-accent) 28%,transparent)}
.srv.focus{border-color:var(--brand);box-shadow:var(--v6-shadow),inset 0 1px 0 var(--v6-hi),0 0 0 3px var(--brand-soft)}
.ucard:hover{border-color:color-mix(in srgb,var(--v6-accent) 55%,var(--v6-stroke))}
.cred,.target,.preview,.explain,.policy,.pwf-once,.pwf-bot,.ibl-r,.fc-s,.secret,.sky-cli,.sky-bind,.sky-json,details{border-color:var(--v6-stroke)}
.explain{border-inline-start-color:var(--v6-accent)}

/* the hero band: dark navy / royal-blue glass with a soft wave horizon (was a starfield); dark in both themes */
.band{
  background:radial-gradient(120% 90% at 100% 0%,rgba(30,120,255,.26),transparent 58%),radial-gradient(90% 80% at 0% 100%,rgba(22,174,248,.15),transparent 62%),linear-gradient(162deg,rgba(6,38,108,.82),rgba(2,10,40,.86));
  border:1px solid rgba(190,215,255,.17);
  box-shadow:var(--v6-shadow),inset 0 1px 0 rgba(200,225,255,.22);
  -webkit-backdrop-filter:var(--v6-bf);backdrop-filter:var(--v6-bf)}
html:root[data-theme="light"] .band{background:radial-gradient(120% 90% at 100% 0%,rgba(30,120,255,.30),transparent 58%),radial-gradient(90% 80% at 0% 100%,rgba(22,174,248,.18),transparent 62%),linear-gradient(162deg,rgb(6,40,114),rgb(2,12,44))}
/* inside the always-dark band the light theme's tone/ink tokens would be dark-on-dark: restate the dark values there */
html:root[data-theme="light"] .band{--ink:#eef4ff;--ink-2:#cbd8ee;--muted:#a8bbdd;--line:rgba(165,200,255,.14);--surface-2:rgba(170,200,255,.055);--surface-3:rgba(170,200,255,.11);
  --ok:#4be0a0;--ok-soft:rgba(75,224,160,.15);--warn:#ffc857;--warn-soft:rgba(255,200,87,.15);--bad:#ff8590;--bad-soft:rgba(255,133,144,.16);--info:#7cc0ff;--info-soft:rgba(124,192,255,.15);--idle:#9fb2d4;--idle-soft:rgba(190,215,255,.09)}
.band::after{border-block-start:1px solid rgba(130,190,255,.36);box-shadow:0 -10px 42px rgba(40,130,255,.20),inset 0 14px 40px rgba(40,130,255,.10)}
.band h1{font-weight:400}
.band .eyebrow{font-weight:500}
.fl,.lim .box,.band-live,.pill-glass,.band-btn{border-color:rgba(190,215,255,.18)}
.band-live{box-shadow:0 0 22px rgba(40,130,255,.20),inset 0 1px 0 rgba(200,225,255,.16)}
.fl:hover{border-color:rgba(200,225,255,.5)}
.band,.splash,.login{--wm-one:#2b8cff}
.wm{--wm-one:#2b8cff}
html:root[data-theme="light"] .topbar .wm,html:root[data-theme="light"] .side-head .wm{--wm-1:#6a7890;--wm-2:#26354d;--wm-3:#0f1b2e;--wm-one:#0a58e0}
html:root[data-theme="light"] .side-brand .wm{--wm-1:#eef3fa;--wm-2:#aebbd0;--wm-3:#5d6b82;--wm-one:#2b8cff}
/* splash / in-app sign-in sample: the dark wallpaper */
.splash,.login{background:var(--v6-wall-dark)}
.splash-bar i{background:var(--v6-grad-accent)}

/* ================= 5. TABLES ================= */
.tbl th{background:transparent;font-weight:500;font-size:12.5px;color:var(--muted);letter-spacing:.02em;border-block-end:1px solid var(--v6-stroke)}
.tbl td{border-block-end:1px solid color-mix(in srgb,var(--v6-stroke) 70%,transparent)}
.tbl tbody tr:last-child td{border-block-end:0}
.tbl tr.click:hover td,.tbl tbody tr:hover td{background:var(--surface-2)}
.tbl tfoot td{background:var(--surface-2);font-weight:500;border-block-start:1px solid var(--v6-stroke)}
.nl-b{border-block-end-color:var(--v6-stroke)}
.feed li{border-block-end-color:var(--v6-stroke)}
.al{background:transparent;border-block-end-color:var(--v6-stroke)}
.al-t{font-weight:500}

/* ================= 6. CONTROLS ================= */
/* buttons: glass pills; primary = accent gradient pill; icon buttons = round glass */
.btn,.seg,.fchip,.ck,.tab,.skc-fc{font-weight:500}
.btn{border-radius:var(--r-pill);border:1px solid var(--v6-stroke);background:var(--v6-glass-soft);color:var(--ink);box-shadow:inset 0 1px 0 var(--v6-hi);padding-inline:18px}
.btn.sm{padding-inline:14px}
.btn:hover{background:color-mix(in srgb,var(--v6-text) 11%,var(--v6-glass-soft));border-color:color-mix(in srgb,var(--v6-accent) 55%,var(--v6-stroke))}
.btn:active{transform:translateY(.5px)}
.btn.primary{background:var(--v6-grad-accent);border-color:rgba(255,255,255,.34);color:var(--v6-on-accent);font-weight:600;box-shadow:0 8px 22px color-mix(in srgb,var(--v6-accent) 34%,transparent),inset 0 1px 0 rgba(255,255,255,.55)}
.btn.primary:hover{background:var(--v6-grad-accent);filter:brightness(1.07) saturate(1.05);border-color:rgba(255,255,255,.5)}
.btn.danger{color:var(--bad);border-color:color-mix(in srgb,var(--bad) 48%,transparent);background:var(--v6-glass-soft)}
.btn.danger:hover{background:var(--bad-soft)}
.btn.danger.solid{background:linear-gradient(180deg,#ffa4ab,#f2737f);border-color:rgba(255,255,255,.3);color:#3a0a12;box-shadow:0 8px 20px color-mix(in srgb,var(--bad) 30%,transparent),inset 0 1px 0 rgba(255,255,255,.45)}
html:root[data-theme="light"] .btn.danger.solid{background:linear-gradient(180deg,#d6475a,#a8202f);color:#fff}
.btn.ghost{background:transparent;border-color:transparent;box-shadow:none}
.btn.ghost:hover{background:var(--v6-glass-soft);border-color:var(--v6-stroke)}
.btn.band-btn{background:var(--band-glass);color:var(--band-ink)}
.icon-btn{border-radius:50%;border:1px solid var(--v6-stroke);background:var(--v6-glass-soft);color:var(--ink-2);box-shadow:inset 0 1px 0 var(--v6-hi)}
.icon-btn:hover{border-color:color-mix(in srgb,var(--v6-accent) 55%,var(--v6-stroke));color:var(--brand-ink);background:color-mix(in srgb,var(--v6-text) 10%,var(--v6-glass-soft))}
.link{font-weight:500}
/* pills: role switcher, filter chips */
.seg,.fchip,.skc-fc{border-color:var(--v6-stroke);background:var(--v6-glass-soft);color:var(--ink-2);box-shadow:inset 0 1px 0 color-mix(in srgb,var(--v6-hi) 60%,transparent)}
.seg:hover,.fchip:hover,.skc-fc:hover{border-color:color-mix(in srgb,var(--v6-accent) 50%,var(--v6-stroke));color:var(--ink)}
html:root .seg[aria-pressed="true"],html:root .fchip[aria-pressed="true"],html:root .skc-fc[aria-pressed="true"]{background:color-mix(in srgb,var(--v6-accent) 24%,transparent);border-color:color-mix(in srgb,var(--v6-accent) 62%,transparent);color:var(--ink)}
html:root .fchip[aria-pressed="true"] b{color:var(--brand-ink)}
.fchip b{font-weight:500;font-variant-numeric:tabular-nums}
/* segmented tabs: a pill track with a raised thumb (macOS style) */
.tabs{gap:2px;box-shadow:none;background:var(--v6-glass-soft);border:1px solid var(--v6-stroke);border-radius:var(--r-pill);padding:4px;width:max-content;max-width:100%}
.tab{border-radius:var(--r-pill);border-block-end:0;padding:7px 16px;font-weight:500;color:var(--muted);transition:background var(--dur),color var(--dur)}
.tab:hover{color:var(--ink)}
html:root .tab[aria-selected="true"]{background:var(--v6-thumb);color:var(--ink);border-block-end:0;box-shadow:0 2px 8px rgba(0,0,0,.18),inset 0 1px 0 var(--v6-hi)}
/* inputs: soft glass wells with a clear accent focus ring */
input[type="text"],input[type="search"],input[type="password"],input[type="number"],input[type="email"],input[type="url"],input[type="tel"],input[type="date"],input[type="datetime-local"],select,textarea{
  border-radius:var(--v6-radius-sm);border:1px solid var(--v6-stroke);background:var(--v6-glass-soft);box-shadow:var(--v6-well);color:var(--ink);transition:border-color var(--dur),box-shadow var(--dur),background var(--dur)}
input::placeholder,textarea::placeholder{color:color-mix(in srgb,var(--muted) 82%,transparent)}
input:hover,select:hover,textarea:hover{border-color:color-mix(in srgb,var(--v6-text) 30%,transparent)}
input:focus-visible,select:focus-visible,textarea:focus-visible,input:focus,textarea:focus{outline:2px solid var(--v6-accent);outline-offset:0;border-color:var(--v6-accent);box-shadow:0 0 0 5px color-mix(in srgb,var(--v6-accent) 22%,transparent)}
input[aria-invalid="true"]{border-color:var(--bad)}
input[readonly],.pwf-row>input[readonly]{background:var(--surface-2)}
select,input[type="checkbox"],input[type="radio"],input[type="range"]{accent-color:var(--v6-accent)}
.search input[type="search"]{border-radius:var(--r-pill)}
.ck{border-radius:var(--v6-radius-sm);border-color:var(--v6-stroke);background:var(--v6-glass-soft)}
.ck:has(input:checked){border-color:color-mix(in srgb,var(--v6-accent) 60%,transparent);background:var(--brand-soft)}
.pwf-row>.pwf-eye:hover{background:var(--v6-glass-soft)}
.field label,.lbl,legend{font-weight:500}

/* progress / quota bars: thin, rounded */
.bar{height:6px;background:var(--surface-3);box-shadow:inset 0 1px 1px rgba(0,0,0,.14)}
.bar>span{background:var(--bc,linear-gradient(90deg,var(--v6-accent-2),var(--v6-accent)));border-radius:99px}
.bar.tone-warn{--bc:linear-gradient(90deg,#ffc857,#f0a93f)}
.bar.tone-bad{--bc:linear-gradient(90deg,#ff9aa3,#f2737f)}
html:root[data-theme="light"] .bar.tone-warn{--bc:linear-gradient(90deg,#d9a02c,#b9780a)}
html:root[data-theme="light"] .bar.tone-bad{--bc:linear-gradient(90deg,#d6475a,#a8202f)}
.bar.big{height:14px;border-radius:99px}
.bar.big>span:first-child{border-start-start-radius:99px;border-end-start-radius:99px}
.lim .bar{background:var(--band-glass)}
.q-t .p{font-weight:500}

/* ================= 7. CHIPS, BADGES, NOTICES ================= */
.chip{font-weight:500;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--tc,var(--ink-2)) 26%,transparent)}
.chip::before{box-shadow:0 0 6px color-mix(in srgb,currentColor 55%,transparent)}
.tag,.nchip{border-color:var(--v6-stroke);background:var(--v6-glass-soft);font-weight:500}
.sky-cnt{font-weight:500}
.notice{border-radius:var(--v6-radius-sm);background:var(--ts);border:1px solid color-mix(in srgb,var(--tc) 28%,transparent);border-inline-start:3px solid var(--tc)}
.notice strong{font-weight:500}
.empty .ic{color:var(--v6-accent)}

/* ================= 8. OVERLAYS: dialogs, toasts, menus, popovers ================= */
.dlg{background:var(--v6-glass-strong);border:1px solid var(--v6-stroke);border-radius:var(--v6-radius-lg);box-shadow:var(--shadow-2),inset 0 1px 0 var(--v6-hi);-webkit-backdrop-filter:var(--v6-bf);backdrop-filter:var(--v6-bf)}
.dlg::backdrop{background:var(--scrim);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
.dlg header{border-block-end-color:var(--v6-stroke)}
.dlg header h2{font-weight:500}
.dlg footer{background:var(--surface-2);border-block-start-color:var(--v6-stroke)}
.dlg.tone-bad header{border-block-end-color:color-mix(in srgb,var(--bad) 60%,transparent);box-shadow:inset 0 2px 0 var(--bad)}
.toast{background:var(--v6-glass-strong);color:var(--ink);border:1px solid var(--v6-stroke);border-radius:var(--v6-radius);box-shadow:var(--shadow-2),inset 0 1px 0 var(--v6-hi);-webkit-backdrop-filter:var(--v6-bf);backdrop-filter:var(--v6-bf)}
html:root .toast .icon-btn,html:root .toast .undo-b{color:var(--ink);background:transparent;border-color:transparent}
html:root .toast .undo-b{border-color:var(--v6-stroke)}
.telegram-ptoast{background:var(--v6-glass-strong);color:var(--ink);border:1px solid var(--v6-stroke)}
.sky-menu,.sky-find-r,.skc-pop,.spd-tip{background:var(--v6-glass-strong);border:1px solid var(--v6-stroke);box-shadow:var(--shadow-2),inset 0 1px 0 var(--v6-hi);-webkit-backdrop-filter:var(--v6-bf);backdrop-filter:var(--v6-bf)}
.skc-popbox{background:var(--surface-2);border-color:var(--v6-stroke)}
.sky-menu{border-radius:var(--v6-radius)}
.sky-mi{border-radius:var(--v6-radius-sm);font-weight:500}
.sky-menu-scrim{-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.spd-tip{color:var(--ink);border-radius:var(--v6-radius-sm)}
.spd-tip .tp-d,.spd-tip .tp-f,.spd-tip .tp-m,.spd-tip .tp-n,.spd-tip .tp-h span{color:var(--muted)}
.spd-tip .a-up{color:var(--spd-up)}.spd-tip .a-dn{color:var(--spd-dn)}
.spd-tip .nchip{background:var(--v6-glass-soft);border-color:var(--v6-stroke);color:var(--ink)}
.services-drawer{background:var(--v6-glass-strong);-webkit-backdrop-filter:var(--v6-bf);backdrop-filter:var(--v6-bf);border-color:var(--v6-stroke)}
.telegram-behind{background:color-mix(in srgb,var(--v6-glass-strong) 88%,transparent)}

/* ================= 9. STATES THAT USED THE INVERSE (ink background, surface text) ================= */
html:root .services-ssh-mode[aria-checked="true"],html:root .ix-tab[aria-selected="true"],html:root .ps-steps li.on{background:color-mix(in srgb,var(--v6-accent) 26%,transparent);border-color:color-mix(in srgb,var(--v6-accent) 62%,transparent);color:var(--ink)}
html:root .services-fchip[aria-pressed="true"] .services-fch-s{color:var(--brand-ink)}
html:root .services-safe-n{color:var(--v6-on-accent)}
.sky-steps li.on b{background:var(--v6-grad-accent);color:var(--v6-on-accent)}

/* ================= 10. LIVE SPEED, MAP, CONN ================= */
.spd{font-weight:500}
.lv-chart svg{background:var(--surface-2);border-color:var(--v6-stroke)}
.lv-scale{background:color-mix(in srgb,var(--v6-glass-strong) 70%,transparent)}
.conn-th>div{background:var(--surface-2)}
.skc-seg,.skc-tag{border-color:var(--v6-stroke)}
.skc-seg button[aria-pressed="true"]{background:var(--v6-thumb)}
.skc-ds-t thead th{background:var(--surface-2)}

/* ================= 11. SIGN-IN PAGE (login.css, no JS: dark glass) ================= */
body>main.wrap>.card{background:var(--v6-glass-strong);border:1px solid var(--v6-stroke);border-radius:var(--v6-radius-lg);box-shadow:var(--shadow-2),inset 0 1px 0 var(--v6-hi);-webkit-backdrop-filter:var(--v6-bf);backdrop-filter:var(--v6-bf);padding:22px 22px 18px}
body>main.wrap>.card .hero{border-radius:var(--v6-radius);mix-blend-mode:screen;-webkit-mask-image:radial-gradient(ellipse 72% 88% at 50% 46%,#000 62%,transparent 100%);mask-image:radial-gradient(ellipse 72% 88% at 50% 46%,#000 62%,transparent 100%)}
body>main.wrap>.card h1{font-weight:500}
body>main.wrap>.card .v{color:var(--v6-accent);font-weight:500}
body>main.wrap>.card label{font-weight:500;color:var(--ink-2)}
body>main.wrap>.card input{border-radius:var(--v6-radius-sm);border:1px solid var(--v6-stroke);background:var(--v6-glass-soft);box-shadow:var(--v6-well);color:var(--ink)}
body>main.wrap>.card button[type="submit"]{border:1px solid rgba(255,255,255,.34);border-radius:999px;background:var(--v6-grad-accent);color:var(--v6-on-accent);font-weight:600;box-shadow:0 8px 22px color-mix(in srgb,var(--v6-accent) 34%,transparent),inset 0 1px 0 rgba(255,255,255,.55)}
body>main.wrap>.card button[type="submit"] .en{color:inherit;opacity:.72}
body>main.wrap>.card button[type="submit"]:hover{filter:brightness(1.07)}
body>main.wrap>.card button[type="submit"]:focus-visible{outline:2px solid #fff;outline-offset:2px}
body>main.wrap>.card .err{border-radius:var(--v6-radius-sm)}

/* ================= 12. MOTION: panels fade / slide in once on a route change =================
   v6-glass.js adds .v6-enter to <html> for ~0.7 s after a navigation click / hash change, so live refresh renders never replay it. */
@keyframes v6-rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
html.v6-enter #main>*,html.v6-enter .rv>*{animation:v6-rise .42s cubic-bezier(.2,.7,.2,1) backwards}
html.v6-enter #main>*:nth-child(2),html.v6-enter .rv>*:nth-child(2){animation-delay:.04s}
html.v6-enter #main>*:nth-child(3),html.v6-enter .rv>*:nth-child(3){animation-delay:.08s}
html.v6-enter #main>*:nth-child(n+4),html.v6-enter .rv>*:nth-child(n+4){animation-delay:.12s}

/* ================= 13. PHONES ================= */
@media (max-width:760px){
  /* lighter blur on phones (owner 2026-10-02): a small radius and no saturate() stage (the wallpaper is smooth now, a big blur shows nothing it
     could hide); the blur cost grows with the radius, and the full-screen scrims are the most expensive blur of all */
  html:root{--v6-blur:10px;--v6-bf:blur(var(--v6-blur))}
  .scrim,.sky-menu-scrim,.dlg::backdrop{-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
  /* in-flow panels keep the translucent fill (the wallpaper is smooth, so the blur is invisible there); only bars, drawers and dialogs blur */
  .panel,.stat,.srv,.plan,.rs,.tbl-wrap,.al-list,.bi-card,.spec,.band{-webkit-backdrop-filter:none;backdrop-filter:none}
  .panel{padding:16px}
  .stat .v{font-size:28px}
  .tab{padding:7px 13px}
}

/* ================= 14. FALLBACKS ================= */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  html:root:not([data-theme="light"]){--v6-glass:rgba(14,32,80,.90);--v6-glass-strong:rgba(7,18,52,.97);--v6-glass-bar:rgba(5,14,42,.96)}
  html:root[data-theme="light"]{--v6-glass:rgba(250,252,255,.92);--v6-glass-strong:rgba(252,253,255,.98);--v6-glass-bar:rgba(250,252,255,.97)}
  .band{background:linear-gradient(162deg,rgb(8,40,110),rgb(3,12,44))}
}
@media (prefers-reduced-transparency:reduce){
  html:root:not([data-theme="light"]){--v6-glass:rgb(14,30,72);--v6-glass-strong:rgb(7,18,50);--v6-glass-bar:rgb(5,13,38);--v6-glass-soft:rgb(26,46,92)}
  html:root[data-theme="light"]{--v6-glass:rgb(246,249,255);--v6-glass-strong:rgb(251,253,255);--v6-glass-bar:rgb(247,250,255);--v6-glass-soft:rgb(236,243,254)}
  *,*::before,*::after,.dlg::backdrop{-webkit-backdrop-filter:none!important;backdrop-filter:none!important}
  .band{background:linear-gradient(162deg,rgb(8,40,110),rgb(3,12,44))}
}
@media (prefers-reduced-motion:reduce){
  html::after,body::before{animation:none;will-change:auto}   /* the two waves stand still (section 2) */
  html.v6-enter #main>*,html.v6-enter .rv>*{animation:none}
  .btn:active{transform:none}
}
/* Web Panel v6 beta: v6-dash.css (see web-src/v6/README.md)
   The dashboards are rings, directly on the glass: no tile backgrounds, no borders.  v6-dash.js builds each ring inside the slot the app
   drew (`.v6o-r[data-v6k]`: the ring, then its short label); this file draws them and lays the owner overview and the reseller home out
   so that everything is on ONE screen at 1440x900 and 1180x820 (the owner's goal) and in tight 2-4 per row grids on a phone / iPad portrait.
   One style everywhere: a segmented ring (32 thin segments, 16 for the servers' small rings) around a light centre number with a tiny
   unit, a soft glow behind the lit segments, and an optional thin outer arc for a second ratio.  Motion is CSS transitions / keyframes
   only: no per-frame JS, nothing runs while a value does not change, and prefers-reduced-motion turns all of it off.
   The segments are one shared SVG mask (#v6d-seg / #v6d-seg16, in the hidden <svg id="v6d-defs"> v6-dash.js adds to <body>).
     1. tokens   2. the ring   3. a slot   4. the owner overview board   5. the fleet map's frame   6. server health   7. the lists
     8. the reseller home   9. sizes (desk, iPad, phone)   10. motion off */

/* ---------- 1. tokens: dark glass is the default, light glass and the always-dark hero band override ---------- */
.v6d-ring,.v6o,.rv{
  --v6d-ink:var(--v6-text,#eef4ff);--v6d-muted:var(--v6-muted,#a8bbdd);
  --v6d-ok:#4be0a0;--v6d-acc:#4a98ff;--v6d-info:#46c8ff;--v6d-warn:#ffc857;--v6d-bad:#ff8590;
}
html:root[data-theme="light"] .v6d-ring,html:root[data-theme="light"] .v6o,html:root[data-theme="light"] .rv{
  --v6d-ok:#12a874;--v6d-acc:#1d6bf0;--v6d-info:#0e90e0;--v6d-warn:#e0920f;--v6d-bad:#d63447;
}
.v6d-ring{
  --v6d-size:80px;
  --v6d-track:color-mix(in srgb,var(--v6d-ink) 14%,transparent);
  --v6d-glow:.5;
  --v6d-c:var(--v6d-acc);--v6d-oc:var(--v6d-acc);
}
html:root[data-theme="light"] .v6d-ring{--v6d-glow:.34}
/* the hero band (the reseller portal's header) is dark in both themes (its ink tokens are restated dark there): same for the ring */
html:root .band .v6d-ring,html:root[data-theme="light"] .band .v6d-ring{
  --v6d-ink:#eef4ff;--v6d-muted:#b2c4e6;--v6d-track:rgba(190,215,255,.16);
  --v6d-ok:#4be0a0;--v6d-acc:#4a98ff;--v6d-info:#46c8ff;--v6d-warn:#ffc857;--v6d-bad:#ff8590;--v6d-glow:.5;
}
.v6d-ring[data-tone="ok"]{--v6d-c:var(--v6d-ok)}
.v6d-ring[data-tone="acc"]{--v6d-c:var(--v6d-acc)}
.v6d-ring[data-tone="info"]{--v6d-c:var(--v6d-info)}
.v6d-ring[data-tone="warn"]{--v6d-c:var(--v6d-warn)}
.v6d-ring[data-tone="bad"]{--v6d-c:var(--v6d-bad)}
.v6d-ring[data-otone="ok"]{--v6d-oc:var(--v6d-ok)}
.v6d-ring[data-otone="acc"]{--v6d-oc:var(--v6d-acc)}
.v6d-ring[data-otone="warn"]{--v6d-oc:var(--v6d-warn)}
.v6d-ring[data-otone="bad"]{--v6d-oc:var(--v6d-bad)}
#v6d-defs{position:absolute;width:0;height:0;overflow:hidden}

/* ---------- 2. the ring ---------- */
.v6d-ring{position:relative;display:block;flex:0 0 auto;width:var(--v6d-size);height:var(--v6d-size);margin:0;padding:0;
  direction:ltr;unicode-bidi:isolate;transition:transform .22s cubic-bezier(.3,.62,.25,1),opacity .3s ease}
.v6d-svg,.v6d-glow{position:absolute;display:block;overflow:visible;pointer-events:none}
.v6d-svg{inset:0;width:100%;height:100%}
.v6d-glow{inset:-6%;width:112%;height:112%;opacity:var(--v6d-glow);filter:blur(3.4px);transition:opacity .3s ease}
.v6d-tr,.v6d-a,.v6d-ga,.v6d-ot,.v6d-oa{fill:none}
.v6d-tr{stroke:var(--v6d-track);stroke-width:6}
.v6d-a{stroke:var(--v6d-c);stroke-width:6;stroke-dasharray:100 100}
.v6d-ga{stroke:var(--v6d-c);stroke-width:6.6;stroke-dasharray:100 100}
.v6d-ot{stroke:var(--v6d-track);stroke-width:1.5}
.v6d-oa{stroke:var(--v6d-oc);stroke-width:1.5;stroke-linecap:round;stroke-dasharray:100 100}
.v6d-a,.v6d-ga,.v6d-oa{transition:stroke-dashoffset .9s cubic-bezier(.3,.62,.25,1),stroke .45s ease}
/* a total with no ratio (count ring): every segment lit, dimmer, so it reads as «the whole» and not as a percentage */
.v6d-ring[data-kind="count"] .v6d-a{opacity:.46}
.v6d-ring[data-kind="count"] .v6d-glow{opacity:calc(var(--v6d-glow) * .35)}
/* still loading («…»): the empty track only */
.v6d-ring[data-kind="pending"] .v6d-glow{opacity:0}
/* the servers' small rings: bolder segments (16 of them) and just the number */
.v6d-ring[data-sz="s"] .v6d-tr,.v6d-ring[data-sz="s"] .v6d-a{stroke-width:10}
.v6d-ring[data-sz="s"] .v6d-ga{stroke-width:10.5}
.v6d-ring[data-sz="s"] .v6d-glow{filter:blur(2.4px)}

.v6d-c{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;text-align:center;line-height:1;pointer-events:none}
.v6d-n{display:block;font-size:calc(var(--v6d-size) * .3);font-weight:400;letter-spacing:-.02em;color:var(--v6d-ink);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.v6d-c[data-len="4"] .v6d-n,.v6d-c[data-len="5"] .v6d-n{font-size:calc(var(--v6d-size) * .235)}
.v6d-c[data-len="6"] .v6d-n,.v6d-c[data-len="7"] .v6d-n,.v6d-c[data-len="8"] .v6d-n{font-size:calc(var(--v6d-size) * .19)}
.v6d-u{display:block;max-width:80%;overflow:hidden;text-overflow:clip;font-size:max(9px,calc(var(--v6d-size) * .118));font-weight:400;
  color:var(--v6d-muted);white-space:nowrap}
.v6d-u:empty{display:none}
.v6d-ring[data-sz="s"] .v6d-n,.v6d-ring[data-sz="s"] .v6d-c[data-len="1"] .v6d-n,.v6d-ring[data-sz="s"] .v6d-c[data-len="2"] .v6d-n,.v6d-ring[data-sz="s"] .v6d-c[data-len="3"] .v6d-n{font-size:calc(var(--v6d-size) * .32);font-weight:500}
.v6d-ring[data-sz="s"] .v6d-u{display:none}

/* ---------- alerts: a gentle pulse while anything is urgent; live totals breathe very slowly ---------- */
@keyframes v6d-pulse{0%,100%{opacity:calc(var(--v6d-glow) * .45)}50%{opacity:calc(var(--v6d-glow) * 1.7)}}
@keyframes v6d-breathe{0%,100%{opacity:calc(var(--v6d-glow) * .16)}50%{opacity:calc(var(--v6d-glow) * .5)}}
.v6d-ring[data-pulse="1"] .v6d-glow{animation:v6d-pulse 2.3s ease-in-out infinite}
.v6d-ring[data-live="1"] .v6d-glow{animation:v6d-breathe 4.2s ease-in-out infinite}
/* the number the app printed is in the ring now: it stays in the DOM (and in the page text) for code and readers */
.v6d-hid{position:absolute!important;width:1px!important;height:1px!important;margin:-1px!important;padding:0!important;border:0!important;
  overflow:hidden!important;clip:rect(0 0 0 0)!important;clip-path:inset(50%)!important;white-space:nowrap!important}

/* ---------- 3. a slot: the ring and its short label, nothing around them ---------- */
.v6o-r{position:relative;display:grid;justify-items:center;align-content:start;gap:7px;min-width:0;margin:0;padding:6px 4px 4px;
  border:0;border-radius:18px;background:none;color:var(--v6-text);font:inherit;text-align:center;
  -webkit-tap-highlight-color:transparent;transition:background-color .2s ease}
button.v6o-r{cursor:pointer;touch-action:manipulation}
.v6o-r .v6d-ring{--v6d-size:var(--v6o-d,80px)}
.v6o-l{display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;font-weight:500;line-height:1.2;
  color:var(--v6-muted);transition:color .2s ease}
.v6o-r>.v{font-size:19px;font-weight:400;line-height:1.1;font-variant-numeric:tabular-nums}
/* alive: the ring lifts a little and its glow wakes up; a tap target on touch screens, a focus ring for the keyboard */
@media (hover:hover){
  button.v6o-r:hover{background:color-mix(in srgb,var(--v6-glass-soft) 70%,transparent)}
  button.v6o-r:hover .v6d-ring{transform:scale(1.07)}
  button.v6o-r:hover .v6d-glow{opacity:calc(var(--v6d-glow) * 1.45)}
  button.v6o-r:hover .v6o-l{color:var(--v6-text)}
}
button.v6o-r:active .v6d-ring{transform:scale(.97)}
button.v6o-r:focus-visible,button.v6o-sv:focus-visible,.v6o-lk:focus-visible{outline:2px solid var(--focus,var(--v6-accent));outline-offset:2px}
.v6o-rs{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:4px 6px;align-items:start}

/* ---------- 4. the owner overview: the map on one side, the rings on the other (one column below 1000 px) ---------- */
.v6o{display:grid;grid-template-columns:minmax(0,1fr);grid-template-areas:"top" "side" "map";gap:12px 30px;align-items:start;margin:0;
  --v6o-d:clamp(58px,19vw,78px);
  /* the map, the pill and the legend sit on the page glass, so the hero band's ink tokens are the page's here (both themes) */
  --band-ink:var(--v6-text);--band-muted:var(--v6-muted);--band-line:var(--v6-stroke);--band-2:var(--v6-base);--band-glass:var(--v6-glass-soft);--band-star:var(--v6-accent-2)}
#main:has(>.v6o){padding-block-end:20px}
.v6o-top{grid-area:top;min-width:0}
.v6o-side{grid-area:side}
.v6o-map{grid-area:map}
/* the app's shell is at least a screen tall (100dvh - 100px) but the bars above it are 106 px: on the overview, let its content decide */
.shell:has(.v6o){min-height:0}
.v6o-side{display:grid;gap:14px;min-width:0;align-content:start}
.v6o-g{min-width:0}
.v6o-h{display:flex;align-items:center;gap:10px;margin:0 0 4px;font-size:12px;font-weight:500;letter-spacing:.05em;color:var(--v6-muted)}
.v6o-h>span{order:1}
.v6o-h::after{content:"";order:2;flex:1;height:1px;background:var(--v6-stroke)}
.v6o-lk{order:3;margin:0;padding:2px 8px;border:0;border-radius:99px;background:none;color:var(--brand-ink);font:inherit;font-size:12px;font-weight:500;letter-spacing:0;cursor:pointer}
.v6o-lk:hover{background:var(--v6-glass-soft)}
@media (min-width:1000px){
  .v6o{grid-template-columns:minmax(0,1.08fr) minmax(0,1fr);grid-template-areas:"top side" "map side";grid-template-rows:auto 1fr;--v6o-d:clamp(64px,min(6.8vw,11.6vh),112px)}
}
@media (min-width:641px) and (max-width:999px){
  .v6o{--v6o-d:clamp(64px,10vw,88px)}
  .v6o-map{max-width:620px;justify-self:center;width:100%}
}

/* ---------- 5. the fleet map's frame (the rings on the map itself are v6-fleet.css) ---------- */
.v6o-map{min-width:0}
.v6o-mh{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:6px 14px}
.v6o-mt{min-width:0}
.v6o-top .eyebrow{margin:0;font-size:12px;color:var(--v6-muted)}
.v6o-top h1{margin:2px 0 0;font-size:21px;font-weight:500;line-height:1.25}
.v6o-top .band-sub{margin:6px 0 0;max-width:none;font-size:12.5px;color:var(--v6-muted)}
.v6o-top .band-live{margin:0;padding:5px 12px}
.v6o-map .map{margin-block-start:4px;max-height:min(470px,54vh)}
.v6o-map .legend{margin-block-start:4px;font-size:11.5px;gap:4px 12px}

/* ---------- 6. server health: one group per server (the name with its status dot, then CPU / RAM / disk) ---------- */
.v6o-sg{display:grid;grid-template-columns:repeat(auto-fit,minmax(calc(var(--v6o-sd,42px) * 3 + 30px),1fr));gap:2px 8px;align-items:start}
.v6o-sv{--sc:var(--v6d-muted);position:relative;display:grid;justify-items:center;align-content:start;gap:6px;min-width:0;margin:0;padding:6px 4px 4px;
  border:0;border-radius:16px;background:none;color:var(--v6-text);font:inherit;cursor:pointer;touch-action:manipulation;
  -webkit-tap-highlight-color:transparent;transition:background-color .2s ease}
.v6o-sv.st-ok{--sc:var(--v6d-ok)}
.v6o-sv.st-warn{--sc:var(--v6d-warn)}
.v6o-sv.st-bad{--sc:var(--v6d-bad)}
.v6o-sv.st-info{--sc:var(--v6d-info)}
.v6o-sv.st-idle{--sc:var(--v6d-muted)}
.v6o-sn{display:inline-flex;align-items:center;gap:7px;max-width:100%;min-width:0;font-size:13px;line-height:1.2}
.v6o-sn b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600;letter-spacing:.02em}
.v6o-dot{flex:0 0 auto;width:8px;height:8px;border-radius:50%;background:var(--sc);box-shadow:0 0 0 3px color-mix(in srgb,var(--sc) 20%,transparent),0 0 9px color-mix(in srgb,var(--sc) 55%,transparent)}
.v6o-sv.st-idle .v6o-dot{box-shadow:0 0 0 3px color-mix(in srgb,var(--sc) 16%,transparent)}
.v6o-hr{display:flex;align-items:flex-start;justify-content:center;gap:7px}
.v6o-hc{display:grid;justify-items:center;gap:3px;min-width:0}
.v6o-hc .v6d-ring{--v6d-size:var(--v6o-sd,42px)}
.v6o-hl{display:block;font-size:10.5px;line-height:1.1;color:var(--v6-muted);white-space:nowrap}
.v6o-sv[data-dim="1"] .v6d-ring{opacity:.5}
.v6o-sv[data-dim="1"] .v6o-sn b{color:var(--v6-muted)}
@media (hover:hover){
  .v6o-sv:hover{background:color-mix(in srgb,var(--v6-glass-soft) 70%,transparent)}
  .v6o-sv:hover .v6d-ring{transform:scale(1.07)}
}
.v6o-sv:active .v6d-ring{transform:scale(.97)}

/* ---------- 7. the lists: folded under «متقدم» (live-simple.js moves #lm-cap there); plain panels in there ---------- */
.v6o-lists{display:grid;gap:16px;min-width:0}
.v6o-lists:empty{display:none}
.v6o-lists>section:empty{display:none}

/* ---------- 8. the reseller portal: the home is rings (the header, the overview, protocols, servers), then the actions and who needs attention ---------- */
.rv .v6o-rs{grid-template-columns:repeat(auto-fit,minmax(calc(var(--v6o-d,80px) + 12px),1fr))}
/* the dark band the other tabs keep: its two rings side by side */
.rv .band .v6o-rs{grid-template-columns:repeat(2,minmax(0,1fr));margin-block-start:14px}
.rv .band .v6o-r{--v6o-d:var(--v6o-bd,76px);color:var(--band-ink)}
.rv .band .v6o-l{color:var(--band-muted)}
/* the home's header: flat on the glass, page tokens (the hero band is always dark; this is not a band) */
.v6o-hd{min-width:0;--band-ink:var(--v6-text);--band-muted:var(--v6-muted);--band-line:var(--v6-stroke)}
.v6o-hd .eyebrow{margin:0;font-size:12px;color:var(--v6-muted)}
.v6o-hd h1{margin:2px 0 0;font-size:22px;font-weight:500;line-height:1.25}
.v6o-hd .v6o-rs{margin-block-start:8px;grid-template-columns:repeat(2,minmax(0,1fr));max-width:calc(var(--v6o-d,80px) * 2 + 60px)}
.v6o-hd .band-sub{margin:4px 0 0;max-width:none;font-size:12.5px;color:var(--v6-muted)}
@media (max-width:899px){
  .v6o-hd{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:12px;align-items:center}
  .v6o-hd .eyebrow{grid-area:1/1;align-self:end}
  .v6o-hd h1{grid-area:2/1;align-self:start;overflow-wrap:anywhere}
  .v6o-hd .v6o-lim{grid-area:1/2/span 2;margin:0}
  .v6o-hd .band-sub{grid-area:3/1/auto/-1}
}
.v6o-rh{display:grid;gap:10px;min-width:0;align-content:start}
.v6o-rg{min-width:0}
.v6o-rg2{display:grid;grid-template-columns:minmax(0,1fr);gap:10px}
.v6o-sr{display:grid;grid-template-columns:repeat(auto-fit,minmax(calc(var(--v6o-d,80px) + 12px),1fr));gap:4px 6px;align-items:start}
.v6o-rg .muted.small{margin:2px 0 0;font-size:12.5px}
.v6o-r[data-v6k="note"]{grid-column:1/-1;justify-items:start;text-align:start}
.v6o-r[data-v6k="note"] .v{font-size:12.5px}
/* a long label (English «Need attention») wraps to two lines instead of being cut; a server's label (IP + specs) shows whole */
.rv .v6o-r .v6o-l{white-space:normal;line-height:1.2;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
.rv .v6o-rsrv .v6o-l{max-width:calc(var(--v6o-d,80px) + 36px);display:block;overflow:visible}
.v6o-rsrv .v6o-sp{display:block;margin-block-start:1px;font-size:11px;color:var(--v6-muted)}
.v6o-si{display:inline-block;white-space:nowrap;margin-inline:3px}
.v6o-acts{gap:8px;flex-wrap:wrap;margin-block:10px 0}
.v6o-ha{margin:14px 0 8px}
.v6o-none{margin:0}
.rv:has(.v6o-hd){padding-block-end:84px}
@media (min-width:641px){
  .rv:has(.v6o-hd){max-width:min(760px,calc(100vw - 24px))}
}
@media (min-width:900px){
  /* iPad landscape / desk: the header and the rings side by side, the actions and the customers who need attention under them */
  .rv:has(.v6o-hd){display:grid;grid-template-columns:minmax(250px,.5fr) minmax(0,1.5fr);gap:4px 32px;align-items:start;max-width:min(1240px,calc(100vw - 32px))}
  .rv:has(.v6o-hd)>*{grid-column:1/-1}
  .rv:has(.v6o-hd)>.v6o-hd{grid-area:1/1}
  .rv:has(.v6o-hd)>.v6o-rh{grid-area:1/2}
  .rv:has(.v6o-hd):not(:has(.v6o-rh))>.v6o-hd{grid-area:auto;grid-column:1/-1}
  .rv:has(.v6o-hd) .v6o-rg2{grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));gap:10px 26px}
  .rv:has(.v6o-hd) .rs-home-att{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:8px 14px;align-items:start}
}

/* ---------- 9. sizes ---------- */
.rv{--v6o-d:clamp(58px,17vw,78px);--v6o-bd:clamp(60px,18vw,76px)}
@media (min-width:641px){.rv{--v6o-d:76px;--v6o-bd:80px}}
/* iPad landscape / desk: width AND height decide, so the home stays on one screen */
@media (min-width:900px){.rv{--v6o-d:clamp(60px,min(6.4vw,10.4vh),100px);--v6o-bd:var(--v6o-d)}}
/* desk / iPad landscape: the ring follows the width AND the height, so the whole board stays on one screen */
@media (min-width:1000px){.v6o{--v6o-d:clamp(64px,min(6.8vw,11.6vh),112px)}}
.v6o{--v6o-sd:clamp(36px,10vw,44px)}
@media (min-width:1000px){.v6o{--v6o-sd:clamp(36px,min(3.4vw,5.6vh),56px)}}
@media (min-width:641px) and (max-width:999px){.v6o-map .map{max-height:min(420px,40vh)}}
@media (max-width:640px){.v6o-map .map{max-height:300px}}
@media (max-width:420px){
  .v6o-rs{gap:2px 2px}
  .v6o-l{font-size:11.5px}
  .v6o-sg{grid-template-columns:repeat(2,minmax(0,1fr))}
  .v6o-hr{gap:4px}
}

/* ---------- 10. motion off: the final state at once, no pulse ---------- */
@media (prefers-reduced-motion:reduce){
  .v6d-a,.v6d-ga,.v6d-oa,.v6d-ring,.v6d-glow,.v6o-r,.v6o-sv,.v6o-l{transition:none}
  .v6d-ring[data-pulse="1"] .v6d-glow,.v6d-ring[data-live="1"] .v6d-glow{animation:none}
  button.v6o-r:hover .v6d-ring,.v6o-sv:hover .v6d-ring{transform:none}
}
/* no blur filter where the OS asks for less transparency / effects */
@media (prefers-reduced-transparency:reduce){
  .v6d-glow{filter:none;opacity:calc(var(--v6d-glow) * .4)}
}
/* Web Panel v6 beta: v6-mobile.css (see web-src/v6/README.md)
   Phone and iPad layouts.  Runs after every design style and after v6-glass.css; uses its tokens (--v6-glass, --v6-stroke,
   --v6-hi, --v6-text, --v6-muted, --v6-accent, --v6-ok/warn/bad, --v6-radius ...).  Looks and layout only: no data, text or action.

   1. the collapsible customer item  (.v6-clist > .v6-ci: head button + body; behaviour in v6-mobile.js)
   2. «العملاء» (owner): which list is shown at which width, the table at iPad-landscape widths
   3. iPad (641-1180 px): the app shell, the other pages
   4. phones (<= 760 px): the other pages
   5. touch sizes                                                                                                   */

/* ================= 1. THE COLLAPSIBLE CUSTOMER ITEM ================= */
.v6-clist{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:minmax(0,1fr);gap:10px;align-items:start}
.v6-ci{position:relative;min-width:0;border:1px solid var(--v6-stroke);border-radius:var(--v6-radius);background:var(--v6-glass);
  box-shadow:var(--v6-shadow),inset 0 1px 0 var(--v6-hi);overflow:hidden;
  transition:border-color .2s ease,box-shadow .2s ease,background-color .2s ease}
.v6-ci.is-open{border-color:color-mix(in srgb,var(--v6-accent) 48%,var(--v6-stroke));background:var(--v6-glass-strong)}

/* the head: one line (name, state, online dot, chevron) and a 3 px usage meter under it; 60 px tall, a whole-row touch target */
.v6-ci-head{all:unset;box-sizing:border-box;display:grid;grid-template-columns:minmax(0,1fr) auto auto auto;align-items:center;width:100%;min-height:60px;
  padding:10px 14px 11px;cursor:pointer;color:var(--v6-text);-webkit-tap-highlight-color:transparent;touch-action:manipulation}
.v6-ci-head:hover{background:color-mix(in srgb,var(--v6-glass-soft) 55%,transparent)}
.v6-ci-head:active{background:var(--v6-glass-soft)}
.v6-ci-head:focus-visible{outline:2px solid var(--focus,var(--v6-accent));outline-offset:-3px;border-radius:var(--v6-radius)}
.v6-ci-name{grid-column:1;grid-row:1;justify-self:start;max-width:100%;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:16px;font-weight:600;line-height:30px;letter-spacing:.01em;unicode-bidi:isolate}
.v6-ci-state{grid-column:2;grid-row:1;margin-inline-start:10px;display:inline-flex;align-items:center;min-width:0}
.v6-ci-on{grid-column:3;grid-row:1;margin-inline-start:10px;display:inline-flex;align-items:center;gap:5px;height:26px;padding-inline:9px;border-radius:999px;
  background:var(--ok-soft);color:var(--v6-ok);font-size:12.5px;font-weight:600}
.v6-ci-on[data-n="0"]{display:none}
.v6-ci-on b{font-weight:600;font-variant-numeric:tabular-nums}
.v6-ci-dot{width:7px;height:7px;border-radius:50%;background:currentColor;box-shadow:0 0 0 3px color-mix(in srgb,currentColor 22%,transparent)}
.v6-ci-chev{grid-column:4;grid-row:1;margin-inline-start:12px;width:9px;height:9px;border-right:2px solid var(--v6-muted);border-bottom:2px solid var(--v6-muted);
  transform:translateY(-2px) rotate(45deg);transition:transform .26s cubic-bezier(.2,.7,.2,1),border-color .2s ease}
.v6-ci.is-open .v6-ci-chev{transform:translateY(2px) rotate(-135deg);border-color:var(--v6-accent)}
.v6-ci-meter{grid-column:1/-1;grid-row:2;display:block;position:relative;height:3px;margin-block-start:8px;border-radius:3px;overflow:hidden;
  background:color-mix(in srgb,var(--v6-muted) 26%,transparent);--mc:var(--v6-accent)}
.v6-ci-meter::after{content:"";position:absolute;inset-block:0;inset-inline-start:0;inline-size:calc(var(--p,0) * 100%);border-radius:3px;background:var(--mc);
  transition:inline-size .4s ease}
.v6-ci-meter[data-level="warn"]{--mc:var(--v6-warn)}
.v6-ci-meter[data-level="bad"]{--mc:var(--v6-bad)}

/* the body: height is animated by v6-mobile.js (inline height + .v6-anim), so it carries no padding of its own */
.v6-ci-body{overflow:hidden}
.v6-ci-body[hidden]{display:none!important}
.v6-ci-body.v6-anim{transition:height .26s cubic-bezier(.2,.7,.2,1)}
.v6-ci-kv{margin:0;padding:2px 14px 0;border-block-start:1px solid var(--v6-stroke)}
.v6-ci-kv>div{display:grid;grid-template-columns:minmax(4.6em,27%) minmax(0,1fr);align-items:center;gap:4px 12px;min-height:44px;padding-block:8px;
  border-block-end:1px solid color-mix(in srgb,var(--v6-stroke) 70%,transparent)}
.v6-ci-kv>div:last-child{border-block-end:0}
.v6-ci-kv>div.wide{grid-template-columns:minmax(0,1fr);align-items:start}
.v6-ci-kv dt{margin:0;font-size:12.5px;font-weight:500;color:var(--v6-muted)}
.v6-ci-kv dd{margin:0;min-width:0;overflow-wrap:anywhere;font-size:14px}
.v6-ci-kv dd .q{width:100%}
.v6-ci-kv dd .tags{flex-wrap:wrap}
.v6-ci-live{display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px;min-width:0}
.v6-ci-live .spd{max-width:100%}
.v6-ci-live .uc-dev{flex:1 1 100%;font-size:12.5px;color:var(--v6-muted)}
.v6-ci-acts{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:10px 14px 14px;border-block-start:1px solid var(--v6-stroke)}
.v6-ci-acts>.btn,.v6-ci-acts>.icon-btn,.v6-ci-sel{min-height:44px}
.v6-ci-acts>.btn{height:auto;padding-block:8px}
.v6-ci-acts>.btn{flex:1 1 calc(50% - 4px);min-width:0}
.v6-ci-acts>.btn.primary{flex:1 1 100%}
.v6-ci-sel{flex:1 1 100%}
.v6-ci-sel{display:inline-flex;align-items:center;gap:10px;padding-inline:12px;border-radius:var(--r-8);border:1px dashed var(--v6-stroke);font-size:13.5px;color:var(--ink-2);cursor:pointer}
.v6-ci-sel input{width:22px;height:22px;margin:0;accent-color:var(--v6-accent)}
/* update 16: the tick box of a customer sits in the collapsed head (an absolutely placed sibling of the head button) */
.v6-ci-pick{position:absolute;inset-inline-start:12px;top:19px;z-index:2;width:22px;height:22px;margin:0;accent-color:var(--v6-accent)}
.v6-ci.has-pick>.v6-ci-head{padding-inline-start:48px}
@media (min-width:641px){
  .v6-clist{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (prefers-reduced-motion:reduce){
  .v6-ci,.v6-ci-chev,.v6-ci-meter::after,.v6-ci-body.v6-anim{transition:none!important}
}

/* ================= 2. «العملاء» (OWNER) ================= */
/* <= 900 px (phones, iPad portrait): the collapsible list; above: the table.  (the design's own .only-narrow cards are gone from this page) */
@media (max-width:900px){
  #user-results>.tbl-wrap.only-wide{display:none}
}
@media (min-width:901px){
  #user-results>.v6-clist{display:none}
}
/* update 16: «تحديد الكل» above the phone list (the design's .only-narrow shows it below 761 px only; the list replaces the table up to 900 px) */
@media (max-width:900px){.sk-allrow.only-narrow{display:flex}}
@media (min-width:901px){.sk-allrow.only-narrow{display:none}}
/* filters: on tablets the chip rows wrap instead of scrolling sideways, the four selects sit in one row */
@media (min-width:641px) and (max-width:1180px){
  .filters{gap:10px}
  .filters .fchips{flex-wrap:wrap;overflow:visible}
  .conn-f .skc-frow{flex-wrap:wrap}
  .filters .frow{grid-template-columns:repeat(4,minmax(0,1fr))}
  .count{margin-block-end:10px}
}
/* the table at iPad-landscape widths (901-1400): only the essential columns (select, edit, user, state, connected, usage, expiry;
   the speed pill stays in the customer window and page), the header sticks under the top bar while the page scrolls.
   If the table still does not fit, v6-mobile.js adds .v6-scroll: it scrolls sideways and the header stops sticking. */
@media (min-width:901px) and (max-width:1400px){
  #user-results .tbl.users{min-width:0}
  #user-results>.tbl-wrap:not(.v6-scroll){overflow-x:auto;overflow-x:clip;overflow-y:visible}
  #user-results>.tbl-wrap:not(.v6-scroll) .tbl.users thead th{position:sticky;top:calc(56px + env(safe-area-inset-top,0px));z-index:3;background:var(--v6-base)}
  #user-results>.tbl-wrap:not(.v6-scroll) .tbl.users thead th:first-child{border-start-start-radius:var(--v6-radius)}
  #user-results>.tbl-wrap:not(.v6-scroll) .tbl.users thead th:last-child{border-start-end-radius:var(--v6-radius)}
}
@media (min-width:901px) and (max-width:1280px){
  #user-results .tbl.users :is(th,td):nth-child(6){display:none}
  #user-results .tbl.users td:nth-child(7){min-width:150px}
}

/* ================= 3. iPAD (641-1180 px) ================= */
/* any table that really scrolls sideways keeps its first column in view */
.tbl-wrap.v6-scroll .tbl :is(th,td):first-child{position:sticky;inset-inline-start:0;z-index:2;background:var(--v6-glass-strong)}
.tbl-wrap.v6-scroll{overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch}
@media (min-width:761px) and (max-width:1180px){
  .main{padding-inline:22px}
  .srvs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-items:start}
  .srvs>.srv{margin:0}
}
@media (min-width:761px) and (max-width:900px){
  .stats.resellers-mini{grid-template-columns:repeat(3,minmax(0,1fr))!important}
}
/* touch tablets (no hover) keep the side menu as a 60 px icon rail instead of a 14 px edge nobody can hit: a tap opens it, a tap
   elsewhere closes it (live-sidebar.js toggles .peek).  The rail is the menu itself, clipped: icons sit at its inline-start edge. */
@media (min-width:761px) and (hover:none){
  html.side-auto .side{inset-inline-start:0;width:60px;padding-inline:8px;overflow:hidden;box-shadow:none;
    transition:width .2s ease .3s,box-shadow .2s ease .3s}
  html.side-auto .side::after{display:none}
  html.side-auto .main{margin-inline-start:66px}
  html.side-auto .strip-in{padding-inline-start:74px}
  html.side-auto .side:is(:hover,.peek,:has(:focus-visible)){width:248px;padding-inline:12px;overflow-y:auto;box-shadow:var(--shadow-2);transition-delay:0s}
  html.side-auto .side .nv{overflow:hidden;white-space:nowrap}
  html.side-auto .side .nv>span,html.side-auto .side .ng-t{min-width:0;overflow:hidden;white-space:nowrap}
  html.side-auto .side:not(:is(:hover,.peek,:has(:focus-visible))) .ng-t{visibility:hidden;height:8px;margin-block:4px;padding:0}
  html.side-auto .side:not(:is(:hover,.peek,:has(:focus-visible))) .side-brand{background:none;border:0;box-shadow:none;padding-inline:4px;justify-content:center}
  html.side-auto .side:not(:is(:hover,.peek,:has(:focus-visible))) .side-brand::after{display:none}
  html.side-auto .side:not(:is(:hover,.peek,:has(:focus-visible))) .pin-btn{display:none}
}

/* ================= 4. PHONES (<= 760 px) ================= */
@media (max-width:760px){
  /* the «live data / error log / refresh» strip: two tight lines instead of two airy ones */
  .strip-in{padding:6px 14px;gap:0 10px}
  .sample{font-size:12px;gap:2px 8px}
  .strip .roles{gap:0;margin-inline-start:-8px}
  .strip .roles .btn.sm{height:36px;padding-inline:8px;font-size:12.5px}
  .ph{margin-block-end:14px;gap:10px 14px}
  .ph-act{width:100%}
  .ph-act>.btn{flex:1 1 calc(50% - 4px);min-width:0}
  .ph-act>.btn.primary{flex-basis:100%}
  /* the customer page's actions: a tidy two-column grid of equal buttons */
  .actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
  .actions>.row{display:contents}
  .actions .btn{width:100%;min-width:0;white-space:normal;text-align:center;line-height:1.3}
  .actions>.btn.ghost,.actions>.row>.btn.ghost{border-color:var(--v6-stroke)}
  .actions>.sp{display:none}
  .actions>details,.actions>#ua-delete{grid-column:1/-1}
  /* wide tables scroll inside their own box, never the page */
  .tbl-wrap{max-width:100%}
  .panel{min-width:0}
  /* the overview's short customer cards: the name + chip + speed pill wrap instead of pushing the page wider (320-340px) */
  .ucard{min-width:0;max-width:100%}
  .ucard-h{flex-wrap:wrap;min-width:0}
  .ucard-h b{min-width:0;overflow-wrap:anywhere}
  .ucard .spd{max-width:100%}
}
@media (max-width:760px){
  .filters{gap:10px}
}

/* very narrow phones (320-350): the logo alone is enough, the wordmark would push the bar wider than the screen */
@media (max-width:420px){.tb-in{gap:4px;padding-inline:12px}}
@media (max-width:350px){.topbar .wm{display:none}}

/* ================= 5. TOUCH SIZES ================= */
@media (pointer:coarse){
  .btn{min-height:44px}
  .btn.sm{min-height:40px}
  .icon-btn{min-width:44px;min-height:44px}
  .icon-btn.sm{min-width:40px;min-height:40px}
  .fchip,.skc-fc{min-height:40px}
  .tab{min-height:44px}
  .nv{min-height:46px}
  .rb{min-height:58px}
  /* 44px tall; width stays close to the design (32-36px) so five controls + the brand still fit a 360px phone */
  .topbar .icon-btn,.topbar .btn{min-width:36px;min-height:44px}
  .cw-sel,.tbl input[type="checkbox"]{width:22px;height:22px}
  .tbl td:has(>input[type="checkbox"]){min-width:48px}
}
/* Web Panel v6 beta: v6-res.css, the reseller portal customers page (see web-src/v6/README.md)
   The reseller's «عملائي» = the owner's «العملاء»: the same table (desktop, iPad landscape), the same collapsible item (phone, iPad portrait).
   Looks and layout only (no data, text or action).  This file is also loaded by the owner page, so every rule is scoped to
   .rs-users-page (the reseller customers page) or the reseller window (.rs-menu).  Uses the glass tokens of v6-glass.css.
     1. table <-> collapsible list (one switch at 900 px, the owner's own switch), the widened page
     2. the filters
     3. the table
     4. the window of one customer (pencil / row tap)
     5. the collapsible item: the phone items' extras + a fallback look (:where, zero specificity, so v6-mobile.css always wins) */

/* ================= 1. TABLE <-> LIST ================= */
.rs-users-page .v6-clist.rs-narrow{display:none}
@media (max-width:900px){
  .rs-users-page .rs-wide{display:none}
  .rs-users-page .v6-clist.rs-narrow{display:grid}
}
/* the portal column is a 600 px phone column; the customers page needs the room (the table, or two items side by side on an iPad),
   the header band stays a centred card */
@media (min-width:641px){
  .rv:has(.rs-users-page){max-width:min(860px,calc(100vw - 24px));padding-inline:12px}
  .rv:has(.rs-users-page)>.band{max-width:640px;margin-inline:auto}
}
@media (min-width:901px){
  .rv:has(.rs-users-page){max-width:min(1600px,calc(100vw - 24px))}
}

/* ================= 2. FILTERS ================= */
.rs-users-page .rs-filters{margin-block-end:12px}
.rs-users-page .rs-filters .fchips,.rs-users-page .rs-filters .conn-f .skc-frow{scrollbar-width:thin}
@media (min-width:901px){
  .rs-users-page .rs-filters .fchips{flex-wrap:wrap;overflow:visible}
  .rs-users-page .rs-filters .frow{grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),260px))}
}
.rs-users-page .count{margin-block-start:2px}

/* ================= 3. THE TABLE ================= */
.rs-users-page .tbl-wrap.rs-wide{box-shadow:var(--v6-shadow)}
.rs-users-page .tbl.users.rs-users{min-width:0;--conn-cell-w:108px}   /* the design pins .tbl.users at 1360 px for ALL its columns; this table keeps only the columns the keys show */
.rs-users-page .rs-users td{vertical-align:middle}
.rs-users-page .rs-users .who{max-width:170px}
.rs-users-page .rs-users .rs-c-exp{min-width:128px}
.rs-users-page .rs-users .rs-c-exp .who{max-width:none}
.rs-users-page .rs-users .rs-c-exp .who>*{white-space:nowrap}
.rs-users-page .rs-users .who .link,.rs-users-page .rs-users .who b{overflow-wrap:anywhere}
/* iPad landscape and small laptops (901-1400 px): the owner's essential columns only (speed, plan, servers stay in the customer window) */
@media (min-width:901px) and (max-width:1400px){
  .rs-users-page .rs-users .rs-c-spd,.rs-users-page .rs-users .rs-c-plan,.rs-users-page .rs-users .rs-c-srv{display:none}
}
.rs-users-page .rs-users .rs-c-act{width:56px;padding-inline-end:0}
.rs-users-page .rs-users .rs-pencil{width:38px;height:38px;border-radius:50%}
.rs-users-page .rs-users tr.click{cursor:pointer}
.rs-users-page .rs-users tr.click:hover td{background:var(--v6-glass-soft)}
.rs-users-page .rs-users .who .link{color:var(--v6-text);font-size:14.5px}
.rs-users-page .rs-users .who .link:hover{color:var(--v6-accent);text-decoration:underline}
.rs-users-page .rs-users .ucard-f{margin:0}
.rs-users-page .rs-users .spd{max-width:100%}

/* ================= 4. THE WINDOW OF ONE CUSTOMER ================= */
.rs-menu{display:grid;gap:14px;min-width:0}
.rs-menu .rs-kv{margin:0;grid-template-columns:minmax(6em,auto) minmax(0,1fr);gap:8px 14px;padding:12px 14px;border:1px solid var(--v6-stroke);border-radius:var(--v6-radius-sm);background:var(--v6-glass-soft)}
.rs-menu .rs-kv dd .q{width:100%}
.rs-menu .rs-kv dd .tags{flex-wrap:wrap}
.rs-menu-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,190px),1fr));gap:8px}
.rs-menu-list>.btn{width:100%;height:auto;min-height:44px;padding-block:8px}
.rs-menu-list>.btn.ghost{border-color:var(--v6-stroke)}
.rs-menu-list>.btn.primary{grid-column:1/-1}
@media (max-width:640px){
  .rs-menu-list{grid-template-columns:minmax(0,1fr)}
  .rs-menu .rs-kv{grid-template-columns:minmax(0,1fr);gap:2px 0}
  .rs-menu .rs-kv dd{margin-block-end:8px}
}

/* ================= 5. THE COLLAPSIBLE ITEM ================= */
/* what the reseller's items add to the shared look (v6-mobile.css): the speed pill fits the row, the count is a <bdi>, the status chip may hold the fair-use chip */
.rs-users-page .v6-ci-kv dd .spd{max-width:100%}
.rs-users-page .v6-ci-on bdi{font-weight:600;font-variant-numeric:tabular-nums}
.rs-users-page .v6-ci-state{flex-wrap:wrap;gap:4px}
.rs-users-page .v6-ci-acts>.btn.ghost{border-color:var(--v6-stroke)}

/* the fallback look: only what makes the markup usable when v6-mobile.css is missing; :where() has no specificity, so the shared look always wins */
:where(.rs-users-page .v6-clist){list-style:none;margin:0;padding:0;display:grid;gap:10px}
:where(.rs-users-page .v6-ci){border:1px solid var(--v6-stroke,var(--line));border-radius:var(--v6-radius,14px);background:var(--v6-glass,var(--surface));overflow:hidden}
:where(.rs-users-page .v6-ci-head){display:flex;align-items:center;gap:10px;width:100%;min-height:56px;padding:10px 14px;border:0;background:none;color:inherit;font:inherit;text-align:start;cursor:pointer}
:where(.rs-users-page .v6-ci-name){flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}
:where(.rs-users-page .v6-ci-meter){display:none}
:where(.rs-users-page .v6-ci-chev){width:9px;height:9px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg)}
:where(.rs-users-page .v6-ci-head[aria-expanded="true"] .v6-ci-chev){transform:rotate(-135deg)}
:where(.rs-users-page .v6-ci-kv){margin:0;padding:4px 14px;border-block-start:1px solid var(--v6-stroke,var(--line))}
:where(.rs-users-page .v6-ci-kv>div){display:grid;grid-template-columns:minmax(4.6em,27%) minmax(0,1fr);gap:4px 12px;padding-block:8px}
:where(.rs-users-page .v6-ci-kv dt){color:var(--v6-muted,var(--muted))}
:where(.rs-users-page .v6-ci-kv dd){margin:0;min-width:0}
:where(.rs-users-page .v6-ci-acts){display:flex;flex-wrap:wrap;gap:8px;padding:10px 14px 14px;border-block-start:1px solid var(--v6-stroke,var(--line))}
.rs-users-page .v6-ci-body[hidden]{display:none!important}
/* Web Panel v6 beta: v6-fleet.css, the overview fleet map (hub + servers) as segmented rings (see web-src/v6/README.md)
   The same look as the dashboard ring gauges (v6-dash.css): a 32-segment ring (one shared SVG mask, #v6f-seg, in the hidden
   <svg id="v6f-defs"> v6-fleet.js adds to <body>), a soft glow behind the lit segments, a light name in the centre, a sweep
   from empty the first time a ring appears and a glide on every update.  Motion is CSS only: no per-frame JS, and
   prefers-reduced-motion turns all of it off.  v6-fleet.js adds the ring elements inside the app's own `g.tn` nodes (the
   app's markup, data-act="node-focus" and the focus class stay), sets the lit fraction and shortens the connection lines so
   they stop at the rings; this file only draws.
   The map sits directly on the page glass (the overview has no hero band any more): the colours are the dashboard ring tokens
   (--v6d-*, v6-dash.css) and the page's --v6-* ink, which flip with the theme. */

/* ---------- tokens: the map sits directly on the page glass (no hero band), so both themes use the page's tokens ---------- */
.v6o-map.v6f-on{
  --v6f-acc:var(--v6d-acc,var(--v6-accent));--v6f-acc2:var(--v6-accent-2);
  --v6f-warn:var(--v6d-warn,var(--v6-warn));--v6f-bad:var(--v6d-bad,var(--v6-bad));--v6f-info:var(--v6d-info,var(--map-info,var(--v6-accent-2)));
  --v6f-ink:var(--v6-text);--v6f-muted:var(--v6-muted);--v6f-line:var(--v6-stroke);
  --v6f-face:color-mix(in srgb,var(--v6-glass-strong) 58%,transparent);
  --v6f-glow:.5;
}
html:root[data-theme="light"] .v6o-map.v6f-on{--v6f-glow:.34}
/* status colours in this block (rings, lines, legend): online is the accent */
.v6o-map.v6f-on .st-ok{--sc:var(--v6f-acc)}
.v6o-map.v6f-on .st-warn{--sc:var(--v6f-warn)}
.v6o-map.v6f-on .st-bad{--sc:var(--v6f-bad)}
.v6o-map.v6f-on .st-info{--sc:var(--v6f-info)}
.v6o-map.v6f-on .st-idle{--sc:var(--v6f-muted)}

/* ---------- the rings ---------- */
.v6f-map .v6f-rg{pointer-events:none}
.v6f-map .v6f-tr,.v6f-map .v6f-a,.v6f-map .v6f-ga,.v6f-map .v6f-ot,.v6f-map .v6f-oa{fill:none}
.v6f-map .tn{--v6f-c:var(--sc);--v6f-track:color-mix(in srgb,var(--v6f-c) 33%,transparent);--v6f-g:var(--v6f-glow)}
.v6f-map .tn.st-idle,.v6f-map .tn[data-v6f-nd="1"]{--v6f-track:color-mix(in srgb,var(--v6f-ink) 16%,transparent)}
.v6f-map .tn[data-v6f-nd="1"]{--v6f-c:var(--v6f-muted)}
.v6f-map .v6f-tr{stroke:var(--v6f-track);stroke-width:6}
.v6f-map .v6f-a{stroke:var(--v6f-c);stroke-width:6;stroke-dasharray:100 100}
.v6f-map .v6f-ga{stroke:var(--v6f-c);stroke-width:6.6;stroke-dasharray:100 100;opacity:var(--v6f-g);filter:url(#v6f-blur)}
.v6f-map .v6f-ot{stroke:color-mix(in srgb,var(--v6f-ink) 16%,transparent);stroke-width:1.5}
.v6f-map .v6f-oa{stroke:var(--v6f-oc,var(--v6f-acc));stroke-width:1.5;stroke-linecap:round;stroke-dasharray:100 100}
.v6f-map .tn[data-v6f-ot="warn"]{--v6f-oc:var(--v6f-warn)}
.v6f-map .tn[data-v6f-ot="bad"]{--v6f-oc:var(--v6f-bad)}
.v6f-map .v6f-a,.v6f-map .v6f-ga,.v6f-map .v6f-oa{transition:stroke-dashoffset .9s cubic-bezier(.3,.62,.25,1),stroke .45s ease}
.v6f-map .v6f-tr{transition:stroke .45s ease}

/* a server in its grace period (offline) pulses gently; the busy ones and the hub breathe very slowly */
@keyframes v6f-pulse{0%,100%{opacity:.5}50%{opacity:1}}
@keyframes v6f-breathe{0%,100%{opacity:calc(var(--v6f-glow) * .3)}50%{opacity:calc(var(--v6f-glow) * 1.05)}}
.v6f-map .tn[data-v6f-pulse="1"] .v6f-tr{animation:v6f-pulse 2.6s ease-in-out infinite}
.v6f-map .tn[data-v6f-live="1"] .v6f-ga{animation:v6f-breathe 4.2s ease-in-out infinite}

/* ---------- a server node: a dark face inside its ring, the name in the centre, the sessions under the ring ---------- */
.v6f-map .tn:not(.hub) .c{fill:var(--v6f-face);stroke:none}
.v6f-map .tn:not(.hub):not(.plan) .n{font-weight:500;letter-spacing:.01em}
.v6f-map .tn:not(.hub):not(.plan) .s{transform:translateY(8px)}
.v6f-map .tn .s{paint-order:stroke;stroke:var(--band-2,var(--v6-glass-strong));stroke-width:4px;stroke-linejoin:round}
.v6f-map .v6f-halo{fill:none;stroke:var(--v6f-c);stroke-width:1.5;opacity:0;pointer-events:none;transition:opacity .25s ease}
.v6f-map .tn:hover .v6f-halo{opacity:.5}
.v6f-map .tn.focus .v6f-halo{opacity:1;stroke-width:2}
.v6f-map .tn:hover,.v6f-map .tn.focus{--v6f-g:calc(var(--v6f-glow) * 1.5)}
.v6f-map .v6f-hit{fill:transparent;stroke:none}

/* ---------- planned slots: a faint dotted ghost ring ---------- */
.v6f-map .tn.plan{cursor:default}
.v6f-map .tn.plan .c{fill:none;stroke:none}
.v6f-map .tn.plan .v6f-tr{stroke:var(--v6f-line);opacity:.62}
.v6f-map .tn.plan .n{fill:var(--v6f-muted);opacity:.72;font-weight:400;font-size:11px}

/* ---------- the hub: the logo medallion inside a bigger ring, its name and sessions pushed under it ---------- */
.v6f-map .hub .c{stroke:var(--v6f-acc);stroke-width:2}
.v6f-map .hub:hover .c{stroke-width:3}
.v6f-map .hub-ring{stroke:color-mix(in srgb,var(--v6f-acc) 55%,transparent);stroke-width:1}
.v6f-map .pulse{stroke:var(--v6f-acc);stroke-width:1.2;stroke-opacity:.5}
.v6f-map #hubGlow stop{stop-color:var(--v6f-acc)!important}
.v6f-map .hub .n,.v6f-map .hub .s{transform:translateY(14px)}

/* ---------- connection lines: thin, accent-tinted, the flow a thin trail of dots ---------- */
.v6f-map .ln{stroke-width:1;stroke:var(--v6f-line);stroke-opacity:1}
.v6f-map .ln.ok{stroke:color-mix(in srgb,var(--v6f-acc) 50%,transparent)}
.v6f-map .ln.warn{stroke:color-mix(in srgb,var(--v6f-warn) 66%,transparent)}
.v6f-map .ln.bad{stroke:color-mix(in srgb,var(--v6f-bad) 66%,transparent);stroke-dasharray:5 5}
.v6f-map .ln.info{stroke:color-mix(in srgb,var(--v6f-info) 66%,transparent);stroke-dasharray:1.5 5;stroke-linecap:round}
.v6f-map .ln.idle{stroke:var(--v6f-line);stroke-dasharray:1.5 5;stroke-linecap:round}
/* the dash period (18) stays what the app's `flow` keyframes expect, so the loop never jumps */
.v6f-map .flow{stroke:var(--v6f-acc2);stroke-width:calc(1.4px + var(--fl,.5) * 1.4px);stroke-dasharray:.01 17.99;stroke-linecap:round;
  opacity:calc(.2 + var(--fl,.5) * .55)}
.v6f-map .flow.hot{stroke:var(--v6f-acc);filter:none}

/* ---------- motion off: the final state at once ---------- */
@media (prefers-reduced-motion:reduce){
  .v6f-map .v6f-a,.v6f-map .v6f-ga,.v6f-map .v6f-oa,.v6f-map .v6f-tr,.v6f-map .v6f-halo{transition:none}
  .v6f-map .tn[data-v6f-pulse="1"] .v6f-tr,.v6f-map .tn[data-v6f-live="1"] .v6f-ga{animation:none}
}
/* no blur filter where the OS asks for less transparency / effects */
@media (prefers-reduced-transparency:reduce){
  .v6f-map .v6f-ga{filter:none;opacity:calc(var(--v6f-g) * .4)}
}
/* Web Panel v6 beta: v6-forms.css (see web-src/v6/README.md)
   Native form controls in BOTH themes.  Owner 2026-10-02 (phone): «some fields turn WHITE when I tap them and you can't read them,
   especially choosing the plan (الباقة) when adding a customer».
   Cause: the glass theme paints a select with a translucent well (rgba) and light text.  A phone browser draws the opened list
   (and a date picker, a datalist, an autofilled field) outside the page, on its own opaque surface: the translucent well
   falls back to white, the text stays near-white, so the list is unreadable.  The fix is the standard one: every control that
   opens something native states an OPAQUE background, its own text colour and `color-scheme` for the theme in use, and the
   options / optgroups / datalist options / autofill / pickers / spinners follow.
   Dark is the default (like v6-glass.css); [data-theme="light"] is the light variant.  The v5 tree has the same rules in
   web-src/ui-forms.css with the v5 theme selectors; everything below the two theme blocks is identical in both files.
   Looks only: no layout, text or data. */

/* ---- the two theme blocks (the only part that differs from panel-v5/web-src/ui-forms.css) ---- */
html:root:not([data-theme="light"]){
  --ff-scheme:dark;
  --ff-bg:#0b1d4d;--ff-ink:#eef4ff;--ff-sel:#1b4fb8;--ff-sel-ink:#ffffff;--ff-muted:#9fb4d8;
}
html:root[data-theme="light"]{
  --ff-scheme:light;
  --ff-bg:#ffffff;--ff-ink:#0a1a3a;--ff-sel:#cfe0ff;--ff-sel-ink:#0a1a3a;--ff-muted:#445a82;
}

/* ---- shared rules ---- */
select,option,optgroup,
input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"],input[type="week"],
input[type="number"],input[list],textarea,input[type="text"],input[type="search"],input[type="password"],
input[type="email"],input[type="url"],input[type="tel"]{color-scheme:var(--ff-scheme,normal)}

/* a select opens a native list: opaque well + readable text, also while it is open, focused or pressed */
html:root select,html:root select:hover,html:root select:focus,html:root select:focus-visible,html:root select:active{
  background-color:var(--ff-bg);color:var(--ff-ink)}
select{background-clip:padding-box}
select[multiple],select[size]:not([size="1"]){background-color:var(--ff-bg)}
html:root option,html:root optgroup{background-color:var(--ff-bg);color:var(--ff-ink)}
html:root option:checked,html:root option:hover,html:root option:focus{background-color:var(--ff-sel);color:var(--ff-sel-ink)}
html:root option:disabled,html:root optgroup:disabled{color:var(--ff-muted)}
/* the input a datalist hangs from opens the same native list */
html:root input[list]{background-color:var(--ff-bg);color:var(--ff-ink)}
datalist,datalist option{background-color:var(--ff-bg);color:var(--ff-ink)}

/* date / time pickers: the field keeps its glass look, the picker pop-up follows color-scheme; the icon is visible on both */
input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"],input[type="week"]{
  background-color:var(--ff-bg);color:var(--ff-ink);min-height:40px}
input::-webkit-calendar-picker-indicator{opacity:.85;cursor:pointer}
html:root:not([data-theme="light"]) input::-webkit-calendar-picker-indicator{filter:invert(1) brightness(1.1)}

/* number spinners */
input[type="number"]{-moz-appearance:textfield;appearance:textfield}
input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{opacity:.7;margin:0}

/* autofill (Chrome / Safari paint a pale yellow or white well and dark text): put the theme back */
input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus,input:-webkit-autofill:active,
textarea:-webkit-autofill,select:-webkit-autofill{
  -webkit-text-fill-color:var(--ff-ink);caret-color:var(--ff-ink);
  box-shadow:0 0 0 1000px var(--ff-bg) inset;-webkit-box-shadow:0 0 0 1000px var(--ff-bg) inset;
  transition:background-color 99999s ease-out 0s}
input:autofill,textarea:autofill{background-color:var(--ff-bg);color:var(--ff-ink);-webkit-text-fill-color:var(--ff-ink)}

/* the text selection and the placeholder stay readable inside the wells */
input::selection,textarea::selection{background:var(--ff-sel);color:var(--ff-sel-ink)}
input::placeholder,textarea::placeholder{color:var(--ff-muted);opacity:.85}

/* a phone zooms the page when a focused field is under 16px: keep them at 16px there (no jump, no white flash while it zooms) */
@media (max-width:760px){
  select,input[type="text"],input[type="search"],input[type="password"],input[type="number"],input[type="email"],input[type="url"],
  input[type="tel"],input[type="date"],input[type="time"],input[type="datetime-local"],textarea{font-size:16px}
}
/* Web Panel v6 beta: v6-phone.css (the phone pass of 2026-10-02; see web-src/v6/README.md)
   Owner 2026-10-02: «pages on the phone look very bad, e.g. choosing customers and their permissions (reseller permissions);
   review the whole phone design so it fits a phone».  CSS only, loaded after v6-mobile.css / v6-forms.css; the same rules live in
   panel-v5/web-src/ui-phone.css for the v5 panel (both use the design's own tokens, no --v6-* variable).
   What it fixes (found by measuring every page and dialog at 390 px with tests/e2e_phone_pass.py):
   1. a dialog body is a one-column grid whose column was `auto`: its widest child set the column, so a six-tab strip (reseller window,
      customer window) made the body 563 px wide in a 356 px dialog: text cut at the edge, a hidden sideways scroll.  The column is now
      `minmax(0,1fr)` (all widths) and the tab strip scrolls inside its own box.
   2. the permission checklist («صلاحيات البائع»): the labels were pills of every width; on a phone each is a full-width row, one column.
   3. touch targets: 40 px at least (buttons, tabs, filter chips, links), whatever the browser says about `pointer`.
   4. the reseller card: its lone pencil (an icon in an empty strip) is a labelled full-width button.
   5. rows of chips (a waiting plan request) wrap instead of running past the card edge.
   6. `.dlg.wide` is full-screen on a phone like every other dialog (it stayed 358 px wide, flush right, with a gap on the left).
   7. the host picker of the customer form: a long type tag squeezed the host name to 16 px (one letter per line).
   Looks and layout only: no data, text or action. */

/* ================= 1. dialogs, every width ================= */
.dlg-body{grid-template-columns:minmax(0,1fr)}
.dlg-body>*{min-width:0}
.dlg .tabs{max-width:100%;overflow-x:auto;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.dlg .tabs::-webkit-scrollbar{display:none}
.dlg .tabs .tab{flex:none;white-space:nowrap}

@media (max-width:760px){
  /* the design makes a dialog full-screen on a phone (.dlg{width:100vw;margin:0}), but `.dlg.wide` (more specific, 760px max) kept its
     desktop width: 358 px, pushed against the right edge with a 32 px gap on the left, on every wide dialog (reseller, permissions, customer window) */
  .dlg.wide{width:100vw;max-width:100vw}

  /* a dialog's tab strip wraps into two rows instead of hiding «إجراءات / النشاط / حذف» behind a sideways swipe (the reseller window has six tabs) */
  .dlg .tabs{flex-wrap:wrap;overflow:visible;width:100%;border-radius:22px}
  .dlg .tabs .tab{flex:1 1 auto;text-align:center}

  /* ================= 2. the permission checklist (and any checklist with long labels) ================= */
  #dlg-body:has(#lr-plans-fs) .checks{display:grid;grid-template-columns:minmax(0,1fr);gap:8px}
  .dlg .ck:has(.small,br){flex:1 1 100%;width:100%;min-width:0;align-items:flex-start}
  .dlg .ck:has(.small,br)>input{margin-block-start:3px}
  .dlg .ck{min-height:44px;line-height:1.5;overflow-wrap:anywhere}
  .dlg .ck input[type="checkbox"],.dlg .ck input[type="radio"]{flex:none;width:22px;height:22px}
  #dlg-body:has(#lr-plans-fs) .lr-pm-star{min-width:0}

  /* ================= 3. touch targets: 40 px at least, whatever `pointer` says ================= */
  .btn{min-height:44px}
  .btn.sm{min-height:40px}
  .icon-btn{min-width:44px;min-height:44px}
  .icon-btn.sm{min-width:40px;min-height:40px}
  .fchip,.skc-fc,.tab{min-height:40px}
  .nv{min-height:46px}
  .strip .roles .btn.sm{height:40px}
  .topbar .icon-btn,.topbar .btn{min-width:38px;min-height:44px}
  .link,.v6o-lk,button.spd,.spd.ecg-cell{min-height:40px}
  .link,.v6o-lk{display:inline-flex;align-items:center;padding-inline:4px}
  select,input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="hidden"]),textarea{min-height:44px}
  .dlg footer .btn{min-width:96px}

  /* ================= 4. the reseller card ================= */
  .uc-live>.rr-pencil{flex:1 1 100%;width:100%;height:auto;min-height:44px;margin:0;border:1px solid var(--line-strong,currentColor);border-radius:var(--r-12,12px);
    gap:8px;padding-inline:14px;display:inline-flex;align-items:center;justify-content:center;font-size:14px;font-weight:500}

  /* ================= 5. rows of chips wrap inside the card ================= */
  .v6-ci-body :is(.chip,.tag,.rq-chip,[data-rq-state]){max-width:100%;white-space:normal}
  .v6-ci-body>[class*="rq"],.v6-ci-body .rq-line{display:flex;flex-wrap:wrap;gap:6px 8px;padding-inline:14px;min-width:0}
  .v6-ci-body>*{min-width:0;max-width:100%}
  /* ================= 6. the host picker of the customer form (live-hosts.js): the long type tag squeezed the host name to 16 px, one letter per line ================= */
  .hp-r{flex-wrap:wrap}
  .hp-r .hp-l{flex:1 1 9em}
  .hp-r .hp-t{max-width:100%;white-space:normal;overflow-wrap:anywhere}
  /* the page title takes focus when a page opens (screen readers): no ring around it on a touch screen (a white frame around «العملاء» / «عميل جديد») */
  #main h1[tabindex="-1"]:focus,#main h1[tabindex="-1"]:focus-visible,#main [tabindex="-1"]:focus:not(input):not(select):not(textarea):not(button){outline:0}
}
