| 1 | <html> |
| 2 | |
| 3 | <head> |
| 4 | <title>WhatsApp Integration</title> |
| 5 | <script type="module"> |
| 6 | import { store } from "/plugins/_whatsapp_integration/webui/whatsapp-config-store.js"; |
| 7 | </script> |
| 8 | </head> |
| 9 | |
| 10 | <body> |
| 11 | <div x-data x-init="$store.whatsappConfig.init(config, context)" x-destroy="$store.whatsappConfig.cleanup()"> |
| 12 | <template x-if="config"> |
| 13 | <div class="wa-page"> |
| 14 | <div class="section-title">WhatsApp</div> |
| 15 | |
| 16 | <template x-if="config.enabled && $store.whatsappConfig.hasMeaningfulConfig()"> |
| 17 | <div class="wa-summary-card"> |
| 18 | <div class="wa-summary-copy"> |
| 19 | <div class="wa-summary-title">Current setup</div> |
| 20 | <div class="wa-summary-subtitle" |
| 21 | x-text="$store.whatsappConfig.modeSummary() + ' · ' + $store.whatsappConfig.projectSummary()"> |
| 22 | </div> |
| 23 | </div> |
| 24 | <span class="wa-status-pill" :class="'tone-' + $store.whatsappConfig.statusTone()" |
| 25 | x-text="$store.whatsappConfig.statusLabel()"></span> |
| 26 | </div> |
| 27 | </template> |
| 28 | |
| 29 | <div class="wa-wizard-card"> |
| 30 | <div class="wa-step-header"> |
| 31 | <div class="wa-step-copy"> |
| 32 | <div class="wa-step-title" x-text="$store.whatsappConfig.currentStepMeta().title"></div> |
| 33 | <div class="wa-step-description" |
| 34 | x-text="$store.whatsappConfig.currentStepMeta().description"></div> |
| 35 | </div> |
| 36 | <div class="wa-step-dots" aria-hidden="true"> |
| 37 | <template x-for="(step, idx) in $store.whatsappConfig.steps" :key="step.title"> |
| 38 | <button type="button" class="wa-step-dot" |
| 39 | :class="{ 'is-active': $store.whatsappConfig.currentStep === idx }" |
| 40 | @click="$store.whatsappConfig.setStep(idx)"></button> |
| 41 | </template> |
| 42 | </div> |
| 43 | </div> |
| 44 | |
| 45 | <template x-if="$store.whatsappConfig.currentStep === 0"> |
| 46 | <div class="wa-step-panel"> |
| 47 | |
| 48 | <div class="field"> |
| 49 | <div class="field-label"> |
| 50 | <div class="field-title">Turn on WhatsApp</div> |
| 51 | <div class="field-description">Enable the local bridge to start.</div> |
| 52 | </div> |
| 53 | <div class="field-control"> |
| 54 | <label class="toggle"> |
| 55 | <input type="checkbox" |
| 56 | x-model="config.enabled" |
| 57 | @change="$store.whatsappConfig.onEnabledChange()" /> |
| 58 | <span class="toggler"></span> |
| 59 | </label> |
| 60 | </div> |
| 61 | </div> |
| 62 | |
| 63 | <template x-if="config.enabled"> |
| 64 | <div> |
| 65 | <div class="field"> |
| 66 | <div class="field-label"> |
| 67 | <div class="field-title">WhatsApp account</div> |
| 68 | <div class="field-description"> |
| 69 | <span x-show="!$store.whatsappConfig.disconnectMessage">Click "Show QR code" to pair your WhatsApp account.</span> |
| 70 | <span x-show="$store.whatsappConfig.disconnectMessage" |
| 71 | x-text="$store.whatsappConfig.disconnectMessage"></span> |
| 72 | </div> |
| 73 | </div> |
| 74 | <div class="field-control wa-inline-actions"> |
| 75 | <button class="btn btn-field" @click="$store.whatsappConfig.showQr()"> |
| 76 | Show QR code |
| 77 | </button> |
| 78 | <button class="btn btn-field" @click="$store.whatsappConfig.disconnectAccount()" |
| 79 | :disabled="$store.whatsappConfig.disconnecting"> |
| 80 | <span x-show="!$store.whatsappConfig.disconnecting">Disconnect</span> |
| 81 | <span x-show="$store.whatsappConfig.disconnecting">Disconnecting...</span> |
| 82 | </button> |
| 83 | </div> |
| 84 | </div> |
| 85 | |
| 86 | <template x-if="$store.whatsappConfig.qrVisible"> |
| 87 | <div class="wa-qr-panel"> |
| 88 | <template x-if="$store.whatsappConfig.qrStatus === 'connected'"> |
| 89 | <div> |
| 90 | <div class="wa-qr-status ok">Connected</div> |
| 91 | <div class="wa-qr-message" x-text="$store.whatsappConfig.qrMessage"></div> |
| 92 | <button class="btn btn-field" @click="$store.whatsappConfig.hideQr()" |
| 93 | style="margin-top: 12px;"> |
| 94 | Close |
| 95 | </button> |
| 96 | </div> |
| 97 | </template> |
| 98 | |
| 99 | <template |
| 100 | x-if="$store.whatsappConfig.qrStatus === 'waiting_scan' && $store.whatsappConfig.qrDataUrl"> |
| 101 | <div> |
| 102 | <div class="wa-qr-status">Scan with WhatsApp on your phone</div> |
| 103 | <img :src="$store.whatsappConfig.qrDataUrl" alt="WhatsApp QR Code" |
| 104 | class="wa-qr-image" /> |
| 105 | <div class="wa-qr-help">The QR code refreshes automatically.</div> |
| 106 | <button class="btn btn-field" @click="$store.whatsappConfig.hideQr()" |
| 107 | style="margin-top: 12px;"> |
| 108 | Cancel |
| 109 | </button> |
| 110 | </div> |
| 111 | </template> |
| 112 | |
| 113 | <template |
| 114 | x-if="$store.whatsappConfig.qrStatus !== 'connected' && !($store.whatsappConfig.qrStatus === 'waiting_scan' && $store.whatsappConfig.qrDataUrl)"> |
| 115 | <div> |
| 116 | <div class="wa-qr-status" |
| 117 | x-text="$store.whatsappConfig.qrMessage || 'Connecting...'"></div> |
| 118 | <div class="wa-qr-help" |
| 119 | x-show="$store.whatsappConfig.qrStatus !== 'error'"> |
| 120 | Please wait...</div> |
| 121 | <div class="wa-qr-help error" |
| 122 | x-show="$store.whatsappConfig.qrStatus === 'error'" |
| 123 | x-text="$store.whatsappConfig.qrMessage"></div> |
| 124 | <button class="btn btn-field" @click="$store.whatsappConfig.hideQr()" |
| 125 | style="margin-top: 12px;"> |
| 126 | Cancel |
| 127 | </button> |
| 128 | </div> |
| 129 | </template> |
| 130 | </div> |
| 131 | </template> |
| 132 | </div> |
| 133 | </template> |
| 134 | |
| 135 | <div class="wa-note" x-show="!config.enabled"> |
| 136 | Turn on WhatsApp to pair or switch your account. |
| 137 | </div> |
| 138 | |
| 139 | <div class="field"> |
| 140 | <div class="field-label"> |
| 141 | <div class="field-title">Mode</div> |
| 142 | <div class="field-description"> |
| 143 | <span x-show="config.mode === 'self-chat'"> |
| 144 | Use your own number. You can message yourself to talk to the agent. |
| 145 | </span> |
| 146 | <span x-show="config.mode !== 'self-chat'"> |
| 147 | Use a separate number dedicated to Agent Zero conversations. |
| 148 | </span> |
| 149 | </div> |
| 150 | </div> |
| 151 | <div class="field-control"> |
| 152 | <select x-model="config.mode"> |
| 153 | <option value="self-chat">Personal number (self-chat)</option> |
| 154 | <option value="dedicated">Separate number (dedicated)</option> |
| 155 | </select> |
| 156 | </div> |
| 157 | </div> |
| 158 | |
| 159 | <div class="wa-mode-note"> |
| 160 | <strong>Good to know:</strong> Self-chat uses your own number. Dedicated is better for |
| 161 | shared or public access. You can pair now or come back to it later. |
| 162 | </div> |
| 163 | |
| 164 | <div class="wa-warning" x-show="$store.whatsappConfig.accessWarning()"> |
| 165 | <div class="wa-warning-title"> |
| 166 | <span aria-hidden="true">⚠</span> |
| 167 | <span>Warning</span> |
| 168 | </div> |
| 169 | <div class="wa-warning-body" x-text="$store.whatsappConfig.accessWarning()"></div> |
| 170 | </div> |
| 171 | |
| 172 | <div class="field"> |
| 173 | <div class="field-label"> |
| 174 | <div class="field-title">Allowed numbers</div> |
| 175 | <div class="field-description">Comma-separated phone numbers. Punctuation and + |
| 176 | prefixes are okay. Leave empty only if you want open access.</div> |
| 177 | </div> |
| 178 | <div class="field-control"> |
| 179 | <input type="text" :value="$store.whatsappConfig.allowedText()" |
| 180 | @input="$store.whatsappConfig.setAllowed($event.target.value)" |
| 181 | placeholder="+1 (415) 555-1234, +44 7911 123456" /> |
| 182 | </div> |
| 183 | </div> |
| 184 | |
| 185 | <div class="field"> |
| 186 | <div class="field-label"> |
| 187 | <div class="field-title">Allow groups</div> |
| 188 | <div class="field-description">Reply in group chats when mentioned or replied to. |
| 189 | </div> |
| 190 | </div> |
| 191 | <div class="field-control"> |
| 192 | <label class="toggle"> |
| 193 | <input type="checkbox" x-model="config.allow_group" /> |
| 194 | <span class="toggler"></span> |
| 195 | </label> |
| 196 | </div> |
| 197 | </div> |
| 198 | </div> |
| 199 | </template> |
| 200 | |
| 201 | <template x-if="$store.whatsappConfig.currentStep === 1"> |
| 202 | <div class="wa-step-panel"> |
| 203 | <div class="field"> |
| 204 | <div class="field-label"> |
| 205 | <div class="field-title">Project</div> |
| 206 | <div class="field-description">Optional project to activate for WhatsApp |
| 207 | conversations.</div> |
| 208 | </div> |
| 209 | <div class="field-control"> |
| 210 | <select :value="config.project" @change="config.project = $event.target.value"> |
| 211 | <option value="">No project</option> |
| 212 | <template x-for="proj in $store.whatsappConfig.projects" :key="$store.whatsappConfig.projectOptionValue(proj)"> |
| 213 | <option :value="$store.whatsappConfig.projectOptionValue(proj)" |
| 214 | x-text="$store.whatsappConfig.projectOptionLabel(proj)" |
| 215 | :selected="config.project === $store.whatsappConfig.projectOptionValue(proj)"> |
| 216 | </option> |
| 217 | </template> |
| 218 | </select> |
| 219 | </div> |
| 220 | </div> |
| 221 | |
| 222 | <div class="field"> |
| 223 | <div class="field-label"> |
| 224 | <div class="field-title">Agent instructions</div> |
| 225 | <div class="field-description">Extra guidance for how the agent should reply in |
| 226 | WhatsApp chats.</div> |
| 227 | </div> |
| 228 | <div class="field-control"> |
| 229 | <textarea x-model="config.agent_instructions" rows="3" |
| 230 | placeholder="Reply briefly and naturally, like a mobile conversation."></textarea> |
| 231 | </div> |
| 232 | </div> |
| 233 | </div> |
| 234 | </template> |
| 235 | |
| 236 | <div class="wa-test-panel"> |
| 237 | <div class="wa-test-copy"> |
| 238 | <div class="wa-test-title">Check the connection</div> |
| 239 | <div class="wa-test-description">We will check whether the local WhatsApp bridge is up and |
| 240 | connected.</div> |
| 241 | </div> |
| 242 | <button class="btn btn-field" @click="$store.whatsappConfig.testConnection()" |
| 243 | :disabled="$store.whatsappConfig.testing"> |
| 244 | <span x-text="$store.whatsappConfig.testButtonLabel()"></span> |
| 245 | </button> |
| 246 | </div> |
| 247 | |
| 248 | <template x-if="$store.whatsappConfig.testResults"> |
| 249 | <div class="wa-results" :class="{ 'is-error': !$store.whatsappConfig.testResults.success }"> |
| 250 | <template x-for="result in $store.whatsappConfig.testResults.results" |
| 251 | :key="result.test + result.message"> |
| 252 | <div class="wa-result-row"> |
| 253 | <span class="wa-result-icon" x-text="result.ok ? '✓' : '✗'"></span> |
| 254 | <div class="wa-result-copy"> |
| 255 | <div class="wa-result-title" x-text="result.test"></div> |
| 256 | <div class="wa-result-message" x-text="result.message"></div> |
| 257 | </div> |
| 258 | </div> |
| 259 | </template> |
| 260 | </div> |
| 261 | </template> |
| 262 | |
| 263 | <template x-if="$store.whatsappConfig.currentStep > 0"> |
| 264 | <details class="wa-advanced"> |
| 265 | <summary> |
| 266 | <span>Advanced</span> |
| 267 | <x-icon class="wa-advanced-chevron" |
| 268 | aria-hidden="true" name="keyboard_arrow_down"></x-icon> |
| 269 | </summary> |
| 270 | <div class="wa-advanced-body"> |
| 271 | <div class="wa-info-box"> |
| 272 | These settings are here when you need them, but the defaults are fine for most |
| 273 | setups. |
| 274 | </div> |
| 275 | |
| 276 | <div class="field"> |
| 277 | <div class="field-label"> |
| 278 | <div class="field-title">Bridge port</div> |
| 279 | <div class="field-description">Local port for the WhatsApp bridge HTTP server. |
| 280 | </div> |
| 281 | </div> |
| 282 | <div class="field-control"> |
| 283 | <input type="number" x-model.number="config.bridge_port" placeholder="3100" /> |
| 284 | </div> |
| 285 | </div> |
| 286 | |
| 287 | <div class="field"> |
| 288 | <div class="field-label"> |
| 289 | <div class="field-title">Poll interval (seconds)</div> |
| 290 | <div class="field-description">How often to check for new messages. The minimum |
| 291 | is 2 seconds.</div> |
| 292 | </div> |
| 293 | <div class="field-control"> |
| 294 | <input type="number" x-model.number="config.poll_interval_seconds" min="2" |
| 295 | placeholder="3" /> |
| 296 | </div> |
| 297 | </div> |
| 298 | |
| 299 | </div> |
| 300 | </details> |
| 301 | </template> |
| 302 | </div> |
| 303 | </div> |
| 304 | </template> |
| 305 | </div> |
| 306 | |
| 307 | <style> |
| 308 | .wa-page { |
| 309 | display: flex; |
| 310 | flex-direction: column; |
| 311 | gap: 0.9rem; |
| 312 | } |
| 313 | |
| 314 | .wa-summary-card, |
| 315 | .wa-wizard-card { |
| 316 | border-radius: 0.5rem; |
| 317 | } |
| 318 | |
| 319 | .wa-advanced summary { |
| 320 | cursor: pointer; |
| 321 | list-style: none; |
| 322 | font-weight: 700; |
| 323 | display: flex; |
| 324 | align-items: center; |
| 325 | gap: 0.75rem; |
| 326 | } |
| 327 | |
| 328 | .wa-advanced summary::-webkit-details-marker { |
| 329 | display: none; |
| 330 | } |
| 331 | |
| 332 | .wa-summary-title, |
| 333 | .wa-step-title, |
| 334 | .wa-test-title { |
| 335 | font-weight: 700; |
| 336 | } |
| 337 | |
| 338 | .wa-summary-subtitle, |
| 339 | .wa-step-description, |
| 340 | .wa-note, |
| 341 | .wa-mode-note, |
| 342 | .wa-test-description, |
| 343 | .wa-result-message { |
| 344 | color: var(--color-text-secondary); |
| 345 | line-height: 1.5; |
| 346 | } |
| 347 | |
| 348 | .wa-summary-card { |
| 349 | padding: 1rem; |
| 350 | border: 1px solid var(--color-border); |
| 351 | display: flex; |
| 352 | justify-content: space-between; |
| 353 | gap: 1rem; |
| 354 | align-items: center; |
| 355 | } |
| 356 | |
| 357 | .wa-step-header { |
| 358 | display: flex; |
| 359 | justify-content: space-between; |
| 360 | gap: 1rem; |
| 361 | align-items: flex-start; |
| 362 | margin-bottom: 1rem; |
| 363 | } |
| 364 | |
| 365 | .wa-step-dots { |
| 366 | display: flex; |
| 367 | gap: 0.5rem; |
| 368 | flex-wrap: wrap; |
| 369 | justify-content: flex-end; |
| 370 | align-items: center; |
| 371 | } |
| 372 | |
| 373 | .wa-step-dot { |
| 374 | width: 0.85rem; |
| 375 | height: 0.85rem; |
| 376 | border-radius: 999px; |
| 377 | border: 1px solid var(--color-border); |
| 378 | background: transparent; |
| 379 | cursor: pointer; |
| 380 | padding: 0; |
| 381 | } |
| 382 | |
| 383 | .wa-step-dot.is-active { |
| 384 | background: rgba(59, 130, 246, 0.9); |
| 385 | border-color: rgba(59, 130, 246, 0.9); |
| 386 | } |
| 387 | |
| 388 | .wa-step-panel { |
| 389 | display: flex; |
| 390 | flex-direction: column; |
| 391 | gap: 0.2rem; |
| 392 | } |
| 393 | |
| 394 | .wa-info-box, |
| 395 | .wa-note { |
| 396 | margin-bottom: 0.9rem; |
| 397 | padding: 0.8rem 0.9rem; |
| 398 | border-radius: 12px; |
| 399 | font-size: var(--font-size-small); |
| 400 | } |
| 401 | |
| 402 | .wa-info-box { |
| 403 | background: color-mix(in srgb, #3b82f6 12%, var(--color-background) 88%); |
| 404 | } |
| 405 | |
| 406 | .wa-note { |
| 407 | background: color-mix(in srgb, var(--color-background) 88%, white 12%); |
| 408 | } |
| 409 | |
| 410 | .wa-warning { |
| 411 | margin: 0.5rem 0 1.25rem; |
| 412 | padding: 0.75rem 0.9rem; |
| 413 | border-radius: 10px; |
| 414 | border: 1px solid rgba(255, 170, 0, 0.45); |
| 415 | background: rgba(255, 170, 0, 0.12); |
| 416 | color: var(--color-warning-text); |
| 417 | font-size: var(--font-size-small); |
| 418 | } |
| 419 | |
| 420 | .wa-warning-title { |
| 421 | font-weight: 600; |
| 422 | display: flex; |
| 423 | align-items: center; |
| 424 | gap: 0.5rem; |
| 425 | } |
| 426 | |
| 427 | .wa-warning-body { |
| 428 | margin-top: 0.25rem; |
| 429 | line-height: 1.45; |
| 430 | } |
| 431 | |
| 432 | .wa-mode-note { |
| 433 | margin-top: -0.2rem; |
| 434 | margin-bottom: 0.9rem; |
| 435 | font-size: var(--font-size-small); |
| 436 | } |
| 437 | |
| 438 | .wa-inline-actions { |
| 439 | display: flex; |
| 440 | gap: 0.75rem; |
| 441 | flex-wrap: wrap; |
| 442 | } |
| 443 | |
| 444 | .wa-qr-panel { |
| 445 | margin-top: 0.25rem; |
| 446 | padding: 1rem; |
| 447 | border-radius: 14px; |
| 448 | border: 1px solid color-mix(in srgb, var(--color-border) 88%, white 12%); |
| 449 | background: color-mix(in srgb, var(--color-background) 90%, white 10%); |
| 450 | text-align: center; |
| 451 | } |
| 452 | |
| 453 | .wa-qr-status { |
| 454 | font-weight: 700; |
| 455 | margin-bottom: 0.5rem; |
| 456 | } |
| 457 | |
| 458 | .wa-qr-status.ok { |
| 459 | color: #7ee7a4; |
| 460 | } |
| 461 | |
| 462 | .wa-qr-message, |
| 463 | .wa-qr-help { |
| 464 | color: var(--color-text-secondary); |
| 465 | line-height: 1.5; |
| 466 | } |
| 467 | |
| 468 | .wa-qr-help { |
| 469 | font-size: var(--font-size-small); |
| 470 | margin-top: 0.4rem; |
| 471 | } |
| 472 | |
| 473 | .wa-qr-help.error { |
| 474 | color: #fca5a5; |
| 475 | } |
| 476 | |
| 477 | .wa-qr-image { |
| 478 | width: 256px; |
| 479 | height: 256px; |
| 480 | max-width: 100%; |
| 481 | border-radius: 8px; |
| 482 | background: white; |
| 483 | padding: 4px; |
| 484 | } |
| 485 | |
| 486 | .wa-advanced { |
| 487 | margin-top: 1rem; |
| 488 | border: 1px solid color-mix(in srgb, var(--color-border) 88%, white 12%); |
| 489 | border-radius: 14px; |
| 490 | overflow: hidden; |
| 491 | } |
| 492 | |
| 493 | .wa-advanced summary { |
| 494 | padding: 0.9rem 1rem; |
| 495 | background: color-mix(in srgb, var(--color-background) 88%, white 12%); |
| 496 | } |
| 497 | |
| 498 | .wa-advanced-chevron { |
| 499 | margin-left: auto; |
| 500 | flex: 0 0 auto; |
| 501 | transition: transform 0.18s ease, opacity 0.18s ease; |
| 502 | opacity: 0.72; |
| 503 | } |
| 504 | |
| 505 | .wa-advanced[open] .wa-advanced-chevron { |
| 506 | transform: rotate(180deg); |
| 507 | opacity: 1; |
| 508 | } |
| 509 | |
| 510 | .wa-advanced-body { |
| 511 | padding: 1rem; |
| 512 | display: flex; |
| 513 | flex-direction: column; |
| 514 | gap: 0.2rem; |
| 515 | } |
| 516 | |
| 517 | .wa-test-panel { |
| 518 | margin-top: 1rem; |
| 519 | padding: var(--spacing-xs) 0; |
| 520 | display: flex; |
| 521 | justify-content: space-between; |
| 522 | align-items: center; |
| 523 | gap: 1rem; |
| 524 | } |
| 525 | |
| 526 | .wa-test-copy, |
| 527 | .wa-result-copy { |
| 528 | min-width: 0; |
| 529 | } |
| 530 | |
| 531 | .wa-results { |
| 532 | margin-top: 0.9rem; |
| 533 | border-radius: 14px; |
| 534 | border: 1px solid color-mix(in srgb, #22c55e 28%, var(--color-border) 72%); |
| 535 | background: color-mix(in srgb, #22c55e 8%, var(--color-background) 92%); |
| 536 | padding: 0.35rem 0.9rem; |
| 537 | } |
| 538 | |
| 539 | .wa-results.is-error { |
| 540 | border-color: color-mix(in srgb, #ef4444 28%, var(--color-border) 72%); |
| 541 | background: color-mix(in srgb, #ef4444 8%, var(--color-background) 92%); |
| 542 | } |
| 543 | |
| 544 | .wa-result-row { |
| 545 | display: flex; |
| 546 | align-items: flex-start; |
| 547 | gap: 0.8rem; |
| 548 | padding: 0.7rem 0; |
| 549 | } |
| 550 | |
| 551 | .wa-result-row+.wa-result-row { |
| 552 | border-top: 1px solid color-mix(in srgb, var(--color-border) 85%, white 15%); |
| 553 | } |
| 554 | |
| 555 | .wa-result-icon { |
| 556 | width: 1.25rem; |
| 557 | font-weight: 800; |
| 558 | line-height: 1.3; |
| 559 | } |
| 560 | |
| 561 | .wa-result-title { |
| 562 | font-weight: 700; |
| 563 | margin-bottom: 0.18rem; |
| 564 | } |
| 565 | |
| 566 | .wa-status-pill { |
| 567 | display: inline-flex; |
| 568 | align-items: center; |
| 569 | justify-content: center; |
| 570 | min-width: 5.25rem; |
| 571 | padding: 0.35rem 0.7rem; |
| 572 | border-radius: 999px; |
| 573 | font-size: 0.8rem; |
| 574 | font-weight: 700; |
| 575 | } |
| 576 | |
| 577 | .wa-status-pill.tone-success { |
| 578 | background: rgba(34, 197, 94, 0.14); |
| 579 | color: #7ee7a4; |
| 580 | } |
| 581 | |
| 582 | .wa-status-pill.tone-ready { |
| 583 | background: rgba(59, 130, 246, 0.16); |
| 584 | color: #93c5fd; |
| 585 | } |
| 586 | |
| 587 | .wa-status-pill.tone-warning { |
| 588 | background: rgba(245, 158, 11, 0.16); |
| 589 | color: #fcd34d; |
| 590 | } |
| 591 | |
| 592 | .wa-status-pill.tone-muted { |
| 593 | background: rgba(148, 163, 184, 0.14); |
| 594 | color: #cbd5e1; |
| 595 | } |
| 596 | |
| 597 | @media (max-width: 640px) { |
| 598 | |
| 599 | .wa-summary-card, |
| 600 | .wa-step-header, |
| 601 | .wa-test-panel { |
| 602 | flex-direction: column; |
| 603 | align-items: stretch; |
| 604 | } |
| 605 | |
| 606 | .wa-step-dots { |
| 607 | width: 100%; |
| 608 | justify-content: space-between; |
| 609 | } |
| 610 | |
| 611 | .wa-status-pill { |
| 612 | min-width: 0; |
| 613 | align-self: flex-start; |
| 614 | } |
| 615 | } |
| 616 | </style> |
| 617 | </body> |
| 618 | |
| 619 | </html> |