*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } :root { --bg: #000000; --text: #ffffff; --muted: #9ca3af; --input-bg: #1a1a1a; --border: #374151; --border-focus: #6b7280; --confirm-bg: #374151; --confirm-active: #4b5563; --sos: #cc2626; --sos-pressed: #991c1c; --sos-success: #16a34a; --banner-bg: #7c2d12; --banner-text: #fed7aa; } html, body { height: 100%; background: var(--bg); color: var(--text); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; -webkit-tap-highlight-color: transparent; overscroll-behavior: none; user-select: none; } body { display: flex; flex-direction: column; min-height: 100vh; /* Use dynamic viewport height on mobile to account for browser chrome */ min-height: 100dvh; } /* ===== Private mode banner (decision #1041) ===== */ .private-banner { background: var(--banner-bg); color: var(--banner-text); padding: 10px 16px; font-size: 13px; line-height: 1.5; text-align: center; flex-shrink: 0; } .private-banner[hidden] { display: none; } /* ===== Top bar ===== */ .topbar { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; flex-shrink: 0; } .user-avatar { width: 36px; height: 36px; border-radius: 50%; background: #374151; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; color: var(--text); letter-spacing: 0; } .network-indicator { width: 22px; height: 22px; border-radius: 50%; background: var(--muted); transition: background 0.3s ease; } .network-indicator.online { background: #16a34a; } .network-indicator.offline { background: #4b5563; } /* ===== Screens ===== */ .screen { flex: 1; display: flex; flex-direction: column; min-height: 0; } .screen[hidden] { display: none; } .screen-content { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; padding: 24px 20px; } /* ===== Onboarding ===== */ .name-input { width: 100%; max-width: 320px; padding: 14px 16px; background: var(--input-bg); border: 1.5px solid var(--border); border-radius: 12px; color: var(--text); font-size: 17px; outline: none; transition: border-color 0.15s; -webkit-appearance: none; user-select: text; } .name-input::placeholder { color: var(--muted); } .name-input:focus { border-color: var(--border-focus); } .btn-confirm { width: 100%; max-width: 320px; padding: 14px; background: var(--confirm-bg); border: none; border-radius: 12px; color: var(--text); font-size: 17px; font-weight: 600; cursor: pointer; transition: background 0.15s, opacity 0.15s; } .btn-confirm:disabled { opacity: 0.35; cursor: default; } .btn-confirm:not(:disabled):active { background: var(--confirm-active); } /* ===== SOS button (min 60vmin × 60vmin per UX spec) ===== */ .btn-sos { width: 60vmin; height: 60vmin; min-width: 180px; min-height: 180px; border-radius: 50%; border: none; background: var(--sos); color: #fff; font-size: clamp(24px, 9vmin, 60px); font-weight: 900; letter-spacing: 0.08em; cursor: pointer; touch-action: manipulation; transition: background 0.15s ease, transform 0.1s ease; } .btn-sos:active, .btn-sos[data-state="sending"] { background: var(--sos-pressed); transform: scale(0.96); } .btn-sos[data-state="sending"] { animation: baton-pulse 1s ease-in-out infinite; cursor: default; pointer-events: none; } .btn-sos[data-state="success"] { background: var(--sos-success); transform: none; } @keyframes baton-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } } /* ===== Status message ===== */ .status { padding: 12px 20px; text-align: center; font-size: 14px; flex-shrink: 0; } .status[hidden] { display: none; } .status--error { color: #f87171; } .status--success { color: #4ade80; }