styles.scss 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  1. @use '../../shared/ui/dropdown';
  2. @use './app/pages/operations-schedule-layout';
  3. @use './app/pages/operations-overview-metrics';
  4. :root {
  5. --brand: #2f9b82;
  6. --brand-strong: #1f7b68;
  7. --brand-deep: #155d50;
  8. --brand-pale: #e8f5f1;
  9. --brand-wash: #f1f8f6;
  10. --accent: #f59b23;
  11. --accent-strong: #df8211;
  12. --accent-pale: #fff3dc;
  13. --rose: #a34d67;
  14. --rose-pale: #faeaf0;
  15. --blue: #4f73aa;
  16. --blue-pale: #eaf0f9;
  17. --danger: #c94f4f;
  18. --danger-pale: #fff0ef;
  19. --success: #2f8b61;
  20. --ink: #172522;
  21. --ink-soft: #697673;
  22. --ink-faint: #96a29f;
  23. --surface: #ffffff;
  24. --surface-muted: #f4f7f6;
  25. --surface-hover: #f1f6f4;
  26. --line: #dce5e2;
  27. --line-soft: #eaf0ee;
  28. --radius-xs: 4px;
  29. --radius-sm: 6px;
  30. --radius-md: 8px;
  31. --radius-lg: 8px;
  32. --shadow-xs: 0 2px 8px rgb(24 54 47 / 5%);
  33. --shadow-sm: 0 5px 18px rgb(24 54 47 / 7%);
  34. --shadow-lg: 0 16px 40px rgb(24 54 47 / 16%);
  35. --shadow-brand: 0 14px 30px rgb(24 89 74 / 20%);
  36. --page-gutter: 14px;
  37. --panel-gap: 12px;
  38. --panel-radius: 8px;
  39. color-scheme: light;
  40. font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", sans-serif;
  41. font-synthesis: none;
  42. text-rendering: optimizeLegibility;
  43. }
  44. * { box-sizing: border-box; }
  45. html,
  46. body {
  47. min-height: 100%;
  48. margin: 0;
  49. color: var(--ink);
  50. background: var(--surface-muted);
  51. }
  52. body { min-width: 320px; }
  53. button,
  54. input,
  55. textarea,
  56. select { font: inherit; }
  57. button,
  58. a { -webkit-tap-highlight-color: transparent; }
  59. button { cursor: pointer; }
  60. a,
  61. button,
  62. input,
  63. textarea,
  64. select { transition: color 160ms ease, background-color 160ms ease, border-color 160ms ease, box-shadow 160ms ease, opacity 160ms ease, transform 160ms ease; }
  65. :focus-visible {
  66. outline: 3px solid rgb(245 155 35 / 48%);
  67. outline-offset: 2px;
  68. }
  69. img {
  70. max-width: 100%;
  71. object-fit: cover;
  72. }
  73. .page { padding: 16px; }
  74. .section {
  75. padding: 18px 16px;
  76. background: var(--surface);
  77. border-bottom: 1px solid var(--line-soft);
  78. }
  79. .section + .section { margin-top: 10px; }
  80. .section-title {
  81. margin: 0 0 14px;
  82. font-size: 17px;
  83. letter-spacing: 0;
  84. }
  85. .muted { color: var(--ink-soft); }
  86. .primary-button,
  87. .secondary-button,
  88. .danger-button {
  89. min-height: 46px;
  90. padding: 10px 18px;
  91. border: 1px solid transparent;
  92. border-radius: var(--radius-md);
  93. font-weight: 700;
  94. letter-spacing: 0;
  95. }
  96. .primary-button {
  97. color: white;
  98. background: var(--brand-strong);
  99. box-shadow: 0 6px 14px rgb(31 123 104 / 17%);
  100. }
  101. .secondary-button {
  102. color: var(--brand-strong);
  103. background: white;
  104. border-color: var(--brand);
  105. }
  106. .danger-button {
  107. color: white;
  108. background: var(--danger);
  109. }
  110. .primary-button:disabled,
  111. .secondary-button:disabled,
  112. .danger-button:disabled {
  113. cursor: not-allowed;
  114. opacity: 0.48;
  115. box-shadow: none;
  116. }
  117. .field { display: grid; gap: 7px; }
  118. .field + .field { margin-top: 15px; }
  119. .field label {
  120. color: var(--ink-soft);
  121. font-size: 13px;
  122. font-weight: 550;
  123. }
  124. .field input,
  125. .field textarea,
  126. .field select,
  127. input:not([type='checkbox']):not([type='radio']):not([type='range']),
  128. textarea,
  129. select {
  130. width: 100%;
  131. min-height: 46px;
  132. padding: 10px 12px;
  133. color: var(--ink);
  134. background: white;
  135. border: 1px solid var(--line);
  136. border-radius: var(--radius-sm);
  137. outline: none;
  138. }
  139. .field textarea,
  140. textarea { min-height: 110px; resize: vertical; }
  141. .field input:focus,
  142. .field textarea:focus,
  143. .field select:focus,
  144. input:focus,
  145. textarea:focus,
  146. select:focus {
  147. border-color: var(--brand);
  148. box-shadow: 0 0 0 3px rgb(47 155 130 / 12%);
  149. }
  150. .empty-state,
  151. .center-state {
  152. display: grid;
  153. min-height: 220px;
  154. padding: 28px 20px;
  155. place-items: center;
  156. color: var(--ink-soft);
  157. text-align: center;
  158. }
  159. .empty-state lucide-icon,
  160. .center-state lucide-icon { color: var(--ink-faint); }
  161. .empty-state > *,
  162. .center-state > * {
  163. min-width: 0;
  164. max-width: 100%;
  165. }
  166. .empty-state p,
  167. .center-state p {
  168. max-width: 100%;
  169. overflow-wrap: anywhere;
  170. word-break: break-word;
  171. }
  172. @media (hover: hover) {
  173. .primary-button:hover { background: var(--brand-deep); transform: translateY(-1px); }
  174. .secondary-button:hover { background: var(--brand-wash); }
  175. }
  176. @media (prefers-reduced-motion: reduce) {
  177. *,
  178. *::before,
  179. *::after {
  180. scroll-behavior: auto !important;
  181. animation-duration: 0.01ms !important;
  182. animation-iteration-count: 1 !important;
  183. transition-duration: 0.01ms !important;
  184. }
  185. }
  186. /* Shared visual language for the route families that implement the 95 migrated pages. */
  187. app-account-page .profile-header,
  188. app-appointment-page .appointment-status,
  189. app-finance-page .finance-summary,
  190. app-merchant-page :is(.stock-summary, .settle-summary),
  191. app-study-records-page :is(.mastery, .income-summary),
  192. app-team-page .team-summary,
  193. app-game-page .game-intro {
  194. background: linear-gradient(135deg, var(--brand-deep), var(--brand-strong));
  195. box-shadow: var(--shadow-brand);
  196. }
  197. app-account-page :is(.wallet-strip, .order-strip, .role-panel, .service-section, .settings-list),
  198. app-course-center-page :is(.course-band, .schedule-band),
  199. app-study-records-page :is(.filter-row, .record-tabs, .record-list),
  200. app-team-page :is(.team-stats, .detail-link, .members),
  201. app-merchant-page :is(.stock-list, .settlement-list, .settlement-preview, .sales-group),
  202. app-order-page :is(.order-tabs, .order-list),
  203. app-finance-page :is(.finance-list, .finance-actions),
  204. app-resource-page :is(.description, .action-row, .tabs, .resource-list, .detail-list),
  205. app-checkout-page :is(.checkout-section, .totals),
  206. app-product-page :is(.product-info, .product-tools, .product-content, .comments) {
  207. border-color: var(--line-soft);
  208. }
  209. app-product-list-page .product-grid article,
  210. app-appointment-page .unit-grid article,
  211. app-game-page .game-menu button,
  212. app-support-feedback-page :is(.agent-header, .message-intro),
  213. app-form-page .order-context,
  214. app-english-reading-page .question-block,
  215. app-reading-exercise .question-block {
  216. border-color: var(--line);
  217. border-radius: var(--radius-md);
  218. box-shadow: var(--shadow-xs);
  219. }
  220. app-product-list-page .product-grid article,
  221. app-game-page .game-menu button,
  222. app-appointment-page .unit-grid article { transition: border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease; }
  223. app-resource-page :is(.resource-item, .detail-list div),
  224. app-study-records-page :is(.learning-item, .history-item, .progress-item, .income-item),
  225. app-course-center-page :is(.course-list li, .schedule-list article),
  226. app-team-page .members article,
  227. app-order-page .order-card,
  228. app-finance-page .finance-item { border-color: var(--line-soft); }
  229. app-resource-page :is(.resource-item:hover, .resource-item:focus-within),
  230. app-study-records-page :is(.learning-item:hover, .progress-item:hover),
  231. app-course-center-page .schedule-list article:hover,
  232. app-team-page .members article:hover { background: var(--surface-hover); }
  233. app-product-list-page .node-list button.active,
  234. app-study-records-page .record-tabs button.active,
  235. app-resource-page .tabs button.active,
  236. app-auth-page .mode-tabs button.active,
  237. app-login-page .mode-tabs button.active {
  238. color: var(--brand-strong);
  239. border-color: var(--brand-strong);
  240. }
  241. app-form-page :is(.audit-line, .status-line),
  242. app-auth-page .audit-notice,
  243. app-login-page .audit-notice { border-radius: var(--radius-md); }
  244. app-form-page :is(.load-error, .upload-control, .image-item),
  245. app-support-feedback-page :is(.error-state, input, textarea),
  246. app-reading-setup :is(input, select, textarea),
  247. app-english-reading-page :is(input, select, textarea) { border-radius: var(--radius-sm); }
  248. app-product-page :is(.purchase-bar),
  249. app-checkout-page footer,
  250. app-appointment-page .appointment-actions,
  251. app-reading-exercise .answer-footer {
  252. border-color: var(--line);
  253. box-shadow: 0 -8px 24px rgb(24 54 47 / 6%);
  254. backdrop-filter: blur(12px);
  255. }
  256. app-support-page .messages p,
  257. app-support-page :is(.image-message, .file-message),
  258. app-support-page form textarea { border-radius: var(--radius-md); }
  259. app-auth-page,
  260. app-login-page {
  261. background: linear-gradient(180deg, var(--brand-pale) 0, var(--surface-muted) 42%, var(--surface) 100%);
  262. }
  263. @media (hover: hover) {
  264. app-product-list-page .product-grid article:hover,
  265. app-game-page .game-menu button:hover,
  266. app-appointment-page .unit-grid article:hover {
  267. border-color: color-mix(in srgb, var(--brand) 55%, var(--line));
  268. box-shadow: var(--shadow-sm);
  269. transform: translateY(-1px);
  270. }
  271. }
  272. /* Shared page geometry: business subpages use the same inset surfaces as the main tabs. */
  273. app-learning-page .catalog-tabs {
  274. display: grid;
  275. margin: var(--panel-gap) var(--page-gutter) 0;
  276. overflow: hidden;
  277. grid-template-columns: repeat(5, minmax(0, 1fr));
  278. background: var(--surface);
  279. border: 1px solid var(--line);
  280. border-radius: var(--panel-radius);
  281. box-shadow: var(--shadow-sm);
  282. }
  283. app-learning-page .catalog-tabs button {
  284. min-width: 0;
  285. min-height: 44px;
  286. padding: 0 4px;
  287. color: var(--ink-soft);
  288. background: transparent;
  289. border: 0;
  290. border-right: 1px solid var(--line);
  291. font-size: 12px;
  292. }
  293. app-learning-page .catalog-tabs button:last-child { border-right: 0; }
  294. app-learning-page .catalog-tabs button.active { color: white; background: var(--brand-strong); font-weight: 700; }
  295. app-learning-page .unit-selection-summary {
  296. display: flex;
  297. min-height: 48px;
  298. align-items: center;
  299. justify-content: space-between;
  300. margin: var(--panel-gap) var(--page-gutter) 0;
  301. padding: 0 14px;
  302. color: var(--ink-soft);
  303. background: var(--surface);
  304. border: 1px solid var(--line);
  305. border-radius: var(--panel-radius);
  306. box-shadow: var(--shadow-sm);
  307. gap: 10px;
  308. }
  309. app-learning-page .unit-selection-summary span { font-size: 13px; }
  310. app-learning-page .unit-selection-summary strong { color: var(--brand-strong); font-size: 17px; }
  311. app-learning-page .unit-selection-summary small { font-size: 11px; }
  312. app-learning-page .node-list > button.selected { background: var(--brand-pale); }
  313. app-learning-page .node-list > button.unit-node { justify-content: flex-start !important; }
  314. app-learning-page .node-list .node-check {
  315. display: grid !important;
  316. width: 24px;
  317. height: 24px;
  318. flex: 0 0 24px;
  319. color: white;
  320. background: white;
  321. border: 1px solid #b5c6c1;
  322. border-radius: 6px;
  323. place-items: center;
  324. }
  325. app-learning-page .node-list > button.selected .node-check { background: var(--brand-strong); border-color: var(--brand-strong); }
  326. app-learning-page .node-list .node-copy { flex: 1; }
  327. app-learning-page .node-list .unit-progress-ring {
  328. display: grid;
  329. width: 44px;
  330. height: 44px;
  331. flex: 0 0 44px;
  332. margin-left: auto;
  333. position: relative;
  334. color: var(--brand-deep);
  335. background: conic-gradient(var(--brand) var(--progress, 0%), #e3ebe8 0);
  336. border-radius: 50%;
  337. place-items: center;
  338. }
  339. app-learning-page .node-list .unit-progress-ring::before {
  340. position: absolute;
  341. background: white;
  342. border-radius: 50%;
  343. content: '';
  344. inset: 5px;
  345. }
  346. app-learning-page .node-list .unit-progress-ring.complete { background: var(--brand-strong); }
  347. app-learning-page .node-list .unit-progress-ring strong { z-index: 1; font-size: 9px; }
  348. app-learning-page .unit-actions { grid-template-columns: minmax(0, 1fr) minmax(150px, 1.4fr); align-items: center; }
  349. app-learning-page .unit-actions > span { color: var(--ink-soft); font-size: 13px; text-align: center; }
  350. app-resource-page .resource-page > :is(.description, .order-context, .action-row, .tabs, .state-line, .error-state, .resource-list, .detail-list, .empty-state),
  351. app-appointment-page .appointment-page > :is(.course-section, .comment-panel, .report-panel),
  352. app-article-page .article-page > :is(header, .article-content),
  353. app-checkout-page .checkout-section,
  354. app-finance-page .balance-band,
  355. app-form-page .form-page,
  356. app-order-page .order-page > :is(header, .timeline, .order-card, .order-links),
  357. app-product-page .product-page > :is(.gallery-strip, .product-summary, .product-tools, .product-content, .comments),
  358. app-study-records-page .records-page > :is(.mastery, .income-summary, .filter-row, .record-tabs, .record-list),
  359. app-team-page :is(.team-summary, .team-stats, .detail-link, .members),
  360. app-merchant-page :is(.stock-summary, .settle-summary, .stock-list, .settlement-list, .settlement-preview, .sales-group),
  361. app-learning-page .learning-page > :is(.node-intro, .node-list, .selection-header, .word-select-list, .stage-banner, .repeat-list, .game-heading, .review-summary, .record-overview, .record-tip, .record-list, .anti-heading, .exam-status) {
  362. overflow: hidden;
  363. border: 1px solid var(--line);
  364. border-radius: var(--panel-radius);
  365. box-shadow: var(--shadow-sm);
  366. }
  367. app-resource-page .resource-page {
  368. padding: var(--panel-gap) var(--page-gutter) 24px;
  369. }
  370. app-resource-page .resource-page > :is(.description, .order-context, .action-row, .tabs, .state-line, .error-state, .resource-list, .detail-list, .empty-state) {
  371. margin: 0 0 var(--panel-gap);
  372. background: white;
  373. }
  374. app-resource-page :is(.resource-item, .detail-list div):last-child { border-bottom: 0; }
  375. app-learning-page .learning-page > :is(.node-intro, .node-list, .game-heading, .review-summary, .record-overview, .anti-heading, .exam-status) {
  376. margin: var(--panel-gap) var(--page-gutter) 0;
  377. }
  378. app-learning-page .learning-page > .node-list { margin-bottom: var(--panel-gap); }
  379. app-learning-page .learning-page > .selection-header,
  380. app-learning-page .learning-page > .stage-banner,
  381. app-learning-page .learning-page > .record-tip {
  382. margin: var(--panel-gap) var(--page-gutter) 0;
  383. border-radius: var(--panel-radius) var(--panel-radius) 0 0;
  384. }
  385. app-learning-page .learning-page > .selection-header { top: 52px; }
  386. app-learning-page .learning-page > :is(.word-select-list, .repeat-list, .record-list) {
  387. margin: 0 var(--page-gutter) var(--panel-gap);
  388. border-top: 0;
  389. border-radius: 0 0 var(--panel-radius) var(--panel-radius);
  390. }
  391. app-learning-page :is(.node-list, .word-select-list, .repeat-list, .record-list) > :last-child { border-bottom: 0; }
  392. app-learning-page .learning-page > :is(.review-list, .match-grid, .anti-grid, .option-list) {
  393. padding-right: var(--page-gutter);
  394. padding-left: var(--page-gutter);
  395. }
  396. app-learning-page .learning-page > :is(.memory-calendar, .memory-date-tasks) {
  397. margin-right: var(--page-gutter);
  398. margin-left: var(--page-gutter);
  399. }
  400. app-appointment-page .appointment-page > .appointment-status {
  401. margin: var(--panel-gap) var(--page-gutter) 0;
  402. overflow: hidden;
  403. border-radius: var(--panel-radius) var(--panel-radius) 0 0;
  404. }
  405. app-appointment-page .appointment-page > .appointment-info {
  406. margin: 0 var(--page-gutter);
  407. overflow: hidden;
  408. border: 1px solid var(--line);
  409. border-top: 0;
  410. border-radius: 0 0 var(--panel-radius) var(--panel-radius);
  411. box-shadow: var(--shadow-sm);
  412. }
  413. app-appointment-page .appointment-page > :is(.course-section, .comment-panel, .report-panel) {
  414. margin: var(--panel-gap) var(--page-gutter) 0;
  415. border-block: 1px solid var(--line);
  416. }
  417. app-article-page .article-page > :is(header, .article-content) {
  418. margin: var(--panel-gap) var(--page-gutter) 0;
  419. }
  420. app-article-page .article-video {
  421. width: calc(100% - (2 * var(--page-gutter)));
  422. margin: var(--panel-gap) var(--page-gutter) 0;
  423. overflow: hidden;
  424. border-radius: var(--panel-radius);
  425. box-shadow: var(--shadow-sm);
  426. }
  427. app-checkout-page .checkout-page { padding-top: var(--panel-gap); }
  428. app-checkout-page .checkout-section { margin: 0 var(--page-gutter) var(--panel-gap); }
  429. app-finance-page .balance-band {
  430. margin: var(--panel-gap) var(--page-gutter) 0;
  431. }
  432. app-finance-page .log-heading {
  433. margin: var(--panel-gap) var(--page-gutter) 0;
  434. overflow: hidden;
  435. border: 1px solid var(--line);
  436. border-radius: var(--panel-radius) var(--panel-radius) 0 0;
  437. box-shadow: var(--shadow-sm);
  438. }
  439. app-finance-page .finance-logs {
  440. margin: 0 var(--page-gutter) 24px;
  441. overflow: hidden;
  442. border: 1px solid var(--line);
  443. border-top: 0;
  444. border-radius: 0 0 var(--panel-radius) var(--panel-radius);
  445. box-shadow: var(--shadow-sm);
  446. }
  447. app-finance-page .finance-logs article:last-child { border-bottom: 0; }
  448. app-form-page {
  449. display: block;
  450. min-height: 100%;
  451. padding-top: 1px;
  452. background: var(--surface-muted);
  453. }
  454. app-form-page .form-page {
  455. margin: var(--panel-gap) var(--page-gutter) 24px;
  456. padding: 18px 16px 24px;
  457. background: white;
  458. }
  459. app-order-page .order-page { padding-top: 1px; }
  460. app-order-page .order-page > :is(header, .timeline, .order-card, .order-links) { margin: var(--panel-gap) var(--page-gutter) 0; }
  461. app-product-page .hero-image {
  462. display: block;
  463. width: calc(100% - (2 * var(--page-gutter)));
  464. margin: var(--panel-gap) var(--page-gutter) 0;
  465. overflow: hidden;
  466. border: 1px solid var(--line);
  467. border-radius: var(--panel-radius);
  468. box-shadow: var(--shadow-sm);
  469. }
  470. app-product-page .product-page > :is(.gallery-strip, .product-summary, .product-tools, .product-content, .comments) {
  471. margin: var(--panel-gap) var(--page-gutter) 0;
  472. }
  473. app-product-list-page .browse-page:not(.with-nodes) > .search-row {
  474. margin: var(--panel-gap) var(--page-gutter) 0;
  475. overflow: hidden;
  476. border: 1px solid var(--line);
  477. border-radius: var(--panel-radius);
  478. box-shadow: var(--shadow-sm);
  479. }
  480. app-product-list-page .browse-page:not(.with-nodes) > .product-region {
  481. padding-right: var(--page-gutter);
  482. padding-left: var(--page-gutter);
  483. }
  484. app-product-list-page .browse-page.with-nodes {
  485. width: calc(100% - (2 * var(--page-gutter)));
  486. height: calc(100dvh - 52px - (2 * var(--panel-gap)));
  487. margin: var(--panel-gap) var(--page-gutter);
  488. overflow: hidden;
  489. border: 1px solid var(--line);
  490. border-radius: var(--panel-radius);
  491. box-shadow: var(--shadow-sm);
  492. }
  493. app-team-page .team-summary { margin: var(--panel-gap) var(--page-gutter) 0; }
  494. app-team-page .team-stats {
  495. margin: var(--panel-gap) var(--page-gutter) 0;
  496. border-radius: var(--panel-radius) var(--panel-radius) 0 0;
  497. }
  498. app-team-page .detail-link {
  499. margin: 0 var(--page-gutter);
  500. border-top: 0;
  501. border-radius: 0 0 var(--panel-radius) var(--panel-radius);
  502. }
  503. app-team-page .members { margin: var(--panel-gap) var(--page-gutter) 24px; }
  504. app-team-page .members article:last-child { border-bottom: 0; }
  505. app-merchant-page :is(.stock-summary, .settle-summary) { margin: var(--panel-gap) var(--page-gutter) 0; }
  506. app-merchant-page :is(.stock-list, .settlement-list, .settlement-preview, .sales-group) { margin: var(--panel-gap) var(--page-gutter) 0; border-block: 1px solid var(--line); }
  507. app-merchant-page :is(.stock-list, .settlement-list, .sales-group) article:last-child { border-bottom: 0; }
  508. app-study-records-page .records-page > :is(.mastery, .income-summary, .filter-row, .record-tabs, .record-list) {
  509. margin: var(--panel-gap) var(--page-gutter) 0;
  510. }
  511. app-study-records-page .records-page > .record-list { margin-bottom: 24px; }
  512. app-study-records-page .current-learning-card {
  513. margin: var(--panel-gap) var(--page-gutter) 0;
  514. overflow: hidden;
  515. background: white;
  516. border: 1px solid var(--line);
  517. border-radius: var(--panel-radius);
  518. box-shadow: var(--shadow-sm);
  519. }
  520. app-study-records-page .current-learning-card > header {
  521. display: flex;
  522. min-height: 58px;
  523. align-items: center;
  524. justify-content: space-between;
  525. padding: 10px 14px;
  526. color: white;
  527. background: var(--brand-strong);
  528. gap: 12px;
  529. }
  530. app-study-records-page .current-learning-card > header > div {
  531. display: flex;
  532. min-width: 0;
  533. flex-direction: column;
  534. gap: 2px;
  535. }
  536. app-study-records-page .current-learning-card > header span { color: rgb(255 255 255 / 78%); font-size: 10px; }
  537. app-study-records-page .current-learning-card > header strong { font-size: 16px; }
  538. app-study-records-page .current-learning-list button {
  539. display: grid;
  540. width: 100%;
  541. min-height: 66px;
  542. grid-template-columns: 36px minmax(0, 1fr) auto;
  543. align-items: center;
  544. padding: 9px 14px;
  545. color: var(--ink);
  546. text-align: left;
  547. background: white;
  548. border: 0;
  549. border-bottom: 1px solid var(--line);
  550. gap: 10px;
  551. }
  552. app-study-records-page .current-learning-list button:last-child { border-bottom: 0; }
  553. app-study-records-page .current-learning-list button > i {
  554. display: grid;
  555. width: 36px;
  556. height: 36px;
  557. color: var(--brand-strong);
  558. background: var(--brand-pale);
  559. border-radius: var(--radius-md);
  560. place-items: center;
  561. }
  562. app-study-records-page .current-learning-list button > span { display: flex; min-width: 0; flex-direction: column; gap: 4px; }
  563. app-study-records-page .current-learning-list button strong,
  564. app-study-records-page .current-learning-list button small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  565. app-study-records-page .current-learning-list button strong { font-size: 13px; }
  566. app-study-records-page .current-learning-list button small { color: var(--ink-soft); font-size: 10px; }
  567. app-study-records-page .current-learning-list button:disabled { cursor: not-allowed; opacity: .58; }
  568. app-study-records-page .current-learning-list button.readonly:not(:disabled) { cursor: pointer; }
  569. app-study-records-page .current-learning-list button.readonly:disabled { opacity: .58; }
  570. app-learning-page .node-list > button.readonly { cursor: pointer; }
  571. app-learning-page .readonly-word-header { display: flex; min-height: 70px; align-items: center; justify-content: space-between; padding: 12px 16px; color: white; background: var(--brand-strong); gap: 12px; }
  572. app-learning-page .readonly-word-header > div { display: flex; min-width: 0; flex-direction: column; gap: 4px; }
  573. app-learning-page .readonly-word-header strong { font-size: 18px; }
  574. app-learning-page .readonly-word-header span { color: rgb(255 255 255 / 76%); font-size: 11px; }
  575. app-learning-page .readonly-word-header em { padding: 5px 9px; color: var(--brand-deep); background: var(--brand-pale); border-radius: 999px; font-size: 10px; font-style: normal; font-weight: 750; white-space: nowrap; }
  576. app-learning-page .readonly-word-list { background: white; }
  577. app-learning-page .readonly-word-list article { display: grid; min-height: 72px; grid-template-columns: minmax(120px, .7fr) minmax(0, 1.3fr); align-items: center; padding: 10px 16px; border-bottom: 1px solid var(--line); gap: 14px; }
  578. app-learning-page .readonly-word-list article > div { display: flex; min-width: 0; flex-direction: column; gap: 4px; }
  579. app-learning-page .readonly-word-list strong { overflow: hidden; font-size: 17px; text-overflow: ellipsis; white-space: nowrap; }
  580. app-learning-page .readonly-word-list small { color: var(--ink-soft); font-size: 12px; }
  581. app-learning-page .readonly-word-list p { margin: 0; color: var(--ink); font-size: 14px; line-height: 1.5; }
  582. app-learning-page .readonly-word-note { margin: 12px 14px 0; padding: 10px 12px; color: var(--ink-soft); background: var(--brand-wash); border: 1px solid var(--line); border-radius: var(--radius-md); font-size: 11px; line-height: 1.5; text-align: center; }
  583. app-study-records-page .current-learning-toggle {
  584. display: flex;
  585. width: 100%;
  586. min-height: 44px;
  587. align-items: center;
  588. justify-content: center;
  589. color: var(--brand-strong);
  590. background: var(--brand-pale);
  591. border: 0;
  592. border-top: 1px solid var(--line);
  593. font-size: 12px;
  594. font-weight: 750;
  595. gap: 6px;
  596. }
  597. app-study-records-page .current-learning-toggle lucide-icon { transition: transform .18s ease; transform: rotate(90deg); }
  598. app-study-records-page .current-learning-toggle.expanded lucide-icon { transform: rotate(-90deg); }
  599. app-learning-page .memory-watermark { position: absolute; top: -28px; right: -26px; color: white; opacity: .07; pointer-events: none; }
  600. app-learning-page .memory-copy { min-width: 0; }
  601. app-learning-page .memory-copy strong,
  602. app-learning-page .memory-copy small { display: block; }
  603. app-learning-page .memory-kicker { display: inline-flex; align-items: center; color: rgb(255 255 255 / 72%); font-size: 11px; font-weight: 650; gap: 5px; }
  604. app-learning-page .memory-copy strong { margin-top: 7px; color: white; font-size: 21px; line-height: 1.2; }
  605. app-learning-page .memory-copy small { margin-top: 6px; color: rgb(255 255 255 / 72%); font-size: 10px; }
  606. app-learning-page .memory-score { display: flex; width: 68px; height: 68px; flex: 0 0 68px; align-items: center; justify-content: center; color: white; background: rgb(255 255 255 / 12%); border: 1px solid rgb(255 255 255 / 32%); border-radius: 50%; box-shadow: 0 0 0 5px rgb(255 255 255 / 5%); flex-direction: column; }
  607. app-learning-page .memory-score b { font-size: 18px; line-height: 1; }
  608. app-learning-page .memory-score small { margin-top: 5px; color: rgb(255 255 255 / 70%); font-size: 8px; }
  609. app-learning-page .memory-curve { position: absolute; inset: 0; margin: 0; overflow: hidden; background: rgb(3 45 39 / 12%); pointer-events: none; z-index: 0; }
  610. app-learning-page .memory-curve figcaption { position: absolute; top: 116px; right: 20px; left: 20px; display: flex; align-items: center; justify-content: space-between; color: rgb(255 255 255 / 78%); font-size: 11px; z-index: 2; }
  611. app-learning-page .memory-curve figcaption strong { display: inline-flex; align-items: center; color: #b8ef9f; font-size: 10px; gap: 5px; }
  612. app-learning-page .memory-curve figcaption strong i { width: 6px; height: 6px; background: #8bd47a; border-radius: 50%; box-shadow: 0 0 0 3px rgb(139 212 122 / 14%); }
  613. app-learning-page .memory-curve-chart { position: absolute; top: 136px; right: 8px; bottom: 61px; left: 8px; }
  614. app-learning-page .memory-curve-chart svg { display: block; width: 100%; height: 100%; overflow: visible; }
  615. app-learning-page .memory-curve-chart text { fill: rgb(255 255 255 / 62%); font-family: inherit; font-size: 7px; }
  616. app-learning-page .memory-chart-axis { stroke: rgb(255 255 255 / 24%); stroke-width: 1; vector-effect: non-scaling-stroke; }
  617. app-learning-page .memory-forgetting-line,
  618. app-learning-page .memory-learning-line,
  619. app-learning-page .memory-review-decay { fill: none; stroke-linecap: round; vector-effect: non-scaling-stroke; }
  620. app-learning-page .memory-forgetting-line { stroke: #e58b72; stroke-dasharray: 4 4; stroke-width: 1.7; }
  621. app-learning-page .memory-learning-line { stroke: #8bd47a; stroke-width: 2.7; }
  622. app-learning-page .memory-review-decay { stroke: #ffd084; stroke-width: 1.8; }
  623. app-learning-page .memory-review-lift { stroke: #b8ef9f; stroke-dasharray: 90; stroke-dashoffset: 90; stroke-linecap: round; stroke-width: 2; vector-effect: non-scaling-stroke; animation: memory-review-lift 15s ease-out infinite; animation-delay: var(--pulse-delay); }
  624. app-learning-page .memory-review-dot { fill: #ffad32; stroke: #126c5d; stroke-width: 1.2; }
  625. app-learning-page .memory-reset-dot { fill: #8bd47a; stroke: #126c5d; stroke-width: 1.1; }
  626. app-learning-page .memory-review-ripple { fill: none; stroke: #ffd084; stroke-width: 1.2; opacity: 0; transform-box: fill-box; transform-origin: center; animation: memory-review-ripple 15s ease-out infinite; animation-delay: var(--pulse-delay); }
  627. app-learning-page .memory-review-label { fill: #ffdba0; font-size: 6px; font-weight: 700; }
  628. app-learning-page .memory-line-label { font-size: 6px; font-weight: 700; }
  629. app-learning-page .memory-line-label.forgetting { fill: #f2aa96; }
  630. app-learning-page .memory-line-label.learning { fill: #b8ef9f; }
  631. app-learning-page .memory-day-dot { fill: rgb(255 255 255 / 58%); transform-box: fill-box; transform-origin: center; animation: memory-day-pulse 12s ease-in-out infinite; animation-delay: var(--pulse-delay); }
  632. app-learning-page .memory-day-ripple { fill: none; stroke: #ffd084; stroke-width: .8; opacity: 0; transform-box: fill-box; transform-origin: center; animation: memory-day-ripple 12s ease-out infinite; animation-delay: var(--pulse-delay); }
  633. @keyframes memory-day-pulse { 0%, 9%, 100% { fill: rgb(255 255 255 / 58%); transform: scale(1); } 4.5% { fill: #ffad32; transform: scale(1.8); } }
  634. @keyframes memory-day-ripple { 0%, 100% { opacity: 0; transform: scale(.6); } 3% { opacity: .8; } 10% { opacity: 0; transform: scale(3); } }
  635. @keyframes memory-review-lift { 0%, 100% { opacity: .2; stroke-dashoffset: 90; } 5%, 14% { opacity: 1; stroke-dashoffset: 0; } 22% { opacity: .52; stroke-dashoffset: 0; } }
  636. @keyframes memory-review-ripple { 0%, 100% { opacity: 0; transform: scale(.7); } 5% { opacity: .9; } 15% { opacity: 0; transform: scale(4); } }
  637. @media (prefers-reduced-motion: reduce) {
  638. app-learning-page .memory-day-dot,
  639. app-learning-page .memory-day-ripple,
  640. app-learning-page .memory-review-lift,
  641. app-learning-page .memory-review-ripple { animation: none; }
  642. }
  643. app-study-records-page .ai-reading-feature { margin: 12px 14px 0; overflow: hidden; background: white; border: 1px solid color-mix(in srgb, var(--brand-strong) 34%, var(--line)); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); }
  644. app-study-records-page .ai-reading-visual { position: relative; min-height: 230px; overflow: hidden; background: #116b5a; }
  645. app-study-records-page .ai-reading-visual > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: left center; }
  646. app-study-records-page .ai-reading-copy { display: flex; width: 52%; min-height: 230px; padding: 18px 0 18px 18px; position: relative; z-index: 1; align-items: flex-start; color: white; flex-direction: column; }
  647. app-study-records-page .ai-reading-eyebrow { display: inline-flex; align-items: center; color: #dff8ef; font-size: 11px; font-weight: 700; gap: 6px; }
  648. app-study-records-page .ai-reading-copy h2 { margin: 10px 0 7px; font-size: 23px; line-height: 1.28; letter-spacing: 0; }
  649. app-study-records-page .ai-reading-copy p { width: 185px; margin: 0; color: rgb(255 255 255 / 82%); font-size: 12px; line-height: 1.6; }
  650. app-study-records-page .ai-reading-cta { display: inline-flex; min-height: 44px; margin-top: auto; padding: 0 12px; align-items: center; justify-content: center; color: #14352f; background: var(--accent); border: 0; border-radius: var(--radius-sm); box-shadow: 0 6px 16px rgb(6 47 39 / 24%); font-size: 12px; font-weight: 750; gap: 7px; }
  651. app-study-records-page .ai-reading-cta:disabled { color: rgb(255 255 255 / 72%); background: rgb(255 255 255 / 14%); box-shadow: none; cursor: not-allowed; }
  652. app-study-records-page .ai-reading-flow { display: grid; min-height: 62px; margin: 0; padding: 0 8px; list-style: none; grid-template-columns: repeat(4, minmax(0, 1fr)); }
  653. app-study-records-page .ai-reading-flow li { display: flex; min-width: 0; align-items: center; justify-content: center; position: relative; color: var(--ink-soft); font-size: 10px; flex-direction: column; gap: 4px; }
  654. app-study-records-page .ai-reading-flow li:not(:last-child)::after { width: 1px; height: 24px; position: absolute; top: 19px; right: 0; background: var(--line); content: ''; }
  655. app-study-records-page .ai-reading-flow b { display: grid; width: 20px; height: 20px; color: white; background: var(--brand-strong); border-radius: 50%; font-size: 10px; place-items: center; }
  656. app-study-records-page .ai-reading-flow span { overflow: hidden; max-width: 100%; text-overflow: ellipsis; white-space: nowrap; }
  657. app-learning-page .word-refine-item { background: white; border-bottom: 1px solid var(--line); }
  658. app-learning-page .word-refine-item.selected { background: var(--brand-pale); }
  659. app-learning-page .word-refine-item:last-child { border-bottom: 0; }
  660. app-learning-page .word-refine-main { display: grid; min-height: 72px; align-items: center; padding: 8px 14px; grid-template-columns: 32px minmax(0, 1fr) 34px; gap: 10px; }
  661. app-learning-page .word-select-check { display: grid; width: 32px; height: 32px; padding: 0; color: white; background: white; border: 1px solid var(--line); border-radius: var(--radius-sm); place-items: center; }
  662. app-learning-page .word-select-check[aria-pressed='true'] { background: var(--brand-strong); border-color: var(--brand-strong); }
  663. app-learning-page .word-reveal { display: flex; min-width: 0; min-height: 52px; padding: 5px 0; align-items: flex-start; color: var(--ink); text-align: left; background: transparent; border: 0; flex-direction: column; gap: 5px; }
  664. app-learning-page .word-reveal strong { font-size: 18px; }
  665. app-learning-page .word-reveal small { overflow: hidden; max-width: 100%; color: var(--ink-faint); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
  666. app-learning-page .word-reveal small.revealed { color: var(--ink-soft); font-size: 13px; }
  667. app-learning-page .word-refine-main .audio { display: grid; width: 34px; height: 34px; color: var(--brand-strong); place-items: center; }
  668. app-learning-page .word-assessment { display: grid; padding: 0 14px 12px 56px; grid-template-columns: minmax(0, .85fr) minmax(0, 1.45fr); gap: 7px; }
  669. app-learning-page .word-assessment > span { grid-column: 1 / -1; color: var(--ink-soft); font-size: 10px; }
  670. app-learning-page .word-assessment button { display: inline-flex; min-width: 0; min-height: 38px; padding: 0 9px; align-items: center; justify-content: center; background: white; border: 1px solid var(--line); border-radius: var(--radius-sm); font-size: 11px; font-weight: 650; gap: 5px; }
  671. app-learning-page .word-assessment .known-button { color: var(--brand-strong); }
  672. app-learning-page .word-assessment .unknown-button { color: #9a6407; }
  673. app-learning-page .word-assessment .known-button.active { color: white; background: var(--brand-strong); border-color: var(--brand-strong); }
  674. app-learning-page .word-assessment .unknown-button.active { color: #4d3100; background: var(--accent-soft); border-color: var(--accent); }
  675. @media (hover: hover) { app-study-records-page .ai-reading-cta:not(:disabled):hover { filter: brightness(1.04); transform: translateY(-1px); } }
  676. @media (prefers-reduced-motion: reduce) { app-study-records-page .ai-reading-cta { transition: none; } }
  677. @media (max-width: 360px) { app-study-records-page .ai-reading-feature { margin-inline: 10px; } app-study-records-page .ai-reading-copy { width: 58%; padding-left: 14px; } app-study-records-page .ai-reading-copy h2 { font-size: 21px; } app-study-records-page .ai-reading-copy p { width: 160px; } app-study-records-page .ai-reading-cta { padding-inline: 9px; } }
  678. @media (max-width: 360px) { app-learning-page .word-assessment { padding-left: 14px; } }
  679. @media (min-width: 500px) { app-study-records-page .ai-reading-copy { width: 44%; max-width: 334px; } app-study-records-page .ai-reading-copy p { width: 230px; } }
  680. @media (max-width: 360px) {
  681. :root { --page-gutter: 10px; }
  682. }
  683. /* Compact selectors in technical resource toolbars keep their horizontal layout. */
  684. body .bulk-toolbar > button.xs-dropdown-trigger { flex: 0 0 auto; width: auto; min-width: 130px; min-height: 38px; padding-block: 8px; font-size: 12px; }