diff --git a/app/editor/[id].tsx b/app/editor/[id].tsx
new file mode 100644
index 0000000..9de7175
--- /dev/null
+++ b/app/editor/[id].tsx
@@ -0,0 +1,308 @@
+import { useCallback, useMemo } from "react";
+import {
+ ActivityIndicator,
+ Dimensions,
+ Pressable,
+ ScrollView,
+ StyleSheet,
+ Text,
+ View,
+} from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { useRouter, useLocalSearchParams } from "expo-router";
+import {
+ Canvas,
+ Image as SkImage,
+ Shader,
+ Fill,
+ useImage,
+} from "@shopify/react-native-skia";
+import Animated, { FadeIn, FadeInUp } from "react-native-reanimated";
+import { ArrowLeft, Check, Export } from "phosphor-react-native";
+import { GlassBottomSheet, GlassButton, GlassCard, GlassPill, GlassSlider } from "@/components/glass";
+import { useWallpaperStore } from "@/stores/wallpaper.store";
+import { useAnimation } from "@/hooks/useAnimation";
+import { useGyroscope } from "@/hooks/useGyroscope";
+import { useWallpaperExport } from "@/hooks/useWallpaperExport";
+import { shaders } from "@/shaders";
+import {
+ ANIMATION_META,
+ type AnimationType,
+} from "@/types/wallpaper";
+import { colors, typography, spacing, layout } from "@/theme";
+
+const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get("window");
+
+const AVAILABLE_ANIMATIONS: AnimationType[] = [
+ "ken-burns",
+ "color-shift",
+ "particles",
+ "vignette-pulse",
+ "glitch",
+];
+
+export default function EditorScreen() {
+ const insets = useSafeAreaInsets();
+ const router = useRouter();
+ const { id } = useLocalSearchParams<{ id: string }>();
+
+ const {
+ sourceUri,
+ animation,
+ uniforms,
+ particlePreset,
+ setAnimation,
+ setUniform,
+ setParticlePreset,
+ saveWallpaper,
+ } = useWallpaperStore();
+
+ const { time } = useAnimation(animation, uniforms);
+ const gyro = useGyroscope(animation === "depth-parallax");
+ const { status, exportAsWallpaper } = useWallpaperExport();
+
+ const image = useImage(sourceUri);
+ const shader = useMemo(() => shaders[animation], [animation]);
+
+ const handleApply = useCallback(async () => {
+ const config = saveWallpaper();
+ if (config) {
+ await exportAsWallpaper(config);
+ }
+ }, [saveWallpaper, exportAsWallpaper]);
+
+ const handleSaveOnly = useCallback(() => {
+ saveWallpaper();
+ router.back();
+ }, [saveWallpaper, router]);
+
+ // No image selected — redirect back
+ if (!sourceUri) {
+ return (
+
+
+
+ Aucune image sélectionnée
+
+
+ Retournez à la galerie pour choisir une photo
+
+ router.back()}
+ variant="primary"
+ size="md"
+ />
+
+
+ );
+ }
+
+ // Image loading
+ if (!image) {
+ return (
+
+
+
+ Chargement de l'image...
+
+
+ );
+ }
+
+ return (
+
+ {/* Full-screen animated preview */}
+
+
+ {/* Top bar overlay */}
+
+ router.back()} style={styles.iconButton}>
+
+
+
+
+
+
+
+
+ {/* Bottom sheet with controls */}
+
+
+ {/* Animation selector */}
+ Animation
+
+ {AVAILABLE_ANIMATIONS.map((type) => (
+ setAnimation(type)}
+ />
+ ))}
+
+
+ {/* Particle preset selector (only for particles animation) */}
+ {animation === "particles" && (
+ <>
+ Style
+
+ {(["snow", "rain", "bokeh"] as const).map((preset) => (
+ setParticlePreset(preset)}
+ />
+ ))}
+
+ >
+ )}
+
+ {/* Uniform controls */}
+
+ setUniform("intensity", v)}
+ />
+ setUniform("speed", v)}
+ />
+ {(animation === "ken-burns" || animation === "glitch") && (
+ setUniform("direction", v)}
+ formatValue={(v) => `${Math.round((v * 180) / Math.PI)}°`}
+ />
+ )}
+
+
+ {/* Export button */}
+
+
+ ) : undefined
+ }
+ />
+
+
+
+
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: colors.background,
+ },
+ centered: {
+ justifyContent: "center",
+ alignItems: "center",
+ paddingHorizontal: layout.screenPadding,
+ },
+ canvas: {
+ position: "absolute",
+ top: 0,
+ left: 0,
+ width: SCREEN_WIDTH,
+ height: SCREEN_HEIGHT,
+ },
+ topBar: {
+ position: "absolute",
+ left: 16,
+ right: 16,
+ flexDirection: "row",
+ justifyContent: "space-between",
+ zIndex: 10,
+ },
+ iconButton: {
+ width: 40,
+ height: 40,
+ borderRadius: 20,
+ backgroundColor: "rgba(0, 0, 0, 0.4)",
+ borderWidth: 1,
+ borderColor: colors.glass.border,
+ alignItems: "center",
+ justifyContent: "center",
+ },
+ animationScroll: {
+ marginBottom: spacing.lg,
+ },
+ controls: {
+ marginBottom: spacing.lg,
+ },
+ ctaContainer: {
+ marginTop: spacing.sm,
+ },
+});