@tailwind base; @tailwind components; @tailwind utilities; :root { font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; @apply bg-black text-slate-100; } body { margin: 0; min-height: 100vh; @apply bg-black text-slate-100; } html, body { scrollbar-width: thin; scrollbar-color: rgba(148, 163, 184, 0.55) transparent; } * { scrollbar-width: thin; scrollbar-color: rgba(148, 163, 184, 0.55) transparent; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } *::-webkit-scrollbar { width: 2px; height: 2px; } *::-webkit-scrollbar-track { background: transparent; } *::-webkit-scrollbar-thumb { background-color: rgba(148, 163, 184, 0.55); border-radius: 9999px; } @supports (scrollbar-width: thin) { @media (pointer: coarse) { html, body, * { scrollbar-width: none; } } } @layer components { .pride-page-bg { background-color: #050505; background-image: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0)), repeating-linear-gradient( 45deg, #5bcefa 0 1.818%, #f5a9b8 1.818% 3.636%, #ffffff 3.636% 5.455%, #f5a9b8 5.455% 7.273%, #5bcefa 7.273% 9.091%, #e40303 9.091% 10.909%, #ff8c00 10.909% 12.727%, #ffed00 12.727% 14.545%, #00a651 14.545% 16.364%, #0066ff 16.364% 18.182%, #9b2fae 18.182% 20% ); background-attachment: fixed; } .panel { @apply bg-black text-white p-0 rounded-md; } .panel-section { @apply bg-neutral-900 text-white p-0 rounded-md; } .panel-muted { @apply text-sm text-slate-400 rounded-md; } .surface { @apply bg-neutral-800 text-white px-0.5 py-0.5 rounded-md; } .surface-muted { @apply bg-neutral-700 text-neutral-100 px-0.5 py-0.5 rounded-md; } .field-input { @apply bg-neutral-700 border border-neutral-600 text-white placeholder:text-slate-400 px-0.5 py-0.5 focus:outline-none focus:ring-1 focus:ring-sky-500 rounded-md; } .button-dark { @apply px-0.5 py-0.5 text-sm font-medium text-white transition-colors bg-sky-600 hover:bg-sky-500 rounded-md border border-sky-300 hover:border-sky-500; } .button-danger { @apply px-0.5 py-0.5 text-sm font-medium text-white transition-colors bg-rose-600 hover:bg-rose-500 rounded-md; } .chat-composer { /* The chat bar lives in several panel widths, so container queries are more accurate than viewport media queries. The default narrow layout preserves a usable chat row first, then moves all TTS controls to a second row. */ container-type: inline-size; display: flex; flex-wrap: wrap; align-items: stretch; gap: 0.125rem; min-width: 0; overflow: hidden; } .chat-composer-nickname { /* Keep nickname deliberately compact so the message input and Send button remain usable on mobile while still allowing longer typed nicknames. */ flex: 0 0 5rem; min-width: 0; order: 1; } .chat-composer-input { /* This input is the pressure valve for the first row. It can shrink to the remaining space, but the TTS controls no longer steal that row on mobile. */ flex: 1 1 0%; min-width: 0; order: 2; } .chat-composer-send { /* Send must stay with the message input in the narrow two-row layout. */ flex: 0 0 auto; align-self: stretch; order: 3; } .chat-composer-tts { /* The full-width basis is what creates the second row when the composer is narrow; the controls themselves still remain one compact TTS strip. */ display: flex; flex: 1 1 100%; align-items: center; gap: 0.125rem; min-width: 0; overflow: hidden; order: 4; } @container (min-width: 44rem) { .chat-composer { /* Once there is enough room for a meaningful message field, all controls return to the single-row desktop layout. */ flex-wrap: nowrap; } .chat-composer-nickname { flex-basis: 7rem; order: 1; } .chat-composer-input { order: 2; } .chat-composer-tts { flex: 0 1 auto; order: 3; } .chat-composer-send { order: 4; } } } @layer utilities { @keyframes batteryTickWarn { 0%, 49% { background-color: rgba(255, 255, 255, 0.95); } 50%, 100% { background-color: rgba(239, 68, 68, 0.95); } } .battery-tick-warn { animation: batteryTickWarn 0.4s steps(2, end) infinite; } @keyframes batteryUrgentFlash { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0.25; } } .battery-urgent-flash { animation: batteryUrgentFlash 0.4s steps(2, end) infinite; } .no-touch-select { user-select: none; -webkit-user-select: none; -ms-user-select: none; -webkit-touch-callout: none; } .mobile-touch-control { /* Mobile rover controls are press surfaces, not document text. These flags deliberately stack the browser-specific knobs because iOS Safari can still show callouts, selection handles, tap highlights, or delayed gesture behavior when only the standard property is present. */ user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; touch-action: manipulation; overscroll-behavior: contain; } .mobile-drag-control { /* Drag controls need the stricter touch-action value so the browser does not reinterpret a held thumb as page pan, pinch zoom, double-tap zoom, or text selection while the control is actively tracking pointer movement. */ touch-action: none; } .mobile-text-entry { /* iOS Safari zooms focused form fields whose computed text size is below 16px. Keep HUD chat inputs at that threshold instead of fighting focus with JavaScript, because the input still needs normal editing and caret behavior. */ font-size: 16px; -webkit-text-size-adjust: 100%; touch-action: manipulation; } .ios-safe-screen { /* viewport-fit=cover stops iOS from reserving automatic bars on both ends of a homescreen app. We then add back only the unsafe notch edges so controls do not sit under camera hardware, while the opposite edge stays flush. */ /* padding-top: env(safe-area-inset-top); */ /* padding-left: env(safe-area-inset-left); */ /* padding-right: env(safe-area-inset-right); */ /* padding-bottom: 0; */ } }