@pghoya2956/livemap 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/site/map.css CHANGED
@@ -1,167 +1,451 @@
1
+ /* livemap 모니터 화면 토큰과 컴포넌트 스타일. 같은 출처 파일로만 읽힌다(CSP style-src self). */
1
2
  @font-face{font-family:'Pretendard Variable';font-weight:45 920;font-style:normal;font-display:swap;src:url('fonts/PretendardVariable.woff2') format('woff2-variations')}
2
-
3
3
  :root{
4
- --bg:#f4f5f6; --card:#ffffff; --ink:#222222; --muted:#717171; --line:#dddddd; --soft:#eef1f4; --side:#0a2540; --side-ink:#d6e0ea; --side-on:#ffffff;
5
- --navy:#0a2540; --accent:#0a2540; --red:#d92e40; --red-soft:#fde8ea; --live:#1f8a4c; --live-soft:#e3f3e8; --mock:#b86e00; --mock-soft:#fff1dc; --plan:#5b6b7c; --plan-soft:#e9edf1; --new:#f23d4e;
6
- --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; --sans:'Pretendard Variable',-apple-system,BlinkMacSystemFont,'Segoe UI','Apple SD Gothic Neo','Noto Sans KR',sans-serif;
4
+ --bg:#05070A; --panel:#0A0E13; --panel2:#0E131A; --line:#18202A; --line2:#222B36;
5
+ --ink:#DCE3EA; --muted:#828E9C; --dim:#46505C;
6
+ --cyan:#2FD3E6; --green:#22D38A; --amber:#F5A524; --violet:#A48DFF; --plan:#8C98A5; --red:#FF4D5E;
7
+ --cyan-soft:rgba(47,211,230,.10); --green-soft:rgba(34,211,138,.12); --amber-soft:rgba(245,165,36,.14); --violet-soft:rgba(164,141,255,.14); --red-soft:rgba(255,77,94,.14);
8
+ --sans:'Pretendard Variable',-apple-system,BlinkMacSystemFont,'Apple SD Gothic Neo','Noto Sans KR',sans-serif;
9
+ --mono:ui-monospace,SFMono-Regular,Menlo,monospace;
10
+ color-scheme:dark;
7
11
  }
8
- @media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--bg:#0f1418;--card:#171d23;--ink:#e6e9ec;--muted:#9aa4ad;--line:#2a333c;--soft:#1e262e;--side:#0b1219;--side-ink:#8fa3b8;--side-on:#fff;--navy:#8fb3e0;--accent:#8fb3e0;--red:#ff6b7a;--red-soft:#3a1c22;--live:#5ccf86;--live-soft:#16301f;--mock:#f0b25a;--mock-soft:#3a2a12;--plan:#a4b0bb;--plan-soft:#242c34}}
9
- :root[data-theme="dark"]{--bg:#0f1418;--card:#171d23;--ink:#e6e9ec;--muted:#9aa4ad;--line:#2a333c;--soft:#1e262e;--side:#0b1219;--side-ink:#8fa3b8;--side-on:#fff;--navy:#8fb3e0;--accent:#8fb3e0;--red:#ff6b7a;--red-soft:#3a1c22;--live:#5ccf86;--live-soft:#16301f;--mock:#f0b25a;--mock-soft:#3a2a12;--plan:#a4b0bb;--plan-soft:#242c34}
10
12
  *{box-sizing:border-box}
11
- html,body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);font-size:13.5px;line-height:1.45}
12
- a{color:inherit}
13
- code{font-family:var(--mono);font-size:.92em;background:var(--soft);padding:0 4px;border-radius:4px}
14
- .app{display:grid;grid-template-columns:200px 1fr;min-height:100vh}
15
- @media (max-width:900px){.app{grid-template-columns:1fr}}
16
- .side{background:var(--side);color:var(--side-ink);padding:16px 12px;position:sticky;top:0;height:100vh;display:flex;flex-direction:column;gap:6px}
17
- @media (max-width:900px){.side{position:static;height:auto;flex-direction:row;flex-wrap:wrap;align-items:center;padding:10px 16px}}
18
- .brand{color:var(--side-on);font-weight:700;font-size:15px;margin-bottom:6px;display:flex;flex-direction:column}
19
- .brand small{font-weight:400;font-size:11px;color:var(--side-ink);font-family:var(--mono)}
20
- .nav{display:flex;flex-direction:column;gap:2px}
21
- @media (max-width:900px){.nav{flex-direction:row;flex-wrap:wrap;gap:4px;margin-left:auto}}
22
- .nav a{display:flex;justify-content:space-between;align-items:center;gap:8px;text-decoration:none;padding:7px 10px;border-radius:8px;font-size:13px;color:var(--side-ink)}
23
- .nav a:hover{background:rgba(255,255,255,.06);color:var(--side-on)}
24
- .nav a.on{background:rgba(255,255,255,.12);color:var(--side-on);font-weight:500}
25
- .nav a b{font-family:var(--mono);font-weight:400;font-size:11px;opacity:.7}
26
- .side .foot{margin-top:auto;font-size:11px;color:var(--side-ink);opacity:.8;line-height:1.6}
27
- @media (max-width:900px){.side .foot{display:none}}
28
- .main{padding:10px 16px 24px;min-width:0}
29
- .head{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 14px;margin-bottom:8px}
30
- .head h1{font-size:18px;margin:0}
31
- .head .sub{color:var(--muted);font-size:12.5px}
32
- .head .meta{margin-left:auto;font-family:var(--mono);font-size:11.5px;color:var(--muted);display:flex;gap:12px;flex-wrap:wrap}
33
- .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:10px}
34
- .panel{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:8px 12px;min-width:0;display:flex;flex-direction:column}
35
- .panel h2{font-size:11.5px;margin:0 0 6px;color:var(--muted);font-weight:500;letter-spacing:.05em;text-transform:uppercase;display:flex;gap:8px;align-items:baseline;flex-wrap:wrap}
36
- .panel h2 b{color:var(--ink);font-weight:700;letter-spacing:0;text-transform:none;font-size:14px}
37
- .panel h2 .r{margin-left:auto;font-size:11.5px;letter-spacing:0;text-transform:none}
38
- .span12{grid-column:span 12}.span8{grid-column:span 8}.span7{grid-column:span 7}.span6{grid-column:span 6}.span5{grid-column:span 5}.span4{grid-column:span 4}
39
- @media (max-width:1100px){.span8,.span7,.span5,.span4{grid-column:span 12}}
40
- @media (max-width:760px){.span6{grid-column:span 12}}
41
- .chip{display:inline-block;padding:0 7px;border-radius:999px;font-size:11.5px;font-weight:500;white-space:nowrap;line-height:1.5}
42
- .c-live{background:var(--live-soft);color:var(--live)} .c-mock,.c-mixed{background:var(--mock-soft);color:var(--mock)} .c-planned,.c-next,.c-static{background:var(--plan-soft);color:var(--plan)} .c-partial{background:var(--live-soft);color:var(--live);outline:1px dashed var(--live)} .c-red,.c-missing,.c-fail,.c-behind{background:var(--red-soft);color:var(--red)} .c-navy{background:var(--soft);color:var(--navy)}
43
- .g{font-family:var(--mono)} .dim{color:var(--muted)}
44
- .light{display:inline-block;width:9px;height:9px;border-radius:50%;background:var(--plan);vertical-align:middle;margin-right:5px}
45
- .light.ok{background:var(--live)} .light.fail,.light.behind{background:var(--red)} .light.stale,.light.partial{background:var(--mock)}
46
- .new{position:relative} .new::after{content:'';position:absolute;top:-2px;right:-6px;width:6px;height:6px;border-radius:50%;background:var(--new)}
47
- /* 상단 띠 */
48
- .ticker{display:flex;flex-wrap:wrap;align-items:center;gap:6px 14px;background:var(--navy);color:#fff;border-radius:10px;padding:6px 14px;margin-bottom:8px;font-size:12.5px}
49
- .ticker .l{font-weight:700}
50
- .ticker .s{display:flex;gap:12px;flex-wrap:wrap;margin-left:auto;font-size:12px;opacity:.95}
51
- .ticker .s span{white-space:nowrap}
52
- /* 여정 매트릭스 */
53
- .jrow{display:grid;grid-template-columns:minmax(130px,.8fr) 74px 1.6fr 74px;gap:8px;align-items:center;padding:3px 0;border-top:1px solid var(--line);text-decoration:none;color:inherit}
54
- .jrow:first-of-type{border-top:0}
55
- .jrow:hover{background:var(--soft)}
56
- .jrow .t{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
57
- .jrow .a{font-size:11.5px;color:var(--muted);white-space:nowrap}
58
- .dots{display:flex;gap:3px;flex-wrap:wrap}
59
- .dot{display:inline-flex;align-items:center;gap:3px;font-size:10.5px;line-height:1.4;padding:0 5px;border:1px solid var(--line);border-radius:999px;white-space:nowrap;color:var(--muted)}
60
- .dot .g{font-size:10px}
61
- .dot.live{border-color:var(--live);color:var(--live)} .dot.mock{border-color:var(--mock);color:var(--mock)} .dot.planned{color:var(--plan)} .dot.next{border-style:dashed;color:var(--muted)}
62
- .dot.warn{border-color:var(--red)}
63
- .lane-h{font-size:10.5px;color:var(--muted);margin:4px 0 0}
64
- /* 목록 */
13
+ html,body{height:100%}
14
+ body{margin:0;background:var(--bg);color:var(--ink);font:13px/1.45 var(--sans);-webkit-font-smoothing:antialiased;overflow-x:hidden}
15
+ button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
16
+ a{color:inherit;text-decoration:none}
17
+ :focus-visible{outline:2px solid var(--cyan);outline-offset:2px;border-radius:4px}
18
+ .num{font-family:var(--mono);font-variant-numeric:tabular-nums}
19
+
20
+ /* 상단 바 */
21
+ .top{display:flex;align-items:center;gap:28px;height:60px;padding:0 max(16px,24px);border-bottom:1px solid var(--line);background:linear-gradient(180deg,#080B10,#05070A)}
22
+ .brand{display:flex;align-items:center;gap:12px;min-width:0}
23
+ .brand .bt{min-width:0}
24
+ .brand svg{flex:none}
25
+ .brand b{display:block;font:600 14px/1 var(--sans);letter-spacing:.34em;color:#F1F5F8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
26
+ .brand small{display:block;margin-top:5px;font-size:11px;color:var(--muted);letter-spacing:.02em;white-space:nowrap}
27
+ .nav{display:flex;gap:4px}
28
+ .nav a{padding:8px 12px;font-size:12.5px;font-weight:500;letter-spacing:.12em;color:#9AA5B1;border-radius:6px}
29
+ .nav a:hover{color:#fff;background:#0E141B}
30
+ .nav a.on{color:var(--cyan)}
31
+ .top .right{margin-left:auto;display:flex;align-items:center;gap:8px}
32
+ .pill{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 10px;border:1px solid var(--line2);border-radius:999px;font-size:11.5px;color:#B7C1CB;white-space:nowrap}
33
+ .pill.good{border-color:rgba(34,211,138,.45);color:var(--green);background:var(--green-soft)}
34
+ .pill.warn{border-color:rgba(245,165,36,.5);color:var(--amber);background:var(--amber-soft)}
35
+ .dot{width:7px;height:7px;border-radius:50%;background:currentColor;flex:none}
36
+ .dot.pulse{box-shadow:0 0 0 0 currentColor;animation:pulse 2s infinite}
37
+ @keyframes pulse{0%{box-shadow:0 0 0 0 rgba(34,211,138,.6)}70%{box-shadow:0 0 0 7px rgba(34,211,138,0)}100%{box-shadow:0 0 0 0 rgba(34,211,138,0)}}
38
+ .clock{text-align:right;margin-left:10px}
39
+ .clock b{display:block;font:600 19px/1 var(--mono);letter-spacing:.04em;color:#F1F5F8}
40
+ .clock small{display:block;margin-top:4px;font-size:11px;color:var(--muted)}
41
+
42
+ /* 전광판 */
43
+ .ticker{height:34px;border-bottom:1px solid var(--line);overflow:hidden;position:relative;background:#06090D}
44
+ .ticker .track{display:flex;gap:44px;white-space:nowrap;height:100%;align-items:center;padding-left:24px;width:max-content;animation:tick 70s linear infinite}
45
+ .ticker:hover .track{animation-play-state:paused}
46
+ @keyframes tick{to{transform:translateX(-50%)}}
47
+ .tk{display:inline-flex;align-items:baseline;gap:8px;font-size:12px;color:#9AA5B1}
48
+ .tk .num{color:#EEF2F6;font-weight:600;font-size:12.5px}
49
+ .up{color:var(--green)} .dn{color:var(--red)} .fl{color:var(--muted)}
50
+
51
+ /* 격자 */
52
+ .grid{display:grid;grid-template-columns:minmax(330px,380px) minmax(0,1fr) minmax(340px,400px);gap:12px;padding:12px 16px 16px;height:calc(100vh - 94px);min-height:780px}
53
+ .col{display:grid;gap:12px;min-height:0;min-width:0}
54
+ .col.l{grid-template-rows:minmax(0,1.25fr) max-content minmax(0,1fr)}
55
+ .col.c{grid-template-rows:minmax(0,1.7fr) minmax(0,1fr)}
56
+ .col.r{grid-template-rows:auto minmax(0,1fr)}
57
+ .split{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:12px;min-height:0}
58
+ .panel{background:var(--panel);border:1px solid var(--line);border-radius:10px;display:flex;flex-direction:column;min-height:0;min-width:0;overflow:hidden}
59
+ .ph{display:flex;align-items:center;gap:8px;height:42px;padding:0 14px;flex:none;border-bottom:1px solid var(--line)}
60
+ .ph svg{flex:none;color:var(--cyan)}
61
+ .ph h2{margin:0;font-size:13px;font-weight:600;letter-spacing:.02em;white-space:nowrap}
62
+ .ph .sub{font-size:11.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
63
+ .ph .at{margin-left:auto;font:11px var(--mono);color:var(--muted);white-space:nowrap}
64
+ .pb{padding:12px 14px;min-height:0;flex:1;display:flex;flex-direction:column;overflow:hidden;scrollbar-width:thin;scrollbar-color:#222B36 transparent}
65
+ .chips{display:flex;gap:6px;flex-wrap:wrap}
66
+ .chip{display:inline-flex;align-items:center;gap:5px;height:22px;padding:0 9px;border:1px solid var(--line2);border-radius:6px;font-size:11.5px;color:#A9B3BD;white-space:nowrap}
67
+ button.chip:hover{border-color:#34404D;color:#fff}
68
+ .chip.on{border-color:rgba(47,211,230,.55);color:var(--cyan);background:var(--cyan-soft)}
69
+ .chip .n{font-family:var(--mono);font-size:10.5px;color:var(--muted)}
70
+ .tag{display:inline-flex;align-items:center;justify-content:center;min-width:34px;height:18px;padding:0 6px;border-radius:4px;font-size:10.5px;font-weight:600;letter-spacing:.02em;flex:none}
71
+ .t-live,.t-기능,.t-완료{color:var(--green);background:var(--green-soft)}
72
+ .t-mock,.t-진행,.t-수정{color:var(--amber);background:var(--amber-soft)}
73
+ .t-next,.t-다음,.t-대기,.t-이후{color:var(--violet);background:var(--violet-soft)}
74
+ .t-planned,.t-문서,.t-정리,.t-변경{color:#AEB8C2;background:rgba(140,152,165,.14)}
75
+ .t-배포,.t-화면,.t-운영{color:var(--cyan);background:var(--cyan-soft)}
76
+ .t-검사{color:#8FB4FF;background:rgba(79,140,255,.14)}
77
+
78
+ /* 로드맵 브리핑 */
79
+ .brief{display:flex;gap:12px;padding:12px 14px;border-bottom:1px solid var(--line);background:linear-gradient(90deg,rgba(245,165,36,.07),transparent 70%)}
80
+ .brief .av{width:42px;height:42px;border-radius:50%;flex:none;display:grid;place-items:center;background:#0F151C;border:1px solid var(--line2)}
81
+ .brief .bb{min-width:0}
82
+ .brief .who{display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600;min-width:0}
83
+ .brief .who .wt-t{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
84
+ .onair{display:inline-flex;align-items:center;gap:5px;font:600 10px var(--mono);letter-spacing:.08em;color:var(--amber)}
85
+ .brief p{margin:6px 0 8px;font-size:12.5px;color:#C9D2DB;line-height:1.55}
86
+ .brief .mini{font-size:11px;color:var(--muted)}
65
87
  .rows{display:flex;flex-direction:column}
66
- .row{display:grid;gap:8px;align-items:center;padding:4px 0;border-top:1px solid var(--line);font-size:12.5px;text-decoration:none;color:inherit}
67
- .row:first-child{border-top:0}
68
- .row:hover{background:var(--soft)}
69
- .row .t{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
70
- .row .g.dim{font-size:11px}
71
- .pbar{display:flex;height:6px;border-radius:3px;overflow:hidden;background:var(--plan-soft);min-width:60px}
72
- .pbar i{display:block;height:100%}
73
- .pbar .live{background:var(--live)}.pbar .mock{background:var(--mock)}.pbar .planned{background:var(--plan)}
74
- .tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}
75
- .tile{background:var(--soft);border-radius:7px;padding:6px 8px}
76
- .tile .v{font-size:17px;font-weight:700;font-family:var(--mono);font-variant-numeric:tabular-nums;line-height:1.1}
77
- .tile .v small{font-size:11px;color:var(--muted);font-weight:400}
78
- .tile .k{font-size:11px;color:var(--muted);margin-top:2px}
79
- .bars{display:flex;flex-direction:column;gap:3px}
80
- .bar{display:grid;grid-template-columns:56px 1fr 28px;gap:6px;align-items:center;font-size:11.5px}
81
- .bar i{display:block;height:7px;border-radius:4px;background:var(--navy);opacity:.75}
82
- .bar b{font-family:var(--mono);font-weight:500;text-align:right;color:var(--muted)}
83
- .lights{display:grid;grid-template-columns:1fr 1fr;gap:3px 10px;font-size:11.5px;margin-bottom:6px}
84
- /* 표·상세 */
88
+ .row{display:flex;gap:10px;align-items:flex-start;padding:9px 0;border-bottom:1px solid #121820;text-align:left;width:100%}
89
+ a.row,button.row{cursor:pointer}
90
+ .row:last-child{border-bottom:0}
91
+ a.row:hover .tt,button.row:hover .tt{color:#fff}
92
+ .row .tt{font-size:13px;color:#D5DDE5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
93
+ .row .meta{margin-top:2px;font-size:11px;color:var(--muted)}
94
+ .row .body{min-width:0;flex:1}
95
+ .row.sel .tt{color:var(--cyan)}
96
+
97
+ /* 진척 계기 */
98
+ .gauge{display:grid;grid-template-columns:132px 1fr;gap:14px;align-items:center;padding:12px 14px 14px}
99
+ .gauge .big{font:700 26px/1 var(--mono);fill:var(--green);text-anchor:middle}
100
+ .gauge .cap{font-size:10px;fill:var(--muted);text-anchor:middle}
101
+ .stats3{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
102
+ .stat small{display:block;font-size:10.5px;color:var(--muted);white-space:nowrap}
103
+ .stat b{display:block;font:600 19px/1.2 var(--mono)}
104
+ .stat-ms{margin-bottom:8px}
105
+ .stat-ms b{color:var(--amber)}
106
+ .stat i{font-style:normal;font-size:10.5px;color:var(--muted);margin-left:3px}
107
+ .seg{display:flex;height:6px;border-radius:3px;overflow:hidden;background:#141A22;margin-top:12px;gap:2px}
108
+ .seg span{display:block;height:100%}
109
+ .gnote{margin-top:8px;font:10.5px var(--mono);color:var(--muted)}
110
+
111
+ /* 기능 지도 */
112
+ .mapwrap{position:relative;flex:1;min-height:0;background:radial-gradient(ellipse at 40% 50%,#0C1218 0%,#070A0E 75%)}
113
+ .mapwrap svg.map{position:absolute;inset:0;width:100%;height:100%}
114
+ .zone{fill:rgba(47,211,230,.025);stroke:rgba(47,211,230,.16);stroke-width:1}
115
+ .zone.warm{fill:rgba(245,165,36,.05);stroke:rgba(245,165,36,.35)}
116
+ .zone.cool{fill:rgba(164,141,255,.05);stroke:rgba(164,141,255,.35);stroke-dasharray:4 4}
117
+ .route{fill:none;stroke:#2A3440;stroke-width:1.4}
118
+ .route.live{stroke:rgba(34,211,138,.45)}
119
+ .route.mock{stroke:rgba(245,165,36,.45)}
120
+ .route.next{stroke:rgba(164,141,255,.4);stroke-dasharray:3 4}
121
+ .link{fill:none;stroke:var(--cyan);stroke-linecap:round;stroke-dasharray:2 6;animation:flow 3.5s linear infinite}
122
+ @keyframes flow{to{stroke-dashoffset:-32}}
123
+ .hub{fill:#0B1016;stroke:var(--cyan);stroke-width:1.5}
124
+ .n-live{fill:var(--green)}
125
+ .n-mock{fill:var(--amber)}
126
+ .n-planned{fill:none;stroke:var(--plan);stroke-width:1.5}
127
+ .n-next{fill:#0B1016;stroke:var(--violet);stroke-width:1.5;stroke-dasharray:2.5 2}
128
+ .ring{fill:none;stroke:var(--green);stroke-width:1;opacity:.7;transform-box:fill-box;transform-origin:center;animation:ring 2.6s ease-out infinite}
129
+ @keyframes ring{from{transform:scale(1);opacity:.7}to{transform:scale(2.6);opacity:0}}
130
+ .jg{cursor:pointer;transition:opacity .2s}
131
+ .dim .jg:not(.sel){opacity:.22}
132
+ .dim .link:not(.sel){opacity:.08}
133
+ .layers{position:absolute;top:10px;right:12px;display:flex;gap:4px;padding:3px;background:rgba(9,13,18,.92);border:1px solid var(--line2);border-radius:8px}
134
+ .lyr{display:flex;align-items:center;gap:6px;height:24px;padding:0 8px;border-radius:5px;font-size:11.5px;color:#B8C2CC;white-space:nowrap}.lyr .num{font-size:10.5px;color:var(--muted)}
135
+ .lyr:hover{background:#111820}
136
+ .lyr .sw{width:10px;height:10px;border-radius:3px;flex:none;background:var(--cyan)}
137
+ .lyr.off{color:#56606B}.lyr.off .sw{opacity:.25}
138
+ .badges{position:absolute;top:12px;left:14px;display:flex;gap:6px}
139
+ .badge{height:22px;padding:0 8px;display:inline-flex;align-items:center;border-radius:4px;font-size:11px;font-weight:600}
140
+ .badge.amber{color:#1A1203;background:var(--amber)}
141
+ .badge.violet{color:#120C24;background:var(--violet)}
142
+ .mapbar{position:absolute;left:12px;right:12px;bottom:12px;display:flex;gap:6px;align-items:center;overflow:hidden}
143
+ .mapbar .chip{flex:none}
144
+ .mapbar .dot{color:var(--cyan)}
145
+ .mapfold{color:var(--cyan)}
146
+ .mapnote{margin-left:auto;min-width:0;padding:5px 10px;border:1px solid rgba(245,165,36,.5);border-radius:6px;background:rgba(26,18,3,.85);color:var(--amber);font-size:11.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
147
+ .mapnote:hover{border-color:var(--amber)}
148
+ .mapwrap.empty{display:grid;place-items:center}
149
+ .mapempty{margin:0;padding:24px;color:var(--muted)}
150
+ .jlabels{position:absolute;inset:0;pointer-events:none}
151
+ .zl{position:absolute;height:14px;font:600 11px/14px var(--sans);letter-spacing:.14em;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
152
+ .jl{position:absolute;display:flex;align-items:baseline;gap:8px;height:16px;line-height:16px;white-space:nowrap;text-shadow:0 0 3px #070A0E,0 0 2px #070A0E,0 0 1px #070A0E;transition:opacity .2s}
153
+ .jl .t{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;font-size:12.5px;font-weight:600;color:#E3E9EF}
154
+ .jl .s{flex:0 1 auto;max-width:45%;min-width:0;margin-left:auto;display:flex;gap:4px;font-size:10.5px;color:var(--muted)}
155
+ .jl .s .a{min-width:0;overflow:hidden;text-overflow:ellipsis}
156
+ .jl .s .c{flex:none}
157
+ .jlabels.dim .jl:not(.sel){opacity:.22}
158
+ .warnring{fill:none;stroke:var(--red);stroke-width:1}
159
+
160
+ /* 기능별 진척(시장형) */
161
+ .mk{display:grid;grid-template-columns:minmax(0,1fr) 84px 76px;gap:10px;align-items:center;padding:8px 0;border-bottom:1px solid #121820;cursor:pointer;text-align:left;width:100%}
162
+ .mk:last-child{border-bottom:0}
163
+ .mk .tt{font-size:13px;color:#D5DDE5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
164
+ .mk .meta{font-size:10.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
165
+ .mk-b{min-width:0}
166
+ .mk .v{text-align:right}
167
+ .mk .v b{display:block;font:600 14px/1.2 var(--mono)}
168
+ .mk .v span{font:10.5px var(--mono)}
169
+ .mk.sel .tt{color:var(--cyan)}
170
+ .spark{display:block;width:84px;height:26px;overflow:visible}
171
+
172
+ /* 특보 */
173
+ .alert{border:1px solid rgba(245,165,36,.35);border-radius:8px;padding:10px;background:rgba(245,165,36,.05)}
174
+ .alert .h{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--amber);font-weight:600}
175
+ .alert p{margin:6px 0 0;font-size:12px;color:#C9D2DB}
176
+ .al{display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid #121820}
177
+ .al:last-child{border-bottom:0}
178
+ .mag{width:36px;height:30px;border-radius:5px;display:grid;place-items:center;font:600 13px var(--mono);flex:none;background:#10161D;color:#C7D0D9}
179
+ .mag.hot{background:var(--red-soft);color:var(--red)}
180
+ .mag.warm{background:var(--amber-soft);color:var(--amber)}
181
+ .al .tt{font-size:12.5px;color:#D5DDE5}
182
+ .al .meta{font:10.5px var(--mono);color:var(--muted)}
183
+ .sect{display:flex;align-items:center;gap:8px;margin:12px 0 4px;font-size:11px;color:var(--muted)}
184
+ .sect:first-child{margin-top:0}
185
+
186
+ /* 화면 라이브 */
187
+ .capbox{display:flex;flex-direction:column;min-height:0}
188
+ .live .ov a{color:inherit}
189
+ .live .ov a:hover b{text-decoration:underline}
190
+ .live{position:relative;background:#000;aspect-ratio:16/8;flex:none;overflow:hidden}
191
+ .live img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top;opacity:.92;transition:opacity .35s}
192
+ .live .ov{position:absolute;inset:auto 0 0 0;padding:28px 14px 12px;background:linear-gradient(180deg,transparent,rgba(0,0,0,.85))}
193
+ .live .ov b{display:block;font-size:15px;color:#fff}
194
+ .live .ov small{font-size:11.5px;color:#B8C2CC}
195
+ .live .rec{position:absolute;top:10px;left:10px;display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 8px;border-radius:4px;background:rgba(0,0,0,.7);font:600 10.5px var(--mono);letter-spacing:.08em;color:#fff}
196
+ .live .rec .dot{color:var(--red)}
197
+ .live .cnt{position:absolute;top:10px;right:10px;font:11px var(--mono);color:#C9D2DB;background:rgba(0,0,0,.6);padding:2px 7px;border-radius:4px}
198
+ .thumbs{display:flex;gap:6px;padding:10px 14px;border-top:1px solid var(--line)}
199
+ .thumbs button{flex:1;height:34px;border-radius:4px;overflow:hidden;border:1px solid var(--line2);opacity:.55;position:relative}
200
+ .thumbs button img{width:100%;height:100%;object-fit:cover;object-position:top;display:block}
201
+ .thumbs button.on{opacity:1;border-color:var(--cyan)}
202
+
203
+ /* 기능 현황표(날씨형) */
204
+ .wt{display:grid;grid-template-columns:minmax(0,1fr) 68px 64px 44px 12px;gap:8px;align-items:center;height:30px;padding:0 8px;border-radius:6px;cursor:pointer;width:100%;text-align:left}
205
+ .wt:hover{background:#0F151C}
206
+ .wt.sel{background:rgba(47,211,230,.07);box-shadow:inset 0 0 0 1px rgba(47,211,230,.35)}
207
+ .wt .tt{font-size:12.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
208
+ .wt .st{font-size:11px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
209
+ .wt .v{font:600 12px var(--mono);text-align:right}
210
+ .wt .sd{width:9px;height:9px;border-radius:50%}
211
+ .detail{border-top:1px solid var(--line);padding:10px 14px 12px;flex:none}
212
+ .detail .hd{display:flex;align-items:baseline;gap:8px;min-width:0;white-space:nowrap}
213
+ .detail .hd b{font-size:13px;min-width:0;flex:0 1 auto;overflow:hidden;text-overflow:ellipsis}
214
+ .detail .hd span{font-size:11px;color:var(--muted);min-width:0;flex:0 1 auto;max-width:30%;overflow:hidden;text-overflow:ellipsis}
215
+ .detail .hd em{margin-left:auto;flex:none;font-style:normal;font:11px var(--mono);color:var(--muted)}
216
+ .area{display:block;width:100%;height:60px;margin:6px 0 4px}
217
+ .axis{display:flex;justify-content:space-between;font:10px var(--mono);color:var(--muted)}
218
+ .kv{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:0 16px;margin-top:10px}
219
+ .kv div{display:flex;justify-content:space-between;gap:8px;white-space:nowrap;min-width:0;padding:5px 0;border-bottom:1px solid #121820;font-size:11.5px;color:var(--muted)}
220
+ .kv b{font:600 12px var(--mono);color:#DCE3EA;min-width:0;overflow:hidden;text-overflow:ellipsis}
221
+ .goal{margin-top:10px;padding:8px 10px;border-radius:6px;background:#0E141B;font-size:12px;color:#C9D2DB}
222
+
223
+ /* routes: common(하위 화면 틀·카드·표·상태 칩). 경로별 규칙은 아래 각 절에 둔다 */
224
+ .screen{min-height:100%}
225
+ .page{padding:16px 24px 32px;max-width:1440px;margin:0 auto}
226
+ .page-hd{display:flex;align-items:baseline;gap:10px;margin:2px 0 14px}
227
+ .page-hd h1{margin:0;font-size:15px;font-weight:600;letter-spacing:.02em}
228
+ .page-hd .sub,.card-hd .sub{font-size:11.5px;color:var(--muted)}
229
+ .card{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:12px 14px}
230
+ .card+.card{margin-top:12px}
231
+ .card-hd{display:flex;align-items:baseline;gap:8px;margin-bottom:8px}
232
+ .card-hd h2{margin:0;font-size:13px;font-weight:600}
85
233
  .tbl{overflow-x:auto}
86
- table{border-collapse:collapse;width:100%;font-size:12.5px}
87
- th,td{text-align:left;padding:6px 8px;border-bottom:1px solid var(--line);vertical-align:top;white-space:nowrap}
88
- th{color:var(--muted);font-weight:500;font-size:11.5px}
89
- td.mono,th.mono{font-family:var(--mono);font-size:12px}
90
- td.wrap{white-space:normal;min-width:200px}
91
- tr.link{cursor:pointer} tr.link:hover td{background:var(--soft)} tr.hl td{background:var(--live-soft)}
92
- .kv{display:grid;grid-template-columns:auto 1fr;gap:5px 12px;font-size:12.5px;margin:0}
93
- .kv dt{color:var(--muted);white-space:nowrap}.kv dd{margin:0;min-width:0}
234
+ .tbl table{width:100%;border-collapse:collapse;font-size:12px}
235
+ .tbl th{padding:6px 8px;text-align:left;font-size:11px;font-weight:500;color:var(--muted);border-bottom:1px solid var(--line2);white-space:nowrap}
236
+ .tbl td{padding:7px 8px;border-bottom:1px solid #121820;vertical-align:top}
237
+ .tbl tr.hl td,.tbl tr.sel td{background:var(--panel2)}
238
+ .schip{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;white-space:nowrap}
239
+ .empty{margin:0;padding:24px 0;color:var(--muted)}
240
+
241
+ /* routes: journeys */
94
242
  .jcards{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px}
95
- .jcard{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:14px;display:flex;flex-direction:column;gap:8px;text-decoration:none;color:inherit}
96
- .jcard:hover{border-color:var(--accent);box-shadow:0 0 0 2px var(--soft)}
97
- .jcard .t{font-weight:700;font-size:15px;display:flex;justify-content:space-between;gap:8px;align-items:baseline}
243
+ .jcard{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:14px;display:flex;flex-direction:column;gap:8px;text-decoration:none;color:inherit}
244
+ .jcard:hover{border-color:var(--cyan);box-shadow:0 0 0 2px var(--cyan-soft)}
245
+ .jcard-hd{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-weight:600}
246
+ .jcard-meta{font-size:12px;color:var(--muted)}
247
+ .jsteps{display:flex;gap:3px;flex-wrap:wrap}
248
+ .jstep{display:inline-flex;align-items:center;gap:3px;height:18px;padding:0 6px;border:1px solid var(--line2);border-radius:999px;font-size:10.5px;color:var(--muted);white-space:nowrap;max-width:150px;overflow:hidden;text-overflow:ellipsis}
249
+ .jcard-specs{font-size:11.5px;color:var(--muted)}
250
+ .jback{margin:0 0 10px;font-size:12.5px;color:var(--muted)}
251
+ .jhead{display:flex;align-items:center;gap:8px;margin:-4px 0 12px}
252
+ .jhead-actor{font-size:12.5px;color:var(--muted)}
98
253
  .board{display:flex;gap:10px;overflow-x:auto;padding:4px 2px 10px}
99
- .scene{flex:0 0 240px;background:var(--card);border:1px solid var(--line);border-radius:12px;overflow:hidden;display:flex;flex-direction:column;position:relative;text-decoration:none;color:inherit}
100
- .scene:hover,.scene.on{border-color:var(--accent);box-shadow:0 0 0 2px var(--soft)}
101
- .scene .num{position:absolute;left:8px;top:8px;background:var(--navy);color:#fff;font-family:var(--mono);font-size:11px;padding:1px 7px;border-radius:999px;z-index:1}
102
- .scene .shot{aspect-ratio:16/10;background:var(--soft);display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:12px;overflow:hidden;border-bottom:1px solid var(--line)}
103
- .scene .shot img{width:100%;height:100%;object-fit:cover;object-position:top;display:block}
104
- .scene .body{padding:10px 12px;display:flex;flex-direction:column;gap:4px}
105
- .scene .l{font-weight:700;display:flex;justify-content:space-between;gap:6px;align-items:baseline}
106
- .scene .intent{font-size:12px;color:var(--muted);min-height:2.6em}
107
- .scene .warn{font-size:11px;color:var(--red)}
254
+ .scene{flex:0 0 240px;background:var(--panel);border:1px solid var(--line);border-radius:12px;overflow:hidden;display:flex;flex-direction:column;position:relative;text-decoration:none;color:inherit}
255
+ .scene:hover,.scene.on{border-color:var(--cyan);box-shadow:0 0 0 2px var(--cyan-soft)}
108
256
  .scene.next{border-style:dashed}
109
- .detail{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:14px 16px;margin-top:8px}
110
- .detail h3{margin:0 0 8px;font-size:16px;display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
111
- .detail .cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px}
112
- .detail h4{margin:10px 0 6px;font-size:11.5px;color:var(--muted);font-weight:500;letter-spacing:.04em;text-transform:uppercase}
113
- .detail h4:first-child{margin-top:0}
114
- .detail .big{width:100%;border:1px solid var(--line);border-radius:8px;display:block}
257
+ .scene-num{position:absolute;left:8px;top:8px;background:var(--panel2);border:1px solid var(--line2);color:var(--ink);font-size:11px;padding:1px 7px;border-radius:999px;z-index:1;font-family:var(--mono)}
258
+ .scene-shot{aspect-ratio:16/10;background:var(--panel2);display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:12px;overflow:hidden;border-bottom:1px solid var(--line)}
259
+ .scene-shot img{width:100%;height:100%;object-fit:cover;object-position:top;display:block}
260
+ .scene-body{padding:10px 12px;display:flex;flex-direction:column;gap:4px}
261
+ .scene-l{font-weight:700;display:flex;justify-content:space-between;align-items:baseline;gap:6px;flex-wrap:wrap}
262
+ .scene-grade{font-size:10.5px;color:var(--muted);white-space:nowrap}
263
+ .scene-actor{font-size:11px;color:var(--muted)}
264
+ .scene-intent{font-size:12px;color:var(--muted);min-height:2.6em}
265
+ .scene-warn{font-size:11px;color:var(--red)}
266
+ [data-screen="journeys"] .detail{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:14px 16px;margin-top:8px}
267
+ .detail-h{margin:0 0 8px;font-size:15px;display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
268
+ .detail-sub{font-size:12.5px;color:var(--muted);font-weight:400}
269
+ .detail-grade{font-size:11.5px;color:var(--muted)}
270
+ .detail-note{margin:0 0 8px;font-size:12.5px;color:var(--muted)}
271
+ .detail-warn{margin:0 0 8px;font-size:12.5px;color:var(--red)}
272
+ .cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px}
273
+ .cols h4{margin:10px 0 6px;font-size:11.5px;color:var(--muted);font-weight:500;letter-spacing:.04em;text-transform:uppercase}
274
+ .cols h4:first-child{margin-top:0}
275
+ .detail-big{width:100%;border:1px solid var(--line);border-radius:8px;display:block}
115
276
  .node{display:flex;flex-direction:column;gap:2px;padding:6px 8px;border:1px solid var(--line);border-radius:8px;font-size:12.5px;margin-bottom:6px;background:var(--bg)}
116
- .node .n{font-family:var(--mono);font-size:12px;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
117
- .node .s{font-size:11.5px;color:var(--muted)}
277
+ .node-n{font-size:12px;display:flex;gap:8px;align-items:center;flex-wrap:wrap;font-family:var(--mono)}
278
+ .node-s{font-size:11.5px;color:var(--muted);font-family:var(--sans)}
279
+ .refbadge{font-family:var(--mono);font-size:11px;color:var(--cyan);background:var(--cyan-soft);padding:0 6px;border-radius:4px}
280
+ .jmuted{color:var(--muted)}
281
+ .jwarn-inline{color:var(--red);font-size:11.5px;margin-left:6px}
118
282
  .src{font-size:11px;color:var(--muted);font-family:var(--mono)}
119
- .filters{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}
120
- .filters button,.tabs button{border:1px solid var(--line);background:var(--card);color:var(--ink);border-radius:999px;padding:2px 10px;font-size:12px;cursor:pointer;font-family:inherit}
121
- .filters button.on,.tabs button.on{background:var(--navy);color:#fff;border-color:var(--navy)}
122
- .filters button b{font-family:var(--mono);font-weight:500;margin-left:4px;opacity:.8}
123
- .tabs{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px}
124
283
  .log{list-style:none;margin:0;padding:0}
125
- .log li{display:grid;grid-template-columns:52px 74px 1fr;gap:8px;padding:5px 0;border-bottom:1px solid var(--line);font-size:12.5px;align-items:baseline}
126
- .log .d{font-family:var(--mono);color:var(--muted);font-size:11.5px}
127
- .log .s{min-width:0}.log .s .t{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
128
- .log .tags{display:flex;gap:4px;flex-wrap:wrap;margin-top:2px}
129
- .log .tags span{font-size:11px;padding:0 6px;border-radius:999px;background:var(--soft);color:var(--muted)}
130
- .log .tags span.j{background:var(--live-soft);color:var(--live)}
131
- .thumbs{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px}
132
- .thumb{border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--card);text-decoration:none;color:inherit}
133
- .thumb img{width:100%;aspect-ratio:16/10;object-fit:cover;object-position:top;display:block;border-bottom:1px solid var(--line)}
134
- .thumb .c{padding:6px 8px;font-size:12px;display:flex;justify-content:space-between;gap:6px}
135
- .prose{max-width:72ch;font-size:13.5px}.prose h3{font-size:15px;margin:18px 0 6px}.prose p{margin:6px 0}.prose ul{padding-left:18px;margin:6px 0}
136
- .empty{color:var(--muted);font-size:12.5px}
137
- ul.plain{margin:0;padding-left:16px;font-size:12.5px}ul.plain li{margin:3px 0}
138
- button:focus-visible,a:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
139
-
140
- /* CSP(style-src 'self')로 인라인 style 속성을 못 쓰므로 자잘한 배치도 클래스로 둔다 */
141
- .fs11{font-size:11px}.fs115{font-size:11.5px}.fs12{font-size:12px}.fs125{font-size:12.5px}.normal{font-weight:400}
142
- .mt6{margin-top:6px}.mt8{margin-top:8px}.mt12{margin-top:12px}.mb10{margin-bottom:10px}.mb12{margin:0 0 12px}
143
- .wrapn{white-space:normal}.nolink{text-decoration:none}
144
- .note{margin:0 0 8px;font-size:12.5px;color:var(--muted)}.warnnote{color:var(--red)}
145
- .chip.off{opacity:.45}
146
- .row.r-task{grid-template-columns:1fr 64px 46px 60px}.row.r-next{grid-template-columns:auto 1fr}.row.r-recent{grid-template-columns:38px 1fr}
147
- .panel h2.mt8{margin-top:8px}
148
-
149
- /* 로드맵 */
150
- .row.r-road{grid-template-columns:auto 1fr auto auto}
151
- .chip.c-planned.off{opacity:.6}
152
- .fixmark{display:inline-block;padding:0 5px;border-radius:4px;font-size:10.5px;background:var(--mock-soft);color:var(--mock)}
153
- .rm{display:flex;flex-direction:column;gap:10px;max-width:980px}
154
- .rm-item{display:grid;grid-template-columns:36px 1fr;gap:12px;background:var(--card);border:1px solid var(--line);border-radius:12px;padding:14px 16px}
155
- .rm-item.on{outline:2px solid var(--navy)}
156
- .rm-item.is-done{opacity:.72}
157
- .rm-num{font-size:18px;font-weight:700;color:var(--muted);text-align:center;padding-top:2px}
158
- .rm-h{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
159
- .rm-h h3{margin:0;font-size:16px;text-wrap:balance}
160
- .rm-goal{margin:6px 0 8px;max-width:70ch}
161
- .rm-kv{display:grid;grid-template-columns:76px 1fr;gap:6px 12px;margin:0;font-size:12.5px}
162
- .rm-kv dt{color:var(--muted)}
163
- .rm-kv dd{margin:0;min-width:0}
164
- .rm-wait{color:var(--mock);font-weight:500}
165
- .rm-scenes{display:flex;flex-wrap:wrap;gap:4px}
166
- .rm-scenes .dot{text-decoration:none}
167
- @media (max-width:640px){.rm-item{grid-template-columns:1fr}.rm-num{text-align:left}.rm-kv{grid-template-columns:1fr}}
284
+ .log li{display:grid;grid-template-columns:56px 84px 1fr;gap:8px;padding:5px 0;border-bottom:1px solid var(--line);font-size:12.5px;align-items:baseline}
285
+ .log-d{font-family:var(--mono);color:var(--muted);font-size:11.5px}
286
+ .log-t{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
287
+
288
+ /* routes: roadmap */
289
+ [data-screen="roadmap"] .rm-filter{margin:0 0 12px}
290
+ [data-screen="roadmap"] .rm{display:flex;flex-direction:column;gap:10px;max-width:980px}
291
+ [data-screen="roadmap"] .rm-item{display:grid;grid-template-columns:36px 1fr;gap:12px;background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:14px 16px;scroll-margin-top:12px}
292
+ [data-screen="roadmap"] .rm-item.on{border-color:var(--cyan);box-shadow:0 0 0 2px var(--cyan-soft)}
293
+ [data-screen="roadmap"] .rm-num{font:600 19px var(--mono);color:var(--muted);text-align:center;padding-top:1px;font-variant-numeric:tabular-nums}
294
+ [data-screen="roadmap"] .rm-body{min-width:0}
295
+ [data-screen="roadmap"] .rm-h{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
296
+ [data-screen="roadmap"] .rm-h h3{margin:0;font-size:15px;font-weight:600;text-wrap:balance}
297
+ [data-screen="roadmap"] .rm-dim{font-size:12px;color:var(--muted)}
298
+ [data-screen="roadmap"] .rm-date{font:11.5px var(--mono);color:var(--green)}
299
+ [data-screen="roadmap"] .rm-block{display:inline-flex;align-items:center;height:20px;padding:0 7px;border:1px solid rgba(245,165,36,.5);border-radius:6px;font-size:11.5px;color:var(--amber);background:var(--amber-soft);white-space:nowrap}
300
+ [data-screen="roadmap"] .rm-goal{margin:6px 0 8px;max-width:70ch;font-size:13px;color:var(--ink)}
301
+ [data-screen="roadmap"] .rm-goal code,[data-screen="roadmap"] .rm-kv code{font:12px var(--mono);color:var(--ink)}
302
+ [data-screen="roadmap"] .rm-warn{margin:0 0 8px;font-size:12.5px;color:var(--red)}
303
+ [data-screen="roadmap"] .rm-kv{display:grid;grid-template-columns:76px 1fr;gap:6px 12px;margin:0;font-size:12.5px}
304
+ [data-screen="roadmap"] .rm-kv dt{color:var(--muted)}
305
+ [data-screen="roadmap"] .rm-kv dd{margin:0;min-width:0}
306
+ [data-screen="roadmap"] .rm-wait{color:var(--amber);font-weight:500}
307
+ [data-screen="roadmap"] .rm-who{display:inline-flex;align-items:center;height:18px;padding:0 6px;margin-right:6px;border-radius:4px;font-size:10.5px;font-weight:600;color:var(--violet);background:var(--violet-soft)}
308
+ [data-screen="roadmap"] .rm-days{margin-left:6px;font:11.5px var(--mono);color:var(--muted);font-weight:400}
309
+ [data-screen="roadmap"] .rm-deps{display:flex;flex-wrap:wrap;gap:4px 12px;align-items:center}
310
+ [data-screen="roadmap"] .rm-steps{display:flex;flex-wrap:wrap;gap:4px}
311
+ [data-screen="roadmap"] .rm-step{display:inline-flex;align-items:center;gap:4px;height:20px;padding:0 7px;border:1px solid var(--line2);border-radius:999px;font-size:11px;color:var(--ink);text-decoration:none;max-width:260px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
312
+ [data-screen="roadmap"] .rm-step:hover{border-color:var(--cyan)}
313
+ [data-screen="roadmap"] .rm-fixed{padding:0 5px;border-radius:4px;font-size:10.5px;color:var(--amber);background:var(--amber-soft)}
314
+ [data-screen="roadmap"] .rm-miss{font-size:11.5px;color:var(--red)}
315
+ [data-screen="roadmap"] .rm-ms{margin:0 0 12px;max-width:980px;scroll-margin-top:12px}
316
+ [data-screen="roadmap"] .rm-ms>summary{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:9px 12px;border:1px solid var(--line);border-radius:10px;background:var(--panel);cursor:pointer;list-style:none;font-size:13px}
317
+ [data-screen="roadmap"] .rm-ms>summary::-webkit-details-marker{display:none}
318
+ [data-screen="roadmap"] .rm-ms>summary::before{content:'▸';color:var(--muted);font-size:11px}
319
+ [data-screen="roadmap"] .rm-ms[open]>summary::before{content:'▾'}
320
+ [data-screen="roadmap"] .rm-ms>summary:hover{background:var(--panel2)}
321
+ [data-screen="roadmap"] .rm-ms[open]>summary{margin-bottom:10px}
322
+ [data-screen="roadmap"] .rm-ms-t{font-weight:600}
323
+ [data-screen="roadmap"] .rm-ms.is-done .rm-ms-t{font-weight:400;color:var(--muted)}
324
+ [data-screen="roadmap"] .rm-ms-hd{margin:-2px 0 10px 12px}
325
+ [data-screen="roadmap"] .rm-ms-hd .rm-goal{margin:0 0 4px}
326
+ [data-screen="roadmap"] .rm-ms-hd .rm-wait{margin:0;font-size:12.5px}
327
+ [data-screen="roadmap"] .rm-ms .rm{margin-left:12px}
328
+ [data-screen="roadmap"] .rm-src{margin-top:14px}
329
+ @media (max-width:640px){[data-screen="roadmap"] .rm-item{grid-template-columns:1fr}[data-screen="roadmap"] .rm-num{text-align:left}[data-screen="roadmap"] .rm-kv{grid-template-columns:1fr}[data-screen="roadmap"] .rm-ms .rm{margin-left:0}}
330
+
331
+ /* routes: tasks */
332
+ [data-screen="tasks"] .tk-filter{margin:0 0 12px}
333
+ [data-screen="tasks"] .detail{margin-bottom:12px}
334
+ [data-screen="tasks"] .tk-name{margin-left:2px;font:12px var(--mono);color:var(--muted)}
335
+ [data-screen="tasks"] .tk-pipe{display:flex;flex-wrap:wrap;gap:4px;margin:2px 0 0}
336
+ [data-screen="tasks"] .tk-stage{display:inline-flex;align-items:center;height:18px;padding:0 7px;border:1px solid var(--line2);border-radius:999px;font-size:10.5px;color:var(--dim);white-space:nowrap}
337
+ [data-screen="tasks"] .tk-stage.on{color:var(--green);background:var(--green-soft);border-color:transparent}
338
+ [data-screen="tasks"] .tk-date{font:11.5px var(--mono);color:var(--muted);white-space:nowrap}
339
+ [data-screen="tasks"] .tk-num{font:12px var(--mono);white-space:nowrap}
340
+ [data-screen="tasks"] .t-폐기{color:var(--red);background:var(--red-soft)}
341
+ [data-screen="tasks"] .t-기록{color:var(--muted);background:transparent}
342
+
343
+ /* routes: more */
344
+ [data-screen="more"] .tabs{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 14px}
345
+ [data-screen="more"] .mm-filters{margin:0 0 12px}
346
+ [data-screen="more"] .mm-changes-sub{margin:0 0 10px;font-size:12px}
347
+ [data-screen="more"] .mm-log li{align-items:flex-start}
348
+ [data-screen="more"] .mm-log .log-t{white-space:normal;overflow:visible;text-overflow:clip}
349
+ [data-screen="more"] .mm-subject{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
350
+ [data-screen="more"] .mm-tags{display:flex;flex-wrap:wrap;gap:4px;margin-top:3px}
351
+ [data-screen="more"] .mm-area{display:inline-flex;align-items:center;height:16px;padding:0 5px;border:1px solid var(--line2);border-radius:4px;font-size:10.5px;color:var(--muted)}
352
+ [data-screen="more"] .mm-jlink{font-size:10.5px;color:var(--cyan)}
353
+ [data-screen="more"] .mm-mono{font-family:var(--mono)}
354
+ [data-screen="more"] .mm-wrap{white-space:normal}
355
+ [data-screen="more"] .mm-rawstatus{font-size:11px}
356
+ [data-screen="more"] .mm-fixed{font-size:10.5px;color:var(--amber)}
357
+ [data-screen="more"] .mm-fs12{font-size:12px}
358
+ [data-screen="more"] .mm-gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:8px}
359
+ [data-screen="more"] .mm-thumb{display:block;color:inherit;border:1px solid var(--line);border-radius:8px;overflow:hidden}
360
+ [data-screen="more"] .mm-thumb:hover{border-color:var(--cyan)}
361
+ [data-screen="more"] .mm-thumb img{width:100%;aspect-ratio:16/10;object-fit:cover;object-position:top;display:block}
362
+ [data-screen="more"] .mm-thumb-c{display:flex;flex-direction:column;gap:2px;padding:6px 8px;font-size:11px}
363
+ [data-screen="more"] .mm-grid12{display:grid;grid-template-columns:repeat(12,1fr);gap:12px}
364
+ [data-screen="more"] .mm-span6{grid-column:span 6}
365
+ [data-screen="more"] .mm-span12{grid-column:span 12}
366
+ [data-screen="more"] .t-fail{color:var(--red);background:var(--red-soft)}
367
+ [data-screen="more"] .mm-signals{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:8px 16px}
368
+ [data-screen="more"] .mm-sig{display:flex;align-items:center;gap:8px;font-size:12.5px}
369
+ [data-screen="more"] .mm-dot{width:8px;height:8px;border-radius:50%;flex:none;background:var(--green)}
370
+ [data-screen="more"] .mm-dot.warn{background:var(--amber)}
371
+ [data-screen="more"] .mm-sig-l{min-width:78px;color:var(--ink)}
372
+ [data-screen="more"] .mm-tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
373
+ [data-screen="more"] .mm-tile{padding:10px;border:1px solid var(--line);border-radius:8px;text-align:center}
374
+ [data-screen="more"] .mm-tile-v{font-size:19px;font-weight:600}
375
+ [data-screen="more"] .mm-tile-k{margin-top:4px;font-size:10.5px;color:var(--muted)}
376
+ [data-screen="more"] .mm-issues{list-style:none;margin:0;padding:0}
377
+ [data-screen="more"] .mm-issue{padding:6px 0;border-bottom:1px solid #121820;font-size:12.5px}
378
+ [data-screen="more"] .mm-issue.warn{color:var(--amber)}
379
+ [data-screen="more"] .mm-issue.error{color:var(--red)}
380
+ [data-screen="more"] .mm-prose h3{margin:14px 0 6px;font-size:13px}
381
+ [data-screen="more"] .mm-prose h3:first-child{margin-top:0}
382
+ [data-screen="more"] .mm-prose p{margin:0 0 8px;font-size:12.5px;color:#C9D2DB;line-height:1.55}
383
+ [data-screen="more"] .mm-prose ul{margin:0 0 8px;padding-left:18px;font-size:12.5px;color:#C9D2DB;line-height:1.6}
384
+ [data-screen="more"] .mm-prose li{margin-bottom:4px}
385
+ @media (max-width:760px){
386
+ [data-screen="more"] .mm-grid12{grid-template-columns:1fr}
387
+ [data-screen="more"] .mm-span6,[data-screen="more"] .mm-span12{grid-column:1/-1}
388
+ [data-screen="more"] .mm-tiles{grid-template-columns:repeat(2,1fr)}
389
+ }
390
+
391
+ @media (max-width:1279px){
392
+ .grid{grid-template-columns:1fr 1fr;height:auto;min-height:0}
393
+ .col.c{grid-column:1/-1;order:-1;grid-template-rows:520px auto}
394
+ .col.l,.col.r{grid-template-rows:none}
395
+ .col.l .panel,.col.r .panel{max-height:520px}
396
+ .top{flex-wrap:wrap;height:auto;padding-top:10px;row-gap:4px}
397
+ .brand{flex:1 1 auto}
398
+ .nav{order:3;width:100%;margin:0 -12px}
399
+ }
400
+ @media (max-width:760px){
401
+ .grid{grid-template-columns:1fr;padding:12px 16px}
402
+ .col.c{grid-template-rows:440px auto}
403
+ .split{grid-template-columns:1fr}
404
+ .top{gap:12px}
405
+ .top .right .pill:not(.deploy){display:none}
406
+ .nav{overflow-x:auto;scrollbar-width:none}
407
+ .nav a{flex:none}
408
+ .brand small{display:none}
409
+ .layers{display:none}
410
+ }
411
+ @media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
412
+ .pb-tight{padding-top:8px}
413
+ .pb-top{padding-top:10px}
414
+ .rows-gap{margin-top:6px}
415
+ .pill-sm{height:20px;font-size:10.5px}
416
+ .mag-cyan{color:var(--cyan)}
417
+ .pb-table{padding:6px}
418
+ .boot{margin:0;padding:24px;color:var(--muted)}
419
+ .boot-error{color:var(--red)}
420
+ .tasks-link{display:inline-block;margin-top:8px;font-size:11.5px;color:var(--cyan)}
421
+
422
+ /* 스펙 1.1.0 보정: 목록 맞춤, 접은 행, 더보기 링크, 상태 표식, 신선도, 전광판 정지 */
423
+ .rows{min-height:0;overflow:hidden}
424
+ .fit{flex:1;min-height:0;overflow:hidden}
425
+ .row{height:48px;padding:0;align-items:center;overflow:hidden}
426
+ .row .tt,.row .meta{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
427
+ .row .right{margin-left:auto;padding-left:8px;font-size:11px;color:var(--muted);white-space:nowrap;flex:none}
428
+ .row.slim{height:30px}
429
+ .row.fold{height:30px;color:var(--muted);font-size:11.5px}
430
+ .row.fold .tt{font-size:12px;color:var(--muted)}
431
+ .ph .more{margin-left:8px;font-size:11.5px;color:var(--cyan);white-space:nowrap}
432
+ .ph .at+.more{margin-left:10px}
433
+ .newdot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--cyan);margin-right:6px;vertical-align:middle}
434
+ .mk{height:52px;padding:0}
435
+ .al{height:48px;padding:0}
436
+ .wt.fold{color:var(--muted)}
437
+ .wt.fold .tt{color:var(--muted)}
438
+ .detail .open{flex:none;margin-left:10px;font-size:11.5px;color:var(--cyan);white-space:nowrap}
439
+ .brief .who .tag{margin-left:2px}
440
+ .pb.pb-tight{padding-top:10px}
441
+ .ticker .pause{position:absolute;right:8px;top:5px;height:24px;padding:0 8px;border:1px solid var(--line2);border-radius:6px;background:#06090D;color:var(--muted);font-size:11px}
442
+ .ticker.paused .track{animation-play-state:paused}
443
+ .stepmark{display:inline-block;flex:none;vertical-align:middle}
444
+ .gauge .cap-html{margin-top:-30px;text-align:center;font-size:10px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:132px}
445
+ .gline{margin-top:6px;font-size:11px;color:var(--muted)}
446
+ .gauge .gw{position:relative;height:122px}
447
+ .gauge .gw svg{display:block}
448
+ .gauge .cap-html{position:absolute;left:0;top:108px;margin:0;width:132px;height:14px;line-height:14px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
449
+ .wt.row{height:30px}
450
+ .ticker .pause{box-shadow:-18px 0 14px #06090D}
451
+