/* Схема «Как устроена мобильная сеть» (/lab/telecom/).
   Цвета потоков: сигнализация, голос, данные, H.248, SIP, CDR, радио. Всё внутри .tl, чтобы не задевать стили сайта. */
.tl{
  --surface:#0A0B1C; --band:#080918; --band2:#10122A; --node:#12142F; --node-ink:var(--text);
  --ink:var(--text); --line:#2A2D55;
  --sig:#F0A03A; --voice:#2FC7C7; --data:#6AA3FF; --h248:#AB8CF2; --cdr:#62C472; --sip:#EE6AA8; --radio:#7F91A3; --bad:#FF6A5F;
  --f-display:var(--serif); --f-body:var(--sans);
  --f-mono:"JetBrains Mono",ui-monospace,Consolas,monospace;
  display:flex;flex-direction:column;gap:16px;font-size:15px;line-height:1.5;margin-top:8px
}
.container.tl-wide{max-width:1500px}
.tl [hidden]{display:none}
.tl h2,.tl h3,.tl h4{letter-spacing:0}
.tl-note{color:var(--text-2);font-size:13px;margin-top:8px}
.tl .views{display:flex;flex-wrap:wrap;gap:0;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--surface);width:fit-content;max-width:100%}
.tl .view{font:600 14px var(--f-body);color:var(--ink);background:transparent;border:0;border-right:1px solid var(--line);padding:9px 16px;cursor:pointer}
.view:last-child{border-right:0}
.view[aria-selected="true"]{background:var(--ink);color:var(--bg)}
.scens{display:flex;flex-wrap:wrap;gap:6px}
.scen{font:500 13.5px var(--f-body);color:var(--ink);background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:6px 12px;cursor:pointer;display:flex;gap:7px;align-items:center}
.scen b{font-family:var(--f-mono);font-size:11.5px;color:var(--muted);font-weight:500}
.scen[aria-selected="true"]{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.scen[aria-selected="true"] b{color:inherit;opacity:.75}
button:focus-visible,select:focus-visible,.nd:focus-visible,input:focus-visible+span{outline:2px solid var(--accent);outline-offset:2px}

.tl-main{display:grid;grid-template-columns:minmax(0,1fr) 360px;gap:16px;align-items:stretch}
@media (max-width:1100px){.tl-main{grid-template-columns:minmax(0,1fr)}}

.stagebox{background:var(--surface);border:1px solid var(--line);border-radius:14px;overflow:hidden;min-width:0}
.scroller{overflow-x:auto}
#stage{display:block;width:100%;min-width:780px;height:auto;font-family:var(--f-body)}
.controls{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:10px 12px;border-top:1px solid var(--line)}
.tl-btn{font:600 14px var(--f-body);background:var(--band2);color:var(--ink);border:1px solid var(--line);border-radius:8px;padding:7px 12px;cursor:pointer}
.tl-btn:disabled{opacity:.45;cursor:default}
.tl-btn.primary{background:var(--accent);color:var(--on-accent);border-color:var(--accent);min-width:96px}
.tl-btn[aria-pressed="true"]{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.spacer{flex:1}
.controls label{font-size:13px;color:var(--muted);display:flex;gap:6px;align-items:center}
.controls select{font:500 13px var(--f-body);background:var(--surface);color:var(--ink);border:1px solid var(--line);border-radius:6px;padding:4px 6px}
.switch{cursor:pointer;user-select:none}
.switch input{position:absolute;opacity:0;width:1px;height:1px}
.switch span{display:inline-flex;align-items:center;gap:8px;color:var(--ink);font-weight:500}
.switch span::before{content:"";flex:none;width:32px;height:18px;border-radius:9px;background:radial-gradient(circle 7px at 9px 50%,var(--surface) 96%,transparent 100%),var(--line)}
.switch input:checked+span::before{background:radial-gradient(circle 7px at 23px 50%,var(--on-accent) 96%,transparent 100%),var(--accent)}
.legend{display:flex;flex-wrap:wrap;gap:6px 16px;padding:10px 12px;border-top:1px solid var(--line);font-size:12.5px;color:var(--muted)}
.legend span{display:flex;align-items:center;gap:6px}
.legend svg{flex:none}

.panel{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.2fr) minmax(0,1fr);gap:16px;align-items:start}
@media (max-width:1100px){.panel{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.panel .info{grid-column:1/-1}}
@media (max-width:720px){.panel{grid-template-columns:minmax(0,1fr)}}

/* Чат сети справа от схемы — как чат прямого эфира: растёт снизу, прокручивается внутри */
.chat{background:var(--surface);border:1px solid var(--line);border-radius:14px;display:flex;flex-direction:column;min-width:0;min-height:0;position:relative}
.chat-head{display:flex;flex-wrap:wrap;align-items:center;gap:4px 10px;padding:12px 14px;border-bottom:1px solid var(--line)}
.chat-title{font-family:var(--f-display);font-weight:500;font-size:15px}
.chat-sub{order:3;font-size:12.5px;color:var(--muted);flex-basis:100%}
.live{order:2;margin-left:auto;display:inline-flex;align-items:center;gap:6px;font:700 10.5px var(--f-mono);letter-spacing:.08em;text-transform:uppercase;color:#fff;background:#E5303C;border-radius:4px;padding:3px 7px}
.live::before{content:"";width:6px;height:6px;border-radius:50%;background:#fff;animation:blink 1.2s ease-in-out infinite}
.live.off{background:var(--band2);color:var(--muted)}
.live.off::before{background:var(--muted);animation:none}
@keyframes blink{50%{opacity:.25}}
.chat-list{list-style:none;margin:0;padding:8px 6px 10px;overflow-y:auto;flex:1 1 0;min-height:0;display:flex;flex-direction:column;gap:2px;font-size:13.5px;line-height:1.4;scrollbar-width:thin;scrollbar-color:var(--line) transparent}
.chat-list li{display:grid;grid-template-columns:24px 1fr;gap:8px;align-items:start;padding:4px 8px;border-radius:8px;animation:chat-in .25s var(--ease)}
.chat-list li:hover{background:var(--band2)}
.chat-list .av{width:24px;height:24px;border-radius:50%;display:grid;place-items:center;font:700 8.5px var(--f-mono);color:var(--bg);background:var(--c);overflow:hidden;white-space:nowrap}
.chat-list .who{font:700 12.5px var(--f-mono)}
.chat-list .to{font:500 12px var(--f-mono);color:var(--muted)}
.chat-list .msg{color:var(--ink)}
.chat-list .tc{display:none;margin-top:2px;font:600 11.5px var(--f-mono);color:var(--muted)}
.chat-list.tech .tc{display:block}
.chat-list li.sys{display:block;text-align:center;font:600 11px var(--f-mono);color:var(--muted);padding:8px 8px 4px;letter-spacing:.03em}
.chat-list li.sys.scen{color:var(--accent);text-transform:uppercase;letter-spacing:.08em}
.chat-list li.sys:hover{background:none}
@keyframes chat-in{from{opacity:0;transform:translateY(6px)}}
@media (max-width:1100px){.chat{height:340px}}
@media (prefers-reduced-motion: reduce){.chat-list li,.live::before{animation:none}}
.card{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:16px 18px;display:flex;flex-direction:column;gap:10px;min-width:0}
.card h2{font-family:var(--f-display);font-weight:500;font-size:19px;line-height:1.2;margin:0;text-wrap:balance}
.card .sub{margin:0;color:var(--muted);font-size:14px}
ol.steps{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
ol.steps button{all:unset;box-sizing:border-box;width:100%;cursor:pointer;display:grid;grid-template-columns:26px 1fr;gap:8px;align-items:center;
  padding:5px 8px;border-radius:8px;font-size:14px;color:var(--muted)}
ol.steps button:focus-visible{outline:2px solid var(--accent)}
ol.steps .n{font-family:var(--f-mono);font-size:12px;width:24px;height:24px;border-radius:50%;display:grid;place-items:center;border:1px solid var(--line)}
ol.steps li.done button{color:var(--ink)}
ol.steps li.done .n{background:var(--band2)}
ol.steps li.cur button{background:var(--band2);color:var(--ink);font-weight:600}
ol.steps li.cur .n{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.now h3{margin:0;font-family:var(--f-display);font-weight:500;font-size:17px;line-height:1.25}
.now p{margin:0}
.techp{font-size:13.5px;border:1px dashed var(--line);border-radius:8px;padding:8px 10px;background:var(--band)}
.techp b{font-family:var(--f-mono);font-size:11px;letter-spacing:.07em;color:var(--muted);display:block;margin-bottom:2px}
.chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{font:500 12px var(--f-mono);border-radius:6px;padding:3px 7px;border:1px solid currentColor;background:transparent}
.chip.sig{color:var(--sig)}.chip.voice{color:var(--voice)}.chip.data{color:var(--data)}.chip.h248{color:var(--h248)}.chip.cdr{color:var(--cdr)}.chip.sip{color:var(--sip)}.chip.radio{color:var(--radio)}
.analogy{border-left:3px solid var(--line);padding-left:12px;color:var(--muted);font-size:14px}
.analogy b{color:var(--ink);font-weight:600}
.info dl{margin:0;display:flex;flex-direction:column;gap:8px}
.info dt,.ref dt{font-family:var(--f-mono);font-size:11px;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
.info dd,.ref dd{margin:0}
.info ul,.ref ul{margin:0;padding-left:18px}
.info .hint{color:var(--muted);font-size:14px;margin:0}

.refsec{display:flex;flex-direction:column;gap:14px;margin-top:18px}
.refsec>h2{font-family:var(--f-display);font-weight:700;font-size:clamp(22px,3vw,30px);margin:0}
.refsec h3{font-family:var(--f-display);font-weight:500;font-size:17px;margin:10px 0 0}
.refgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:12px}
.ref{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:14px 16px;display:flex;flex-direction:column;gap:8px;font-size:14px;min-width:0}
.ref h4{margin:0;font:700 14px var(--f-mono)}
.ref p{margin:0;color:var(--muted)}
.ref dl{margin:0;display:flex;flex-direction:column;gap:6px}
.tablewrap{overflow-x:auto;background:var(--surface);border:1px solid var(--line);border-radius:12px}
.tl table{border-collapse:collapse;width:100%;font-size:14px;min-width:640px}
.tl th,.tl td{text-align:left;padding:8px 12px;border-bottom:1px solid var(--line);vertical-align:top}
.tl th{font:700 11px var(--f-mono);letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
.tl td:first-child{font-family:var(--f-mono);font-weight:700;white-space:nowrap}
.tl tr:last-child td{border-bottom:0}

/* SVG */
.band-label{font:700 10.5px var(--f-mono);letter-spacing:.12em;fill:var(--muted)}
.edge{fill:none;stroke-width:1.6;opacity:.4}
.e-sig{stroke:var(--sig);stroke-dasharray:6 5}
.e-sbi{stroke:var(--sig);stroke-width:2.2}
.e-h248{stroke:var(--h248);stroke-dasharray:3 4}
.e-voice{stroke:var(--voice)}
.e-data{stroke:var(--data)}
.e-cdr{stroke:var(--cdr);stroke-dasharray:1.5 4;stroke-linecap:round}
.e-sip{stroke:var(--sip);stroke-dasharray:8 4}
.e-radio{stroke:var(--radio);stroke-dasharray:2 4}
.e-ran{stroke:var(--radio)}
.dimmed .edge{opacity:.1}
.busline{stroke:var(--sig);stroke-width:6;opacity:.35;stroke-linecap:round}
.ifc{font:600 10px var(--f-mono);fill:var(--muted);paint-order:stroke;stroke:var(--surface);stroke-width:3.5px;text-anchor:middle;display:none}
.tech .ifc{display:block}
.grp{fill:none;stroke:var(--muted);stroke-width:1;stroke-dasharray:4 4;opacity:.75}
.grp-label{font:500 11px var(--f-mono);fill:var(--muted)}
.nd{cursor:pointer;outline:none;transition:opacity .3s}
.nd.dim{opacity:.18}
.nd .box{fill:var(--node);stroke:var(--ink);stroke-width:1.4}
.nd .nm{font:700 13px var(--f-mono);fill:var(--node-ink);text-anchor:middle}
.nd .sb{font:400 10.5px var(--f-body);fill:var(--muted);text-anchor:middle}
.nd .ico{fill:none;stroke:var(--ink);stroke-width:1.6;stroke-linejoin:round;stroke-linecap:round}
.nd .ico-fill{fill:var(--node);stroke:var(--ink);stroke-width:1.6}
.nd:hover .box,.nd.sel .box{stroke:var(--accent);stroke-width:2.2}
.nd.down .box{stroke:var(--bad);fill:var(--band2)}
.nd.down .nm{fill:var(--bad)}
.xmark{stroke:var(--bad);stroke-width:3;stroke-linecap:round}
.trail{fill:none;stroke-width:3.2;stroke-linecap:round;opacity:.85}
.pk-label,.tag-text{font:600 11px var(--f-mono)}
.ring{fill:none;stroke-width:2}
.flow-base{fill:none;stroke:var(--fc);stroke-width:9;opacity:.18;stroke-linecap:round;stroke-linejoin:round}
.flow{fill:none;stroke:var(--fc);stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1 13;animation:flow .7s linear infinite}
.flow.rev{stroke-dasharray:6 22;stroke-width:2;animation-duration:1.1s;animation-direction:reverse;opacity:.8}
@keyframes flow{to{stroke-dashoffset:-14}}
.paused .flow{animation-play-state:paused}
.timer{font:700 13px var(--f-mono);fill:var(--voice)}
.cell{fill:var(--radio);fill-opacity:.07;stroke:var(--radio);stroke-dasharray:4 4;stroke-width:1.2}
.sector{stroke:var(--surface);stroke-width:2}
.beam{fill:var(--data);opacity:.16}
.cell-label{font:600 11px var(--f-mono);fill:var(--muted);text-anchor:middle}
@media (prefers-reduced-motion: reduce){.flow{animation:none;stroke-dasharray:none}}
