+
{activeTool === 'transitions' ? (
) : (selectedElementIds && selectedElementIds.size >= 2) ? (
diff --git a/src/components/properties/ImageLayersPanel.tsx b/src/components/properties/ImageLayersPanel.tsx
index e18be6b..f3a57b9 100644
--- a/src/components/properties/ImageLayersPanel.tsx
+++ b/src/components/properties/ImageLayersPanel.tsx
@@ -241,6 +241,15 @@ export const ImageLayersPanel: React.FC
= ({
{getLabel(el)}
+ {el.isBrandElement ? (
+
+ 🏷️ Marca
+
+ ) : (
+
+ Editable
+
+ )}
{TYPE_LABELS[el.type] || el.type}
diff --git a/src/components/studio/StudioEditor.tsx b/src/components/studio/StudioEditor.tsx
index 706c473..f272a6c 100644
--- a/src/components/studio/StudioEditor.tsx
+++ b/src/components/studio/StudioEditor.tsx
@@ -19,6 +19,7 @@ import { TimelineMarkerList, TimelineMarker } from '../timeline/TimelineMarkerLi
import { ResponsivePreviewToggle } from '../ui/ResponsivePreviewToggle';
import { AutoSaveIndicator } from '../ui/AutoSaveIndicator';
import { CanvasGridOverlay } from '../ui/CanvasGridOverlay';
+import { FloatingContextToolbar } from '../ui/FloatingContextToolbar';
import { useEditor } from '../../context/EditorContext';
import { useKeyboardShortcuts } from '../../hooks/useKeyboardShortcuts';
@@ -337,6 +338,16 @@ export const StudioEditor: React.FC<{ onAssetSaved?: (url: string) => void }> =
{/* Canvas Grid + Safe Zone Overlay */}
+
+ {/* Contextual Floating Toolbar */}
+ el.id === selectedElementId) || null}
+ onDuplicate={handleDuplicate}
+ onDelete={handleDelete}
+ onLock={handleLock}
+ setTimelineElements={setTimelineElements}
+ />
+
{/* Auto-save indicator */}
diff --git a/src/components/ui/FloatingContextToolbar.tsx b/src/components/ui/FloatingContextToolbar.tsx
new file mode 100644
index 0000000..1fddcc1
--- /dev/null
+++ b/src/components/ui/FloatingContextToolbar.tsx
@@ -0,0 +1,94 @@
+import React from 'react';
+import { motion, AnimatePresence } from 'motion/react';
+import { Wand2, Copy, Trash2, Lock, Unlock, AlignCenter, AlignVerticalSpaceAround } from 'lucide-react';
+import { TimelineElement } from '../../types';
+
+import { removeImageBackground } from '../../utils/backgroundRemoval';
+
+interface FloatingContextToolbarProps {
+ element: TimelineElement | null;
+ onDuplicate: (id: string) => void;
+ onDelete: (id: string) => void;
+ onLock: (id: string) => void;
+ setTimelineElements: React.Dispatch
>;
+}
+
+export const FloatingContextToolbar: React.FC = ({
+ element,
+ onDuplicate,
+ onDelete,
+ onLock,
+ setTimelineElements,
+}) => {
+ const [isRemovingBg, setIsRemovingBg] = React.useState(false);
+
+ if (!element) return null;
+
+ const handleRemoveBg = async () => {
+ if (!element || element.type !== 'image') return;
+ setIsRemovingBg(true);
+ try {
+ const newUrl = await removeImageBackground(element.content);
+ setTimelineElements(prev => prev.map(el =>
+ el.id === element.id ? { ...el, content: newUrl } : el
+ ));
+ } catch (error) {
+ alert('Error al extraer el sujeto. Inténtalo de nuevo.');
+ } finally {
+ setIsRemovingBg(false);
+ }
+ };
+
+ return (
+
+
+ {element.type === 'image' && (
+
+ )}
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/index.css b/src/index.css
index cf936fd..ec83ff4 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,5 +1,14 @@
@import "tailwindcss";
+@theme {
+ --color-brand-blue: #0D2C54;
+ --color-brand-teal: #00A69C;
+ --color-brand-orange: #F9A826;
+ --color-brand-gray: #E0E0E0;
+ --font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
+}
+
+
/* Brand Content Editor input utility */
.input-sm {
width: 100%;