global-tree-analysis.css 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. :root {
  2. --navy: #172554;
  3. --blue: #1d4ed8;
  4. --blue-soft: #eff6ff;
  5. --orange: #f59e0b;
  6. --purple: #7c3aed;
  7. --ink: #0f172a;
  8. --muted: #64748b;
  9. --line: #dbe3ec;
  10. --paper: #ffffff;
  11. --background: #f8fafc;
  12. --high: #ef4444;
  13. --rise: #f59e0b;
  14. --mid: #22a06b;
  15. --low: #2563eb;
  16. --cold: #bfdbfe;
  17. --missing: #f1f5f9;
  18. }
  19. * { box-sizing: border-box; }
  20. .content {
  21. width: calc(100% - 20px);
  22. max-width: none;
  23. padding-top: 12px;
  24. }
  25. .demand-map-app {
  26. min-height: 100vh;
  27. padding: 12px;
  28. color: var(--ink);
  29. background:
  30. radial-gradient(circle at 8% 0%, rgba(59,130,246,.08), transparent 24%),
  31. radial-gradient(circle at 92% 4%, rgba(245,158,11,.06), transparent 20%),
  32. var(--background);
  33. font-family: Inter, "PingFang SC", "Microsoft YaHei", sans-serif;
  34. }
  35. .page-header {
  36. display: flex;
  37. align-items: flex-end;
  38. justify-content: space-between;
  39. gap: 24px;
  40. max-width: none;
  41. margin: 0 auto 18px;
  42. }
  43. .page-header h1 {
  44. margin: 0 0 6px;
  45. color: #111b3f;
  46. font-family: Georgia, "Noto Serif SC", serif;
  47. font-size: clamp(30px, 3.4vw, 50px);
  48. font-weight: 570;
  49. letter-spacing: -.04em;
  50. }
  51. .page-header p { margin: 0; color: var(--muted); font-size: 14px; }
  52. .source-stats {
  53. display: flex;
  54. flex-wrap: wrap;
  55. justify-content: flex-end;
  56. gap: 7px;
  57. }
  58. .source-stats span {
  59. padding: 7px 10px;
  60. border: 1px solid var(--line);
  61. border-radius: 8px;
  62. background: rgba(255,255,255,.8);
  63. color: #526174;
  64. font-size: 10px;
  65. }
  66. .principle-strip {
  67. display: grid;
  68. grid-template-columns: repeat(4, 1fr);
  69. max-width: none;
  70. margin: 0 auto;
  71. overflow: hidden;
  72. border: 1px solid var(--line);
  73. border-bottom: 0;
  74. border-radius: 16px 16px 0 0;
  75. background: #fff;
  76. }
  77. .principle-strip div { padding: 11px 15px; border-right: 1px solid var(--line); }
  78. .principle-strip div:last-child { border: 0; }
  79. .principle-strip strong { display: block; color: #1e3a8a; font-size: 11px; }
  80. .principle-strip small { display: block; margin-top: 3px; color: var(--muted); font-size: 8px; }
  81. .workspace {
  82. display: grid;
  83. grid-template-columns: minmax(680px, 1fr) minmax(360px, 480px);
  84. max-width: none;
  85. height: min(76vh, 900px);
  86. min-height: 700px;
  87. margin: 0 auto;
  88. overflow: hidden;
  89. border: 1px solid var(--line);
  90. border-radius: 0 0 16px 16px;
  91. background: #fff;
  92. box-shadow: 0 20px 55px rgba(15,23,42,.07);
  93. }
  94. .map-panel {
  95. display: grid;
  96. grid-template-rows: auto auto auto minmax(0, 1fr) auto;
  97. min-width: 0;
  98. min-height: 0;
  99. height: 100%;
  100. overflow: hidden;
  101. border-right: 1px solid var(--line);
  102. }
  103. .map-toolbar {
  104. display: grid;
  105. grid-template-columns: minmax(220px, auto) minmax(330px, 1fr) 220px auto;
  106. align-items: center;
  107. gap: 14px;
  108. padding: 15px 16px 11px;
  109. border-bottom: 1px solid #e8edf2;
  110. }
  111. .map-toolbar h2, .demand-panel-head h2 { margin: 0 0 3px; font-size: 15px; }
  112. .map-toolbar p, .demand-panel-head p { margin: 0; color: var(--muted); font-size: 9px; }
  113. .heat-legend { display: flex; flex-wrap: wrap; gap: 7px; color: #526174; font-size: 8px; }
  114. .heat-legend span { display: inline-flex; align-items: center; gap: 3px; }
  115. .heat-legend i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; }
  116. .heat-high { background: var(--high); }
  117. .heat-rise { background: var(--rise); }
  118. .heat-mid { background: var(--mid); }
  119. .heat-low { background: var(--low); }
  120. .heat-cold { background: var(--cold); border: 1px solid #bfdbfe; }
  121. .heat-missing { background: var(--missing); border: 1px solid #d8e0e8; }
  122. .search-box {
  123. display: flex;
  124. align-items: center;
  125. gap: 6px;
  126. padding: 7px 9px;
  127. border: 1px solid var(--line);
  128. border-radius: 7px;
  129. background: #fff;
  130. color: #94a3b8;
  131. }
  132. .search-box input {
  133. width: 100%;
  134. min-width: 0;
  135. border: 0;
  136. outline: 0;
  137. background: none;
  138. color: var(--ink);
  139. font-size: 10px;
  140. }
  141. .global-button {
  142. height: 31px;
  143. padding: 0 10px;
  144. border: 1px solid #93c5fd;
  145. border-radius: 7px;
  146. background: var(--blue-soft);
  147. color: #1d4ed8;
  148. font-size: 9px;
  149. cursor: pointer;
  150. }
  151. .global-button:disabled { cursor: not-allowed; opacity: .42; }
  152. .view-actions { display: flex; gap: 5px; }
  153. .depth-axis {
  154. display: grid;
  155. min-height: 24px;
  156. padding: 6px 12px 4px;
  157. color: #94a3b8;
  158. background: #fbfdff;
  159. border-bottom: 1px solid #edf1f5;
  160. font-size: 7px;
  161. text-align: center;
  162. }
  163. .depth-axis button {
  164. min-width: 0;
  165. padding: 2px 3px;
  166. border: 0;
  167. border-radius: 4px;
  168. background: transparent;
  169. color: #94a3b8;
  170. font: inherit;
  171. cursor: pointer;
  172. }
  173. .depth-axis button:hover { background: #eff6ff; color: #1d4ed8; }
  174. .depth-axis button.active { background: #dbeafe; color: #1d4ed8; font-weight: 750; }
  175. .breadcrumb-bar {
  176. display: flex;
  177. align-items: center;
  178. gap: 4px;
  179. min-height: 30px;
  180. overflow-x: auto;
  181. padding: 5px 12px;
  182. border-bottom: 1px solid #edf1f5;
  183. background: #fff;
  184. }
  185. .breadcrumb-bar button {
  186. flex: 0 0 auto;
  187. padding: 4px 6px;
  188. border: 0;
  189. border-radius: 5px;
  190. background: #f1f5f9;
  191. color: #526174;
  192. font-size: 8px;
  193. cursor: pointer;
  194. }
  195. .breadcrumb-bar button.current { background: #ede9fe; color: #6d28d9; font-weight: 750; }
  196. .breadcrumb-bar i { color: #94a3b8; font-size: 8px; font-style: normal; }
  197. .icicle-viewport {
  198. position: relative;
  199. min-height: 0;
  200. margin: 12px;
  201. overflow: auto;
  202. border: 1px solid #cbd5e1;
  203. border-radius: 12px;
  204. background: #f8fafc;
  205. scrollbar-gutter: stable;
  206. }
  207. .icicle-wrap {
  208. position: relative;
  209. width: 100%;
  210. min-height: 100%;
  211. overflow: hidden;
  212. background: #f8fafc;
  213. }
  214. #icicle-canvas {
  215. position: absolute;
  216. inset: 0;
  217. display: block;
  218. width: 100%;
  219. height: 100%;
  220. cursor: crosshair;
  221. touch-action: none;
  222. }
  223. .icicle-wrap.dragging #icicle-canvas { cursor: grabbing; }
  224. .map-loading { position: absolute; inset: 0; display: grid; place-items: center; color: var(--muted); font-size: 12px; }
  225. .map-tooltip {
  226. position: absolute;
  227. z-index: 8;
  228. display: none;
  229. width: 235px;
  230. padding: 9px 10px;
  231. border: 1px solid #c4b5fd;
  232. border-radius: 8px;
  233. background: rgba(255,255,255,.97);
  234. color: #334155;
  235. box-shadow: 0 9px 24px rgba(15,23,42,.14);
  236. font-size: 8px;
  237. line-height: 1.55;
  238. pointer-events: none;
  239. }
  240. .map-tooltip strong { display: block; color: #5b21b6; font-size: 10px; }
  241. .map-tooltip span { display: block; color: #64748b; }
  242. .map-guide {
  243. position: absolute;
  244. right: 10px;
  245. top: 10px;
  246. z-index: 5;
  247. width: 190px;
  248. padding: 9px 10px;
  249. border: 1px solid #bfdbfe;
  250. border-radius: 8px;
  251. background: rgba(255,255,255,.94);
  252. color: #526174;
  253. box-shadow: 0 7px 18px rgba(15,23,42,.07);
  254. pointer-events: none;
  255. }
  256. .map-guide strong { display: block; margin-bottom: 3px; color: #1d4ed8; font-size: 9px; }
  257. .map-guide span { display: block; font-size: 7px; line-height: 1.5; }
  258. .zoom-controls {
  259. position: absolute;
  260. right: 10px;
  261. bottom: 10px;
  262. z-index: 6;
  263. display: flex;
  264. gap: 4px;
  265. }
  266. .zoom-controls button {
  267. min-width: 31px;
  268. height: 29px;
  269. padding: 0 7px;
  270. border: 1px solid #bfdbfe;
  271. border-radius: 6px;
  272. background: rgba(255,255,255,.95);
  273. color: #1d4ed8;
  274. font-size: 9px;
  275. cursor: pointer;
  276. }
  277. .map-summary {
  278. display: grid;
  279. grid-template-columns: repeat(3, 1fr);
  280. gap: 7px;
  281. padding: 0 12px 12px;
  282. }
  283. .map-summary div {
  284. padding: 8px 9px;
  285. border-radius: 8px;
  286. background: #eff6ff;
  287. color: #1e3a8a;
  288. font-size: 8px;
  289. line-height: 1.5;
  290. }
  291. .demand-panel {
  292. display: grid;
  293. grid-template-rows: auto auto auto minmax(0, 1fr);
  294. min-width: 0;
  295. min-height: 0;
  296. height: 100%;
  297. overflow: hidden;
  298. background: #fbfdff;
  299. }
  300. .demand-panel-head {
  301. display: flex;
  302. align-items: flex-start;
  303. justify-content: space-between;
  304. gap: 12px;
  305. padding: 15px 15px 11px;
  306. border-bottom: 1px solid #e8edf2;
  307. }
  308. .demand-panel-head > strong {
  309. color: #1d4ed8;
  310. font-family: Georgia, serif;
  311. font-size: 22px;
  312. font-weight: 560;
  313. }
  314. .demand-filters { display: flex; gap: 5px; overflow-x: auto; padding: 10px 14px 7px; }
  315. .demand-filters button {
  316. flex: 0 0 auto;
  317. padding: 5px 8px;
  318. border: 1px solid var(--line);
  319. border-radius: 6px;
  320. background: #fff;
  321. color: var(--muted);
  322. font-size: 8px;
  323. cursor: pointer;
  324. }
  325. .demand-filters button.active { border-color: var(--blue); background: var(--blue); color: #fff; }
  326. .demand-attachments {
  327. display: none;
  328. max-height: 210px;
  329. overflow: auto;
  330. margin: 2px 13px 8px;
  331. padding: 9px;
  332. border: 1px solid #c4b5fd;
  333. border-radius: 9px;
  334. background: #faf8ff;
  335. }
  336. .demand-attachments.visible { display: block; }
  337. .demand-attachments-head {
  338. display: flex;
  339. align-items: center;
  340. justify-content: space-between;
  341. gap: 8px;
  342. margin-bottom: 7px;
  343. }
  344. .demand-attachments-head strong { color: #5b21b6; font-size: 9px; }
  345. .demand-attachments-head span { color: #7c3aed; font-size: 7px; }
  346. .attachment-button {
  347. display: grid;
  348. grid-template-columns: 18px minmax(0, 1fr) auto;
  349. align-items: center;
  350. gap: 6px;
  351. width: 100%;
  352. margin-top: 5px;
  353. padding: 7px;
  354. border: 1px solid #e2e8f0;
  355. border-radius: 7px;
  356. background: #fff;
  357. color: #475569;
  358. text-align: left;
  359. cursor: pointer;
  360. }
  361. .attachment-button:hover, .attachment-button.active { border-color: #8b5cf6; background: #f5f3ff; }
  362. .attachment-button b {
  363. display: grid;
  364. place-items: center;
  365. width: 18px;
  366. height: 18px;
  367. border-radius: 50%;
  368. background: #ede9fe;
  369. color: #6d28d9;
  370. font-size: 7px;
  371. }
  372. .attachment-button span { min-width: 0; font-size: 7px; line-height: 1.5; }
  373. .attachment-button em { color: #7c3aed; font-size: 7px; font-style: normal; white-space: nowrap; }
  374. .demand-list { overflow: auto; padding: 3px 13px 16px; }
  375. .demand-card {
  376. margin-bottom: 9px;
  377. padding: 10px;
  378. border: 1px solid var(--line);
  379. border-left: 3px solid var(--orange);
  380. border-radius: 9px;
  381. background: #fff;
  382. cursor: pointer;
  383. transition: border-color .15s, box-shadow .15s;
  384. }
  385. .demand-card:hover, .demand-card.selected { border-color: #93c5fd; box-shadow: 0 7px 18px rgba(15,23,42,.06); }
  386. .demand-card.selected { border-left-color: var(--purple); }
  387. .demand-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
  388. .demand-card h3 { margin: 0; font-size: 11px; line-height: 1.4; }
  389. .granularity {
  390. flex: 0 0 auto;
  391. padding: 3px 5px;
  392. border-radius: 4px;
  393. background: #fff7ed;
  394. color: #9a3412;
  395. font-size: 7px;
  396. font-weight: 750;
  397. }
  398. .score-row { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 7px; }
  399. .score-row span { padding: 3px 5px; border-radius: 4px; background: #eff6ff; color: #1e40af; font-size: 7px; }
  400. .score-row .path-count { background: #f3e8ff; color: #6b21a8; }
  401. .score-row .missing-data { background: #f1f5f9; color: #64748b; }
  402. .card-reason { margin: 7px 0 0; color: #64748b; font-size: 8px; line-height: 1.55; }
  403. .card-reason strong { color: #334155; }
  404. .empty-state, .explanation-empty { padding: 30px 18px; color: var(--muted); font-size: 11px; line-height: 1.7; }
  405. .explanation-panel {
  406. display: grid;
  407. grid-template-columns: minmax(230px, .72fr) minmax(360px, 1fr) minmax(360px, 1fr);
  408. gap: 12px;
  409. max-width: none;
  410. margin: 14px auto 0;
  411. }
  412. .explanation-panel > article {
  413. min-width: 0;
  414. padding: 15px 16px;
  415. border: 1px solid var(--line);
  416. border-radius: 13px;
  417. background: #fff;
  418. }
  419. .explanation-panel > article.fact-card { border-top: 3px solid var(--orange); }
  420. .explanation-panel > article.model-card { border-top: 3px solid var(--purple); }
  421. .explanation-panel > article.path-context-card {
  422. grid-column: 1 / -1;
  423. border-top: 3px solid #2563eb;
  424. }
  425. .explanation-panel h2 { margin: 0 0 4px; font-size: 14px; }
  426. .explanation-panel h3 { margin: 0 0 8px; color: var(--muted); font-size: 9px; font-weight: 500; }
  427. .explanation-panel p { margin: 0; color: #526174; font-size: 9px; line-height: 1.7; }
  428. .explanation-panel .demand-title { color: #1e3a8a; font-size: 20px; font-family: Georgia, "Noto Serif SC", serif; }
  429. .attachment-list { display: grid; gap: 5px; margin-top: 9px; }
  430. .attachment-list span { padding: 6px 7px; border-radius: 6px; background: #f8fafc; color: #526174; font-size: 8px; line-height: 1.45; }
  431. .raw-reason { margin-top: 8px !important; padding-top: 8px; border-top: 1px dashed var(--line); color: #7c3aed !important; }
  432. .path-node-grid {
  433. display: grid;
  434. grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  435. gap: 8px;
  436. margin-top: 10px;
  437. }
  438. .path-node-grid button {
  439. display: grid;
  440. grid-template-columns: 22px minmax(0, 1fr);
  441. gap: 8px;
  442. min-width: 0;
  443. padding: 9px;
  444. border: 1px solid #dbeafe;
  445. border-radius: 9px;
  446. background: #f8fbff;
  447. color: #334155;
  448. text-align: left;
  449. cursor: pointer;
  450. }
  451. .path-node-grid button:hover,
  452. .path-node-grid button.active {
  453. border-color: #2563eb;
  454. background: #eff6ff;
  455. box-shadow: 0 6px 16px rgba(37,99,235,.08);
  456. }
  457. .path-node-grid b {
  458. display: grid;
  459. place-items: center;
  460. width: 22px;
  461. height: 22px;
  462. border-radius: 50%;
  463. background: #dbeafe;
  464. color: #1d4ed8;
  465. font-size: 8px;
  466. }
  467. .path-node-grid span { min-width: 0; }
  468. .path-node-grid strong,
  469. .path-node-grid small,
  470. .path-node-grid em { display: block; }
  471. .path-node-grid strong { overflow: hidden; font-size: 10px; text-overflow: ellipsis; white-space: nowrap; }
  472. .path-node-grid small { margin-top: 3px; color: #64748b; font-size: 7px; line-height: 1.5; }
  473. .path-node-grid em {
  474. grid-column: 2;
  475. color: #2563eb;
  476. font-size: 7px;
  477. font-style: normal;
  478. }
  479. @media (max-width: 1200px) {
  480. .workspace { grid-template-columns: minmax(600px, 1fr) minmax(340px, 410px); }
  481. .map-toolbar { grid-template-columns: 1fr auto; }
  482. .heat-legend { grid-column: 1 / -1; grid-row: 2; }
  483. .search-box { grid-column: 1; grid-row: 3; }
  484. .global-button { grid-column: 2; grid-row: 3; }
  485. .view-actions { grid-column: 2; grid-row: 3; }
  486. }
  487. @media (max-width: 900px) {
  488. .demand-map-app { padding: 16px; }
  489. .page-header { align-items: flex-start; flex-direction: column; }
  490. .source-stats { justify-content: flex-start; }
  491. .principle-strip { grid-template-columns: 1fr 1fr; }
  492. .workspace { display: block; height: auto; }
  493. .map-panel { height: 730px; border-right: 0; border-bottom: 1px solid var(--line); }
  494. .demand-panel { height: 700px; }
  495. .explanation-panel { grid-template-columns: 1fr; }
  496. .map-guide { display: none; }
  497. .zoom-controls { right: 7px; bottom: 7px; }
  498. }