diff --git a/app/components/live-atc/cockpit/CockpitShell.vue b/app/components/live-atc/cockpit/CockpitShell.vue index 1c66a46..a5a745f 100644 --- a/app/components/live-atc/cockpit/CockpitShell.vue +++ b/app/components/live-atc/cockpit/CockpitShell.vue @@ -1,5 +1,5 @@ @@ -237,16 +263,38 @@ const showExpectedComm = computed( - - {{ bugReportCapturing ? 'mdi-loading mdi-spin' : 'mdi-bug-outline' }} - {{ bugReportCapturing ? '…' : 'Report issue' }} - + + + {{ bugReportCapturing ? 'mdi-loading mdi-spin' : 'mdi-bug-outline' }} + {{ bugReportCapturing ? '…' : 'Report issue' }} + + + + + + + + mdi-bug-outline + Found a bug? + + + Live ATC is an early alpha. Hit Report issue anytime something + feels off — it captures the session and helps us fix it. + + + Got it + + + + + - - mdi-radar - + + mdi-arrow-left + + Back + Switch mode + + - OpenSquawk - | - - - - {{ activeExperience.label }} - mdi-chevron-down - - - - - {{ option.icon }} - - {{ option.label }} - {{ option.description }} - - mdi-check - - - - + + mdi-radar + Classroom + @@ -1086,14 +1054,6 @@ mdi-check mdi-alert - - mdi-microphone - Expected: {{ fieldExpectedValue(segment.key) }} @@ -1126,105 +1086,6 @@ mdi-volume-high Speak answer - - - {{ sttTranscribing ? 'mdi-loading' : (sttRecording ? 'mdi-stop-circle' : 'mdi-microphone') }} - - Transcribing… - Stop ({{ formatSttDuration(sttRecordingSeconds) }}) - Speak readback - - - mdi-microphone-off - Speech server unavailable - - - - - - - - - {{ sttRecording ? 'mdi-microphone' : (sttTranscribing ? 'mdi-loading' : (sttError ? 'mdi-alert-circle' : 'mdi-microphone-message')) }} - - Recording — {{ formatSttDuration(sttRecordingSeconds) }} - Transcribing your readback… - Couldn't transcribe - Whisper heard - - - Filled {{ sttLastFillSummary.filled }} / {{ sttLastFillSummary.total }} field{{ sttLastFillSummary.total === 1 ? '' : 's' }} - - - - - - - {{ f.matched ? 'mdi-check-circle' : 'mdi-close-circle' }} - {{ f.key }} - {{ f.expected || '—' }} - recognised ({{ f.view }}) - not recognised - - folded: {{ sttLastReport.denormalized }} - - - {{ sttError }} - - - - Speak clearly into your microphone. Click Stop when done. - Sending audio to the speech server… - - - - - - - mdi-arrow-down-bold-circle - Apply to fields - - - mdi-microphone - Record again - - - mdi-close - Dismiss - - - {{ result.score }}% @@ -1926,53 +1787,6 @@ const manualSectionsOpen = reactive>({ const router = useRouter() const route = useRoute() -type ExperienceId = 'classroom' | 'live' -type ExperienceOption = { - id: ExperienceId - label: string - description: string - icon: string - to: string - target?: '_self' | '_blank' - matches: (path: string) => boolean -} - -const experiences: ExperienceOption[] = [ - { - id: 'classroom', - label: 'Classroom', - description: 'Mission hub & drills', - icon: 'mdi-school', - to: '/classroom', - target: '_self', - matches: path => path.startsWith('/classroom') || path.startsWith('/classroom-introduction') - }, - { - id: 'live', - label: 'Live ATC', - description: 'Live radio with AI controllers', - icon: 'mdi-radio-handheld', - to: '/bridge', - target: '_blank', - matches: path => path.startsWith('/live-atc') || path.startsWith('/pm') - } -] - -const experienceMenu = ref(false) -const activeExperience = computed(() => { - const path = route.path - return experiences.find(option => option.matches(path)) ?? experiences[0] -}) - -async function handleExperienceSelect(option: ExperienceOption) { - experienceMenu.value = false - if (option.matches(route.path)) return - if (option.target === '_blank') { - window.open(option.to, '_blank') - return - } - await router.push(option.to) -} const ROUTE_STATE_KEYS = ['panel', 'module', 'stage', 'lesson', 'plan'] as const type RouteStateKey = typeof ROUTE_STATE_KEYS[number] @@ -5244,16 +5058,64 @@ onBeforeUnmount(() => { padding: 0 16px; } -.hud-logo { +.hud-back { display: inline-flex; align-items: center; - justify-content: center; - width: 44px; + gap: 8px; height: 44px; + padding: 0 14px 0 10px; border-radius: 14px; border: 1px solid color-mix(in srgb, var(--accent) 38%, transparent); background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); + text-decoration: none; + transition: border-color .2s ease, background .2s ease, color .2s ease; +} + +.hud-back:hover, +.hud-back:focus-visible { + border-color: color-mix(in srgb, var(--accent) 54%, transparent); + background: color-mix(in srgb, var(--accent) 22%, transparent); + outline: none; +} + +.hud-back:focus-visible { + box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 30%, transparent); +} + +.hud-back-icon { + color: currentColor; +} + +.hud-back-body { + display: flex; + flex-direction: column; + line-height: 1.05; +} + +.hud-back-label { + font-weight: 600; + font-size: 14px; +} + +.hud-back-sub { + font-size: 10px; + text-transform: uppercase; + letter-spacing: .12em; + opacity: .7; +} + +.hud-logo { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + height: 44px; + padding: 0 14px; + border-radius: 14px; + border: 1px solid var(--border); + background: transparent; + color: var(--t2); transition: border-color .2s ease, background .2s ease, color .2s ease; } diff --git a/app/pages/start.vue b/app/pages/start.vue index 3d52df6..2f8dcae 100644 --- a/app/pages/start.vue +++ b/app/pages/start.vue @@ -34,10 +34,20 @@ - Classroom + 1. Classroom Structured, self-paced radio practice. No simulator required — this is where most pilots start. + + + + Headphones + + + + No mic needed + + Start Classroom @@ -67,11 +77,21 @@ - Live ATC + 2. Live ATC Connect your simulator and fly against our live AI controller. Early alpha — not everything works reliably yet. We'd love your bug reports; this is also how we figure out where to take it next. + + + + Headphones + + + + Microphone + + Try Live ATC (Alpha) @@ -100,11 +120,21 @@ - Live ATC + 2. Live ATC Connect your simulator and fly against our live AI controller. Early alpha — not everything works reliably yet. We'd love your bug reports; this is also how we figure out where to take it next. + + + + Headphones + + + + Microphone + + Unlocks {{ unlockEstimate }} after signup @@ -116,7 +146,6 @@ + +
+ Live ATC is an early alpha. Hit Report issue anytime something + feels off — it captures the session and helps us fix it. +
Classroom
1. Classroom
Structured, self-paced radio practice. No simulator required — this is where most pilots start.
Live ATC
2. Live ATC
Connect your simulator and fly against our live AI controller. Early alpha — not everything works reliably yet. We'd love your bug reports; this is also how we figure out where to take it next.
Unlocks {{ unlockEstimate }} after signup