Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ function AnimationPhase({
}}
className="flex-1 accent-studio-accent disabled:opacity-40"
/>
<span className="text-2xs text-neutral-400 font-mono w-8 text-right shrink-0">
<span className="text-2xs text-text-secondary font-mono w-8 text-right shrink-0">
{intensity.toFixed(2)}
</span>
</div>
Expand Down Expand Up @@ -239,7 +239,7 @@ export const CaptionAnimationPanel = memo(function CaptionAnimationPanel() {
if (!group || !resolvedGroupId || !animation) {
return (
<div className="flex items-center justify-center h-full px-4 text-center">
<p className="text-xs text-neutral-500">Select a caption word to edit animations</p>
<p className="text-xs text-text-tertiary">Select a caption word to edit animations</p>
</div>
);
}
Expand Down Expand Up @@ -286,13 +286,13 @@ export const CaptionAnimationPanel = memo(function CaptionAnimationPanel() {
</div>

{/* Footer */}
<div className="shrink-0 px-3 py-2 border-t border-neutral-800">
<div className="shrink-0 px-3 py-2 border-t border-border-button-default">
<button
type="button"
onClick={handleApplyToAll}
disabled={gated}
title={gated ? "Disabled until animation editing is applied to playback" : undefined}
className="w-full py-1.5 rounded-sm border border-neutral-700 text-2xs text-neutral-300 hover:border-studio-accent/50 hover:text-accent-ink transition-colors disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:border-neutral-700 disabled:hover:text-neutral-300"
className="w-full py-1.5 rounded-sm border border-border-button-default text-2xs text-text-primary hover:border-studio-accent/50 hover:text-accent-ink transition-colors disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:border-border-button-hover disabled:hover:text-text-primary"
>
Apply to all groups
</button>
Expand Down
2 changes: 1 addition & 1 deletion packages/studio/src/captions/components/CaptionOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ export const CaptionOverlay = memo(function CaptionOverlay({ iframeRef }: Captio
>
{wordBoxes.length === 0 && model && model.segments.size > 0 && (
<div className="absolute inset-x-0 top-3 flex justify-center pointer-events-none">
<span className="px-2.5 py-1 rounded-full bg-black/60 border border-neutral-700 text-2xs text-neutral-300">
<span className="px-2.5 py-1 rounded-full bg-black/60 border border-border-button-default text-2xs text-text-primary">
No captions visible at this frame. Scrub to a caption, or select one in the track below
</span>
</div>
Expand Down
10 changes: 5 additions & 5 deletions packages/studio/src/captions/components/CaptionPropertyPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export const CaptionPropertyPanel = memo(function CaptionPropertyPanel({
if (selectedSegmentIds.size === 0) {
return (
<div className="flex items-center justify-center h-full px-4 text-center">
<p className="text-xs text-neutral-500">Select caption words to edit their style</p>
<p className="text-xs text-text-tertiary">Select caption words to edit their style</p>
</div>
);
}
Expand All @@ -213,9 +213,9 @@ export const CaptionPropertyPanel = memo(function CaptionPropertyPanel({
return (
<div className="flex flex-col h-full min-h-0">
{/* Header */}
<div className="px-3 py-2 border-b border-neutral-800 shrink-0">
<div className="px-3 py-2 border-b border-border-button-default shrink-0">
<div className="flex items-center justify-between mb-1.5">
<span className="text-2xs text-neutral-500">{countLabel}</span>
<span className="text-2xs text-text-tertiary">{countLabel}</span>
</div>
{/* Tab switcher */}
<div className="flex gap-1" role="tablist" aria-label="Caption editing tabs">
Expand All @@ -228,7 +228,7 @@ export const CaptionPropertyPanel = memo(function CaptionPropertyPanel({
"flex-1 py-0.5 rounded-sm text-2xs font-medium transition-colors",
activeTab === "style"
? "bg-studio-accent/20 text-accent-ink border border-studio-accent/50"
: "text-neutral-500 border border-neutral-800 hover:text-neutral-300 hover:border-neutral-600",
: "text-text-tertiary border border-border-button-default hover:text-text-primary hover:border-border-button-hover",
].join(" ")}
>
Style
Expand All @@ -242,7 +242,7 @@ export const CaptionPropertyPanel = memo(function CaptionPropertyPanel({
"flex-1 py-0.5 rounded-sm text-2xs font-medium transition-colors",
activeTab === "animation"
? "bg-studio-accent/20 text-accent-ink border border-studio-accent/50"
: "text-neutral-500 border border-neutral-800 hover:text-neutral-300 hover:border-neutral-600",
: "text-text-tertiary border border-border-button-default hover:text-text-primary hover:border-border-button-hover",
].join(" ")}
>
Animation
Expand Down
6 changes: 3 additions & 3 deletions packages/studio/src/captions/components/shared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import type React from "react";
import { useEffect, useRef, useState } from "react";

export const inputCls =
"w-full bg-neutral-900 border border-neutral-800 rounded-sm px-1.5 py-0.5 text-2xs text-neutral-200 font-mono outline-hidden focus:border-studio-accent disabled:opacity-40 disabled:cursor-not-allowed";
"w-full bg-background-tertiary-default border border-border-button-default rounded-sm px-1.5 py-0.5 text-2xs text-text-primary font-mono outline-hidden focus:border-border-button-active disabled:opacity-40 disabled:cursor-not-allowed";

export function Section({ label, children }: { label: string; children: React.ReactNode }) {
return (
<div className="mb-3">
<div className="flex items-center gap-1.5 mt-2 mb-1.5">
<span className="text-2xs font-medium text-neutral-500 uppercase tracking-wider">
<span className="text-2xs font-medium text-text-tertiary uppercase tracking-wider">
{label}
</span>
</div>
Expand All @@ -20,7 +20,7 @@ export function Section({ label, children }: { label: string; children: React.Re
export function Row({ label, children }: { label: string; children: React.ReactNode }) {
return (
<div className="flex items-center gap-2">
<span className="text-2xs text-neutral-600 w-14 text-right shrink-0">{label}</span>
<span className="text-2xs text-text-tertiary w-14 text-right shrink-0">{label}</span>
<div className="flex-1 min-w-0">{children}</div>
</div>
);
Expand Down
65 changes: 19 additions & 46 deletions packages/studio/src/components/AskAgentModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useState, useRef, type CSSProperties } from "react";
import { useMountEffect } from "../hooks/useMountEffect";
import { type AgentModalAnchorPoint, clampNumber } from "../utils/studioHelpers";
import { Button, cn } from "./ui";
import { DialogHeader, dialogClasses } from "./ui/Dialog";
import { useDialogBehavior } from "./ui/useDialogBehavior";

function getAgentModalPositionStyle(
Expand Down Expand Up @@ -64,11 +66,7 @@ export function AskAgentModal({

return (
<div
className={
anchorPoint
? "hf-backdrop-in fixed inset-0 z-100 bg-black/60 backdrop-blur-xs"
: "hf-backdrop-in fixed inset-0 z-100 flex items-center justify-center bg-black/60 backdrop-blur-xs"
}
className={cn(dialogClasses.backdrop, !anchorPoint && dialogClasses.centered)}
onClick={requestClose}
>
<div
Expand All @@ -77,42 +75,21 @@ export function AskAgentModal({
aria-modal="true"
aria-label="Copy prompt to AI agent"
tabIndex={-1}
className={`w-[480px] rounded-2xl border border-neutral-800 bg-neutral-950 shadow-2xl outline-hidden ${
anchorPoint ? "fixed" : ""
}`}
className={cn(dialogClasses.panel, "w-[480px]", anchorPoint && "fixed")}
style={modalPositionStyle}
onClick={(e) => e.stopPropagation()}
>
<div className="flex items-center justify-between px-5 py-4 border-b border-neutral-800/60">
<div>
<h3 className="text-sm font-medium text-neutral-200">Copy prompt to AI agent</h3>
<p className="text-xs text-neutral-500 mt-0.5">
{selectionLabel.length > 50 ? `${selectionLabel.slice(0, 49)}…` : selectionLabel}
</p>
</div>
<button
className="p-1 rounded-md text-neutral-500 hover:text-neutral-300 hover:bg-neutral-800/50 active:scale-[0.98]"
onClick={onClose}
aria-label="Close"
>
<svg
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
>
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
</svg>
</button>
</div>
<div className="px-5 py-4 space-y-3">
<DialogHeader
title="Copy prompt to AI agent"
description={
selectionLabel.length > 50 ? `${selectionLabel.slice(0, 49)}…` : selectionLabel
}
onClose={onClose}
/>
<div className={cn(dialogClasses.body, "space-y-3")}>
<textarea
ref={inputRef}
className="w-full h-24 px-3 py-2 rounded-lg border border-neutral-800 bg-neutral-900/60 text-sm text-neutral-200 placeholder-neutral-600 resize-none focus:outline-hidden focus:border-studio-accent/60 focus:ring-1 focus:ring-studio-accent/30"
className={cn(dialogClasses.field, "h-24 resize-none")}
placeholder="Describe what you want to change…"
value={value}
onChange={(e) => setValue(e.target.value)}
Expand All @@ -124,26 +101,22 @@ export function AskAgentModal({
/>
{contextPreview && (
<details className="group">
<summary className="text-[11px] text-neutral-500 cursor-pointer select-none hover:text-neutral-400">
<summary className="cursor-pointer select-none text-caption-1-medium text-text-secondary hover:text-text-primary">
Context included in prompt
</summary>
<pre className="mt-2 max-h-40 overflow-auto rounded-lg bg-neutral-900/80 px-3 py-2 text-[11px] leading-relaxed text-neutral-500 whitespace-pre-wrap wrap-break-word border border-neutral-800/50">
<pre className="mt-2 max-h-40 overflow-auto whitespace-pre-wrap wrap-break-word rounded-2lg bg-background-tertiary-default px-3 py-2 text-caption-1-regular text-text-secondary">
{contextPreview}
</pre>
</details>
)}
</div>
<div className="flex items-center justify-between px-5 py-3 border-t border-neutral-800/60">
<span className="text-[11px] text-neutral-600">
<div className={dialogClasses.footer}>
<span className={dialogClasses.hint}>
{navigator.platform.includes("Mac") ? "⌘" : "Ctrl"}+Enter to copy
</span>
<button
className="px-4 py-1.5 rounded-lg bg-accent text-xs font-medium text-on-accent hover:bg-accent-hover disabled:opacity-40 disabled:cursor-not-allowed"
disabled={!value.trim()}
onClick={handleSubmit}
>
<Button variant="primary" disabled={!value.trim()} onClick={handleSubmit}>
Copy prompt
</button>
</Button>
</div>
</div>
</div>
Expand Down
9 changes: 4 additions & 5 deletions packages/studio/src/components/CompositionMissingBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Banner } from "./ui/Dialog";

interface CompositionMissingBannerProps {
/** The composition this tab has open, that the server can no longer find. */
path: string;
Expand All @@ -20,13 +22,10 @@ interface CompositionMissingBannerProps {
*/
export function CompositionMissingBanner({ path }: CompositionMissingBannerProps) {
return (
<div
role="alert"
className="hf-backdrop-in absolute left-1/2 top-14 z-92 flex max-w-[calc(100vw-32px)] -translate-x-1/2 items-center gap-3 rounded-md border border-amber-500/30 bg-amber-950/85 px-4 py-2 text-[12px] font-medium text-amber-100 shadow-lg shadow-black/30"
>
<Banner tone="warning">
<span>
<strong>{path}</strong> is no longer on disk. Select another composition to keep editing.
</span>
</div>
</Banner>
);
}
7 changes: 5 additions & 2 deletions packages/studio/src/components/EditorShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -338,9 +338,12 @@ function EditorShellBody({
onSelectTimelineElement={onSelectTimelineElement}
timelineFooter={
captionEditMode ? (
<div className="border-t border-neutral-800/30 shrink-0" style={{ height: 60 }}>
<div
className="border-t border-border-button-default shrink-0"
style={{ height: 60 }}
>
<div className="flex items-center gap-1.5 px-2 py-0.5">
<span className="text-[9px] font-medium text-neutral-500 uppercase tracking-wider">
<span className="text-[9px] font-medium text-text-tertiary uppercase tracking-wider">
Captions
</span>
</div>
Expand Down
Loading
Loading