@wdyy/skills 0.1.19 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,603 @@
1
+ :root {
2
+ color-scheme: light;
3
+ --bg: #f6f9f6;
4
+ --surface: #ffffff;
5
+ --surface-soft: #ebf7ee;
6
+ --text: #202d23;
7
+ --muted: #6a766d;
8
+ --line: #dce5de;
9
+ --primary: #2b8a3e;
10
+ --primary-strong: #237032;
11
+ --primary-soft: #ebf7ee;
12
+ --secondary: #087f5b;
13
+ --accent: #66a80f;
14
+ --success: #2b8a3e;
15
+ --danger: #c92a2a;
16
+ --warning: #e67700;
17
+ --info: #1971c2;
18
+ --focus: #b2f2bb;
19
+ --shadow: 0 2px 10px color-mix(in srgb, var(--text) 8%, transparent);
20
+ }
21
+
22
+ * {
23
+ box-sizing: border-box;
24
+ }
25
+
26
+ body {
27
+ margin: 0;
28
+ background: var(--bg);
29
+ color: var(--text);
30
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
31
+ font-size: 14px;
32
+ line-height: 1.5;
33
+ }
34
+
35
+ button,
36
+ input,
37
+ select,
38
+ textarea {
39
+ font: inherit;
40
+ }
41
+
42
+ button {
43
+ cursor: pointer;
44
+ }
45
+
46
+ .app-shell {
47
+ min-height: 100vh;
48
+ display: flex;
49
+ flex-direction: column;
50
+ }
51
+
52
+ .topbar {
53
+ display: flex;
54
+ align-items: center;
55
+ justify-content: flex-start;
56
+ gap: 16px;
57
+ min-height: 58px;
58
+ padding: 0 24px;
59
+ background: var(--surface);
60
+ color: var(--text);
61
+ border-bottom: 1px solid var(--line);
62
+ }
63
+
64
+ .brand {
65
+ display: flex;
66
+ align-items: center;
67
+ gap: 10px;
68
+ min-width: 220px;
69
+ }
70
+
71
+ .brand-logo {
72
+ width: 42px;
73
+ height: 42px;
74
+ flex: 0 0 42px;
75
+ object-fit: contain;
76
+ }
77
+
78
+ .brand-copy {
79
+ min-width: 0;
80
+ }
81
+
82
+ .brand h1 {
83
+ margin: 0;
84
+ font-size: 18px;
85
+ font-weight: 700;
86
+ letter-spacing: 0;
87
+ }
88
+
89
+ .brand span {
90
+ display: block;
91
+ color: var(--muted);
92
+ font-size: 13px;
93
+ }
94
+
95
+ .nav-actions {
96
+ display: flex;
97
+ align-items: center;
98
+ gap: 10px;
99
+ flex-wrap: wrap;
100
+ }
101
+
102
+ .nav-actions a,
103
+ .nav-actions button,
104
+ .nav-actions select {
105
+ min-height: 34px;
106
+ border-radius: 6px;
107
+ border: 1px solid var(--line);
108
+ background: var(--surface);
109
+ color: var(--text);
110
+ padding: 0 12px;
111
+ text-decoration: none;
112
+ }
113
+
114
+ .nav-actions a {
115
+ display: inline-flex;
116
+ align-items: center;
117
+ }
118
+
119
+ .nav-actions a:hover,
120
+ .nav-actions button:hover,
121
+ .nav-actions select:hover {
122
+ border-color: var(--primary);
123
+ background: var(--primary-soft);
124
+ color: var(--primary);
125
+ }
126
+
127
+ .nav-actions select option {
128
+ color: var(--text);
129
+ }
130
+
131
+ .page {
132
+ flex: 1;
133
+ padding: 18px 24px 24px;
134
+ }
135
+
136
+ .tabs {
137
+ display: flex;
138
+ gap: 4px;
139
+ border-bottom: 1px solid var(--line);
140
+ margin-bottom: 16px;
141
+ }
142
+
143
+ .tab-button {
144
+ min-height: 40px;
145
+ border: 0;
146
+ border-bottom: 3px solid transparent;
147
+ background: transparent;
148
+ color: var(--muted);
149
+ padding: 0 16px;
150
+ }
151
+
152
+ .tab-button.active {
153
+ color: var(--primary);
154
+ border-color: var(--primary);
155
+ font-weight: 700;
156
+ }
157
+
158
+ .layout-grid {
159
+ display: grid;
160
+ grid-template-columns: minmax(280px, 360px) 1fr;
161
+ gap: 16px;
162
+ align-items: start;
163
+ }
164
+
165
+ .section,
166
+ .panel {
167
+ min-width: 0;
168
+ background: var(--surface);
169
+ border: 1px solid var(--line);
170
+ border-radius: 8px;
171
+ box-shadow: var(--shadow);
172
+ }
173
+
174
+ .section {
175
+ padding: 18px;
176
+ }
177
+
178
+ .panel-header,
179
+ .section-header {
180
+ display: flex;
181
+ align-items: center;
182
+ justify-content: space-between;
183
+ gap: 12px;
184
+ margin-bottom: 14px;
185
+ }
186
+
187
+ .section-header.actions-only {
188
+ justify-content: flex-end;
189
+ }
190
+
191
+ .panel-header {
192
+ padding: 14px 16px;
193
+ border-bottom: 1px solid var(--line);
194
+ margin-bottom: 0;
195
+ }
196
+
197
+ .panel-body {
198
+ padding: 16px;
199
+ }
200
+
201
+ h2,
202
+ h3 {
203
+ margin: 0;
204
+ letter-spacing: 0;
205
+ }
206
+
207
+ h2 {
208
+ font-size: 18px;
209
+ }
210
+
211
+ h3 {
212
+ font-size: 15px;
213
+ }
214
+
215
+ .muted {
216
+ color: var(--muted);
217
+ }
218
+
219
+ .form-grid {
220
+ display: grid;
221
+ grid-template-columns: repeat(3, minmax(180px, 1fr));
222
+ gap: 12px 14px;
223
+ }
224
+
225
+ .form-grid.two {
226
+ grid-template-columns: repeat(2, minmax(180px, 1fr));
227
+ }
228
+
229
+ .field {
230
+ display: flex;
231
+ flex-direction: column;
232
+ gap: 6px;
233
+ }
234
+
235
+ .field label {
236
+ color: var(--text);
237
+ font-weight: 600;
238
+ }
239
+
240
+ .field input,
241
+ .field select,
242
+ .field textarea,
243
+ .search-row input,
244
+ .search-row select {
245
+ width: 100%;
246
+ min-height: 38px;
247
+ border: 1px solid var(--line);
248
+ border-radius: 6px;
249
+ background: var(--surface);
250
+ color: var(--text);
251
+ padding: 7px 10px;
252
+ }
253
+
254
+ .field input:focus,
255
+ .field select:focus,
256
+ .field textarea:focus,
257
+ .search-row input:focus,
258
+ .search-row select:focus,
259
+ .nav-actions a:focus-visible,
260
+ .nav-actions button:focus-visible,
261
+ .nav-actions select:focus-visible,
262
+ .tab-button:focus-visible,
263
+ .btn:focus-visible,
264
+ .list-button:focus-visible,
265
+ .record-template-button:focus-visible {
266
+ outline: 3px solid var(--focus);
267
+ outline-offset: 2px;
268
+ }
269
+
270
+ .field textarea {
271
+ min-height: 78px;
272
+ resize: vertical;
273
+ }
274
+
275
+ .actions {
276
+ display: flex;
277
+ align-items: center;
278
+ gap: 10px;
279
+ flex-wrap: wrap;
280
+ margin-top: 16px;
281
+ }
282
+
283
+ .btn {
284
+ min-height: 38px;
285
+ border-radius: 6px;
286
+ border: 1px solid var(--line);
287
+ background: var(--surface);
288
+ color: var(--text);
289
+ padding: 0 14px;
290
+ font-weight: 600;
291
+ }
292
+
293
+ .btn.primary {
294
+ border-color: var(--primary);
295
+ background: var(--primary);
296
+ color: var(--surface);
297
+ }
298
+
299
+ .btn.primary:hover {
300
+ background: var(--primary-strong);
301
+ }
302
+
303
+ .btn.danger {
304
+ border-color: #ffd5d5;
305
+ color: var(--danger);
306
+ }
307
+
308
+ .btn.ghost {
309
+ background: transparent;
310
+ }
311
+
312
+ .search-row {
313
+ display: grid;
314
+ grid-template-columns: 1fr auto;
315
+ gap: 10px;
316
+ align-items: end;
317
+ }
318
+
319
+ .data-table {
320
+ width: 100%;
321
+ border-collapse: collapse;
322
+ background: var(--surface);
323
+ }
324
+
325
+ .data-table th,
326
+ .data-table td {
327
+ border-bottom: 1px solid var(--line);
328
+ padding: 10px 10px;
329
+ text-align: left;
330
+ vertical-align: top;
331
+ }
332
+
333
+ .data-table th {
334
+ color: var(--muted);
335
+ background: var(--surface-soft);
336
+ font-weight: 700;
337
+ }
338
+
339
+ .data-table tr:hover td {
340
+ background: var(--primary-soft);
341
+ }
342
+
343
+ .status {
344
+ display: inline-flex;
345
+ align-items: center;
346
+ min-height: 24px;
347
+ border-radius: 999px;
348
+ padding: 0 9px;
349
+ font-size: 12px;
350
+ font-weight: 700;
351
+ border: 1px solid var(--line);
352
+ background: var(--surface);
353
+ }
354
+
355
+ .status.success {
356
+ color: var(--success);
357
+ background: #e9f7ed;
358
+ }
359
+
360
+ .status.warning {
361
+ color: var(--warning);
362
+ background: #fff4e6;
363
+ }
364
+
365
+ .status.danger {
366
+ color: var(--danger);
367
+ background: #fff0f0;
368
+ }
369
+
370
+ .message {
371
+ min-height: 38px;
372
+ display: flex;
373
+ align-items: center;
374
+ border: 1px solid var(--line);
375
+ border-radius: 6px;
376
+ background: var(--surface);
377
+ color: var(--muted);
378
+ padding: 8px 10px;
379
+ }
380
+
381
+ .message.success {
382
+ color: var(--success);
383
+ background: #e9f7ed;
384
+ }
385
+
386
+ .message.error {
387
+ color: var(--danger);
388
+ background: #fff0f0;
389
+ }
390
+
391
+ .summary-strip {
392
+ display: grid;
393
+ grid-template-columns: repeat(4, minmax(120px, 1fr));
394
+ gap: 12px;
395
+ margin-bottom: 16px;
396
+ }
397
+
398
+ .metric {
399
+ background: var(--surface);
400
+ border: 1px solid var(--line);
401
+ border-radius: 8px;
402
+ padding: 14px;
403
+ }
404
+
405
+ .metric strong {
406
+ display: block;
407
+ font-size: 22px;
408
+ line-height: 1.1;
409
+ }
410
+
411
+ .metric span {
412
+ color: var(--muted);
413
+ font-size: 13px;
414
+ }
415
+
416
+ .patient-header {
417
+ display: grid;
418
+ grid-template-columns: repeat(6, minmax(100px, 1fr));
419
+ gap: 10px;
420
+ margin-bottom: 16px;
421
+ background: var(--surface);
422
+ border: 1px solid var(--line);
423
+ border-radius: 8px;
424
+ padding: 12px;
425
+ }
426
+
427
+ .info-item span {
428
+ display: block;
429
+ color: var(--muted);
430
+ font-size: 12px;
431
+ }
432
+
433
+ .info-item strong {
434
+ display: block;
435
+ margin-top: 2px;
436
+ }
437
+
438
+ .list {
439
+ display: flex;
440
+ flex-direction: column;
441
+ gap: 8px;
442
+ }
443
+
444
+ .list-button {
445
+ width: 100%;
446
+ border: 1px solid var(--line);
447
+ border-radius: 8px;
448
+ background: var(--surface);
449
+ padding: 10px;
450
+ text-align: left;
451
+ }
452
+
453
+ .list-button.active {
454
+ border-color: var(--primary);
455
+ background: var(--primary-soft);
456
+ }
457
+
458
+ .list-button strong,
459
+ .list-button span {
460
+ display: block;
461
+ }
462
+
463
+ .list-button span {
464
+ color: var(--muted);
465
+ margin-top: 2px;
466
+ }
467
+
468
+ .patient-queue-line {
469
+ overflow: hidden;
470
+ text-overflow: ellipsis;
471
+ white-space: nowrap;
472
+ }
473
+
474
+ .empty {
475
+ border: 1px dashed var(--line);
476
+ border-radius: 8px;
477
+ background: var(--surface-soft);
478
+ color: var(--muted);
479
+ padding: 20px;
480
+ text-align: center;
481
+ }
482
+
483
+ .record-layout {
484
+ display: grid;
485
+ grid-template-columns: 240px minmax(0, 1fr);
486
+ gap: 16px;
487
+ align-items: start;
488
+ }
489
+
490
+ .record-sidebar,
491
+ .record-editor-panel {
492
+ border: 1px solid var(--line);
493
+ border-radius: 8px;
494
+ background: var(--surface);
495
+ padding: 16px;
496
+ }
497
+
498
+ .record-template-list {
499
+ display: grid;
500
+ gap: 10px;
501
+ }
502
+
503
+ .record-template-button {
504
+ width: 100%;
505
+ border: 1px solid var(--line);
506
+ border-radius: 8px;
507
+ background: var(--surface);
508
+ color: var(--text);
509
+ padding: 12px 14px;
510
+ text-align: left;
511
+ font-size: 15px;
512
+ }
513
+
514
+ .record-template-button.active {
515
+ border-color: var(--primary);
516
+ background: var(--primary-soft);
517
+ color: var(--primary);
518
+ font-weight: 600;
519
+ }
520
+
521
+ .record-editor {
522
+ width: 100%;
523
+ min-height: 320px;
524
+ border: 1px solid var(--line);
525
+ border-radius: 8px;
526
+ background: var(--surface);
527
+ color: var(--text);
528
+ padding: 14px 16px;
529
+ resize: vertical;
530
+ font: inherit;
531
+ line-height: 1.7;
532
+ }
533
+
534
+ @media (max-width: 900px) {
535
+ .record-layout {
536
+ grid-template-columns: 1fr;
537
+ }
538
+ }
539
+
540
+ .modal-backdrop {
541
+ position: fixed;
542
+ inset: 0;
543
+ display: none;
544
+ align-items: center;
545
+ justify-content: center;
546
+ background: color-mix(in srgb, var(--text) 42%, transparent);
547
+ padding: 20px;
548
+ z-index: 10;
549
+ }
550
+
551
+ .modal-backdrop.open {
552
+ display: flex;
553
+ }
554
+
555
+ .modal {
556
+ width: min(520px, 100%);
557
+ background: var(--surface);
558
+ border-radius: 8px;
559
+ border: 1px solid var(--line);
560
+ box-shadow: 0 16px 40px color-mix(in srgb, var(--text) 20%, transparent);
561
+ padding: 18px;
562
+ }
563
+
564
+ .modal h2 {
565
+ margin-bottom: 8px;
566
+ }
567
+
568
+ .modal p {
569
+ margin: 0;
570
+ color: var(--muted);
571
+ }
572
+
573
+ @media (max-width: 980px) {
574
+ .topbar {
575
+ align-items: flex-start;
576
+ flex-direction: column;
577
+ padding: 12px 16px;
578
+ }
579
+
580
+ .page {
581
+ padding: 14px 16px 20px;
582
+ }
583
+
584
+ .brand {
585
+ min-width: 0;
586
+ }
587
+
588
+ .layout-grid,
589
+ .form-grid,
590
+ .form-grid.two,
591
+ .summary-strip,
592
+ .patient-header {
593
+ grid-template-columns: 1fr;
594
+ }
595
+
596
+ .tabs {
597
+ overflow-x: auto;
598
+ }
599
+
600
+ .tab-button {
601
+ flex: 0 0 auto;
602
+ }
603
+ }
@@ -0,0 +1,100 @@
1
+ # wdyy-ui 设计规范
2
+
3
+ ## 1. 设计定位
4
+
5
+ 面向医院工作人员的高频生产系统。视觉关键词是清新、生命、专业、可信、低疲劳和高可读性。品牌色只用于关键操作、当前状态和必要强调,页面主体保持白色与浅绿色背景。
6
+
7
+ ## 2. 唯一资源
8
+
9
+ - 共享样式:`../assets/template/styles.css`
10
+ - 医院 Logo:`../assets/template/logo.png`
11
+ - Logo 不得重新绘制、变色、拉伸或替换为文字占位符。
12
+ - 页面与浏览器页签统一使用同一个 Logo 文件。
13
+
14
+ ## 3. 颜色 token
15
+
16
+ | 角色 | CSS 变量 | 色值 | 用途 |
17
+ |---|---|---|---|
18
+ | 页面背景 | `--bg` | `#F6F9F6` | 页面底色 |
19
+ | 表面 | `--surface` | `#FFFFFF` | 顶栏、卡片、输入框、按钮 |
20
+ | 主色 | `--primary` | `#2B8A3E` | 主按钮、当前标签、关键强调 |
21
+ | 深主色 | `--primary-strong` | `#237032` | 主按钮悬停 |
22
+ | 浅主色 | `--primary-soft` | `#EBF7EE` | 选中、悬停、表头和空状态 |
23
+ | 辅助青绿 | `--secondary` | `#087F5B` | 必要的次级品牌强调 |
24
+ | 生命绿 | `--accent` | `#66A80F` | 少量辅助强调 |
25
+ | 正文 | `--text` | `#202D23` | 标题和正文 |
26
+ | 次要文字 | `--muted` | `#6A766D` | 提示、说明和元数据 |
27
+ | 边框 | `--line` | `#DCE5DE` | 控件、卡片和分隔线 |
28
+ | 焦点 | `--focus` | `#B2F2BB` | 键盘焦点环 |
29
+
30
+ 固定状态色:
31
+
32
+ | 状态 | 前景 | 浅背景 |
33
+ |---|---|---|
34
+ | 成功 | `#2B8A3E` | `#E9F7ED` |
35
+ | 警告 | `#E67700` | `#FFF4E6` |
36
+ | 危险 | `#C92A2A` | `#FFF0F0` |
37
+ | 信息 | `#1971C2` | 使用白色或按需求提供的浅信息背景 |
38
+
39
+ 当前设计没有侧边栏,不使用 `#214F2C`。新增颜色前必须说明角色和使用范围并取得确认,不能用近似颜色替换既有 token。
40
+
41
+ ## 4. 顶栏与品牌
42
+
43
+ ```text
44
+ ┌──────────────────────────────────────────────────────────────┐
45
+ │ [42px Logo] 数智医院 HIS [系统选择] [主页] [菜单] [菜单] │
46
+ │ 当前系统名称 │
47
+ └──────────────────────────────────────────────────────────────┘
48
+ ```
49
+
50
+ - 顶栏最小高度 58px,左右内边距 24px,背景为 `--surface`,底部使用 `--line` 边框。
51
+ - 品牌区域最小宽度 220px;Logo 与文字间距 10px。
52
+ - 导航组紧跟品牌区域,使用 `justify-content:flex-start`,组间距 16px,按钮间距 10px。
53
+ - 导航控件最小高度 34px,圆角 6px,水平内边距 12px。
54
+ - `<a>` 必须使用 `inline-flex` 和 `align-items:center`,确保文字垂直居中。
55
+ - 悬停时使用 `--primary-soft` 背景、`--primary` 边框和文字。
56
+
57
+ ## 5. 页面布局模式
58
+
59
+ ### 患者管理
60
+
61
+ - 顶部使用 4 列摘要指标。
62
+ - 操作入口采用横向标签页。
63
+ - 建档表单桌面端使用 3 列网格;挂号和结算可使用左右双面板。
64
+ - 结算明细使用整宽表格。
65
+
66
+ 参考:`../assets/template/common-business.html`
67
+
68
+ ### 药事管理
69
+
70
+ - 主流程第一层为“科室列表 + 患者检索”的左右布局。
71
+ - 左侧宽度使用 `minmax(280px,360px)`;右侧承载检索和患者列表。
72
+ - 第二层使用整宽药品明细表,主操作位于标题区域右侧。
73
+
74
+ 参考:`../assets/template/pharmacy-management.html`
75
+
76
+ ### 医生工作站
77
+
78
+ - 顶部先展示患者摘要信息条。
79
+ - 主体使用“患者队列 + 临床工作区”的左右布局。
80
+ - 临床工作区使用横向标签页承载医嘱、病历、诊断、检验、检查和费用等模块。
81
+
82
+ 参考:`../assets/template/clinical-workstation.html`
83
+
84
+ ## 6. 组件规则
85
+
86
+ - 卡片与面板:白色背景、`--line` 边框、8px 圆角、轻量阴影。
87
+ - 主按钮:主色背景、白色文字;悬停使用深主色。
88
+ - 普通按钮:白色背景、标准边框;幽灵按钮使用透明背景。
89
+ - 表格:表头使用浅主色背景,单元格用标准边框分隔,行悬停使用浅主色。
90
+ - 输入控件:最小高度 38px,6px 圆角,必须有可见标签或可访问名称。
91
+ - 消息和状态:同时显示文字;成功、警告、危险使用固定语义色。
92
+ - 空状态:虚线边框、浅色背景、明确的下一步提示。
93
+
94
+ ## 7. 响应式与可访问性
95
+
96
+ - 980px 以下:顶栏纵向排列,品牌和导航左边缘均为 16px;网格改为单列。
97
+ - 900px 以下:病历侧栏和编辑区改为单列。
98
+ - 标签页可横向滚动,但页面本身不得横向滚动。
99
+ - 所有可操作控件必须显示键盘焦点环;颜色不能成为唯一状态信号。
100
+ - 页面语言使用 `zh-CN`,标题、标签和按钮名称应与业务动作一致。