style: polish dream customs declaration UI

#9
Files changed (2) hide show
  1. dream_customs/ui/app.py +156 -11
  2. dream_customs/ui/styles.py +629 -170
dream_customs/ui/app.py CHANGED
@@ -50,6 +50,105 @@ def _json_schema_to_python_type(schema, defs):
50
 
51
  gradio_client_utils._json_schema_to_python_type = _json_schema_to_python_type
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  def _load_view(view_json: str) -> dict:
55
  try:
@@ -187,7 +286,7 @@ def build_demo() -> gr.Blocks:
187
  initial_state, initial_view = initial_mobile_state()
188
  initial = _load_view(initial_view)
189
 
190
- with gr.Blocks(css=CSS, title="梦境海关") as demo:
191
  session_state = gr.State(initial_state)
192
  view_state = gr.State(initial_view)
193
 
@@ -195,8 +294,27 @@ def build_demo() -> gr.Blocks:
195
  gr.HTML(
196
  f"""
197
  <header class="dc-hero">
198
- <h1>{APP_TITLE}</h1>
199
- <p>{APP_SUBTITLE}</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  </header>
201
  """.strip()
202
  )
@@ -205,32 +323,59 @@ def build_demo() -> gr.Blocks:
205
  with gr.Group(visible=True, elem_classes=["dc-stage"]) as declaration_group:
206
  with gr.Row(elem_classes=["dc-intake-grid"]):
207
  with gr.Group(elem_classes=["dc-composer"]):
 
 
 
 
 
 
 
 
208
  dream_text = gr.Textbox(
209
  label="写下梦的碎片",
210
  placeholder=DREAM_PLACEHOLDER,
211
- lines=8,
212
  value="",
213
  elem_classes=["dc-dream-text"],
214
  )
215
- audio_input = gr.Audio(
216
- label="语音线索",
217
- sources=["microphone"],
218
- type="filepath",
219
- elem_classes=["dc-mic-input"],
 
 
 
 
 
 
 
 
 
 
220
  )
221
  with gr.Column(elem_classes=["dc-side-panel"]):
 
 
 
 
 
 
 
 
222
  mood = gr.Dropdown(label="醒来后的感觉", choices=MOOD_OPTIONS, value=DEFAULT_MOOD)
223
  gr.HTML(
224
  """
225
  <div class="dc-side-stamp">
226
  <span>Dream Customs</span>
227
  <strong>Calm clearance</strong>
 
228
  </div>
229
  """.strip()
230
  )
231
  with gr.Row(elem_classes=["dc-submit-row"]):
232
- example_button = gr.Button("试一个例子", variant="secondary")
233
- submit_button = gr.Button("生成今日通行证", variant="primary")
234
  with gr.Accordion("附加材料", open=False, elem_classes=["dc-attachment-drawer"]):
235
  image_input = gr.Image(label="图片线索", type="filepath", height=160)
236
 
 
50
 
51
  gradio_client_utils._json_schema_to_python_type = _json_schema_to_python_type
52
 
53
+ VOICE_JS = r"""
54
+ () => {
55
+ const bindVoiceButton = () => {
56
+ const button = document.querySelector(".dc-mic-button");
57
+ const status = document.querySelector(".dc-mic-status");
58
+ const textarea = document.querySelector(".dc-dream-text textarea");
59
+
60
+ if (!button || !textarea || button.dataset.bound === "true") {
61
+ return;
62
+ }
63
+ button.dataset.bound = "true";
64
+
65
+ const setStatus = (message, mode) => {
66
+ if (status) {
67
+ status.textContent = message;
68
+ status.dataset.mode = mode || "";
69
+ }
70
+ button.dataset.mode = mode || "";
71
+ button.setAttribute("aria-label", message);
72
+ };
73
+
74
+ const appendTranscript = (text) => {
75
+ const transcript = text.trim();
76
+ if (!transcript) {
77
+ return;
78
+ }
79
+ const spacer = textarea.value.trim() ? "\n" : "";
80
+ textarea.value = `${textarea.value}${spacer}${transcript}`;
81
+ textarea.dispatchEvent(new InputEvent("input", { bubbles: true, inputType: "insertText", data: transcript }));
82
+ textarea.dispatchEvent(new Event("change", { bubbles: true }));
83
+ textarea.focus();
84
+ };
85
+
86
+ button.addEventListener("click", async () => {
87
+ const Recognition = window.SpeechRecognition || window.webkitSpeechRecognition;
88
+ if (!Recognition) {
89
+ setStatus("当前浏览器不支持直接语音输入,可先手动输入,ASR 通道待接入。", "error");
90
+ textarea.focus();
91
+ return;
92
+ }
93
+
94
+ try {
95
+ if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
96
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
97
+ stream.getTracks().forEach((track) => track.stop());
98
+ }
99
+ } catch (error) {
100
+ setStatus("没有获得麦克风权限,请允许浏览器录音后再试。", "error");
101
+ return;
102
+ }
103
+
104
+ const recognition = new Recognition();
105
+ recognition.lang = "zh-CN";
106
+ recognition.interimResults = true;
107
+ recognition.continuous = false;
108
+ recognition.maxAlternatives = 1;
109
+
110
+ let latestTranscript = "";
111
+
112
+ recognition.onstart = () => {
113
+ setStatus("正在听,把梦说出来。", "listening");
114
+ };
115
+
116
+ recognition.onresult = (event) => {
117
+ latestTranscript = Array.from(event.results)
118
+ .map((result) => result[0]?.transcript || "")
119
+ .join("")
120
+ .trim();
121
+ if (latestTranscript) {
122
+ setStatus(`正在记录:${latestTranscript}`, "listening");
123
+ }
124
+ };
125
+
126
+ recognition.onerror = (event) => {
127
+ const message = event.error === "not-allowed"
128
+ ? "麦克风权限被拒绝,请允许录音后再试。"
129
+ : "这次没有听清,可以再点一次话筒。";
130
+ setStatus(message, "error");
131
+ };
132
+
133
+ recognition.onend = () => {
134
+ if (latestTranscript) {
135
+ appendTranscript(latestTranscript);
136
+ setStatus("已写入梦境碎片。", "done");
137
+ } else if (button.dataset.mode === "listening") {
138
+ setStatus("没有检测到语音,可以再点一次话筒。", "idle");
139
+ }
140
+ };
141
+
142
+ recognition.start();
143
+ });
144
+ };
145
+
146
+ bindVoiceButton();
147
+ const observer = new MutationObserver(bindVoiceButton);
148
+ observer.observe(document.body, { childList: true, subtree: true });
149
+ }
150
+ """
151
+
152
 
153
  def _load_view(view_json: str) -> dict:
154
  try:
 
286
  initial_state, initial_view = initial_mobile_state()
287
  initial = _load_view(initial_view)
288
 
289
+ with gr.Blocks(css=CSS, js=VOICE_JS, title="梦境海关") as demo:
290
  session_state = gr.State(initial_state)
291
  view_state = gr.State(initial_view)
292
 
 
294
  gr.HTML(
295
  f"""
296
  <header class="dc-hero">
297
+ <div class="dc-hero-top">
298
+ <div class="dc-menu-mark" aria-hidden="true"><span></span><span></span><span></span></div>
299
+ <div class="dc-brand-lockup">
300
+ <div class="dc-passport-icon" aria-hidden="true">
301
+ <span class="dc-cloud-dot one"></span>
302
+ <span class="dc-cloud-dot two"></span>
303
+ <span class="dc-cloud-dot three"></span>
304
+ </div>
305
+ <div>
306
+ <p class="dc-brand-kicker">DREAM CUSTOMS</p>
307
+ <h1>{APP_TITLE}</h1>
308
+ <p class="dc-brand-subtitle">A gentle dream declaration desk</p>
309
+ </div>
310
+ </div>
311
+ <div class="dc-clearance-badge" aria-hidden="true">
312
+ <span>Dream Clearance</span>
313
+ <strong>DC-2026-0606</strong>
314
+ <small>Status: Ready</small>
315
+ </div>
316
+ </div>
317
+ <p class="dc-hero-copy">{APP_SUBTITLE}</p>
318
  </header>
319
  """.strip()
320
  )
 
323
  with gr.Group(visible=True, elem_classes=["dc-stage"]) as declaration_group:
324
  with gr.Row(elem_classes=["dc-intake-grid"]):
325
  with gr.Group(elem_classes=["dc-composer"]):
326
+ gr.HTML(
327
+ """
328
+ <div class="dc-section-title">
329
+ <span class="dc-title-icon">1</span>
330
+ <strong>Describe your dream</strong>
331
+ </div>
332
+ """.strip()
333
+ )
334
  dream_text = gr.Textbox(
335
  label="写下梦的碎片",
336
  placeholder=DREAM_PLACEHOLDER,
337
+ lines=12,
338
  value="",
339
  elem_classes=["dc-dream-text"],
340
  )
341
+ gr.HTML(
342
+ """
343
+ <div class="dc-mic-control">
344
+ <button type="button" class="dc-mic-button" aria-label="点击话筒开始语音输入">
345
+ <span class="dc-mic-glyph" aria-hidden="true"></span>
346
+ </button>
347
+ <div class="dc-mic-status" aria-live="polite">点击话筒开始语音输入</div>
348
+ </div>
349
+ """.strip()
350
+ )
351
+ audio_input = gr.State(None)
352
+ gr.HTML(
353
+ """
354
+ <p class="dc-field-tip">Tips: include people, places, emotions, colors, and anything that stood out.</p>
355
+ """.strip()
356
  )
357
  with gr.Column(elem_classes=["dc-side-panel"]):
358
+ gr.HTML(
359
+ """
360
+ <div class="dc-section-title">
361
+ <span class="dc-title-icon">2</span>
362
+ <strong>After waking feeling</strong>
363
+ </div>
364
+ """.strip()
365
+ )
366
  mood = gr.Dropdown(label="醒来后的感觉", choices=MOOD_OPTIONS, value=DEFAULT_MOOD)
367
  gr.HTML(
368
  """
369
  <div class="dc-side-stamp">
370
  <span>Dream Customs</span>
371
  <strong>Calm clearance</strong>
372
+ <small>Gentle declarations</small>
373
  </div>
374
  """.strip()
375
  )
376
  with gr.Row(elem_classes=["dc-submit-row"]):
377
+ example_button = gr.Button("清空并试一个例子", variant="secondary")
378
+ submit_button = gr.Button("盖章生成今日通行证", variant="primary")
379
  with gr.Accordion("附加材料", open=False, elem_classes=["dc-attachment-drawer"]):
380
  image_input = gr.Image(label="图片线索", type="filepath", height=160)
381
 
dream_customs/ui/styles.py CHANGED
@@ -1,19 +1,21 @@
1
  CSS = """
2
  :root {
3
- --dc-bg: #f6f8f6;
4
- --dc-ink: #17211f;
5
- --dc-muted: #5f6f68;
6
- --dc-line: #cbd7d1;
7
- --dc-panel: #ffffff;
8
- --dc-panel-soft: #edf4f0;
9
- --dc-paper: #fffaf1;
10
- --dc-graphite: #26302d;
11
- --dc-teal: #0f766e;
12
- --dc-teal-dark: #115e59;
13
- --dc-coral: #c85235;
14
- --dc-gold: #b7791f;
15
- --dc-shadow: 0 24px 70px rgba(23, 33, 31, 0.13);
16
- --dc-soft-shadow: 0 10px 28px rgba(23, 33, 31, 0.08);
 
 
17
  --dc-radius-sm: 6px;
18
  --dc-radius-md: 8px;
19
  }
@@ -22,85 +24,258 @@ html,
22
  body,
23
  .gradio-container {
24
  background:
25
- linear-gradient(180deg, rgba(15, 118, 110, 0.08), rgba(200, 82, 53, 0.04) 42%, rgba(246, 248, 246, 1)),
26
- var(--dc-bg) !important;
 
27
  color: var(--dc-ink) !important;
28
- font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif !important;
29
  }
30
 
31
  .gradio-container {
32
  max-width: none !important;
33
- padding-left: 0 !important;
34
- padding-right: 0 !important;
 
 
 
 
35
  }
36
 
37
  .dc-shell {
38
- margin: 0 auto;
39
- max-width: 1060px;
40
- padding: 28px clamp(18px, 4vw, 46px) 34px;
41
  }
42
 
43
  .dc-hero {
44
- border-bottom: 1px solid var(--dc-line);
45
- margin-bottom: 20px;
46
- padding: 4px 0 20px;
 
 
 
 
 
 
 
 
47
  }
48
 
49
- .dc-hero h1 {
50
- color: var(--dc-ink) !important;
51
- font-size: clamp(2rem, 7vw, 4.4rem);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  letter-spacing: 0;
53
- line-height: 0.98;
 
 
 
 
 
 
54
  margin: 0;
 
55
  }
56
 
57
- .dc-hero p {
58
- color: var(--dc-muted);
59
- font-size: 1.02rem;
60
- line-height: 1.65;
61
- margin: 12px 0 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  max-width: 40rem;
63
  }
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  .dc-stage,
66
  .dc-dev {
67
- background: var(--dc-panel) !important;
68
- border: 1px solid var(--dc-line) !important;
69
- border-radius: var(--dc-radius-md) !important;
 
 
70
  box-shadow: var(--dc-shadow);
71
- padding: clamp(18px, 3vw, 30px);
 
72
  }
73
 
74
- .dc-stage textarea,
75
- .dc-stage input,
76
- .dc-stage select,
77
- .dc-stage .wrap,
78
- .dc-stage .container,
79
- .dc-stage .input-container,
80
- .dc-stage .upload-container,
81
- .dc-stage .image-container,
82
- .dc-stage .audio-container {
83
- background: #fbfdfc !important;
84
- border-color: var(--dc-line) !important;
85
- border-radius: var(--dc-radius-sm) !important;
86
- color: var(--dc-ink) !important;
87
  }
88
 
89
  .dc-intake-grid {
90
  align-items: stretch !important;
91
  display: grid !important;
92
- gap: clamp(16px, 3vw, 24px) !important;
93
- grid-template-columns: minmax(0, 1fr) minmax(210px, 270px);
94
  }
95
 
96
- .dc-composer {
97
- background:
98
- linear-gradient(180deg, rgba(255, 250, 241, 0.86), rgba(251, 253, 252, 0.98)) !important;
99
- border: 1px solid color-mix(in srgb, var(--dc-line) 82%, var(--dc-gold)) !important;
100
  border-radius: var(--dc-radius-md) !important;
101
- box-shadow: var(--dc-soft-shadow);
102
- min-height: 300px;
103
- padding: 12px;
104
  position: relative;
105
  }
106
 
@@ -110,136 +285,307 @@ body,
110
  overflow: visible !important;
111
  }
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  .dc-dream-text textarea {
114
- min-height: 248px !important;
115
- padding-bottom: 78px !important;
 
 
 
116
  resize: vertical !important;
117
  }
118
 
119
- .dc-mic-input {
120
- bottom: 16px;
121
- max-width: 132px;
122
- min-width: 112px !important;
123
- position: absolute !important;
124
- right: 16px;
125
- z-index: 4;
126
  }
127
 
128
- .dc-mic-input label,
129
- .dc-mic-input [data-testid="block-label"] {
130
  display: none !important;
131
  }
132
 
133
- .dc-mic-input,
134
- .dc-mic-input .wrap,
135
- .dc-mic-input .container,
136
- .dc-mic-input .audio-container,
137
- .dc-mic-input .component-wrapper {
138
- background: transparent !important;
139
- border: 0 !important;
140
- box-shadow: none !important;
141
- min-height: 46px !important;
 
142
  }
143
 
144
- .dc-mic-input .audio-container,
145
- .dc-mic-input .wrap {
146
- height: 46px !important;
147
- overflow: hidden !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  }
149
 
150
- .dc-mic-input button {
151
- background: var(--dc-graphite) !important;
152
- border-color: var(--dc-graphite) !important;
153
- border-radius: var(--dc-radius-sm) !important;
154
- color: #ffffff !important;
155
- min-height: 40px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  }
157
 
158
  .dc-side-panel {
159
- background: var(--dc-paper) !important;
160
- border: 1px solid #e3d6bd !important;
161
- border-radius: var(--dc-radius-md) !important;
162
- box-shadow: var(--dc-soft-shadow);
163
  justify-content: space-between;
164
- min-height: 300px;
165
- padding: 14px;
 
 
 
 
166
  }
167
 
168
  .dc-side-stamp {
169
- border: 1px dashed rgba(200, 82, 53, 0.55);
170
- border-radius: var(--dc-radius-md);
171
- color: var(--dc-coral);
172
- margin-top: 12px;
173
- padding: 14px;
174
- text-transform: none;
 
 
 
 
 
 
175
  }
176
 
177
- .dc-side-stamp span {
178
- display: block;
179
  font-size: 0.72rem;
180
  font-weight: 850;
181
- margin-bottom: 6px;
182
  }
183
 
184
  .dc-side-stamp strong {
185
- color: var(--dc-graphite);
186
- display: block;
187
- font-size: 1.12rem;
188
- }
189
-
190
- .dc-attachment-drawer {
191
- background: transparent !important;
192
- border: 1px solid var(--dc-line) !important;
193
- border-radius: var(--dc-radius-md) !important;
194
- box-shadow: none !important;
195
- margin-top: 16px;
196
  }
197
 
198
  .dc-submit-row {
199
  align-items: stretch !important;
200
  background: transparent !important;
201
  display: grid !important;
202
- gap: 14px !important;
203
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
204
- margin-top: 18px;
205
- }
206
-
207
- .dc-stage label,
208
- .dc-stage [data-testid="block-label"],
209
- .dc-dev label,
210
- .dc-dev [data-testid="block-label"] {
211
- color: var(--dc-ink) !important;
212
- font-weight: 700 !important;
213
  }
214
 
215
- .dc-stage textarea::placeholder,
216
- .dc-stage input::placeholder {
217
- color: #87958f !important;
218
- opacity: 1 !important;
 
 
219
  }
220
 
221
- .dc-stage button {
222
- border-radius: var(--dc-radius-md) !important;
223
- font-weight: 750 !important;
224
- min-height: 48px !important;
 
 
 
225
  }
226
 
227
  .dc-stage .primary button,
228
  .dc-stage button.primary,
229
  button.primary {
230
- background: var(--dc-teal) !important;
231
- border-color: var(--dc-teal-dark) !important;
232
- color: white !important;
 
233
  }
234
 
235
- .dc-stage button.secondary {
236
- background: #f3eee3 !important;
237
- border-color: var(--dc-line) !important;
 
 
 
238
  color: var(--dc-ink) !important;
239
  }
240
 
241
  .dc-submit-row button {
242
- box-shadow: var(--dc-soft-shadow);
 
 
 
 
 
 
 
 
243
  }
244
 
245
  .dc-row {
@@ -252,19 +598,19 @@ button.primary {
252
  .dc-question h2,
253
  .dc-card h2 {
254
  color: var(--dc-ink) !important;
 
255
  font-size: 1.55rem;
256
- letter-spacing: 0;
257
  line-height: 1.2;
258
  margin: 0 0 10px;
259
  }
260
 
261
  .dc-notice {
262
- background: #e6f4ef;
263
- border: 1px solid #b9ddd3;
264
  border-radius: var(--dc-radius-sm);
265
  color: var(--dc-teal-dark);
266
  line-height: 1.5;
267
- margin: 0 0 12px;
268
  padding: 10px 12px;
269
  }
270
 
@@ -276,13 +622,27 @@ button.primary {
276
 
277
  .dc-pass-card {
278
  background:
279
- linear-gradient(180deg, rgba(255, 255, 255, 0.94), rgba(237, 244, 240, 0.98));
280
- border: 1px solid var(--dc-line);
281
- border-left: 6px solid var(--dc-teal);
282
  border-radius: var(--dc-radius-md);
283
  color: var(--dc-ink);
284
  line-height: 1.65;
285
- padding: clamp(16px, 3vw, 26px);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
  }
287
 
288
  .dc-pass-topline {
@@ -293,18 +653,19 @@ button.primary {
293
  font-weight: 800;
294
  justify-content: space-between;
295
  margin-bottom: 12px;
 
296
  }
297
 
298
  .dc-pass-card h2 {
299
  color: var(--dc-ink) !important;
300
- font-size: clamp(1.8rem, 7vw, 3.2rem);
301
- letter-spacing: 0;
302
  line-height: 1;
303
  margin: 0 0 6px;
304
  }
305
 
306
  .dc-pass-risk {
307
- color: var(--dc-coral);
308
  font-weight: 750;
309
  margin: 0 0 16px;
310
  }
@@ -317,7 +678,6 @@ button.primary {
317
  .dc-pass-card h3 {
318
  color: var(--dc-teal-dark) !important;
319
  font-size: 0.9rem;
320
- letter-spacing: 0;
321
  margin: 0 0 4px;
322
  }
323
 
@@ -353,7 +713,7 @@ button.primary {
353
 
354
  .dc-actions {
355
  display: grid !important;
356
- gap: 8px !important;
357
  grid-template-columns: repeat(4, minmax(0, 1fr));
358
  }
359
 
@@ -363,17 +723,24 @@ button.primary {
363
  }
364
 
365
  .dc-dev {
366
- box-shadow: none;
367
- margin-top: 16px;
 
 
368
  }
369
 
370
  .dc-dev-grid {
371
  align-items: stretch !important;
372
  display: grid !important;
373
- gap: 12px !important;
374
  grid-template-columns: repeat(3, minmax(0, 1fr));
375
  }
376
 
 
 
 
 
 
377
  .dc-dev .form,
378
  .dc-dev .wrap,
379
  .dc-dev .container,
@@ -388,14 +755,33 @@ button.primary {
388
  font-size: 0.84rem !important;
389
  }
390
 
391
- @media (max-width: 720px) {
392
- .dc-shell {
393
- padding: 16px 12px 24px;
 
 
 
394
  }
 
 
 
 
395
 
396
- .dc-hero {
397
- margin-bottom: 10px;
398
- padding-bottom: 12px;
 
 
 
 
 
 
 
 
 
 
 
 
399
  }
400
 
401
  .dc-intake-grid,
@@ -403,30 +789,103 @@ button.primary {
403
  .dc-row,
404
  .dc-submit-row,
405
  .dc-actions {
406
- grid-template-columns: 1fr;
407
  }
408
 
 
409
  .dc-side-panel {
410
  min-height: 0;
411
  }
412
 
413
  .dc-side-stamp {
414
- display: none;
 
415
  }
416
 
417
- .dc-composer {
418
- min-height: 270px;
419
  }
 
420
 
421
- .dc-dream-text textarea {
422
- min-height: 220px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
423
  }
424
 
425
  .dc-stage,
426
  .dc-dev {
427
- border-radius: 8px !important;
428
  box-shadow: none;
 
 
 
 
 
 
 
 
 
429
  padding: 14px;
430
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  }
432
  """
 
1
  CSS = """
2
  :root {
3
+ --dc-bg: #f4efe4;
4
+ --dc-paper: #fff9ee;
5
+ --dc-paper-deep: #f4ead8;
6
+ --dc-ink: #13292f;
7
+ --dc-muted: #6f746c;
8
+ --dc-line: #d8cbb8;
9
+ --dc-line-strong: #bda88f;
10
+ --dc-teal: #0b5b64;
11
+ --dc-teal-dark: #073c43;
12
+ --dc-teal-soft: #dcebe6;
13
+ --dc-coral: #c75342;
14
+ --dc-coral-dark: #9f3e32;
15
+ --dc-stamp: #de9b8d;
16
+ --dc-cream-button: #fbf4e8;
17
+ --dc-shadow: 0 28px 70px rgba(19, 41, 47, 0.18);
18
+ --dc-soft-shadow: 0 12px 30px rgba(19, 41, 47, 0.1);
19
  --dc-radius-sm: 6px;
20
  --dc-radius-md: 8px;
21
  }
 
24
  body,
25
  .gradio-container {
26
  background:
27
+ repeating-linear-gradient(90deg, rgba(19, 41, 47, 0.024) 0, rgba(19, 41, 47, 0.024) 1px, transparent 1px, transparent 82px),
28
+ repeating-linear-gradient(0deg, rgba(199, 83, 66, 0.018) 0, rgba(199, 83, 66, 0.018) 1px, transparent 1px, transparent 68px),
29
+ linear-gradient(180deg, #f8f3ea 0%, #eee7db 100%) !important;
30
  color: var(--dc-ink) !important;
31
+ font-family: "Avenir Next", "Gill Sans", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif !important;
32
  }
33
 
34
  .gradio-container {
35
  max-width: none !important;
36
+ padding: 0 !important;
37
+ }
38
+
39
+ .gradio-container .main,
40
+ .gradio-container .wrap {
41
+ background: transparent !important;
42
  }
43
 
44
  .dc-shell {
45
+ margin: 18px auto 40px;
46
+ max-width: 1180px;
47
+ padding: 0 clamp(14px, 3vw, 34px);
48
  }
49
 
50
  .dc-hero {
51
+ background:
52
+ linear-gradient(90deg, rgba(7, 60, 67, 0.97), rgba(11, 91, 100, 0.94)),
53
+ var(--dc-teal-dark);
54
+ border: 1px solid rgba(7, 60, 67, 0.35);
55
+ border-radius: var(--dc-radius-md) var(--dc-radius-md) 0 0;
56
+ box-shadow: var(--dc-shadow);
57
+ color: #fff9ee;
58
+ margin: 0;
59
+ overflow: hidden;
60
+ padding: clamp(18px, 3vw, 28px) clamp(20px, 4vw, 42px);
61
+ position: relative;
62
  }
63
 
64
+ .dc-hero::after {
65
+ border: 1px solid rgba(244, 234, 216, 0.55);
66
+ border-radius: 999px;
67
+ color: rgba(160, 214, 211, 0.72);
68
+ content: "DREAM CUSTOMS CLEAR & LOG";
69
+ font-family: Georgia, "Times New Roman", serif;
70
+ font-size: 0.78rem;
71
+ height: 88px;
72
+ line-height: 1.3;
73
+ padding: 18px 10px;
74
+ position: absolute;
75
+ right: 26px;
76
+ text-align: center;
77
+ top: 18px;
78
+ transform: rotate(9deg);
79
+ width: 88px;
80
+ }
81
+
82
+ .dc-hero-top {
83
+ align-items: center;
84
+ display: grid;
85
+ gap: clamp(14px, 3vw, 26px);
86
+ grid-template-columns: 42px minmax(0, 1fr) 184px;
87
+ }
88
+
89
+ .dc-menu-mark {
90
+ display: grid;
91
+ gap: 8px;
92
+ }
93
+
94
+ .dc-menu-mark span {
95
+ background: #f7decf;
96
+ border-radius: 999px;
97
+ display: block;
98
+ height: 3px;
99
+ width: 30px;
100
+ }
101
+
102
+ .dc-brand-lockup {
103
+ align-items: center;
104
+ display: flex;
105
+ gap: 18px;
106
+ min-width: 0;
107
+ }
108
+
109
+ .dc-passport-icon {
110
+ border: 2px solid #f7decf;
111
+ border-radius: 7px;
112
+ height: 62px;
113
+ position: relative;
114
+ width: 54px;
115
+ }
116
+
117
+ .dc-passport-icon::before {
118
+ border: 2px solid #f7decf;
119
+ border-radius: 50%;
120
+ content: "";
121
+ height: 26px;
122
+ left: 13px;
123
+ position: absolute;
124
+ top: 18px;
125
+ width: 26px;
126
+ }
127
+
128
+ .dc-passport-icon::after {
129
+ background: #f7decf;
130
+ content: "";
131
+ height: 2px;
132
+ left: 11px;
133
+ position: absolute;
134
+ top: 31px;
135
+ width: 32px;
136
+ }
137
+
138
+ .dc-cloud-dot {
139
+ background: #f7decf;
140
+ border-radius: 999px;
141
+ display: block;
142
+ height: 4px;
143
+ position: absolute;
144
+ width: 4px;
145
+ }
146
+
147
+ .dc-cloud-dot.one {
148
+ left: 12px;
149
+ top: 10px;
150
+ }
151
+
152
+ .dc-cloud-dot.two {
153
+ right: 12px;
154
+ top: 10px;
155
+ }
156
+
157
+ .dc-cloud-dot.three {
158
+ left: 25px;
159
+ top: 7px;
160
+ }
161
+
162
+ .dc-brand-kicker,
163
+ .dc-brand-subtitle,
164
+ .dc-hero-copy,
165
+ .dc-clearance-badge span,
166
+ .dc-clearance-badge small {
167
  letter-spacing: 0;
168
+ }
169
+
170
+ .dc-brand-kicker {
171
+ color: #f7decf;
172
+ font-family: Georgia, "Times New Roman", serif;
173
+ font-size: clamp(1.35rem, 3vw, 2.35rem);
174
+ line-height: 1;
175
  margin: 0;
176
+ text-transform: uppercase;
177
  }
178
 
179
+ .dc-hero h1 {
180
+ color: #fff9ee !important;
181
+ font-family: Georgia, "Times New Roman", serif;
182
+ font-size: clamp(2.2rem, 7vw, 4.4rem);
183
+ line-height: 0.95;
184
+ margin: 4px 0 0;
185
+ }
186
+
187
+ .dc-brand-subtitle {
188
+ color: rgba(247, 222, 207, 0.82);
189
+ font-size: 0.86rem;
190
+ font-weight: 700;
191
+ margin: 8px 0 0;
192
+ text-transform: uppercase;
193
+ }
194
+
195
+ .dc-hero-copy {
196
+ color: rgba(255, 249, 238, 0.86);
197
+ font-size: 1rem;
198
+ line-height: 1.6;
199
+ margin: 18px 0 0 60px;
200
  max-width: 40rem;
201
  }
202
 
203
+ .dc-clearance-badge {
204
+ border: 1px solid rgba(247, 222, 207, 0.64);
205
+ border-radius: var(--dc-radius-sm);
206
+ display: grid;
207
+ gap: 4px;
208
+ padding: 10px 12px;
209
+ position: relative;
210
+ z-index: 1;
211
+ }
212
+
213
+ .dc-clearance-badge span,
214
+ .dc-clearance-badge small {
215
+ color: rgba(255, 249, 238, 0.76);
216
+ font-size: 0.72rem;
217
+ font-weight: 800;
218
+ text-transform: uppercase;
219
+ }
220
+
221
+ .dc-clearance-badge strong {
222
+ color: #fff9ee;
223
+ font-family: Georgia, "Times New Roman", serif;
224
+ font-size: 1.05rem;
225
+ font-weight: 700;
226
+ }
227
+
228
+ .dc-form-alert {
229
+ background: rgba(255, 249, 238, 0.8);
230
+ border: 1px solid var(--dc-line);
231
+ border-radius: 0;
232
+ color: var(--dc-teal-dark);
233
+ font-weight: 760;
234
+ line-height: 1.5;
235
+ padding: 14px clamp(18px, 4vw, 42px);
236
+ }
237
+
238
  .dc-stage,
239
  .dc-dev {
240
+ background:
241
+ linear-gradient(180deg, rgba(255, 249, 238, 0.97), rgba(250, 244, 235, 0.97)),
242
+ var(--dc-paper) !important;
243
+ border: 1px solid var(--dc-line-strong) !important;
244
+ border-radius: 0 0 var(--dc-radius-md) var(--dc-radius-md) !important;
245
  box-shadow: var(--dc-shadow);
246
+ padding: clamp(20px, 3.4vw, 34px);
247
+ position: relative;
248
  }
249
 
250
+ .dc-stage::before {
251
+ border: 2px solid rgba(199, 83, 66, 0.28);
252
+ border-radius: 6px;
253
+ color: rgba(199, 83, 66, 0.62);
254
+ content: "DREAMS RECEIVED";
255
+ font-size: 0.72rem;
256
+ font-weight: 850;
257
+ left: -44px;
258
+ padding: 12px 16px;
259
+ position: absolute;
260
+ top: 120px;
261
+ transform: rotate(-11deg);
 
262
  }
263
 
264
  .dc-intake-grid {
265
  align-items: stretch !important;
266
  display: grid !important;
267
+ gap: 18px !important;
268
+ grid-template-columns: minmax(0, 1.35fr) minmax(300px, 0.65fr);
269
  }
270
 
271
+ .dc-composer,
272
+ .dc-side-panel {
273
+ background: rgba(255, 252, 246, 0.82) !important;
274
+ border: 1px solid var(--dc-line-strong) !important;
275
  border-radius: var(--dc-radius-md) !important;
276
+ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.52);
277
+ min-height: 470px;
278
+ padding: 18px;
279
  position: relative;
280
  }
281
 
 
285
  overflow: visible !important;
286
  }
287
 
288
+ .dc-composer .html-container,
289
+ .dc-composer [data-testid="HTML"] {
290
+ background: transparent !important;
291
+ border: 0 !important;
292
+ box-shadow: none !important;
293
+ padding: 0 !important;
294
+ }
295
+
296
+ .dc-composer .styler:has(.dc-section-title),
297
+ .dc-composer .styler:has(.dc-mic-control),
298
+ .dc-composer .styler:has(.dc-field-tip),
299
+ .dc-side-panel .styler:has(.dc-section-title),
300
+ .dc-side-panel .styler:has(.dc-side-stamp) {
301
+ background: transparent !important;
302
+ }
303
+
304
+ .dc-section-title {
305
+ align-items: center;
306
+ color: var(--dc-ink);
307
+ display: flex;
308
+ font-family: Georgia, "Times New Roman", serif;
309
+ gap: 12px;
310
+ margin: 0 0 14px;
311
+ text-transform: uppercase;
312
+ }
313
+
314
+ .dc-title-icon {
315
+ align-items: center;
316
+ border: 1px solid var(--dc-teal);
317
+ border-radius: 999px;
318
+ color: var(--dc-teal);
319
+ display: inline-flex;
320
+ font-family: "Avenir Next", "Gill Sans", sans-serif;
321
+ font-size: 0.82rem;
322
+ font-weight: 850;
323
+ height: 30px;
324
+ justify-content: center;
325
+ width: 30px;
326
+ }
327
+
328
+ .dc-section-title strong {
329
+ font-size: 0.98rem;
330
+ }
331
+
332
+ .dc-stage label,
333
+ .dc-stage [data-testid="block-label"],
334
+ .dc-dev label,
335
+ .dc-dev [data-testid="block-label"] {
336
+ color: var(--dc-ink) !important;
337
+ font-size: 0.9rem !important;
338
+ font-weight: 780 !important;
339
+ }
340
+
341
+ .dc-stage textarea,
342
+ .dc-stage input,
343
+ .dc-stage select,
344
+ .dc-stage .wrap,
345
+ .dc-stage .container,
346
+ .dc-stage .input-container,
347
+ .dc-stage .upload-container,
348
+ .dc-stage .image-container,
349
+ .dc-dev textarea,
350
+ .dc-dev input,
351
+ .dc-dev select,
352
+ .dc-dev .wrap,
353
+ .dc-dev .container,
354
+ .dc-dev .input-container {
355
+ background: rgba(255, 253, 248, 0.9) !important;
356
+ border-color: var(--dc-line) !important;
357
+ border-radius: var(--dc-radius-sm) !important;
358
+ color: var(--dc-ink) !important;
359
+ }
360
+
361
  .dc-dream-text textarea {
362
+ box-shadow: inset 0 1px 6px rgba(19, 41, 47, 0.04);
363
+ font-size: 1.02rem !important;
364
+ line-height: 1.65 !important;
365
+ min-height: 390px !important;
366
+ padding: 18px 96px 74px 18px !important;
367
  resize: vertical !important;
368
  }
369
 
370
+ .dc-stage textarea::placeholder,
371
+ .dc-stage input::placeholder {
372
+ color: rgba(111, 116, 108, 0.72) !important;
373
+ opacity: 1 !important;
 
 
 
374
  }
375
 
376
+ .dc-hidden-audio {
 
377
  display: none !important;
378
  }
379
 
380
+ .dc-mic-control {
381
+ align-items: end;
382
+ bottom: 68px;
383
+ display: grid;
384
+ gap: 8px;
385
+ justify-items: end;
386
+ max-width: 280px;
387
+ position: absolute;
388
+ right: 34px;
389
+ z-index: 8;
390
  }
391
 
392
+ .dc-mic-button {
393
+ align-items: center;
394
+ background: rgba(255, 249, 238, 0.96) !important;
395
+ border: 2px solid var(--dc-teal) !important;
396
+ border-radius: 999px !important;
397
+ box-shadow: 0 10px 22px rgba(7, 60, 67, 0.14);
398
+ cursor: pointer;
399
+ display: inline-flex;
400
+ height: 64px !important;
401
+ justify-content: center;
402
+ min-height: 64px !important;
403
+ min-width: 64px !important;
404
+ padding: 0 !important;
405
+ transition: background 160ms ease, transform 160ms ease, border-color 160ms ease;
406
+ width: 64px !important;
407
+ }
408
+
409
+ .dc-mic-button:hover {
410
+ background: var(--dc-teal-soft) !important;
411
+ transform: translateY(-1px);
412
+ }
413
+
414
+ .dc-mic-button[data-mode="listening"] {
415
+ animation: dc-mic-pulse 1.2s ease-in-out infinite;
416
+ background: var(--dc-teal) !important;
417
  }
418
 
419
+ .dc-mic-glyph {
420
+ border: 3px solid var(--dc-teal);
421
+ border-radius: 14px;
422
+ height: 28px;
423
+ position: relative;
424
+ width: 16px;
425
+ }
426
+
427
+ .dc-mic-glyph::before {
428
+ border: 3px solid var(--dc-teal);
429
+ border-top: 0;
430
+ border-radius: 0 0 18px 18px;
431
+ content: "";
432
+ height: 15px;
433
+ left: -9px;
434
+ position: absolute;
435
+ top: 15px;
436
+ width: 28px;
437
+ }
438
+
439
+ .dc-mic-glyph::after {
440
+ background: var(--dc-teal);
441
+ bottom: -19px;
442
+ content: "";
443
+ height: 13px;
444
+ left: 5px;
445
+ position: absolute;
446
+ width: 3px;
447
+ }
448
+
449
+ .dc-mic-button[data-mode="listening"] .dc-mic-glyph,
450
+ .dc-mic-button[data-mode="listening"] .dc-mic-glyph::before {
451
+ border-color: #fff9ee;
452
+ }
453
+
454
+ .dc-mic-button[data-mode="listening"] .dc-mic-glyph::after {
455
+ background: #fff9ee;
456
+ }
457
+
458
+ .dc-mic-status {
459
+ background: rgba(255, 249, 238, 0.9);
460
+ border: 1px solid rgba(11, 91, 100, 0.24);
461
+ border-radius: 999px;
462
+ color: var(--dc-teal-dark);
463
+ font-size: 0.78rem;
464
+ line-height: 1.3;
465
+ max-width: 260px;
466
+ opacity: 0;
467
+ padding: 7px 10px;
468
+ transform: translateY(4px);
469
+ transition: opacity 160ms ease, transform 160ms ease;
470
+ }
471
+
472
+ .dc-mic-control:hover .dc-mic-status,
473
+ .dc-mic-status[data-mode="listening"],
474
+ .dc-mic-status[data-mode="error"],
475
+ .dc-mic-status[data-mode="done"] {
476
+ opacity: 1;
477
+ transform: translateY(0);
478
+ }
479
+
480
+ .dc-mic-status[data-mode="error"] {
481
+ border-color: rgba(199, 83, 66, 0.38);
482
+ color: var(--dc-coral-dark);
483
+ }
484
+
485
+ .dc-field-tip {
486
+ color: var(--dc-muted);
487
+ font-size: 0.88rem;
488
+ line-height: 1.45;
489
+ margin: 12px 0 0;
490
  }
491
 
492
  .dc-side-panel {
493
+ display: flex;
494
+ flex-direction: column;
495
+ gap: 16px;
 
496
  justify-content: space-between;
497
+ }
498
+
499
+ .dc-side-panel .wrap,
500
+ .dc-side-panel .container,
501
+ .dc-side-panel select {
502
+ min-height: 54px !important;
503
  }
504
 
505
  .dc-side-stamp {
506
+ align-items: center;
507
+ border: 2px solid rgba(11, 91, 100, 0.24);
508
+ border-radius: 999px;
509
+ color: rgba(11, 91, 100, 0.62);
510
+ display: flex;
511
+ flex-direction: column;
512
+ height: 156px;
513
+ justify-content: center;
514
+ margin: auto;
515
+ text-align: center;
516
+ transform: rotate(-7deg);
517
+ width: 156px;
518
  }
519
 
520
+ .dc-side-stamp span,
521
+ .dc-side-stamp small {
522
  font-size: 0.72rem;
523
  font-weight: 850;
524
+ text-transform: uppercase;
525
  }
526
 
527
  .dc-side-stamp strong {
528
+ color: var(--dc-teal);
529
+ font-family: Georgia, "Times New Roman", serif;
530
+ font-size: 1.45rem;
531
+ line-height: 1.1;
532
+ margin: 8px 0;
 
 
 
 
 
 
533
  }
534
 
535
  .dc-submit-row {
536
  align-items: stretch !important;
537
  background: transparent !important;
538
  display: grid !important;
539
+ gap: 26px !important;
540
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
541
+ margin-top: 22px;
 
 
 
 
 
 
 
 
542
  }
543
 
544
+ .dc-stage button,
545
+ .dc-dev button {
546
+ border-radius: var(--dc-radius-sm) !important;
547
+ font-family: Georgia, "Times New Roman", serif !important;
548
+ font-weight: 750 !important;
549
+ min-height: 58px !important;
550
  }
551
 
552
+ .dc-stage .dc-mic-button {
553
+ border-radius: 999px !important;
554
+ font-family: "Avenir Next", "Gill Sans", sans-serif !important;
555
+ height: 64px !important;
556
+ min-height: 64px !important;
557
+ min-width: 64px !important;
558
+ width: 64px !important;
559
  }
560
 
561
  .dc-stage .primary button,
562
  .dc-stage button.primary,
563
  button.primary {
564
+ background: linear-gradient(180deg, #d05b4b 0%, var(--dc-coral-dark) 100%) !important;
565
+ border: 1px solid var(--dc-coral-dark) !important;
566
+ box-shadow: 0 12px 24px rgba(159, 62, 50, 0.22);
567
+ color: #fff9ee !important;
568
  }
569
 
570
+ .dc-stage .secondary button,
571
+ .dc-stage button.secondary,
572
+ button.secondary {
573
+ background: rgba(255, 249, 238, 0.82) !important;
574
+ border: 2px solid var(--dc-ink) !important;
575
+ box-shadow: none;
576
  color: var(--dc-ink) !important;
577
  }
578
 
579
  .dc-submit-row button {
580
+ font-size: 1.05rem !important;
581
+ }
582
+
583
+ .dc-attachment-drawer {
584
+ background: rgba(230, 221, 208, 0.52) !important;
585
+ border: 1px solid var(--dc-line) !important;
586
+ border-radius: var(--dc-radius-sm) !important;
587
+ box-shadow: inset 0 1px 2px rgba(19, 41, 47, 0.05) !important;
588
+ margin-top: 18px;
589
  }
590
 
591
  .dc-row {
 
598
  .dc-question h2,
599
  .dc-card h2 {
600
  color: var(--dc-ink) !important;
601
+ font-family: Georgia, "Times New Roman", serif;
602
  font-size: 1.55rem;
 
603
  line-height: 1.2;
604
  margin: 0 0 10px;
605
  }
606
 
607
  .dc-notice {
608
+ background: rgba(220, 235, 230, 0.82);
609
+ border: 1px solid rgba(11, 91, 100, 0.2);
610
  border-radius: var(--dc-radius-sm);
611
  color: var(--dc-teal-dark);
612
  line-height: 1.5;
613
+ margin: 14px 0;
614
  padding: 10px 12px;
615
  }
616
 
 
622
 
623
  .dc-pass-card {
624
  background:
625
+ linear-gradient(180deg, rgba(255, 252, 246, 0.98), rgba(246, 237, 222, 0.98));
626
+ border: 1px solid var(--dc-line-strong);
 
627
  border-radius: var(--dc-radius-md);
628
  color: var(--dc-ink);
629
  line-height: 1.65;
630
+ padding: clamp(16px, 3vw, 28px);
631
+ position: relative;
632
+ }
633
+
634
+ .dc-pass-card::after {
635
+ border: 2px solid rgba(199, 83, 66, 0.38);
636
+ border-radius: 999px;
637
+ color: rgba(199, 83, 66, 0.64);
638
+ content: "CLEAR TO PROCESS";
639
+ font-size: 0.72rem;
640
+ font-weight: 850;
641
+ padding: 24px 12px;
642
+ position: absolute;
643
+ right: 22px;
644
+ top: 22px;
645
+ transform: rotate(8deg);
646
  }
647
 
648
  .dc-pass-topline {
 
653
  font-weight: 800;
654
  justify-content: space-between;
655
  margin-bottom: 12px;
656
+ padding-right: 130px;
657
  }
658
 
659
  .dc-pass-card h2 {
660
  color: var(--dc-ink) !important;
661
+ font-family: Georgia, "Times New Roman", serif;
662
+ font-size: clamp(1.8rem, 6vw, 3.2rem);
663
  line-height: 1;
664
  margin: 0 0 6px;
665
  }
666
 
667
  .dc-pass-risk {
668
+ color: var(--dc-coral-dark);
669
  font-weight: 750;
670
  margin: 0 0 16px;
671
  }
 
678
  .dc-pass-card h3 {
679
  color: var(--dc-teal-dark) !important;
680
  font-size: 0.9rem;
 
681
  margin: 0 0 4px;
682
  }
683
 
 
713
 
714
  .dc-actions {
715
  display: grid !important;
716
+ gap: 10px !important;
717
  grid-template-columns: repeat(4, minmax(0, 1fr));
718
  }
719
 
 
723
  }
724
 
725
  .dc-dev {
726
+ border-radius: var(--dc-radius-md) !important;
727
+ box-shadow: var(--dc-soft-shadow);
728
+ margin-top: 18px;
729
+ padding: 20px !important;
730
  }
731
 
732
  .dc-dev-grid {
733
  align-items: stretch !important;
734
  display: grid !important;
735
+ gap: 0 !important;
736
  grid-template-columns: repeat(3, minmax(0, 1fr));
737
  }
738
 
739
+ .dc-dev-grid > div,
740
+ .dc-dev > div:not(:last-child) {
741
+ border-bottom: 1px solid rgba(189, 168, 143, 0.45);
742
+ }
743
+
744
  .dc-dev .form,
745
  .dc-dev .wrap,
746
  .dc-dev .container,
 
755
  font-size: 0.84rem !important;
756
  }
757
 
758
+ @keyframes dc-mic-pulse {
759
+ 0% {
760
+ box-shadow: 0 0 0 0 rgba(11, 91, 100, 0.32);
761
+ }
762
+ 70% {
763
+ box-shadow: 0 0 0 14px rgba(11, 91, 100, 0);
764
  }
765
+ 100% {
766
+ box-shadow: 0 0 0 0 rgba(11, 91, 100, 0);
767
+ }
768
+ }
769
 
770
+ @media (max-width: 900px) {
771
+ .dc-hero-top {
772
+ grid-template-columns: 36px minmax(0, 1fr);
773
+ }
774
+
775
+ .dc-clearance-badge {
776
+ display: none;
777
+ }
778
+
779
+ .dc-hero::after {
780
+ display: none;
781
+ }
782
+
783
+ .dc-hero-copy {
784
+ margin-left: 54px;
785
  }
786
 
787
  .dc-intake-grid,
 
789
  .dc-row,
790
  .dc-submit-row,
791
  .dc-actions {
792
+ grid-template-columns: 1fr !important;
793
  }
794
 
795
+ .dc-composer,
796
  .dc-side-panel {
797
  min-height: 0;
798
  }
799
 
800
  .dc-side-stamp {
801
+ height: 118px;
802
+ width: 118px;
803
  }
804
 
805
+ .dc-side-stamp strong {
806
+ font-size: 1.08rem;
807
  }
808
+ }
809
 
810
+ @media (max-width: 640px) {
811
+ .dc-shell {
812
+ margin: 0 auto 22px;
813
+ padding: 0 10px;
814
+ }
815
+
816
+ .dc-hero {
817
+ border-radius: 0;
818
+ padding: 16px 14px;
819
+ }
820
+
821
+ .dc-brand-lockup {
822
+ gap: 12px;
823
+ }
824
+
825
+ .dc-passport-icon {
826
+ height: 50px;
827
+ width: 44px;
828
+ }
829
+
830
+ .dc-brand-kicker {
831
+ font-size: 1.12rem;
832
+ }
833
+
834
+ .dc-hero h1 {
835
+ font-size: 2.2rem;
836
+ }
837
+
838
+ .dc-brand-subtitle {
839
+ font-size: 0.72rem;
840
+ }
841
+
842
+ .dc-hero-copy {
843
+ margin: 14px 0 0;
844
  }
845
 
846
  .dc-stage,
847
  .dc-dev {
848
+ border-radius: 0 0 var(--dc-radius-md) var(--dc-radius-md) !important;
849
  box-shadow: none;
850
+ padding: 14px !important;
851
+ }
852
+
853
+ .dc-stage::before {
854
+ display: none;
855
+ }
856
+
857
+ .dc-composer,
858
+ .dc-side-panel {
859
  padding: 14px;
860
  }
861
+
862
+ .dc-dream-text textarea {
863
+ min-height: 300px !important;
864
+ padding-right: 20px !important;
865
+ padding-bottom: 96px !important;
866
+ }
867
+
868
+ .dc-mic-control {
869
+ bottom: 72px;
870
+ left: 20px;
871
+ max-width: calc(100% - 40px);
872
+ right: 20px;
873
+ }
874
+
875
+ .dc-mic-button {
876
+ height: 58px !important;
877
+ min-height: 58px !important;
878
+ min-width: 58px !important;
879
+ width: 58px !important;
880
+ }
881
+
882
+ .dc-pass-topline {
883
+ display: block;
884
+ padding-right: 0;
885
+ }
886
+
887
+ .dc-pass-card::after {
888
+ display: none;
889
+ }
890
  }
891
  """