audex 1.0.7a3__py3-none-any.whl

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.
Files changed (192) hide show
  1. audex/__init__.py +9 -0
  2. audex/__main__.py +7 -0
  3. audex/cli/__init__.py +189 -0
  4. audex/cli/apis/__init__.py +12 -0
  5. audex/cli/apis/init/__init__.py +34 -0
  6. audex/cli/apis/init/gencfg.py +130 -0
  7. audex/cli/apis/init/setup.py +330 -0
  8. audex/cli/apis/init/vprgroup.py +125 -0
  9. audex/cli/apis/serve.py +141 -0
  10. audex/cli/args.py +356 -0
  11. audex/cli/exceptions.py +44 -0
  12. audex/cli/helper/__init__.py +0 -0
  13. audex/cli/helper/ansi.py +193 -0
  14. audex/cli/helper/display.py +288 -0
  15. audex/config/__init__.py +64 -0
  16. audex/config/core/__init__.py +30 -0
  17. audex/config/core/app.py +29 -0
  18. audex/config/core/audio.py +45 -0
  19. audex/config/core/logging.py +163 -0
  20. audex/config/core/session.py +11 -0
  21. audex/config/helper/__init__.py +1 -0
  22. audex/config/helper/client/__init__.py +1 -0
  23. audex/config/helper/client/http.py +28 -0
  24. audex/config/helper/client/websocket.py +21 -0
  25. audex/config/helper/provider/__init__.py +1 -0
  26. audex/config/helper/provider/dashscope.py +13 -0
  27. audex/config/helper/provider/unisound.py +18 -0
  28. audex/config/helper/provider/xfyun.py +23 -0
  29. audex/config/infrastructure/__init__.py +31 -0
  30. audex/config/infrastructure/cache.py +51 -0
  31. audex/config/infrastructure/database.py +48 -0
  32. audex/config/infrastructure/recorder.py +32 -0
  33. audex/config/infrastructure/store.py +19 -0
  34. audex/config/provider/__init__.py +18 -0
  35. audex/config/provider/transcription.py +109 -0
  36. audex/config/provider/vpr.py +99 -0
  37. audex/container.py +40 -0
  38. audex/entity/__init__.py +468 -0
  39. audex/entity/doctor.py +109 -0
  40. audex/entity/doctor.pyi +51 -0
  41. audex/entity/fields.py +401 -0
  42. audex/entity/segment.py +115 -0
  43. audex/entity/segment.pyi +38 -0
  44. audex/entity/session.py +133 -0
  45. audex/entity/session.pyi +47 -0
  46. audex/entity/utterance.py +142 -0
  47. audex/entity/utterance.pyi +48 -0
  48. audex/entity/vp.py +68 -0
  49. audex/entity/vp.pyi +35 -0
  50. audex/exceptions.py +157 -0
  51. audex/filters/__init__.py +692 -0
  52. audex/filters/generated/__init__.py +21 -0
  53. audex/filters/generated/doctor.py +987 -0
  54. audex/filters/generated/segment.py +723 -0
  55. audex/filters/generated/session.py +978 -0
  56. audex/filters/generated/utterance.py +939 -0
  57. audex/filters/generated/vp.py +815 -0
  58. audex/helper/__init__.py +1 -0
  59. audex/helper/hash.py +33 -0
  60. audex/helper/mixin.py +65 -0
  61. audex/helper/net.py +19 -0
  62. audex/helper/settings/__init__.py +830 -0
  63. audex/helper/settings/fields.py +317 -0
  64. audex/helper/stream.py +153 -0
  65. audex/injectors/__init__.py +1 -0
  66. audex/injectors/config.py +12 -0
  67. audex/injectors/lifespan.py +7 -0
  68. audex/lib/__init__.py +1 -0
  69. audex/lib/cache/__init__.py +383 -0
  70. audex/lib/cache/inmemory.py +513 -0
  71. audex/lib/database/__init__.py +83 -0
  72. audex/lib/database/sqlite.py +406 -0
  73. audex/lib/exporter.py +189 -0
  74. audex/lib/injectors/__init__.py +1 -0
  75. audex/lib/injectors/cache.py +25 -0
  76. audex/lib/injectors/container.py +47 -0
  77. audex/lib/injectors/exporter.py +26 -0
  78. audex/lib/injectors/recorder.py +33 -0
  79. audex/lib/injectors/server.py +17 -0
  80. audex/lib/injectors/session.py +18 -0
  81. audex/lib/injectors/sqlite.py +24 -0
  82. audex/lib/injectors/store.py +13 -0
  83. audex/lib/injectors/transcription.py +42 -0
  84. audex/lib/injectors/usb.py +12 -0
  85. audex/lib/injectors/vpr.py +65 -0
  86. audex/lib/injectors/wifi.py +7 -0
  87. audex/lib/recorder.py +844 -0
  88. audex/lib/repos/__init__.py +149 -0
  89. audex/lib/repos/container.py +23 -0
  90. audex/lib/repos/database/__init__.py +1 -0
  91. audex/lib/repos/database/sqlite.py +672 -0
  92. audex/lib/repos/decorators.py +74 -0
  93. audex/lib/repos/doctor.py +286 -0
  94. audex/lib/repos/segment.py +302 -0
  95. audex/lib/repos/session.py +285 -0
  96. audex/lib/repos/tables/__init__.py +70 -0
  97. audex/lib/repos/tables/doctor.py +137 -0
  98. audex/lib/repos/tables/segment.py +113 -0
  99. audex/lib/repos/tables/session.py +140 -0
  100. audex/lib/repos/tables/utterance.py +131 -0
  101. audex/lib/repos/tables/vp.py +102 -0
  102. audex/lib/repos/utterance.py +288 -0
  103. audex/lib/repos/vp.py +286 -0
  104. audex/lib/restful.py +251 -0
  105. audex/lib/server/__init__.py +97 -0
  106. audex/lib/server/auth.py +98 -0
  107. audex/lib/server/handlers.py +248 -0
  108. audex/lib/server/templates/index.html.j2 +226 -0
  109. audex/lib/server/templates/login.html.j2 +111 -0
  110. audex/lib/server/templates/static/script.js +68 -0
  111. audex/lib/server/templates/static/style.css +579 -0
  112. audex/lib/server/types.py +123 -0
  113. audex/lib/session.py +503 -0
  114. audex/lib/store/__init__.py +238 -0
  115. audex/lib/store/localfile.py +411 -0
  116. audex/lib/transcription/__init__.py +33 -0
  117. audex/lib/transcription/dashscope.py +525 -0
  118. audex/lib/transcription/events.py +62 -0
  119. audex/lib/usb.py +554 -0
  120. audex/lib/vpr/__init__.py +38 -0
  121. audex/lib/vpr/unisound/__init__.py +185 -0
  122. audex/lib/vpr/unisound/types.py +469 -0
  123. audex/lib/vpr/xfyun/__init__.py +483 -0
  124. audex/lib/vpr/xfyun/types.py +679 -0
  125. audex/lib/websocket/__init__.py +8 -0
  126. audex/lib/websocket/connection.py +485 -0
  127. audex/lib/websocket/pool.py +991 -0
  128. audex/lib/wifi.py +1146 -0
  129. audex/lifespan.py +75 -0
  130. audex/service/__init__.py +27 -0
  131. audex/service/decorators.py +73 -0
  132. audex/service/doctor/__init__.py +652 -0
  133. audex/service/doctor/const.py +36 -0
  134. audex/service/doctor/exceptions.py +96 -0
  135. audex/service/doctor/types.py +54 -0
  136. audex/service/export/__init__.py +236 -0
  137. audex/service/export/const.py +17 -0
  138. audex/service/export/exceptions.py +34 -0
  139. audex/service/export/types.py +21 -0
  140. audex/service/injectors/__init__.py +1 -0
  141. audex/service/injectors/container.py +53 -0
  142. audex/service/injectors/doctor.py +34 -0
  143. audex/service/injectors/export.py +27 -0
  144. audex/service/injectors/session.py +49 -0
  145. audex/service/session/__init__.py +754 -0
  146. audex/service/session/const.py +34 -0
  147. audex/service/session/exceptions.py +67 -0
  148. audex/service/session/types.py +91 -0
  149. audex/types.py +39 -0
  150. audex/utils.py +287 -0
  151. audex/valueobj/__init__.py +81 -0
  152. audex/valueobj/common/__init__.py +1 -0
  153. audex/valueobj/common/auth.py +84 -0
  154. audex/valueobj/common/email.py +16 -0
  155. audex/valueobj/common/ops.py +22 -0
  156. audex/valueobj/common/phone.py +84 -0
  157. audex/valueobj/common/version.py +72 -0
  158. audex/valueobj/session.py +19 -0
  159. audex/valueobj/utterance.py +15 -0
  160. audex/view/__init__.py +51 -0
  161. audex/view/container.py +17 -0
  162. audex/view/decorators.py +303 -0
  163. audex/view/pages/__init__.py +1 -0
  164. audex/view/pages/dashboard/__init__.py +286 -0
  165. audex/view/pages/dashboard/wifi.py +407 -0
  166. audex/view/pages/login.py +110 -0
  167. audex/view/pages/recording.py +348 -0
  168. audex/view/pages/register.py +202 -0
  169. audex/view/pages/sessions/__init__.py +196 -0
  170. audex/view/pages/sessions/details.py +224 -0
  171. audex/view/pages/sessions/export.py +443 -0
  172. audex/view/pages/settings.py +374 -0
  173. audex/view/pages/voiceprint/__init__.py +1 -0
  174. audex/view/pages/voiceprint/enroll.py +195 -0
  175. audex/view/pages/voiceprint/update.py +195 -0
  176. audex/view/static/css/dashboard.css +452 -0
  177. audex/view/static/css/glass.css +22 -0
  178. audex/view/static/css/global.css +541 -0
  179. audex/view/static/css/login.css +386 -0
  180. audex/view/static/css/recording.css +439 -0
  181. audex/view/static/css/register.css +293 -0
  182. audex/view/static/css/sessions/styles.css +501 -0
  183. audex/view/static/css/settings.css +186 -0
  184. audex/view/static/css/voiceprint/enroll.css +43 -0
  185. audex/view/static/css/voiceprint/styles.css +209 -0
  186. audex/view/static/css/voiceprint/update.css +44 -0
  187. audex/view/static/images/logo.svg +95 -0
  188. audex/view/static/js/recording.js +42 -0
  189. audex-1.0.7a3.dist-info/METADATA +361 -0
  190. audex-1.0.7a3.dist-info/RECORD +192 -0
  191. audex-1.0.7a3.dist-info/WHEEL +4 -0
  192. audex-1.0.7a3.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,501 @@
1
+ @import "../global.css";
2
+ @import "../glass.css";
3
+
4
+ /* ==================== Gradient Text ==================== */
5
+ .gradient-text {
6
+ background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab, #f093fb, #4facfe);
7
+ background-size: 400% 400%;
8
+ -webkit-background-clip: text;
9
+ -webkit-text-fill-color: transparent;
10
+ background-clip: text;
11
+ animation: gradient-shift 8s ease infinite;
12
+ font-weight: 700;
13
+ }
14
+
15
+ @keyframes gradient-shift {
16
+ 0% {
17
+ background-position: 0 50%;
18
+ }
19
+ 50% {
20
+ background-position: 100% 50%;
21
+ }
22
+ 100% {
23
+ background-position: 0 50%;
24
+ }
25
+ }
26
+
27
+ /* ==================== Header ==================== */
28
+ .header-btn {
29
+ border-radius: 12px !important;
30
+ min-width: 100px !important;
31
+ height: 40px !important;
32
+ font-size: 14px !important;
33
+ font-weight: 500 !important;
34
+ transition: all 0.2s ease !important;
35
+ }
36
+
37
+ .header-btn:hover {
38
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15) !important;
39
+ transform: translateY(-1px);
40
+ }
41
+
42
+ .export-btn {
43
+ background: white !important;
44
+ color: #374151 !important;
45
+ border: 1px solid #d1d5db !important;
46
+ }
47
+
48
+ .export-btn:hover {
49
+ border-color: #9ca3af !important;
50
+ }
51
+
52
+ /* ==================== Background ==================== */
53
+
54
+ .bg-white {
55
+ background: #ffffff !important;
56
+ padding: 40px 60px !important;
57
+ margin: 0 !important;
58
+ box-sizing: border-box !important;
59
+ overflow: visible !important;
60
+ min-height: auto !important;
61
+ height: auto !important;
62
+ }
63
+
64
+ /* ==================== Cards ==================== */
65
+
66
+ .glass-card {
67
+ border-radius: 28px !important;
68
+ background: transparent !important;
69
+ box-shadow: none !important;
70
+ border: 1px solid rgba(0, 0, 0, 0.08) !important;
71
+ }
72
+
73
+ .super-card {
74
+ border-radius: 28px !important;
75
+ background: rgba(255, 255, 255, 0.9) !important;
76
+ backdrop-filter: blur(20px) !important;
77
+ -webkit-backdrop-filter: blur(20px) !important;
78
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06), 0 2px 8px rgba(0, 0, 0, 0.04) !important;
79
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
80
+ min-height: 220px !important;
81
+ display: flex !important;
82
+ flex-direction: column !important;
83
+ }
84
+
85
+ .super-card:hover {
86
+ transform: translateY(-6px) scale(1.02);
87
+ box-shadow: 0 12px 28px rgba(0, 0, 0, 0.12), 0 6px 14px rgba(0, 0, 0, 0.08) !important;
88
+ }
89
+
90
+ .super-card:active {
91
+ transform: translateY(-3px) scale(1.01);
92
+ transition: all 0.1s cubic-bezier(0.4, 0, 0.2, 1) !important;
93
+ }
94
+
95
+ .super-card-active {
96
+ border: 2px solid #c10015 !important;
97
+ box-shadow: 0 4px 20px rgba(193, 0, 21, 0.15) !important;
98
+ }
99
+
100
+ .super-card-active:hover {
101
+ box-shadow: 0 12px 32px rgba(193, 0, 21, 0.25) !important;
102
+ }
103
+
104
+ /* ==================== Buttons ==================== */
105
+
106
+ .press-button:active {
107
+ transform: scale(0.95);
108
+ }
109
+
110
+ .rotate-icon {
111
+ transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
112
+ }
113
+
114
+ .super-card:hover .rotate-icon {
115
+ transform: rotate(8deg) scale(1.15);
116
+ }
117
+
118
+ .action-btn {
119
+ transition: all 0.2s ease !important;
120
+ border-radius: 12px !important;
121
+ min-width: 70px !important;
122
+ height: 32px !important;
123
+ padding: 0 12px !important;
124
+ font-size: 13px !important;
125
+ font-weight: 500 !important;
126
+ }
127
+
128
+ .action-btn:hover {
129
+ transform: translateY(-1px);
130
+ box-shadow: 0 3px 8px rgba(0, 0, 0, 0.12);
131
+ }
132
+
133
+ .btn-primary {
134
+ background: #3b82f6 !important;
135
+ color: white !important;
136
+ border: none !important;
137
+ }
138
+
139
+ .btn-secondary {
140
+ background: white !important;
141
+ color: #374151 !important;
142
+ border: 1px solid #d1d5db !important;
143
+ }
144
+
145
+ .btn-secondary:hover {
146
+ border-color: #9ca3af !important;
147
+ }
148
+
149
+ .btn-delete {
150
+ background: white !important;
151
+ border: none !important;
152
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1) !important;
153
+ color: #6b7280 !important;
154
+ border-radius: 50% !important;
155
+ width: 36px !important;
156
+ height: 36px !important;
157
+ min-width: 36px !important;
158
+ transition: all 0.2s ease !important;
159
+ }
160
+
161
+ .btn-delete:hover {
162
+ background: #f3f4f6 !important;
163
+ color: #374151 !important;
164
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15) !important;
165
+ }
166
+
167
+ .btn-delete .q-btn__content {
168
+ min-width: unset !important;
169
+ width: 100% !important;
170
+ padding: 0 !important;
171
+ }
172
+
173
+ .action-button {
174
+ border-radius: 12px !important;
175
+ font-size: 16px !important;
176
+ font-weight: 500 !important;
177
+ letter-spacing: 0.02em !important;
178
+ transition: all 0.2s ease !important;
179
+ min-width: 120px !important;
180
+ }
181
+
182
+ .action-button:hover {
183
+ transform: translateY(-2px);
184
+ }
185
+
186
+ .action-button:active {
187
+ transform: translateY(0);
188
+ }
189
+
190
+ .button-layout {
191
+ display: flex !important;
192
+ justify-content: space-between !important;
193
+ align-items: center !important;
194
+ width: 100% !important;
195
+ margin-top: auto !important;
196
+ gap: 16px !important;
197
+ }
198
+
199
+ .right-buttons {
200
+ display: flex !important;
201
+ gap: 12px !important;
202
+ }
203
+
204
+ /* ==================== Status Badges ==================== */
205
+
206
+ .status-badge {
207
+ padding: 4px 8px;
208
+ border-radius: 12px;
209
+ font-size: 0.75rem;
210
+ font-weight: 500;
211
+ display: inline-block;
212
+ }
213
+
214
+ .status-completed {
215
+ background: #dcfce7;
216
+ color: #166534;
217
+ }
218
+
219
+ .status-in-progress {
220
+ background: #fef3c7;
221
+ color: #92400e;
222
+ }
223
+
224
+ .status-cancelled {
225
+ background: #fee2e2;
226
+ color: #991b1b;
227
+ }
228
+
229
+ /* ==================== Empty State ==================== */
230
+
231
+ .empty-state {
232
+ background: transparent;
233
+ border: none;
234
+ padding: 80px 40px;
235
+ text-align: center;
236
+ display: flex;
237
+ flex-direction: column;
238
+ align-items: center;
239
+ }
240
+
241
+ .empty-content {
242
+ display: flex !important;
243
+ flex-direction: column !important;
244
+ align-items: center !important;
245
+ justify-content: center !important;
246
+ text-align: center !important;
247
+ width: 100% !important;
248
+ height: 100% !important;
249
+ }
250
+
251
+ .empty-state .q-btn {
252
+ border-radius: 12px !important;
253
+ font-size: 16px !important;
254
+ font-weight: 500 !important;
255
+ letter-spacing: 0.02em !important;
256
+ transition: all 0.2s ease !important;
257
+ min-width: 140px !important;
258
+ height: 48px !important;
259
+ text-transform: none !important;
260
+ }
261
+
262
+ .empty-state .q-btn:hover {
263
+ transform: translateY(-2px);
264
+ box-shadow: 0 8px 20px rgba(25, 118, 210, 0.25) !important;
265
+ }
266
+
267
+ .empty-state .q-btn:active {
268
+ transform: translateY(0);
269
+ }
270
+
271
+ /* ==================== Dialog ==================== */
272
+
273
+ .dialog-card {
274
+ background: white !important;
275
+ border-radius: 16px !important;
276
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15) !important;
277
+ }
278
+
279
+ .info-box {
280
+ background: #f9fafb;
281
+ border: 1px solid #e5e7eb;
282
+ border-radius: 12px;
283
+ padding: 20px;
284
+ }
285
+
286
+ .export-summary-box {
287
+ background: white;
288
+ border: 1px solid #e5e7eb;
289
+ border-radius: 12px;
290
+ padding: 16px;
291
+ }
292
+
293
+ .divider {
294
+ height: 1px;
295
+ background: rgba(0, 0, 0, 0.08);
296
+ margin: 12px 0;
297
+ }
298
+
299
+ .info-field {
300
+ padding: 12px 0;
301
+ border-bottom: 1px solid rgba(0, 0, 0, 0.06);
302
+ }
303
+
304
+ /* ==================== Form Inputs ==================== */
305
+
306
+ .clean-input .q-field__control {
307
+ background: transparent !important;
308
+ border: none !important;
309
+ border-radius: 0 !important;
310
+ box-shadow: none !important;
311
+ height: 48px !important;
312
+ }
313
+
314
+ .clean-input .q-field__native,
315
+ .clean-input input,
316
+ .clean-input textarea {
317
+ color: #1f2937 !important;
318
+ font-size: 15px !important;
319
+ }
320
+
321
+ .clean-input .q-field__native::placeholder,
322
+ .clean-input input::placeholder,
323
+ .clean-input textarea::placeholder {
324
+ color: #9ca3af !important;
325
+ opacity: 1 !important;
326
+ }
327
+
328
+ .clean-input .q-field__control:before {
329
+ border: none !important;
330
+ border-bottom: 1px solid rgba(0, 0, 0, 0.12) !important;
331
+ transition: border-color 0.3s ease !important;
332
+ }
333
+
334
+ .clean-input .q-field__control:hover:before {
335
+ border-bottom-color: rgba(0, 0, 0, 0.2) !important;
336
+ }
337
+
338
+ .clean-input .q-field__control:after {
339
+ border: none !important;
340
+ border-bottom: 2px solid rgba(37, 99, 235, 0.8) !important;
341
+ transform: scaleX(0);
342
+ transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
343
+ }
344
+
345
+ .clean-input.q-field--focused .q-field__control:after {
346
+ transform: scaleX(1);
347
+ }
348
+
349
+ .notes-textarea .q-field__control,
350
+ .notes-input .q-field__control {
351
+ height: 100px !important;
352
+ }
353
+
354
+ .notes-textarea textarea,
355
+ .notes-input textarea {
356
+ min-height: 70px !important;
357
+ resize: none !important;
358
+ }
359
+
360
+ /* ==================== Utterances ==================== */
361
+
362
+ .utterances-container {
363
+ display: flex !important;
364
+ flex-direction: column !important;
365
+ width: 100% !important;
366
+ padding: 20px 0 !important;
367
+ }
368
+
369
+ .utterance-final {
370
+ width: 100%;
371
+ display: flex;
372
+ flex-direction: column;
373
+ padding: 16px 0;
374
+ transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
375
+ }
376
+
377
+ .utterance-final.is-doctor {
378
+ align-items: flex-end;
379
+ }
380
+
381
+ .utterance-final.is-patient {
382
+ align-items: flex-start;
383
+ }
384
+
385
+ .utterance-row {
386
+ margin-bottom: 16px;
387
+ width: 100%;
388
+ display: flex !important;
389
+ }
390
+
391
+ .utterance-row-doctor {
392
+ justify-content: flex-end !important;
393
+ }
394
+
395
+ .utterance-row-patient {
396
+ justify-content: flex-start !important;
397
+ }
398
+
399
+ .utterance-doctor {
400
+ display: flex !important;
401
+ flex-direction: column !important;
402
+ align-items: flex-end !important;
403
+ }
404
+
405
+ .utterance-patient {
406
+ display: flex !important;
407
+ flex-direction: column !important;
408
+ align-items: flex-start !important;
409
+ }
410
+
411
+ .speaker-label {
412
+ font-size: 0.75rem;
413
+ font-weight: 500;
414
+ color: #9ca3af;
415
+ margin-bottom: 6px;
416
+ padding: 0 8px;
417
+ text-transform: uppercase;
418
+ letter-spacing: 1px;
419
+ }
420
+
421
+ .utterance-meta {
422
+ font-size: 0.75rem;
423
+ color: #9ca3af;
424
+ margin-bottom: 6px;
425
+ padding: 0 8px;
426
+ }
427
+
428
+ .utterance-doctor .utterance-meta,
429
+ .utterance-doctor .speaker-label {
430
+ text-align: right !important;
431
+ }
432
+
433
+ .utterance-patient .utterance-meta,
434
+ .utterance-patient .speaker-label {
435
+ text-align: left !important;
436
+ }
437
+
438
+ .bubble-doctor {
439
+ background: #6366f1;
440
+ color: white;
441
+ border-radius: 20px 20px 6px 20px;
442
+ padding: 14px 18px;
443
+ min-width: 120px;
444
+ max-width: min(450px, 75vw);
445
+ word-break: break-word;
446
+ white-space: pre-wrap;
447
+ box-shadow: 0 4px 20px rgba(99, 102, 241, 0.25);
448
+ font-size: 15px;
449
+ line-height: 1.5;
450
+ font-weight: 400;
451
+ }
452
+
453
+ .bubble-patient {
454
+ background: #ffffff;
455
+ color: #1f2937;
456
+ border: 1px solid rgba(0, 0, 0, 0.08);
457
+ border-radius: 20px 20px 20px 6px;
458
+ padding: 14px 18px;
459
+ min-width: 120px;
460
+ max-width: min(450px, 75vw);
461
+ word-break: break-word;
462
+ white-space: pre-wrap;
463
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
464
+ font-size: 15px;
465
+ line-height: 1.5;
466
+ font-weight: 400;
467
+ }
468
+
469
+ .bubble {
470
+ padding: 14px 18px;
471
+ border-radius: 16px;
472
+ min-width: 120px;
473
+ max-width: min(450px, 75vw);
474
+ word-break: break-word;
475
+ line-height: 1.5;
476
+ white-space: pre-wrap;
477
+ }
478
+
479
+ /* ==================== Responsive ==================== */
480
+
481
+ @media (max-width: 1400px) {
482
+ .bg-white {
483
+ padding: 40px 60px !important;
484
+ }
485
+
486
+ .px-6 {
487
+ padding-left: 2.5rem !important;
488
+ padding-right: 2.5rem !important;
489
+ }
490
+ }
491
+
492
+ @media (max-width: 1024px) {
493
+ .bg-white {
494
+ padding: 30px 40px !important;
495
+ }
496
+
497
+ .px-6 {
498
+ padding-left: 2rem !important;
499
+ padding-right: 2rem !important;
500
+ }
501
+ }
@@ -0,0 +1,186 @@
1
+ @import "global.css";
2
+ @import "glass.css";
3
+
4
+ /* ==================== Background ==================== */
5
+ .bg-white {
6
+ background: #ffffff !important;
7
+ padding: 40px 60px !important;
8
+ margin: 0 !important;
9
+ box-sizing: border-box !important;
10
+ overflow: visible !important;
11
+ min-height: auto !important;
12
+ height: auto !important;
13
+ }
14
+
15
+ /* ==================== Tab Buttons ==================== */
16
+ .tab-button {
17
+ padding: 12px 24px;
18
+ border-radius: 12px;
19
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
20
+ cursor: pointer;
21
+ font-weight: 500;
22
+ font-size: 15px;
23
+ color: #6b7280;
24
+ user-select: none;
25
+ }
26
+
27
+ .tab-button:hover {
28
+ background: rgba(0, 0, 0, 0.04);
29
+ color: #4b5563;
30
+ }
31
+
32
+ .tab-button-active {
33
+ padding: 12px 24px;
34
+ border-radius: 12px;
35
+ cursor: pointer;
36
+ font-weight: 600;
37
+ font-size: 15px;
38
+ background: linear-gradient(135deg, rgba(102, 126, 234, 0.12) 0%, rgba(118, 75, 162, 0.12) 100%);
39
+ color: #667eea;
40
+ box-shadow: 0 2px 8px rgba(102, 126, 234, 0.15);
41
+ user-select: none;
42
+ }
43
+
44
+ /* ==================== Clean Input ==================== */
45
+ .clean-input .q-field__control {
46
+ background: transparent !important;
47
+ border: none !important;
48
+ border-radius: 0 !important;
49
+ box-shadow: none !important;
50
+ height: 48px !important;
51
+ }
52
+
53
+ .clean-input .q-field__native,
54
+ .clean-input input {
55
+ color: #1f2937 !important;
56
+ font-size: 15px !important;
57
+ font-weight: 400 !important;
58
+ }
59
+
60
+ .clean-input .q-field__native::placeholder,
61
+ .clean-input input::placeholder {
62
+ color: #9ca3af !important;
63
+ opacity: 1 !important;
64
+ }
65
+
66
+ .clean-input .q-field__control:before {
67
+ border: none !important;
68
+ border-bottom: 1px solid rgba(0, 0, 0, 0.12) !important;
69
+ transition: border-color 0.3s ease !important;
70
+ }
71
+
72
+ .clean-input .q-field__control:hover:before {
73
+ border-bottom-color: rgba(0, 0, 0, 0.2) !important;
74
+ }
75
+
76
+ .clean-input .q-field__control:after {
77
+ border: none !important;
78
+ border-bottom: 2px solid #667eea !important;
79
+ transform: scaleX(0);
80
+ transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
81
+ }
82
+
83
+ .clean-input.q-field--focused .q-field__control:after {
84
+ transform: scaleX(1);
85
+ }
86
+
87
+ .clean-input .q-field__append {
88
+ height: 48px !important;
89
+ display: flex !important;
90
+ align-items: center !important;
91
+ justify-content: center !important;
92
+ }
93
+
94
+ .clean-input .q-field__append .q-icon {
95
+ color: #9ca3af !important;
96
+ transition: color 0.2s ease !important;
97
+ }
98
+
99
+ .clean-input .q-field__append .q-icon:hover {
100
+ color: #6b7280 !important;
101
+ }
102
+
103
+ /* ==================== Action Button ==================== */
104
+ .action-button {
105
+ border-radius: 24px !important;
106
+ font-size: 16px !important;
107
+ font-weight: 500 !important;
108
+ letter-spacing: 0.02em !important;
109
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1) !important;
110
+ min-width: 120px !important;
111
+ text-transform: none !important;
112
+ }
113
+
114
+ .action-button:hover {
115
+ transform: translateY(-2px);
116
+ }
117
+
118
+ .action-button:active {
119
+ transform: translateY(0);
120
+ }
121
+
122
+ .action-button[color="primary"] {
123
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
124
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.25), 0 2px 8px rgba(118, 75, 162, 0.15) !important;
125
+ }
126
+
127
+ .action-button[color="primary"]:hover {
128
+ background: linear-gradient(135deg, #7c8ef0 0%, #8a5db0 100%) !important;
129
+ box-shadow: 0 8px 24px rgba(102, 126, 234, 0.35), 0 4px 12px rgba(118, 75, 162, 0.25) !important;
130
+ }
131
+
132
+ .action-button[color="negative"]:hover {
133
+ box-shadow: 0 4px 16px rgba(193, 0, 21, 0.25) !important;
134
+ }
135
+
136
+ /* ==================== Info Display ==================== */
137
+ .info-field {
138
+ padding: 16px 0;
139
+ border-bottom: 1px solid rgba(0, 0, 0, 0.06);
140
+ transition: background 0.2s ease;
141
+ }
142
+
143
+ .info-field:hover {
144
+ background: rgba(0, 0, 0, 0.01);
145
+ }
146
+
147
+ .info-field:last-child {
148
+ border-bottom: none;
149
+ }
150
+
151
+ /* ==================== Separator ==================== */
152
+ .q-separator {
153
+ background-color: rgba(0, 0, 0, 0.08) !important;
154
+ }
155
+
156
+ .my-8 .q-separator {
157
+ background-color: rgba(0, 0, 0, 0.06) !important;
158
+ }
159
+
160
+ /* ==================== Dialog ==================== */
161
+ .q-dialog__backdrop {
162
+ backdrop-filter: blur(4px) !important;
163
+ }
164
+
165
+ /* ==================== Responsive ==================== */
166
+ @media (max-width: 1400px) {
167
+ .bg-white {
168
+ padding: 40px 60px !important;
169
+ }
170
+
171
+ .px-6 {
172
+ padding-left: 2.5rem !important;
173
+ padding-right: 2.5rem !important;
174
+ }
175
+ }
176
+
177
+ @media (max-width: 1024px) {
178
+ .bg-white {
179
+ padding: 30px 40px !important;
180
+ }
181
+
182
+ .px-6 {
183
+ padding-left: 2rem !important;
184
+ padding-right: 2rem !important;
185
+ }
186
+ }
@@ -0,0 +1,43 @@
1
+ @import "./styles.css";
2
+
3
+ /* ==================== Enroll Theme Variables ==================== */
4
+ :root {
5
+ --color-enroll-primary: #f59e0b;
6
+ --color-enroll-secondary: #d97706;
7
+ --color-enroll-light: #fbbf24;
8
+ }
9
+
10
+ /* Recording button - warm amber theme */
11
+ .record-button {
12
+ background: linear-gradient(135deg, var(--color-enroll-primary) 0%, var(--color-enroll-secondary) 100%) !important;
13
+ box-shadow: 0 8px 32px rgba(245, 158, 11, 0.3),
14
+ 0 4px 16px rgba(217, 119, 6, 0.2),
15
+ inset 0 -2px 8px rgba(0, 0, 0, 0.1) !important;
16
+ }
17
+
18
+ .record-button:hover:not(:disabled) {
19
+ background: linear-gradient(135deg, var(--color-enroll-light) 0%, var(--color-enroll-primary) 100%) !important;
20
+ box-shadow: 0 12px 40px rgba(245, 158, 11, 0.4),
21
+ 0 6px 20px rgba(217, 119, 6, 0.25),
22
+ inset 0 -2px 8px rgba(0, 0, 0, 0.1) !important;
23
+ }
24
+
25
+ .record-button:active:not(:disabled) {
26
+ box-shadow: 0 6px 24px rgba(245, 158, 11, 0.35),
27
+ 0 3px 12px rgba(217, 119, 6, 0.2),
28
+ inset 0 2px 8px rgba(0, 0, 0, 0.15) !important;
29
+ }
30
+
31
+ /* Performance mode - pure amber */
32
+ :root[data-theme="performance"] .record-button {
33
+ background: var(--color-enroll-primary) !important;
34
+ box-shadow: none !important;
35
+ }
36
+
37
+ :root[data-theme="performance"] .record-button:hover:not(:disabled) {
38
+ background: var(--color-enroll-secondary) !important;
39
+ }
40
+
41
+ :root[data-theme="performance"] .record-button:active:not(:disabled) {
42
+ background: #b45309 !important;
43
+ }