821de2b0c0
Встраивание дизайн-хэндоффа constellation dashboard отдельной вкладкой рядом с Планы/Карта/Комплексный план/Редактор/Заявки. - модуль src/features/constellation/ (прототип на JSX + realData.ts/ConstellationTab.tsx) - реальные данные вместо симуляции: платформы (OPERATIONAL), станции, заявки→ROI (WKT), трасса flight-line как эфемерида (сэмплер позиции через env.subSat), ЗРВ→сброс, съёмка по пролёту над ROI; оптика/локация — по имени КА из НСИ - d3-geo + topojson-client; карта world-atlas локально (без CDN) - изоляция стилей на .cdash (конфликт --line с theme.css), высота .app=100% - локальное время в часах и оси таймлайна (конвенция проекта) - allowJs:true в tsconfig.app.json под JSX-модуль
185 lines
13 KiB
CSS
185 lines
13 KiB
CSS
/* Fonts — remove this @import if your app already loads IBM Plex */
|
||
@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap");
|
||
|
||
/* Переменные и резеты дашборда оскоплены на .cdash, чтобы не течь в остальное
|
||
приложение (см. INTEGRATION.md §6). В частности, --line здесь свой и не должен
|
||
переопределять --line из styles/theme.css на уровне всего приложения. */
|
||
.cdash {
|
||
--bg0:#0a0c0b; --bg1:#0e1211; --panel:#111514; --ins:#0a0e0d;
|
||
--line:rgba(255,255,255,0.06); --line2:rgba(255,255,255,0.11);
|
||
--hi:#e7ece9; --mid:#95a19d; --dim:#5b6662; --faint:#3c4644;
|
||
--teal:#5fb3a3; --teal-bg:rgba(95,179,163,0.13); --teal-br:rgba(95,179,163,0.35);
|
||
--amber:#d99a4e; --blue:#5b9bd5; --red:#d9685f; --green:#5cae7e; --violet:#a78bdb;
|
||
color:var(--hi); font-family:'IBM Plex Sans',system-ui,sans-serif; font-size:13px;
|
||
-webkit-font-smoothing:antialiased;
|
||
}
|
||
.cdash *{box-sizing:border-box;}
|
||
.mono,.clock-time,.sr-norad,.map-cursor,.tl-tick,.fc-meta{font-family:'IBM Plex Mono',monospace;}
|
||
.cdash button{font-family:inherit; cursor:pointer; color:inherit;}
|
||
.cdash ::-webkit-scrollbar{width:8px;height:8px;}
|
||
.cdash ::-webkit-scrollbar-thumb{background:rgba(255,255,255,0.07);border-radius:4px;}
|
||
.cdash ::-webkit-scrollbar-track{background:transparent;}
|
||
|
||
/* Встроено вкладкой в shell с собственной шапкой: высота от родителя, не 100vh
|
||
(см. INTEGRATION.md §4). display:contents у обёртки вкладки делает .app прямым
|
||
элементом grid-строки shell (minmax(0,1fr)). */
|
||
.app{height:100%; display:flex; flex-direction:column; overflow:hidden;}
|
||
|
||
/* ---------- header ---------- */
|
||
.hdr{
|
||
height:54px; flex:none; display:flex; align-items:center;
|
||
border-bottom:1px solid var(--line); background:linear-gradient(var(--bg1),var(--bg0));
|
||
padding:0 16px; gap:18px; position:relative; z-index:5;
|
||
}
|
||
.hdr-brand{display:flex; align-items:center; gap:11px; min-width:248px;}
|
||
.brand-mark{width:20px;height:20px;border-radius:50%;border:1.5px solid var(--teal);
|
||
box-shadow:0 0 10px rgba(95,179,163,0.4) inset, 0 0 6px rgba(95,179,163,0.3);}
|
||
.brand-1{font-weight:600; font-size:13px; letter-spacing:.04em; white-space:nowrap;}
|
||
.brand-2{font-family:'IBM Plex Mono',monospace; font-size:9px; color:var(--dim); letter-spacing:.12em; margin-top:1px;}
|
||
|
||
.hdr-transport{flex:1; display:flex; align-items:center; justify-content:center; gap:7px;}
|
||
.t-btn{background:var(--bg1); border:1px solid var(--line2); color:var(--mid);
|
||
height:30px; min-width:34px; padding:0 11px; border-radius:6px; font-size:11.5px; letter-spacing:.04em;
|
||
transition:.12s;}
|
||
.t-btn:hover{border-color:var(--teal-br); color:var(--hi);}
|
||
.t-play{font-size:12px; color:var(--teal); border-color:var(--teal-br); background:var(--teal-bg); width:42px;}
|
||
.t-play.on{background:rgba(95,179,163,0.2);}
|
||
.t-now{font-size:10.5px; letter-spacing:.1em;}
|
||
.t-now.live{background:rgba(92,174,126,0.16); border-color:rgba(92,174,126,0.5); color:var(--green);}
|
||
.t-sep{width:1px; height:20px; background:var(--line2); margin:0 4px;}
|
||
.speed-seg{display:flex; border:1px solid var(--line2); border-radius:6px; overflow:hidden; background:var(--bg1);}
|
||
.speed-seg .sp{background:transparent; border:0; color:var(--dim); height:28px; padding:0 11px; font-size:11px;
|
||
font-family:'IBM Plex Mono',monospace; border-right:1px solid var(--line); transition:.12s;}
|
||
.speed-seg .sp:last-child{border-right:0;}
|
||
.speed-seg .sp:hover{color:var(--mid);}
|
||
.speed-seg .sp.on{background:var(--teal-bg); color:var(--teal);}
|
||
|
||
.hdr-clock{display:flex; flex-direction:column; align-items:flex-end; min-width:240px; gap:1px;}
|
||
.live-badge{display:flex; align-items:center; gap:5px; font-size:9.5px; letter-spacing:.16em; color:var(--amber);
|
||
font-family:'IBM Plex Mono',monospace;}
|
||
.live-badge .live-dot{width:6px;height:6px;border-radius:50%;background:var(--amber);}
|
||
.live-badge.on{color:var(--green);}
|
||
.live-badge.on .live-dot{background:var(--green); box-shadow:0 0 6px var(--green); animation:pulse 1.4s infinite;}
|
||
@keyframes pulse{0%,100%{opacity:1;}50%{opacity:.35;}}
|
||
.clock-main{display:flex; align-items:baseline; gap:6px;}
|
||
.clock-time{font-size:22px; font-weight:500; letter-spacing:.02em; line-height:1;}
|
||
.clock-utc{font-size:9px; color:var(--dim); letter-spacing:.1em;}
|
||
.clock-date{font-size:10px; color:var(--mid); font-family:'IBM Plex Mono',monospace; letter-spacing:.06em;}
|
||
|
||
/* ---------- body ---------- */
|
||
.body{flex:1; display:flex; min-height:0;}
|
||
.side{width:328px; flex:none; border-right:1px solid var(--line); background:var(--bg1);
|
||
display:flex; flex-direction:column; overflow:hidden;}
|
||
.main{flex:1; display:flex; flex-direction:column; min-width:0;}
|
||
|
||
.sec-label{font-family:'IBM Plex Mono',monospace; font-size:9.5px; letter-spacing:.16em; color:var(--dim);
|
||
padding:13px 16px 8px; display:flex; align-items:center; gap:8px;}
|
||
.sec-label.tight{padding-top:6px;}
|
||
.sec-label .count{background:var(--bg0); border:1px solid var(--line2); border-radius:8px; padding:0 6px;
|
||
font-size:9px; color:var(--mid);}
|
||
|
||
/* summary */
|
||
.summary{padding:0 14px 6px;}
|
||
.summary-tiles{display:grid; grid-template-columns:repeat(4,1fr); gap:6px;}
|
||
.s-tile{background:var(--ins); border:1px solid var(--line); border-radius:7px; padding:9px 4px 7px; text-align:center;}
|
||
.s-num{font-family:'IBM Plex Mono',monospace; font-size:21px; font-weight:600; line-height:1;}
|
||
.s-lbl{font-size:8px; color:var(--dim); letter-spacing:.1em; margin-top:5px;}
|
||
.summary-foot{display:flex; align-items:center; gap:13px; padding:9px 2px 2px; font-size:10px;
|
||
color:var(--mid); font-family:'IBM Plex Mono',monospace;}
|
||
.summary-foot .dot,.r-domain .dot{width:7px;height:7px;border-radius:2px;display:inline-block;margin-right:5px;vertical-align:middle;}
|
||
.summary-foot .muted{margin-left:auto; color:var(--dim);}
|
||
|
||
/* search */
|
||
.side-search{padding:4px 14px 2px;}
|
||
.side-search input{width:100%; background:var(--ins); border:1px solid var(--line); border-radius:6px;
|
||
color:var(--hi); padding:7px 10px; font-size:11.5px; outline:none; font-family:'IBM Plex Mono',monospace;}
|
||
.side-search input::placeholder{color:var(--faint);}
|
||
.side-search input:focus{border-color:var(--teal-br);}
|
||
|
||
/* roster */
|
||
.roster{flex:1; min-height:0; overflow-y:auto; padding:0 8px 8px;}
|
||
.r-domain{font-family:'IBM Plex Mono',monospace; font-size:10px; letter-spacing:.14em; color:var(--mid);
|
||
padding:11px 8px 5px; display:flex; align-items:center;}
|
||
.r-group{font-size:9.5px; color:var(--faint); letter-spacing:.08em; padding:3px 8px 3px 20px; text-transform:uppercase;}
|
||
.sat-row{display:flex; gap:9px; padding:7px 8px 7px 10px; border-radius:7px; cursor:pointer;
|
||
align-items:center; transition:.1s; border:1px solid transparent;}
|
||
.sat-row:hover{background:rgba(255,255,255,0.025);}
|
||
.sat-row.focus{background:var(--teal-bg); border-color:var(--teal-br);}
|
||
.sr-payload{width:3px; align-self:stretch; border-radius:2px; flex:none;}
|
||
.sr-main{flex:1; min-width:0;}
|
||
.sr-top{display:flex; justify-content:space-between; align-items:baseline; gap:8px;}
|
||
.sr-name{font-size:12.5px; font-weight:500; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
|
||
.sr-status{font-size:9px; letter-spacing:.08em; font-family:'IBM Plex Mono',monospace; flex:none; display:flex; align-items:center; gap:3px;}
|
||
.sr-status .ecl{opacity:.85;}
|
||
.sr-bot{display:flex; align-items:center; gap:8px; margin-top:4px;}
|
||
.sr-norad{font-size:9px; color:var(--dim); flex:none;}
|
||
.mem-bar{flex:1; height:4px; background:rgba(255,255,255,0.07); border-radius:2px; overflow:hidden;}
|
||
.mem-bar span{display:block; height:100%; border-radius:2px; transition:width .2s;}
|
||
.sr-mem{font-size:9.5px; font-family:'IBM Plex Mono',monospace; flex:none; width:30px; text-align:right;}
|
||
|
||
/* activity */
|
||
.activity{flex:none; max-height:34%; display:flex; flex-direction:column; border-top:1px solid var(--line); overflow:hidden;}
|
||
.act-list{overflow-y:auto; padding:0 8px 8px;}
|
||
.act-empty{color:var(--faint); font-size:11px; padding:6px 10px; font-family:'IBM Plex Mono',monospace;}
|
||
.act-row{display:flex; gap:8px; padding:6px 8px; border-radius:6px; cursor:pointer; align-items:center;}
|
||
.act-row:hover{background:rgba(255,255,255,0.025);}
|
||
.act-row.focus{background:var(--teal-bg);}
|
||
.act-bar{width:3px; align-self:stretch; border-radius:2px; flex:none;}
|
||
.act-body{flex:1; min-width:0;}
|
||
.act-top{display:flex; gap:7px; align-items:baseline;}
|
||
.act-type{font-size:9.5px; letter-spacing:.1em; font-family:'IBM Plex Mono',monospace;}
|
||
.act-tgt{font-size:11px; color:var(--hi); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
|
||
.act-sub{display:flex; justify-content:space-between; font-size:9.5px; color:var(--dim); margin-top:2px; font-family:'IBM Plex Mono',monospace;}
|
||
.act-rem{color:var(--mid);}
|
||
|
||
/* ---------- map ---------- */
|
||
.map-area{flex:1; position:relative; min-height:0; overflow:hidden; background:var(--ins);}
|
||
.map-wrap{position:absolute; inset:0;}
|
||
.map-wrap canvas{display:block;}
|
||
.map-caption{position:absolute; top:12px; left:12px; z-index:3;}
|
||
.cap-hint{font-family:'IBM Plex Mono',monospace; font-size:9.5px; letter-spacing:.12em; color:var(--faint);
|
||
background:rgba(10,14,13,0.6); border:1px solid var(--line); padding:6px 10px; border-radius:6px; white-space:nowrap;}
|
||
.focus-card{display:flex; align-items:stretch; gap:11px; background:rgba(11,16,15,0.92); backdrop-filter:blur(6px);
|
||
border:1px solid var(--teal-br); border-radius:8px; padding:10px 13px; min-width:330px;}
|
||
.fc-pay{width:3px; border-radius:2px; flex:none;}
|
||
.fc-info{flex:1;}
|
||
.fc-name{font-size:14px; font-weight:600; display:flex; justify-content:space-between; align-items:center;}
|
||
.fc-x{background:none; border:0; color:var(--dim); font-size:12px; padding:0 2px;}
|
||
.fc-x:hover{color:var(--hi);}
|
||
.fc-meta{font-size:9.5px; color:var(--mid); margin-top:4px; display:flex; gap:6px; align-items:center; letter-spacing:.04em;}
|
||
.fc-dot{color:var(--faint);}
|
||
.fc-pos{text-align:right; font-family:'IBM Plex Mono',monospace; font-size:10px; color:var(--mid); display:flex; flex-direction:column; justify-content:center; gap:4px;}
|
||
.fc-mem b{color:var(--hi);}
|
||
|
||
.map-legend{position:absolute; bottom:12px; left:12px; z-index:3; background:rgba(10,14,13,0.55);
|
||
border:1px solid var(--line); border-radius:7px; padding:8px 11px; display:flex; flex-direction:column; gap:5px;}
|
||
.ml-row{display:flex; align-items:center; gap:8px; font-family:'IBM Plex Mono',monospace; font-size:9px;
|
||
letter-spacing:.08em; color:var(--mid); white-space:nowrap;}
|
||
.ml-tri{width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:7px solid #cdd6d3;}
|
||
.ml-sw{width:14px; height:3px; border-radius:2px; background:var(--teal);}
|
||
.ml-sw.amber{background:var(--amber);}
|
||
.ml-sw.blue{background:var(--blue);}
|
||
.ml-sw.blue.dash{background:repeating-linear-gradient(90deg,var(--blue) 0 4px,transparent 4px 7px);}
|
||
.ml-sw.night{background:rgba(90,120,170,0.5); height:9px; width:14px; border-radius:2px;}
|
||
|
||
.map-cursor{position:absolute; bottom:10px; right:14px; z-index:3; font-family:'IBM Plex Mono',monospace;
|
||
font-size:10px; color:var(--mid); background:rgba(10,14,13,0.6); padding:3px 8px; border-radius:5px; border:1px solid var(--line);}
|
||
.map-tip{position:absolute; z-index:4; pointer-events:none; font-family:'IBM Plex Mono',monospace; font-size:10px;
|
||
background:rgba(11,16,15,0.95); border:1px solid var(--line2); padding:3px 7px; border-radius:5px; color:var(--hi); white-space:nowrap;}
|
||
|
||
/* ---------- timeline ---------- */
|
||
.tl-area{height:248px; flex:none; border-top:1px solid var(--line); background:var(--bg1); display:flex; flex-direction:column;}
|
||
.tl-head{height:34px; flex:none; display:flex; align-items:center; gap:18px; padding:0 16px; border-bottom:1px solid var(--line);}
|
||
.tl-title{font-family:'IBM Plex Mono',monospace; font-size:10px; letter-spacing:.16em; color:var(--mid);}
|
||
.tl-legend{display:flex; gap:15px; flex:1;}
|
||
.leg-item{display:flex; align-items:center; gap:6px; font-family:'IBM Plex Mono',monospace; font-size:9px;
|
||
letter-spacing:.08em; color:var(--dim);}
|
||
.leg-sw{width:13px; height:8px; border-radius:2px; display:inline-block;}
|
||
.leg-sw.hatch{background:repeating-linear-gradient(45deg,rgba(217,104,95,0.7) 0 2px,rgba(217,104,95,0.12) 2px 5px); border:1px solid rgba(217,104,95,0.5);}
|
||
.tl-hint{font-family:'IBM Plex Mono',monospace; font-size:9.5px; color:var(--faint); letter-spacing:.06em;}
|
||
.tl-wrap{flex:1; overflow-y:auto; overflow-x:hidden; user-select:none; cursor:crosshair;}
|
||
.tl-tick{fill:var(--dim); font-size:9px; font-family:'IBM Plex Mono',monospace;}
|
||
.tl-group{fill:var(--faint); font-size:9px; letter-spacing:.14em; font-family:'IBM Plex Mono',monospace;}
|
||
.tl-name{fill:var(--mid); font-size:10.5px;}
|
||
.tl-nowlbl{fill:rgba(95,179,163,0.6); font-size:8px; letter-spacing:.12em; font-family:'IBM Plex Mono',monospace;}
|