diff --git a/apps/desktop/src-tauri/src/lib.rs b/apps/desktop/src-tauri/src/lib.rs
index a01f49fe47..596a9cc67d 100644
--- a/apps/desktop/src-tauri/src/lib.rs
+++ b/apps/desktop/src-tauri/src/lib.rs
@@ -42,7 +42,7 @@ use general_settings::GeneralSettingsStore;
 use mp4::Mp4Reader;
 use notifications::NotificationType;
 use png::{ColorType, Encoder};
-use recording::InProgressRecording;
+use recording::{InProgressRecording, StartRecordingInputs};
 use relative_path::RelativePathBuf;
 
 use scap::capturer::Capturer;
@@ -85,6 +85,12 @@ use windows::EditorWindowIds;
 use windows::set_window_transparent;
 use windows::{CapWindowId, ShowCapWindow};
 
+pub enum RecordingState {
+    None,
+    Pending,
+    Active(InProgressRecording),
+}
+
 #[derive(specta::Type, Serialize)]
 #[serde(rename_all = "camelCase")]
 pub struct App {
@@ -104,7 +110,7 @@ pub struct App {
     #[serde(skip)]
     handle: AppHandle,
     #[serde(skip)]
-    current_recording: Option<InProgressRecording>,
+    recording_state: RecordingState,
     #[serde(skip)]
     recording_logging_handle: LoggingHandle,
     server_url: String,
@@ -140,16 +146,27 @@ pub struct VideoUploadInfo {
 }
 
 impl App {
-    pub fn set_current_recording(&mut self, actor: InProgressRecording) {
-        self.current_recording = Some(actor);
+    pub fn set_pending_recording(&mut self) {
+        self.recording_state = RecordingState::Pending;
+        CurrentRecordingChanged.emit(&self.handle).ok();
+    }
 
+    pub fn set_current_recording(&mut self, actor: InProgressRecording) {
+        self.recording_state = RecordingState::Active(actor);
         CurrentRecordingChanged.emit(&self.handle).ok();
     }
 
     pub fn clear_current_recording(&mut self) -> Option<InProgressRecording> {
-        self.close_occluder_windows();
-
-        self.current_recording.take()
+        match std::mem::replace(&mut self.recording_state, RecordingState::None) {
+            RecordingState::Active(recording) => {
+                self.close_occluder_windows();
+                Some(recording)
+            }
+            _ => {
+                self.close_occluder_windows();
+                None
+            }
+        }
     }
 
     fn close_occluder_windows(&self) {
@@ -175,6 +192,24 @@ impl App {
 
         Ok(())
     }
+
+    pub fn current_recording(&self) -> Option<&InProgressRecording> {
+        match &self.recording_state {
+            RecordingState::Active(recording) => Some(recording),
+            _ => None,
+        }
+    }
+
+    pub fn current_recording_mut(&mut self) -> Option<&mut InProgressRecording> {
+        match &mut self.recording_state {
+            RecordingState::Active(recording) => Some(recording),
+            _ => None,
+        }
+    }
+
+    pub fn is_recording_active_or_pending(&self) -> bool {
+        !matches!(self.recording_state, RecordingState::None)
+    }
 }
 
 #[tauri::command]
@@ -389,7 +424,7 @@ async fn get_current_recording(
     state: MutableState<'_, App>,
 ) -> Result<JsonValue<Option<CurrentRecording>>, ()> {
     let state = state.read().await;
-    Ok(JsonValue::new(&state.current_recording.as_ref().map(|r| {
+    Ok(JsonValue::new(&state.current_recording().map(|r| {
         let bounds = r.bounds();
 
         let target = match r.capture_target() {
@@ -2041,7 +2076,7 @@ pub async fn run(recording_logging_handle: LoggingHandle) {
                     camera_feed_initialization: None,
                     mic_samples_tx: audio_input_tx,
                     mic_feed: None,
-                    current_recording: None,
+                    recording_state: RecordingState::None,
                     recording_logging_handle,
                     server_url: GeneralSettingsStore::get(&app)
                         .ok()
@@ -2130,7 +2165,7 @@ pub async fn run(recording_logging_handle: LoggingHandle) {
                                     let state = app.state::<Arc<RwLock<App>>>();
                                     let app_state = &mut *state.write().await;
 
-                                    if app_state.current_recording.is_none() {
+                                    if !app_state.is_recording_active_or_pending() {
                                         app_state.mic_feed.take();
                                         app_state.camera_feed.take();
 
diff --git a/apps/desktop/src-tauri/src/recording.rs b/apps/desktop/src-tauri/src/recording.rs
index 221fd91eb9..01bcbead86 100644
--- a/apps/desktop/src-tauri/src/recording.rs
+++ b/apps/desktop/src-tauri/src/recording.rs
@@ -192,7 +192,7 @@ pub fn list_cameras() -> Vec<cap_camera::CameraInfo> {
     CameraFeed::list_cameras()
 }
 
-#[derive(Deserialize, Type, Clone)]
+#[derive(Deserialize, Type, Clone, Debug)]
 pub struct StartRecordingInputs {
     pub capture_target: ScreenCaptureTarget,
     #[serde(default)]
@@ -327,6 +327,12 @@ pub async fn start_recording(
         _ => {}
     }
 
+    // Set pending state BEFORE closing main window and starting countdown
+    {
+        let mut state = state_mtx.write().await;
+        state.set_pending_recording();
+    }
+
     if let Some(window) = CapWindowId::Main.get(&app) {
         let _ = general_settings
             .map(|v| v.main_window_recording_start_behaviour)
@@ -496,7 +502,7 @@ pub async fn start_recording(
 pub async fn pause_recording(state: MutableState<'_, App>) -> Result<(), String> {
     let mut state = state.write().await;
 
-    if let Some(recording) = state.current_recording.as_mut() {
+    if let Some(recording) = state.current_recording_mut() {
         recording.pause().await.map_err(|e| e.to_string())?;
     }
 
@@ -508,7 +514,7 @@ pub async fn pause_recording(state: MutableState<'_, App>) -> Result<(), String>
 pub async fn resume_recording(state: MutableState<'_, App>) -> Result<(), String> {
     let mut state = state.write().await;
 
-    if let Some(recording) = state.current_recording.as_mut() {
+    if let Some(recording) = state.current_recording_mut() {
         recording.resume().await.map_err(|e| e.to_string())?;
     }
 
@@ -595,7 +601,7 @@ async fn handle_recording_end(
     app: &mut App,
 ) -> Result<(), String> {
     // Clear current recording, just in case :)
-    app.current_recording.take();
+    app.clear_current_recording();
 
     let res = if let Some(recording) = recording {
         // we delay reporting errors here so that everything else happens first
diff --git a/apps/desktop/src/utils/tauri.ts b/apps/desktop/src/utils/tauri.ts
index 283e5f4a1d..9b072346a1 100644
--- a/apps/desktop/src/utils/tauri.ts
+++ b/apps/desktop/src/utils/tauri.ts
@@ -383,8 +383,8 @@ export type PresetsStore = { presets: Preset[]; default: number | null }
 export type ProjectConfiguration = { aspectRatio: AspectRatio | null; background: BackgroundConfiguration; camera: Camera; audio: AudioConfiguration; cursor: CursorConfiguration; hotkeys: HotkeysConfiguration; timeline?: TimelineConfiguration | null; captions?: CaptionsData | null }
 export type ProjectRecordingsMeta = { segments: SegmentRecordings[] }
 export type RecordingEvent = { variant: "Countdown"; value: number } | { variant: "Started" } | { variant: "Stopped" } | { variant: "Failed"; error: string }
-export type RecordingMeta = (StudioRecordingMeta | InstantRecordingMeta) & { platform: Platform | null; pretty_name: string; sharing?: SharingMeta | null }
-export type RecordingMetaWithType = ((StudioRecordingMeta | InstantRecordingMeta) & { platform: Platform | null; pretty_name: string; sharing?: SharingMeta | null }) & { type: RecordingType }
+export type RecordingMeta = (StudioRecordingMeta | InstantRecordingMeta) & { platform?: Platform | null; pretty_name: string; sharing?: SharingMeta | null }
+export type RecordingMetaWithType = ((StudioRecordingMeta | InstantRecordingMeta) & { platform?: Platform | null; pretty_name: string; sharing?: SharingMeta | null }) & { type: RecordingType }
 export type RecordingMode = "studio" | "instant"
 export type RecordingOptionsChanged = null
 export type RecordingStarted = null
