style.css 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222
  1. /* 编辑器区域滚动条 */
  2. #yaml-editor::-webkit-scrollbar,
  3. #frequency-editor::-webkit-scrollbar,
  4. #timeline-editor::-webkit-scrollbar,
  5. #yaml-backdrop::-webkit-scrollbar,
  6. #frequency-backdrop::-webkit-scrollbar,
  7. #timeline-backdrop::-webkit-scrollbar {
  8. width: 10px;
  9. height: 10px;
  10. }
  11. #yaml-editor::-webkit-scrollbar-track,
  12. #frequency-editor::-webkit-scrollbar-track,
  13. #timeline-editor::-webkit-scrollbar-track,
  14. #yaml-backdrop::-webkit-scrollbar-track,
  15. #frequency-backdrop::-webkit-scrollbar-track,
  16. #timeline-backdrop::-webkit-scrollbar-track {
  17. background: #1e1e1e;
  18. }
  19. #yaml-editor::-webkit-scrollbar-thumb,
  20. #frequency-editor::-webkit-scrollbar-thumb,
  21. #timeline-editor::-webkit-scrollbar-thumb,
  22. #yaml-backdrop::-webkit-scrollbar-thumb,
  23. #frequency-backdrop::-webkit-scrollbar-thumb,
  24. #timeline-backdrop::-webkit-scrollbar-thumb {
  25. background: #424242;
  26. border-radius: 0;
  27. }
  28. #yaml-editor::-webkit-scrollbar-thumb:hover,
  29. #frequency-editor::-webkit-scrollbar-thumb:hover,
  30. #timeline-editor::-webkit-scrollbar-thumb:hover,
  31. #yaml-backdrop::-webkit-scrollbar-thumb:hover,
  32. #frequency-backdrop::-webkit-scrollbar-thumb:hover,
  33. #timeline-backdrop::-webkit-scrollbar-thumb:hover {
  34. background: #4f4f4f;
  35. }
  36. /* 高亮编辑器容器 */
  37. .highlight-editor-wrap {
  38. position: relative;
  39. flex: 1;
  40. display: flex;
  41. overflow: hidden;
  42. }
  43. /* 高亮背景层 */
  44. .highlight-backdrop {
  45. position: absolute;
  46. top: 0;
  47. left: 0;
  48. right: 0;
  49. bottom: 0;
  50. padding: 1rem;
  51. margin: 0;
  52. border: none;
  53. font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  54. font-size: 0.75rem;
  55. line-height: 1.625;
  56. white-space: pre-wrap;
  57. word-wrap: break-word;
  58. overflow: auto;
  59. background: #1e1e1e;
  60. color: #d4d4d4;
  61. pointer-events: none;
  62. z-index: 1;
  63. }
  64. /* 透明输入层 */
  65. .highlight-textarea {
  66. position: absolute;
  67. top: 0;
  68. left: 0;
  69. right: 0;
  70. bottom: 0;
  71. padding: 1rem;
  72. margin: 0;
  73. border: none;
  74. font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  75. font-size: 0.75rem;
  76. line-height: 1.625;
  77. overflow: auto;
  78. background: transparent;
  79. color: transparent;
  80. caret-color: #d4d4d4;
  81. resize: none;
  82. outline: none;
  83. z-index: 2;
  84. }
  85. /* 注释样式 - 灰色 */
  86. .syntax-comment {
  87. color: #6a9955;
  88. }
  89. /* 右侧面板滚动条 */
  90. #modules-container::-webkit-scrollbar {
  91. width: 8px;
  92. }
  93. #modules-container::-webkit-scrollbar-track {
  94. background: transparent;
  95. }
  96. #modules-container::-webkit-scrollbar-thumb {
  97. background: #cbd5e1;
  98. border-radius: 4px;
  99. }
  100. /* 模块卡片样式 */
  101. .module-card {
  102. background: white;
  103. border-radius: 0.5rem; /* rounded-lg */
  104. border: 1px solid #e5e7eb; /* border-gray-200 */
  105. overflow: hidden;
  106. transition: all 0.2s;
  107. }
  108. /* 激活态(可编辑) */
  109. .module-card.active {
  110. box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
  111. }
  112. .module-card.active:hover {
  113. box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
  114. border-color: #bfdbfe; /* blue-200 */
  115. }
  116. .module-card.active .module-header {
  117. background-color: #fff;
  118. border-bottom: 1px solid #f3f4f6;
  119. color: #111827;
  120. }
  121. /* 禁用态(灰色/只读) */
  122. .module-card.disabled {
  123. background-color: #f9fafb; /* gray-50 */
  124. opacity: 0.8;
  125. }
  126. .module-card.disabled .module-header {
  127. background-color: #f3f4f6; /* gray-100 */
  128. color: #6b7280; /* gray-500 */
  129. cursor: not-allowed;
  130. }
  131. .module-card.disabled .module-body {
  132. display: none;
  133. }
  134. .module-card.disabled .locked-badge {
  135. display: inline-flex;
  136. }
  137. /* 输入控件统一 */
  138. input[type="text"],
  139. input[type="password"],
  140. input[type="number"],
  141. select {
  142. font-size: 0.875rem; /* text-sm */
  143. line-height: 1.25rem;
  144. padding: 0.5rem 0.75rem;
  145. border-radius: 0.375rem;
  146. border-width: 1px;
  147. border-color: #d1d5db; /* gray-300 */
  148. width: 100%;
  149. outline: 2px solid transparent;
  150. transition: all 0.15s;
  151. }
  152. input:focus, select:focus {
  153. border-color: #3b82f6; /* blue-500 */
  154. box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
  155. }
  156. /* 开关样式 (Checkbox Toggle) */
  157. .toggle-checkbox:checked {
  158. right: 0;
  159. border-color: #3b82f6;
  160. }
  161. .toggle-checkbox:checked + .toggle-label {
  162. background-color: #3b82f6;
  163. }
  164. /* 列表样式 (Platforms & RSS & Sortable) */
  165. .sortable-list-item {
  166. background: #f8fafc;
  167. border: 1px solid #e2e8f0;
  168. margin-bottom: 0.5rem;
  169. border-radius: 0.375rem;
  170. transition: all 0.2s;
  171. }
  172. .sortable-list-item:hover {
  173. border-color: #cbd5e1;
  174. background: #f1f5f9;
  175. }
  176. .sortable-handle {
  177. cursor: grab;
  178. color: #94a3b8;
  179. }
  180. .sortable-handle:hover {
  181. color: #64748b;
  182. }
  183. .sortable-ghost {
  184. background: #e2e8f0;
  185. opacity: 0.5;
  186. }
  187. /* 禁用状态的勾选框 */
  188. input[type="checkbox"]:disabled {
  189. cursor: not-allowed;
  190. opacity: 0.5;
  191. }
  192. /* Tab 切换样式 */
  193. .tab-button {
  194. transition: all 0.2s;
  195. }
  196. .tab-button.active {
  197. color: #d4d4d4;
  198. border-color: #3b82f6;
  199. }
  200. .tab-content.hidden {
  201. display: none;
  202. }
  203. /* 标签输入样式 */
  204. .tag-input-container {
  205. display: flex;
  206. flex-wrap: wrap;
  207. gap: 0.5rem;
  208. padding: 0.5rem;
  209. border: 1px solid #d1d5db;
  210. border-radius: 0.375rem;
  211. background: white;
  212. min-height: 42px;
  213. }
  214. .tag-item {
  215. display: inline-flex;
  216. align-items: center;
  217. gap: 0.25rem;
  218. padding: 0.25rem 0.5rem;
  219. background: #3b82f6;
  220. color: white;
  221. border-radius: 0.25rem;
  222. font-size: 0.875rem;
  223. }
  224. .tag-item button {
  225. background: none;
  226. border: none;
  227. color: white;
  228. cursor: pointer;
  229. padding: 0;
  230. font-size: 1rem;
  231. line-height: 1;
  232. }
  233. .tag-input {
  234. flex: 1;
  235. border: none;
  236. outline: none;
  237. min-width: 120px;
  238. font-size: 0.875rem;
  239. }
  240. /* 词组卡片样式 */
  241. .word-group-card {
  242. background: white;
  243. border: 1px solid #e5e7eb;
  244. border-radius: 0.5rem;
  245. padding: 1rem;
  246. transition: all 0.2s;
  247. }
  248. .word-group-card:hover {
  249. border-color: #3b82f6;
  250. box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  251. }
  252. /* 插入区域样式 */
  253. .insert-zone {
  254. position: relative;
  255. height: 8px;
  256. margin: 0.5rem 0;
  257. display: flex;
  258. align-items: center;
  259. justify-content: center;
  260. transition: all 0.2s;
  261. }
  262. .insert-zone:hover {
  263. height: 32px;
  264. }
  265. .insert-button {
  266. opacity: 0;
  267. visibility: hidden;
  268. width: 32px;
  269. height: 32px;
  270. border-radius: 50%;
  271. background: linear-gradient(135deg, #3b82f6, #2563eb);
  272. color: white;
  273. border: 2px solid white;
  274. box-shadow: 0 2px 8px rgba(59, 130, 246, 0.4);
  275. display: flex;
  276. align-items: center;
  277. justify-content: center;
  278. cursor: pointer;
  279. transition: all 0.2s;
  280. font-size: 14px;
  281. }
  282. .insert-zone:hover .insert-button {
  283. opacity: 1;
  284. visibility: visible;
  285. }
  286. .insert-button:hover {
  287. transform: scale(1.1);
  288. box-shadow: 0 4px 12px rgba(59, 130, 246, 0.6);
  289. background: linear-gradient(135deg, #2563eb, #1d4ed8);
  290. }
  291. .insert-button:active {
  292. transform: scale(0.95);
  293. }
  294. /* 编辑区域恢复默认鼠标样式 */
  295. .word-group-card .editable-area {
  296. cursor: default;
  297. }
  298. .word-group-card .editable-area input {
  299. cursor: text;
  300. }
  301. .word-group-card .editable-area button {
  302. cursor: pointer;
  303. }
  304. .word-group-card .editable-area .tag-item {
  305. cursor: pointer;
  306. }
  307. /* 拖拽手柄样式 */
  308. .drag-handle {
  309. cursor: grab;
  310. transition: all 0.2s;
  311. }
  312. .drag-handle:active {
  313. cursor: grabbing;
  314. }
  315. /* SortableJS 拖拽样式 */
  316. .sortable-ghost {
  317. opacity: 0.4;
  318. background: #dbeafe;
  319. border: 2px dashed #3b82f6;
  320. }
  321. .sortable-chosen {
  322. background: #f0f9ff;
  323. border-color: #3b82f6;
  324. }
  325. .sortable-drag {
  326. opacity: 0.8;
  327. box-shadow: 0 10px 20px rgba(0,0,0,0.2);
  328. transform: rotate(2deg);
  329. }
  330. /* 独立区域复选框组 */
  331. .checkbox-grid {
  332. display: grid;
  333. grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  334. gap: 0.75rem;
  335. }
  336. .checkbox-card {
  337. display: flex;
  338. align-items: center;
  339. padding: 0.5rem;
  340. border: 1px solid #e5e7eb;
  341. border-radius: 0.375rem;
  342. background-color: #fff;
  343. cursor: pointer;
  344. transition: all 0.15s;
  345. }
  346. .checkbox-card:hover {
  347. border-color: #93c5fd;
  348. background-color: #eff6ff;
  349. }
  350. .checkbox-card input:checked + span {
  351. color: #2563eb;
  352. font-weight: 500;
  353. }
  354. /* ==========================================
  355. 拖拽上传遮罩层
  356. ========================================== */
  357. .drop-overlay {
  358. position: absolute;
  359. top: 0;
  360. left: 0;
  361. right: 0;
  362. bottom: 0;
  363. background: rgba(59, 130, 246, 0.9);
  364. display: flex;
  365. align-items: center;
  366. justify-content: center;
  367. z-index: 100;
  368. pointer-events: all;
  369. }
  370. .drop-overlay.hidden {
  371. display: none;
  372. }
  373. .drop-overlay-content {
  374. text-align: center;
  375. color: white;
  376. }
  377. .drop-overlay-content i {
  378. font-size: 3rem;
  379. margin-bottom: 0.5rem;
  380. animation: bounce 1s infinite;
  381. }
  382. @keyframes bounce {
  383. 0%, 100% { transform: translateY(0); }
  384. 50% { transform: translateY(-10px); }
  385. }
  386. /* ==========================================
  387. Toast 提示
  388. ========================================== */
  389. .toast-notification {
  390. position: fixed;
  391. bottom: 24px;
  392. right: 24px;
  393. display: flex;
  394. align-items: center;
  395. gap: 0.75rem;
  396. padding: 0.875rem 1.25rem;
  397. border-radius: 0.5rem;
  398. font-size: 0.875rem;
  399. font-weight: 500;
  400. box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
  401. z-index: 9999;
  402. opacity: 0;
  403. transform: translateY(20px);
  404. transition: all 0.3s ease;
  405. }
  406. .toast-notification.show {
  407. opacity: 1;
  408. transform: translateY(0);
  409. }
  410. .toast-notification i {
  411. font-size: 1.125rem;
  412. }
  413. /* Toast 类型样式 */
  414. .toast-success {
  415. background: #10b981;
  416. color: white;
  417. }
  418. .toast-error {
  419. background: #ef4444;
  420. color: white;
  421. }
  422. .toast-info {
  423. background: #3b82f6;
  424. color: white;
  425. }
  426. .toast-warning {
  427. background: #f59e0b;
  428. color: white;
  429. }
  430. /* ==========================================
  431. 弹窗样式
  432. ========================================== */
  433. .modal-overlay {
  434. position: fixed;
  435. top: 0;
  436. left: 0;
  437. right: 0;
  438. bottom: 0;
  439. background: rgba(0, 0, 0, 0.5);
  440. display: flex;
  441. align-items: center;
  442. justify-content: center;
  443. z-index: 1000;
  444. }
  445. .modal-overlay.hidden {
  446. display: none;
  447. }
  448. .modal-content {
  449. background: white;
  450. border-radius: 0.75rem;
  451. padding: 1.5rem;
  452. max-width: 450px;
  453. width: 90%;
  454. max-height: 90vh;
  455. overflow-y: auto;
  456. box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
  457. }
  458. /* 弹簧跳动动画 */
  459. @keyframes spring-in {
  460. 0% { transform: scale(0.5); opacity: 0; }
  461. 60% { transform: scale(1.1); }
  462. 80% { transform: scale(0.95); }
  463. 100% { transform: scale(1); opacity: 1; }
  464. }
  465. .support-modal-content {
  466. animation: spring-in 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  467. background: #ffffff;
  468. border: none;
  469. border-radius: 1.5rem;
  470. }
  471. /* ==========================================
  472. Timeline 编辑器样式
  473. ========================================== */
  474. /* 预设模式选择卡片 */
  475. .tl-preset-card {
  476. border: 2px solid #e5e7eb;
  477. border-radius: 0.75rem;
  478. padding: 0.875rem;
  479. cursor: pointer;
  480. transition: all 0.2s;
  481. background: white;
  482. position: relative;
  483. }
  484. .tl-preset-card:hover {
  485. border-color: #93c5fd;
  486. background: #f0f7ff;
  487. }
  488. .tl-preset-card.selected {
  489. border-color: #3b82f6;
  490. background: #eff6ff;
  491. box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
  492. }
  493. .tl-preset-card .tl-card-icon {
  494. width: 2rem;
  495. height: 2rem;
  496. border-radius: 0.5rem;
  497. display: flex;
  498. align-items: center;
  499. justify-content: center;
  500. font-size: 0.875rem;
  501. flex-shrink: 0;
  502. }
  503. .tl-preset-card .tl-recommend-badge {
  504. position: absolute;
  505. top: -1px;
  506. right: -1px;
  507. background: linear-gradient(135deg, #f59e0b, #ef4444);
  508. color: white;
  509. font-size: 0.625rem;
  510. font-weight: 700;
  511. padding: 0.125rem 0.5rem;
  512. border-radius: 0 0.625rem 0 0.5rem;
  513. }
  514. /* 周视图时间线 */
  515. .tl-week-view {
  516. background: white;
  517. border: 1px solid #e5e7eb;
  518. border-radius: 0.75rem;
  519. padding: 1rem;
  520. overflow-x: auto;
  521. }
  522. .tl-week-row {
  523. display: flex;
  524. align-items: center;
  525. height: 2.25rem;
  526. margin-bottom: 0.25rem;
  527. }
  528. .tl-week-row:last-child {
  529. margin-bottom: 0;
  530. }
  531. .tl-day-label {
  532. width: 2.5rem;
  533. flex-shrink: 0;
  534. font-size: 0.6875rem;
  535. font-weight: 600;
  536. color: #6b7280;
  537. text-align: right;
  538. padding-right: 0.5rem;
  539. }
  540. .tl-day-label.today {
  541. color: #3b82f6;
  542. font-weight: 700;
  543. }
  544. .tl-timeline-bar {
  545. flex: 1;
  546. height: 1.75rem;
  547. background: #f1f5f9;
  548. border-radius: 0.25rem;
  549. position: relative;
  550. min-width: 480px;
  551. overflow: hidden;
  552. }
  553. .tl-period-block {
  554. position: absolute;
  555. top: 2px;
  556. bottom: 2px;
  557. border-radius: 0.1875rem;
  558. cursor: pointer;
  559. transition: filter 0.15s, transform 0.15s;
  560. display: flex;
  561. align-items: center;
  562. justify-content: center;
  563. overflow: hidden;
  564. z-index: 1;
  565. }
  566. .tl-period-block:hover {
  567. filter: brightness(1.1);
  568. transform: scaleY(1.15);
  569. z-index: 2;
  570. }
  571. .tl-period-block .tl-block-label {
  572. font-size: 0.5625rem;
  573. font-weight: 600;
  574. color: rgba(255,255,255,0.9);
  575. white-space: nowrap;
  576. text-overflow: ellipsis;
  577. overflow: hidden;
  578. padding: 0 0.25rem;
  579. text-shadow: 0 1px 2px rgba(0,0,0,0.2);
  580. }
  581. /* 时间段颜色 */
  582. .tl-block-push { background: #3b82f6; }
  583. .tl-block-analyze { background: #8b5cf6; }
  584. .tl-block-push-analyze { background: #6366f1; }
  585. .tl-block-collect { background: #94a3b8; }
  586. .tl-block-silent { background: #cbd5e1; }
  587. /* 时间刻度 */
  588. .tl-hour-markers {
  589. display: flex;
  590. padding-left: 2.5rem;
  591. margin-bottom: 0.25rem;
  592. }
  593. .tl-hour-marker {
  594. font-size: 0.5625rem;
  595. color: #9ca3af;
  596. text-align: center;
  597. }
  598. /* 图例 */
  599. .tl-legend {
  600. display: flex;
  601. gap: 0.75rem;
  602. flex-wrap: wrap;
  603. padding-top: 0.5rem;
  604. border-top: 1px solid #f3f4f6;
  605. margin-top: 0.5rem;
  606. }
  607. .tl-legend-item {
  608. display: flex;
  609. align-items: center;
  610. gap: 0.25rem;
  611. font-size: 0.625rem;
  612. color: #6b7280;
  613. }
  614. .tl-legend-color {
  615. width: 0.75rem;
  616. height: 0.5rem;
  617. border-radius: 0.125rem;
  618. }
  619. /* 时间段 Tooltip */
  620. .tl-tooltip {
  621. position: fixed;
  622. background: #1f2937;
  623. color: white;
  624. padding: 0.5rem 0.75rem;
  625. border-radius: 0.375rem;
  626. font-size: 0.75rem;
  627. z-index: 1000;
  628. pointer-events: none;
  629. box-shadow: 0 4px 12px rgba(0,0,0,0.2);
  630. max-width: 220px;
  631. }
  632. .tl-tooltip::after {
  633. content: '';
  634. position: absolute;
  635. bottom: -4px;
  636. left: 50%;
  637. transform: translateX(-50%);
  638. border-left: 5px solid transparent;
  639. border-right: 5px solid transparent;
  640. border-top: 5px solid #1f2937;
  641. }
  642. /* Custom 模式编辑面板 */
  643. .tl-section-title {
  644. font-size: 0.75rem;
  645. font-weight: 700;
  646. color: #374151;
  647. display: flex;
  648. align-items: center;
  649. gap: 0.5rem;
  650. margin-bottom: 0.75rem;
  651. }
  652. .tl-section-title i {
  653. color: #3b82f6;
  654. font-size: 0.6875rem;
  655. }
  656. .tl-period-card {
  657. background: white;
  658. border: 1px solid #e5e7eb;
  659. border-radius: 0.5rem;
  660. padding: 0.75rem;
  661. transition: all 0.2s;
  662. }
  663. .tl-period-card:hover {
  664. border-color: #93c5fd;
  665. box-shadow: 0 2px 4px rgba(0,0,0,0.05);
  666. }
  667. .tl-toggle-row {
  668. display: flex;
  669. align-items: center;
  670. gap: 0.75rem;
  671. flex-wrap: wrap;
  672. }
  673. .tl-toggle-item {
  674. display: flex;
  675. align-items: center;
  676. gap: 0.375rem;
  677. font-size: 0.6875rem;
  678. color: #4b5563;
  679. }
  680. .tl-toggle-item.on { color: #2563eb; font-weight: 600; }
  681. .tl-toggle-item.off { color: #9ca3af; }
  682. /* Timeline 小型 toggle 开关 */
  683. .tl-toggle-item .toggle-checkbox {
  684. width: 1rem;
  685. height: 1rem;
  686. border-width: 3px;
  687. }
  688. .tl-toggle-item .toggle-label {
  689. height: 1rem;
  690. }
  691. .tl-toggle-item .toggle-checkbox:checked {
  692. right: 0;
  693. border-color: #3b82f6;
  694. }
  695. .tl-toggle-item .toggle-checkbox:checked + .toggle-label {
  696. background-color: #3b82f6;
  697. }
  698. /* 日计划和周映射 */
  699. .tl-dayplan-row {
  700. display: flex;
  701. align-items: center;
  702. gap: 0.5rem;
  703. padding: 0.375rem 0;
  704. }
  705. .tl-dayplan-label {
  706. width: 3.5rem;
  707. font-size: 0.6875rem;
  708. font-weight: 600;
  709. color: #374151;
  710. flex-shrink: 0;
  711. }
  712. .tl-weekmap-select {
  713. font-size: 0.75rem;
  714. padding: 0.25rem 0.5rem;
  715. border: 1px solid #d1d5db;
  716. border-radius: 0.25rem;
  717. background: white;
  718. flex: 1;
  719. max-width: 200px;
  720. }
  721. .tl-weekmap-select:focus {
  722. border-color: #3b82f6;
  723. box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
  724. outline: none;
  725. }
  726. /* Default 配置折叠面板 */
  727. .tl-collapsible {
  728. border: 1px solid #e5e7eb;
  729. border-radius: 0.5rem;
  730. overflow: hidden;
  731. }
  732. .tl-collapsible-header {
  733. background: #f9fafb;
  734. padding: 0.625rem 0.75rem;
  735. cursor: pointer;
  736. display: flex;
  737. align-items: center;
  738. justify-content: space-between;
  739. font-size: 0.75rem;
  740. font-weight: 600;
  741. color: #4b5563;
  742. transition: background 0.15s;
  743. }
  744. .tl-collapsible-header:hover {
  745. background: #f3f4f6;
  746. }
  747. .tl-collapsible-body {
  748. padding: 0.75rem;
  749. border-top: 1px solid #e5e7eb;
  750. }
  751. .tl-collapsible-body.collapsed {
  752. display: none;
  753. }
  754. .tl-collapsible-header .fa-chevron-down {
  755. transition: transform 0.2s;
  756. }
  757. .tl-collapsible-header.is-collapsed .fa-chevron-down {
  758. transform: rotate(-90deg);
  759. }
  760. /* Timeline CRUD 新增样式 */
  761. /* 预设卡片操作按钮 */
  762. .tl-card-actions {
  763. display: none;
  764. position: absolute;
  765. top: 0.375rem;
  766. right: 0.375rem;
  767. gap: 0.25rem;
  768. z-index: 2;
  769. }
  770. .tl-preset-card:hover .tl-card-actions {
  771. display: flex;
  772. }
  773. .tl-card-action-btn {
  774. width: 1.5rem;
  775. height: 1.5rem;
  776. display: flex;
  777. align-items: center;
  778. justify-content: center;
  779. border-radius: 0.375rem;
  780. font-size: 0.625rem;
  781. color: #9ca3af;
  782. background: rgba(255,255,255,0.9);
  783. border: 1px solid #e5e7eb;
  784. cursor: pointer;
  785. transition: all 0.15s;
  786. }
  787. .tl-card-action-btn:hover {
  788. color: #3b82f6;
  789. background: white;
  790. border-color: #93c5fd;
  791. }
  792. .tl-card-action-btn.text-red-400:hover {
  793. color: #ef4444;
  794. border-color: #fca5a5;
  795. }
  796. /* 新建模式卡片 */
  797. .tl-new-preset-card {
  798. border-style: dashed;
  799. border-color: #d1d5db;
  800. background: #fafafa;
  801. }
  802. .tl-new-preset-card:hover {
  803. border-color: #a78bfa;
  804. background: #faf5ff;
  805. }
  806. /* section 内的新增按钮 */
  807. .tl-add-btn {
  808. font-size: 0.625rem;
  809. font-weight: 600;
  810. color: #3b82f6;
  811. background: #eff6ff;
  812. border: 1px solid #bfdbfe;
  813. border-radius: 0.375rem;
  814. padding: 0.125rem 0.5rem;
  815. cursor: pointer;
  816. transition: all 0.15s;
  817. }
  818. .tl-add-btn:hover {
  819. background: #dbeafe;
  820. border-color: #93c5fd;
  821. }
  822. /* period 卡片内联操作 */
  823. .tl-inline-btn {
  824. width: 1.375rem;
  825. height: 1.375rem;
  826. display: inline-flex;
  827. align-items: center;
  828. justify-content: center;
  829. border-radius: 0.25rem;
  830. font-size: 0.625rem;
  831. color: #9ca3af;
  832. background: transparent;
  833. border: none;
  834. cursor: pointer;
  835. transition: all 0.15s;
  836. opacity: 0;
  837. }
  838. .tl-period-card:hover .tl-inline-btn,
  839. .tl-dayplan-card:hover .tl-inline-btn {
  840. opacity: 1;
  841. }
  842. .tl-inline-btn:hover {
  843. color: #3b82f6;
  844. background: #eff6ff;
  845. }
  846. .tl-inline-btn.text-red-400:hover {
  847. color: #ef4444;
  848. background: #fef2f2;
  849. }
  850. /* 日计划中的 period tag */
  851. .tl-period-tag {
  852. display: inline-flex;
  853. align-items: center;
  854. gap: 0.25rem;
  855. font-size: 0.625rem;
  856. padding: 0.125rem 0.5rem;
  857. border-radius: 9999px;
  858. color: white;
  859. white-space: nowrap;
  860. }
  861. .tl-tag-remove {
  862. font-size: 0.75rem;
  863. font-weight: 700;
  864. line-height: 1;
  865. color: rgba(255,255,255,0.7);
  866. background: none;
  867. border: none;
  868. cursor: pointer;
  869. padding: 0;
  870. margin-left: 0.125rem;
  871. }
  872. .tl-tag-remove:hover {
  873. color: white;
  874. }
  875. /* 添加时间段到日计划的 select */
  876. .tl-add-period-select {
  877. font-size: 0.625rem;
  878. padding: 0.0625rem 0.375rem;
  879. border: 1px dashed #d1d5db;
  880. border-radius: 9999px;
  881. background: #f9fafb;
  882. color: #6b7280;
  883. cursor: pointer;
  884. transition: all 0.15s;
  885. }
  886. .tl-add-period-select:hover {
  887. border-color: #93c5fd;
  888. color: #3b82f6;
  889. }
  890. /* 周映射快捷按钮 */
  891. .tl-quick-btn {
  892. font-size: 0.625rem;
  893. font-weight: 500;
  894. color: #6b7280;
  895. background: #f3f4f6;
  896. border: 1px solid #e5e7eb;
  897. border-radius: 0.375rem;
  898. padding: 0.25rem 0.5rem;
  899. cursor: pointer;
  900. transition: all 0.15s;
  901. }
  902. .tl-quick-btn:hover {
  903. color: #3b82f6;
  904. background: #eff6ff;
  905. border-color: #93c5fd;
  906. }
  907. /* 当前时间指示线 */
  908. .tl-now-line {
  909. position: absolute;
  910. top: -2px;
  911. bottom: -2px;
  912. width: 2px;
  913. background: #ef4444;
  914. z-index: 5;
  915. pointer-events: none;
  916. }
  917. .tl-now-line::before {
  918. content: '';
  919. position: absolute;
  920. top: -3px;
  921. left: -3px;
  922. width: 8px;
  923. height: 8px;
  924. border-radius: 50%;
  925. background: #ef4444;
  926. }
  927. /* 周视图色块点击态 */
  928. .tl-period-block {
  929. cursor: pointer;
  930. }
  931. .tl-period-block:hover {
  932. filter: brightness(1.1);
  933. box-shadow: 0 0 0 2px rgba(255,255,255,0.6);
  934. }
  935. /* period 卡片高亮动画 */
  936. .tl-period-highlight {
  937. animation: tl-highlight-pulse 1.5s ease-out;
  938. }
  939. @keyframes tl-highlight-pulse {
  940. 0% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.5); }
  941. 30% { box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.3); }
  942. 100% { box-shadow: none; }
  943. }
  944. /* 内联编辑输入框 */
  945. .tl-inline-input {
  946. background: white;
  947. border: 1px solid #93c5fd;
  948. border-radius: 0.25rem;
  949. padding: 0 0.25rem;
  950. outline: none;
  951. box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
  952. color: #1f2937;
  953. }
  954. .tl-editable {
  955. cursor: text;
  956. border-radius: 0.25rem;
  957. transition: background 0.15s;
  958. }
  959. .tl-editable:hover {
  960. background: rgba(59, 130, 246, 0.06);
  961. }
  962. /* 日计划 Tag 拖拽排序 */
  963. .tl-period-tag {
  964. cursor: grab;
  965. }
  966. .tl-period-tag:active {
  967. cursor: grabbing;
  968. }
  969. .tl-tag-ghost {
  970. opacity: 0.4;
  971. }
  972. .tl-tag-drag {
  973. transform: rotate(2deg);
  974. box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  975. }
  976. /* ==========================================
  977. 支持侧栏
  978. ========================================== */
  979. /* 外层容器:承担宽度和 flex 布局角色 */
  980. .support-sidebar-wrap {
  981. width: 20%;
  982. min-width: 180px;
  983. max-width: 280px;
  984. overflow: visible;
  985. transition: width 0.3s ease, min-width 0.3s ease, max-width 0.3s ease;
  986. }
  987. .support-sidebar-wrap.collapsed {
  988. width: 0;
  989. min-width: 0;
  990. max-width: 0;
  991. }
  992. /* 内层侧栏:填满 wrap */
  993. .support-sidebar {
  994. width: 100%;
  995. height: 100%;
  996. overflow: hidden;
  997. transition: opacity 0.3s ease;
  998. }
  999. .support-sidebar-wrap.collapsed .support-sidebar {
  1000. opacity: 0;
  1001. pointer-events: none;
  1002. }
  1003. /* 折叠/展开按钮 */
  1004. .sidebar-toggle-btn {
  1005. position: absolute;
  1006. left: 0;
  1007. top: 50%;
  1008. transform: translate(-100%, -50%);
  1009. width: 20px;
  1010. height: 40px;
  1011. background: white;
  1012. border: 1px solid #e5e7eb;
  1013. border-radius: 6px 0 0 6px;
  1014. display: flex;
  1015. align-items: center;
  1016. justify-content: center;
  1017. cursor: pointer;
  1018. z-index: 10;
  1019. opacity: 0;
  1020. transition: opacity 0.2s ease, background 0.2s ease;
  1021. color: #9ca3af;
  1022. }
  1023. .support-sidebar-wrap:hover .sidebar-toggle-btn {
  1024. opacity: 1;
  1025. }
  1026. .sidebar-toggle-btn:hover {
  1027. background: #f3f4f6;
  1028. color: #6b7280;
  1029. }
  1030. /* 折叠后按钮始终可见,箭头朝左 */
  1031. .sidebar-toggle-btn.is-collapsed {
  1032. opacity: 1;
  1033. }
  1034. .sidebar-toggle-btn.is-collapsed i {
  1035. transform: rotate(180deg);
  1036. }
  1037. /* 侧栏滚动条 */
  1038. .sidebar-scroll::-webkit-scrollbar {
  1039. width: 4px;
  1040. }
  1041. .sidebar-scroll::-webkit-scrollbar-track {
  1042. background: transparent;
  1043. }
  1044. .sidebar-scroll::-webkit-scrollbar-thumb {
  1045. background: #e5e7eb;
  1046. border-radius: 2px;
  1047. }
  1048. .sidebar-scroll::-webkit-scrollbar-thumb:hover {
  1049. background: #d1d5db;
  1050. }
  1051. /* 侧栏卡片 */
  1052. .sidebar-card {
  1053. background: white;
  1054. border: 1px solid #f3f4f6;
  1055. border-radius: 0.75rem;
  1056. padding: 0.75rem;
  1057. transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  1058. text-decoration: none;
  1059. display: block;
  1060. cursor: pointer;
  1061. }
  1062. .sidebar-card:hover {
  1063. border-color: #e5e7eb;
  1064. box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
  1065. transform: translateY(-2px);
  1066. }
  1067. /* 侧栏卡片图标 */
  1068. .sidebar-card-icon {
  1069. width: 2rem;
  1070. height: 2rem;
  1071. border-radius: 0.5rem;
  1072. display: flex;
  1073. align-items: center;
  1074. justify-content: center;
  1075. font-size: 0.75rem;
  1076. flex-shrink: 0;
  1077. transition: all 0.2s ease;
  1078. }
  1079. .sidebar-card:hover .sidebar-card-icon {
  1080. transform: rotate(8deg) scale(1.1);
  1081. }
  1082. /* 侧栏 CTA 按钮 */
  1083. .sidebar-cta {
  1084. text-align: center;
  1085. padding: 0.375rem 0.5rem;
  1086. border-radius: 0.5rem;
  1087. font-size: 0.625rem;
  1088. font-weight: 700;
  1089. transition: all 0.2s ease;
  1090. letter-spacing: 0.02em;
  1091. }
  1092. /* 侧栏二维码 */
  1093. .sidebar-qr {
  1094. width: 100%;
  1095. max-width: 120px;
  1096. aspect-ratio: 1;
  1097. background: white;
  1098. border: 1px solid #f3f4f6;
  1099. border-radius: 0.625rem;
  1100. padding: 0.375rem;
  1101. transition: all 0.3s ease;
  1102. }
  1103. /* 链接样式重置 */
  1104. a.sidebar-card {
  1105. color: inherit;
  1106. }
  1107. a.sidebar-card:hover {
  1108. color: inherit;
  1109. text-decoration: none;
  1110. }
  1111. /* 侧栏标题区引语 */
  1112. .sidebar-quote {
  1113. max-height: 0;
  1114. overflow: hidden;
  1115. opacity: 0;
  1116. margin-top: 0;
  1117. transition: max-height 0.4s ease, opacity 0.3s ease, margin-top 0.3s ease;
  1118. }
  1119. .sidebar-header-hover:hover .sidebar-quote {
  1120. max-height: 3rem;
  1121. opacity: 1;
  1122. margin-top: 0.375rem;
  1123. }
  1124. /* 可点击的二维码卡片 */
  1125. .sidebar-card-clickable {
  1126. cursor: pointer;
  1127. position: relative;
  1128. }
  1129. .sidebar-card-clickable:hover {
  1130. border-color: #d1d5db;
  1131. box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
  1132. }
  1133. /* 点击放大提示 */
  1134. .sidebar-enlarge-hint {
  1135. position: absolute;
  1136. bottom: 0;
  1137. left: 50%;
  1138. transform: translateX(-50%) translateY(4px);
  1139. background: rgba(0, 0, 0, 0.65);
  1140. color: white;
  1141. font-size: 0.5625rem;
  1142. padding: 0.125rem 0.5rem;
  1143. border-radius: 0.25rem;
  1144. white-space: nowrap;
  1145. opacity: 0;
  1146. transition: all 0.2s ease;
  1147. pointer-events: none;
  1148. }
  1149. .sidebar-card-clickable:hover .sidebar-enlarge-hint {
  1150. opacity: 1;
  1151. transform: translateX(-50%) translateY(-4px);
  1152. }