app-sidebar.component.css 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /* ============================================================
  2. * 全局侧栏 — 纯字排版,零图标,分区编号 + 中文标
  3. * --------------------------------------------------------------
  4. * 核心视觉刻画:
  5. * - 分区头:Fraunces 衬线斜体 + 微小分区编号 (01/02/03),与正文 Inter 形成强烈反差
  6. * - 二级条目:纯文字 14px,hover 仅文字颜色变化,active 时左侧 2px 竖线
  7. * - 不使用 hover 背景色块或图标 → 让信息密度专注于"标签文字"本身
  8. * ============================================================ */
  9. .t-sidebar {
  10. width: 220px;
  11. height: 100%;
  12. display: flex;
  13. flex-direction: column;
  14. padding: 28px 0 16px;
  15. background: #ffffff;
  16. border-right: 1px solid rgba(15, 23, 42, 0.06);
  17. font-family: var(--font-body);
  18. color: #1d1d1f;
  19. overflow-y: auto;
  20. flex-shrink: 0;
  21. }
  22. /* ===== 分区列表 ===== */
  23. .t-sidebar__zones {
  24. list-style: none;
  25. margin: 0;
  26. padding: 0;
  27. display: flex;
  28. flex-direction: column;
  29. gap: 28px;
  30. flex: 1;
  31. }
  32. .t-zone {
  33. display: flex;
  34. flex-direction: column;
  35. }
  36. /* —— 分区头:序号 + 中文标 —— */
  37. .t-zone__head {
  38. display: flex;
  39. align-items: baseline;
  40. gap: 12px;
  41. padding: 0 24px;
  42. margin-bottom: 8px;
  43. }
  44. .t-zone__serial {
  45. font-family: var(--font-serif);
  46. font-style: italic;
  47. font-weight: 300;
  48. font-size: 22px;
  49. line-height: 1;
  50. color: rgba(15, 23, 42, 0.32);
  51. font-variant-numeric: tabular-nums;
  52. letter-spacing: -0.02em;
  53. /* Fraunces 可选项:optical sizing 在不同字号下自动调整笔画粗细 */
  54. font-optical-sizing: auto;
  55. }
  56. .t-zone__label {
  57. font-family: var(--font-body);
  58. font-size: 11px;
  59. font-weight: 600;
  60. letter-spacing: 0.18em;
  61. text-transform: uppercase;
  62. color: rgba(15, 23, 42, 0.55);
  63. }
  64. /* ===== 二级条目 ===== */
  65. .t-zone__items {
  66. list-style: none;
  67. margin: 0;
  68. padding: 0;
  69. display: flex;
  70. flex-direction: column;
  71. }
  72. .t-item {
  73. position: relative;
  74. display: flex;
  75. align-items: center;
  76. gap: 8px;
  77. padding: 8px 24px;
  78. font-size: 14px;
  79. font-weight: 500;
  80. color: rgba(15, 23, 42, 0.72);
  81. cursor: pointer;
  82. user-select: none;
  83. outline: none;
  84. transition: color 120ms ease;
  85. }
  86. .t-item:hover,
  87. .t-item:focus-visible {
  88. color: #0f172a;
  89. }
  90. .t-item:focus-visible {
  91. /* 不用粗暴 outline,用左边竖线作为焦点提示 */
  92. background: rgba(15, 23, 42, 0.03);
  93. }
  94. /* 左侧竖线:active 时显示 */
  95. .t-item__rail {
  96. position: absolute;
  97. left: 0;
  98. top: 8px;
  99. bottom: 8px;
  100. width: 2px;
  101. background: transparent;
  102. border-radius: 0 2px 2px 0;
  103. transition: background-color 160ms ease;
  104. }
  105. .t-item.is-active {
  106. color: #0f172a;
  107. font-weight: 700;
  108. }
  109. .t-item.is-active .t-item__rail {
  110. background: #0f172a;
  111. }
  112. /* 标签 */
  113. .t-item__label {
  114. flex: 1;
  115. white-space: nowrap;
  116. overflow: hidden;
  117. text-overflow: ellipsis;
  118. }
  119. /* Beta 微章 */
  120. .t-item__badge {
  121. font-family: var(--font-mono);
  122. font-size: 9px;
  123. font-weight: 600;
  124. letter-spacing: 0.06em;
  125. text-transform: uppercase;
  126. padding: 2px 6px;
  127. border-radius: 3px;
  128. background: rgba(15, 23, 42, 0.06);
  129. color: rgba(15, 23, 42, 0.55);
  130. flex-shrink: 0;
  131. }
  132. .t-item.is-active .t-item__badge {
  133. background: #0f172a;
  134. color: #ffffff;
  135. }
  136. /* ===== 底部主题切换 ===== */
  137. .t-sidebar__foot {
  138. margin-top: 16px;
  139. padding: 16px 24px 0;
  140. border-top: 1px solid rgba(15, 23, 42, 0.06);
  141. }
  142. .t-theme {
  143. display: flex;
  144. align-items: center;
  145. gap: 8px;
  146. width: 100%;
  147. padding: 0;
  148. border: none;
  149. background: transparent;
  150. cursor: pointer;
  151. font-family: var(--font-body);
  152. font-size: 13px;
  153. color: rgba(15, 23, 42, 0.55);
  154. transition: color 120ms ease;
  155. }
  156. .t-theme:hover {
  157. color: #0f172a;
  158. }
  159. .t-theme__dot {
  160. width: 8px;
  161. height: 8px;
  162. border-radius: 50%;
  163. background: linear-gradient(135deg, #fbbf24, #f97316);
  164. box-shadow: 0 0 0 2px rgba(251, 191, 36, 0.18);
  165. transition: background 200ms ease, box-shadow 200ms ease;
  166. }
  167. .t-theme__dot.is-night {
  168. background: linear-gradient(135deg, #1e293b, #475569);
  169. box-shadow: 0 0 0 2px rgba(71, 85, 105, 0.22);
  170. }
  171. /* ===== 夜间主题适配 ===== */
  172. .app-container.theme-night .t-sidebar {
  173. background: #0b0f1a;
  174. border-right-color: rgba(255, 255, 255, 0.06);
  175. color: #e2e8f0;
  176. }
  177. .app-container.theme-night .t-zone__serial {
  178. color: rgba(226, 232, 240, 0.32);
  179. }
  180. .app-container.theme-night .t-zone__label {
  181. color: rgba(226, 232, 240, 0.5);
  182. }
  183. .app-container.theme-night .t-item {
  184. color: rgba(226, 232, 240, 0.7);
  185. }
  186. .app-container.theme-night .t-item:hover,
  187. .app-container.theme-night .t-item:focus-visible,
  188. .app-container.theme-night .t-item.is-active {
  189. color: #f8fafc;
  190. }
  191. .app-container.theme-night .t-item:focus-visible {
  192. background: rgba(255, 255, 255, 0.04);
  193. }
  194. .app-container.theme-night .t-item.is-active .t-item__rail {
  195. background: #f8fafc;
  196. }
  197. .app-container.theme-night .t-item__badge {
  198. background: rgba(255, 255, 255, 0.08);
  199. color: rgba(226, 232, 240, 0.65);
  200. }
  201. .app-container.theme-night .t-item.is-active .t-item__badge {
  202. background: #f8fafc;
  203. color: #0b0f1a;
  204. }
  205. .app-container.theme-night .t-sidebar__foot {
  206. border-top-color: rgba(255, 255, 255, 0.06);
  207. }
  208. .app-container.theme-night .t-theme {
  209. color: rgba(226, 232, 240, 0.55);
  210. }
  211. .app-container.theme-night .t-theme:hover {
  212. color: #f8fafc;
  213. }
  214. /* ===== 响应式:窄屏折叠(仅显示分区编号) ===== */
  215. @media (max-width: 960px) {
  216. .t-sidebar {
  217. width: 64px;
  218. }
  219. .t-zone__head {
  220. padding: 0 12px;
  221. gap: 0;
  222. flex-direction: column;
  223. align-items: center;
  224. margin-bottom: 4px;
  225. }
  226. .t-zone__label {
  227. display: none;
  228. }
  229. .t-item {
  230. padding: 8px 12px;
  231. justify-content: center;
  232. }
  233. .t-item__label {
  234. display: none;
  235. }
  236. .t-item__badge {
  237. display: none;
  238. }
  239. .t-item.is-active::after {
  240. /* 折叠态用一个圆点表示 active */
  241. content: '';
  242. position: absolute;
  243. right: 8px;
  244. top: 50%;
  245. width: 4px;
  246. height: 4px;
  247. border-radius: 50%;
  248. background: currentColor;
  249. transform: translateY(-50%);
  250. }
  251. .t-theme__label {
  252. display: none;
  253. }
  254. .t-sidebar__foot {
  255. padding: 16px 12px 0;
  256. }
  257. }