/* Design tokens from gui.md — same values used throughout the mockups built and approved earlier (QR/PIN, error/security, status, ambient). */ :root { --card-bg: #ffffff; --card-border: rgba(15, 23, 42, 0.08); --text-primary: #0f172a; --text-secondary: #667085; --text-tertiary: #94a3b8; --accent: #2f6fed; --accent-hover: #2559c9; --accent-tint: #e9f0fe; --accent-track: #e2e8f0; --box-border: #d7dce4; --box-bg: #f8fafc; --divider: rgba(15, 23, 42, 0.07); --ghost-hover: rgba(15, 23, 42, 0.04); --btn-border: #d7dce4; --neutral-badge: #94a3b8; --neutral-tint: #eef1f4; --inactive-badge: #cbd5e1; --inactive-tint: #f4f6f8; --amber: #f59e0b; --amber-tint: #fef3e2; --red: #dc2626; --red-tint: #fdecec; --green: #16a34a; --green-tint: #e8f6ec; } @media (prefers-color-scheme: dark) { :root { --card-bg: #12161f; --card-border: rgba(255, 255, 255, 0.08); --text-primary: #f1f5f9; --text-secondary: #94a3b8; --text-tertiary: #64748b; --accent: #5b8bff; --accent-hover: #7fa2ff; --accent-tint: rgba(91, 139, 255, 0.14); --accent-track: #232a38; --box-border: #2a3140; --box-bg: #171c26; --divider: rgba(255, 255, 255, 0.08); --ghost-hover: rgba(255, 255, 255, 0.06); --btn-border: #2a3140; --neutral-badge: #64748b; --neutral-tint: rgba(100, 116, 139, 0.16); --inactive-badge: #475569; --inactive-tint: rgba(71, 85, 105, 0.16); --amber: #fbbf24; --amber-tint: rgba(251, 191, 36, 0.12); --red: #ef4444; --red-tint: rgba(239, 68, 68, 0.12); --green: #22c55e; --green-tint: rgba(34, 197, 94, 0.14); } } * { box-sizing: border-box; } html, body { margin: 0; width: 300px; } body { background: var(--card-bg); color: var(--text-primary); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif; } .card-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 1px solid var(--divider); } .brand { display: flex; align-items: center; gap: 8px; } .brand .mark { width: 20px; height: 20px; border-radius: 6px; background: var(--accent); } .brand .word { font-weight: 700; font-size: 14.5px; letter-spacing: -0.01em; color: var(--text-primary); } .origin { font-size: 12.5px; color: var(--text-tertiary); max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .card-body { padding: 28px 20px 22px; display: flex; flex-direction: column; align-items: center; text-align: center; /* Chrome sizes a popup's window once, from its content height at first paint, and does not reliably resize it as innerHTML later changes (confirmed the hard way: a popup opened during a short state like idle stayed that size through phase_2/3, leaving the real buttons below the window's actual clickable bounds — clicking them landed "outside" the popup and closed it). Sized for phase_2's QR screen (the tallest: 260px canvas + countdown + caption + action ≈ 416px), so every state gets the same window size regardless of which one is showing when the popup first opens. */ min-height: 420px; justify-content: center; } .status-badge { width: 48px; height: 48px; border-radius: 13px; display: flex; align-items: center; justify-content: center; margin-bottom: 16px; flex-shrink: 0; } .status-badge svg { width: 22px; height: 22px; } .pulse { animation: locqr-pulse 1.6s ease-in-out infinite; } @keyframes locqr-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } } .spinner { animation: locqr-spin 1.1s linear infinite; } @keyframes locqr-spin { to { transform: rotate(360deg); } } @media (prefers-reduced-motion: reduce) { .pulse, .spinner { animation: none; } } .status-heading { font-size: 14.5px; font-weight: 650; color: var(--text-primary); margin-bottom: 6px; } .status-heading.security { color: var(--red); } .status-body { font-size: 12.5px; line-height: 1.55; color: var(--text-secondary); max-width: 230px; } .actions { width: 100%; margin-top: 20px; display: flex; flex-direction: column; gap: 8px; } .btn-primary { width: 100%; padding: 10px 0; border: none; border-radius: 10px; background: var(--accent); color: #fff; font-size: 14px; font-weight: 600; cursor: pointer; } .btn-primary:hover { background: var(--accent-hover); } .btn-primary:disabled { opacity: 0.6; cursor: default; } .btn-ghost { width: 100%; padding: 8px 0; border: none; background: none; color: var(--text-secondary); font-size: 13px; font-weight: 600; cursor: pointer; border-radius: 8px; } .btn-ghost:hover { background: var(--ghost-hover); } .status-note { font-size: 12.5px; color: var(--text-tertiary); margin-top: 14px; } .ring-spinner { width: 22px; height: 22px; border: 2.4px solid var(--accent-tint); border-top-color: var(--accent); border-radius: 50%; } .countdown-bar { width: 100%; height: 4px; border-radius: 999px; background: var(--accent-track); overflow: hidden; margin: 16px 0 14px; } .countdown-fill { height: 100%; width: 100%; background: var(--accent); border-radius: 999px; transition: width 0.2s linear; } .qr-canvas { width: 260px; height: 260px; display: block; } .pin-groups { display: flex; gap: 18px; } .pin-group { display: flex; gap: 6px; } .pin-digit { width: 42px; height: 50px; border: 1.5px solid var(--box-border); background: var(--box-bg); border-radius: 10px; display: flex; align-items: center; justify-content: center; font-family: "SF Mono", "Menlo", "Consolas", monospace; font-size: 21px; font-weight: 650; color: var(--text-primary); }