mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-01 19:42:03 +00:00
refactor(studio): unify accent color under studio-accent Tailwind token
Replace all 30 hardcoded [#3CE6AC] and blue-400/blue-500 Tailwind classes with the studio-accent token defined in tailwind.config.js. Single source of truth — change the accent in one place. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
Miguel Ángel
co-authored by
Claude Opus 4.6
parent
821da4fc9a
commit
5e8927f647
@@ -317,7 +317,7 @@ export function StudioApp() {
|
||||
if (resolving || !projectId) {
|
||||
return (
|
||||
<div className="h-screen w-screen bg-neutral-950 flex items-center justify-center">
|
||||
<div className="w-4 h-4 rounded-full bg-[#3CE6AC] animate-pulse" />
|
||||
<div className="w-4 h-4 rounded-full bg-studio-accent animate-pulse" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -338,7 +338,7 @@ export function StudioApp() {
|
||||
onClick={() => setLeftCollapsed((v) => !v)}
|
||||
className={`h-7 w-7 flex items-center justify-center rounded-md border transition-colors ${
|
||||
!leftCollapsed
|
||||
? "text-[#3CE6AC] bg-[#3CE6AC]/10 border-[#3CE6AC]/30"
|
||||
? "text-studio-accent bg-studio-accent/10 border-studio-accent/30"
|
||||
: "bg-transparent border-transparent text-neutral-500 hover:text-neutral-300 hover:bg-neutral-800"
|
||||
}`}
|
||||
title={leftCollapsed ? "Show sidebar" : "Hide sidebar"}
|
||||
@@ -361,7 +361,7 @@ export function StudioApp() {
|
||||
onClick={() => setTimelineVisible((v) => !v)}
|
||||
className={`h-7 w-7 flex items-center justify-center rounded-md border transition-colors ${
|
||||
timelineVisible
|
||||
? "text-[#3CE6AC] bg-[#3CE6AC]/10 border-[#3CE6AC]/30"
|
||||
? "text-studio-accent bg-studio-accent/10 border-studio-accent/30"
|
||||
: "bg-transparent border-transparent text-neutral-500 hover:text-neutral-300 hover:bg-neutral-800"
|
||||
}`}
|
||||
title={timelineVisible ? "Hide timeline" : "Show timeline"}
|
||||
@@ -384,7 +384,7 @@ export function StudioApp() {
|
||||
onClick={() => setRightCollapsed((v) => !v)}
|
||||
className={`h-7 flex items-center gap-1.5 px-2.5 rounded-md text-[11px] font-medium border transition-colors ${
|
||||
!rightCollapsed
|
||||
? "text-[#3CE6AC] bg-[#3CE6AC]/10 border-[#3CE6AC]/30"
|
||||
? "text-studio-accent bg-studio-accent/10 border-studio-accent/30"
|
||||
: "text-neutral-500 hover:text-neutral-300 hover:bg-neutral-800 border-transparent"
|
||||
}`}
|
||||
>
|
||||
@@ -454,7 +454,7 @@ export function StudioApp() {
|
||||
{/* Left resize handle */}
|
||||
{!leftCollapsed && (
|
||||
<div
|
||||
className="w-1 flex-shrink-0 bg-neutral-800 hover:bg-blue-500 cursor-col-resize transition-colors active:bg-blue-400"
|
||||
className="w-1 flex-shrink-0 bg-neutral-800 hover:bg-studio-accent cursor-col-resize transition-colors active:bg-studio-accent/80"
|
||||
style={{ touchAction: "none" }}
|
||||
onPointerDown={(e) => handlePanelResizeStart("left", e)}
|
||||
onPointerMove={handlePanelResizeMove}
|
||||
@@ -487,7 +487,7 @@ export function StudioApp() {
|
||||
{!rightCollapsed && (
|
||||
<>
|
||||
<div
|
||||
className="w-1 flex-shrink-0 bg-neutral-800 hover:bg-blue-500 cursor-col-resize transition-colors active:bg-blue-400"
|
||||
className="w-1 flex-shrink-0 bg-neutral-800 hover:bg-studio-accent cursor-col-resize transition-colors active:bg-studio-accent/80"
|
||||
style={{ touchAction: "none" }}
|
||||
onPointerDown={(e) => handlePanelResizeStart("right", e)}
|
||||
onPointerMove={handlePanelResizeMove}
|
||||
|
||||
@@ -56,8 +56,8 @@ export function LintModal({
|
||||
<WarningIcon size={18} className="text-red-400" weight="fill" />
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-8 h-8 rounded-full bg-[#3CE6AC]/10 flex items-center justify-center">
|
||||
<CheckCircleIcon size={18} className="text-[#3CE6AC]" weight="fill" />
|
||||
<div className="w-8 h-8 rounded-full bg-studio-accent/10 flex items-center justify-center">
|
||||
<CheckCircleIcon size={18} className="text-studio-accent" weight="fill" />
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
@@ -83,7 +83,9 @@ export function LintModal({
|
||||
<button
|
||||
onClick={handleCopyToAgent}
|
||||
className={`px-3 py-1 text-xs font-medium rounded-lg transition-colors ${
|
||||
copied ? "bg-green-600 text-white" : "bg-[#3CE6AC] hover:bg-[#3CE6AC]/80 text-white"
|
||||
copied
|
||||
? "bg-green-600 text-white"
|
||||
: "bg-studio-accent hover:bg-studio-accent/80 text-white"
|
||||
}`}
|
||||
>
|
||||
{copied ? "Copied!" : "Copy to Agent"}
|
||||
@@ -109,8 +111,11 @@ export function LintModal({
|
||||
{f.file && <p className="text-xs text-neutral-600 font-mono mt-0.5">{f.file}</p>}
|
||||
{f.fixHint && (
|
||||
<div className="flex items-start gap-1 mt-1.5">
|
||||
<CaretRightIcon size={10} className="text-[#3CE6AC] flex-shrink-0 mt-0.5" />
|
||||
<p className="text-xs text-[#3CE6AC]">{f.fixHint}</p>
|
||||
<CaretRightIcon
|
||||
size={10}
|
||||
className="text-studio-accent flex-shrink-0 mt-0.5"
|
||||
/>
|
||||
<p className="text-xs text-studio-accent">{f.fixHint}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -126,8 +131,11 @@ export function LintModal({
|
||||
{f.file && <p className="text-xs text-neutral-600 font-mono mt-0.5">{f.file}</p>}
|
||||
{f.fixHint && (
|
||||
<div className="flex items-start gap-1 mt-1.5">
|
||||
<CaretRightIcon size={10} className="text-[#3CE6AC] flex-shrink-0 mt-0.5" />
|
||||
<p className="text-xs text-[#3CE6AC]">{f.fixHint}</p>
|
||||
<CaretRightIcon
|
||||
size={10}
|
||||
className="text-studio-accent flex-shrink-0 mt-0.5"
|
||||
/>
|
||||
<p className="text-xs text-studio-accent">{f.fixHint}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -94,7 +94,7 @@ export const PropertyPanel = memo(function PropertyPanel({
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={isPickMode ? onDisablePick : onEnablePick}
|
||||
className={`mt-3 ${isPickMode ? "bg-blue-500/20 text-blue-400 border-blue-500/30" : ""}`}
|
||||
className={`mt-3 ${isPickMode ? "bg-studio-accent/20 text-studio-accent border-studio-accent/30" : ""}`}
|
||||
>
|
||||
{isPickMode ? "Pick mode active..." : "Enable Pick Mode"}
|
||||
</Button>
|
||||
@@ -109,7 +109,7 @@ export const PropertyPanel = memo(function PropertyPanel({
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between px-3 py-2 border-b border-neutral-800 flex-shrink-0">
|
||||
<div className="flex items-center gap-1.5 min-w-0">
|
||||
<span className="text-2xs font-mono text-blue-400 truncate">{element.selector}</span>
|
||||
<span className="text-2xs font-mono text-studio-accent truncate">{element.selector}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<IconButton
|
||||
@@ -117,7 +117,7 @@ export const PropertyPanel = memo(function PropertyPanel({
|
||||
aria-label={isPickMode ? "Disable pick mode" : "Enable pick mode"}
|
||||
size="sm"
|
||||
onClick={isPickMode ? onDisablePick : onEnablePick}
|
||||
className={isPickMode ? "text-blue-400 bg-blue-500/10" : ""}
|
||||
className={isPickMode ? "text-studio-accent bg-studio-accent/10" : ""}
|
||||
/>
|
||||
<IconButton
|
||||
icon={<X size={11} />}
|
||||
|
||||
@@ -351,7 +351,7 @@ export const NLELayout = memo(function NLELayout({
|
||||
<>
|
||||
{/* Resize divider */}
|
||||
<div
|
||||
className="h-1 flex-shrink-0 bg-neutral-800 hover:bg-blue-500 cursor-row-resize transition-colors active:bg-blue-400 z-10"
|
||||
className="h-1 flex-shrink-0 bg-neutral-800 hover:bg-studio-accent cursor-row-resize transition-colors active:bg-studio-accent/80 z-10"
|
||||
style={{ touchAction: "none" }}
|
||||
onPointerDown={handleDividerPointerDown}
|
||||
onPointerMove={handleDividerPointerMove}
|
||||
|
||||
@@ -34,7 +34,7 @@ function FormatExportButton({
|
||||
<button
|
||||
onClick={() => onStartRender(format)}
|
||||
disabled={isRendering}
|
||||
className="flex items-center gap-1 px-2 py-0.5 text-[10px] font-semibold rounded-r bg-[#3CE6AC] text-[#09090B] hover:brightness-110 transition-colors disabled:opacity-50"
|
||||
className="flex items-center gap-1 px-2 py-0.5 text-[10px] font-semibold rounded-r bg-studio-accent text-[#09090B] hover:brightness-110 transition-colors disabled:opacity-50"
|
||||
>
|
||||
{isRendering ? "Rendering..." : "Export"}
|
||||
</button>
|
||||
|
||||
@@ -90,7 +90,7 @@ export const RenderQueueItem = memo(function RenderQueueItem({
|
||||
)}
|
||||
{job.status === "rendering" && (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<div className="w-2 h-2 rounded-full bg-[#3CE6AC] animate-pulse" />
|
||||
<div className="w-2 h-2 rounded-full bg-studio-accent animate-pulse" />
|
||||
</div>
|
||||
)}
|
||||
{job.status === "failed" && (
|
||||
@@ -122,11 +122,11 @@ export const RenderQueueItem = memo(function RenderQueueItem({
|
||||
<div className="mt-1">
|
||||
<div className="flex items-center justify-between mb-0.5">
|
||||
<span className="text-[9px] text-neutral-500">{job.stage || "Rendering"}</span>
|
||||
<span className="text-[9px] font-mono text-[#3CE6AC]">{job.progress}%</span>
|
||||
<span className="text-[9px] font-mono text-studio-accent">{job.progress}%</span>
|
||||
</div>
|
||||
<div className="w-full h-1 bg-neutral-800 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-[#3CE6AC] rounded-full transition-all duration-300"
|
||||
className="h-full bg-studio-accent rounded-full transition-all duration-300"
|
||||
style={{ width: `${job.progress}%` }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -100,7 +100,7 @@ function AssetCard({
|
||||
onPointerLeave={() => setHovered(false)}
|
||||
className={`w-full text-left px-2 py-1.5 flex items-center gap-2.5 transition-colors cursor-pointer ${
|
||||
isCopied
|
||||
? "bg-[#3CE6AC]/10 border-l-2 border-[#3CE6AC]"
|
||||
? "bg-studio-accent/10 border-l-2 border-studio-accent"
|
||||
: "border-l-2 border-transparent hover:bg-neutral-800/50"
|
||||
}`}
|
||||
>
|
||||
@@ -127,7 +127,7 @@ function AssetCard({
|
||||
<div className="min-w-0 flex-1">
|
||||
<span className="text-[11px] font-medium text-neutral-300 truncate block">{name}</span>
|
||||
{isCopied ? (
|
||||
<span className="text-[9px] text-[#3CE6AC]">Copied!</span>
|
||||
<span className="text-[9px] text-studio-accent">Copied!</span>
|
||||
) : (
|
||||
<span className="text-[9px] text-neutral-600 truncate block">{asset}</span>
|
||||
)}
|
||||
@@ -164,7 +164,7 @@ export const AssetsTab = memo(function AssetsTab({ projectId, assets, onImport }
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex-1 flex flex-col min-h-0 transition-colors ${dragOver ? "bg-blue-950/20" : ""}`}
|
||||
className={`flex-1 flex flex-col min-h-0 transition-colors ${dragOver ? "bg-studio-accent/[0.05]" : ""}`}
|
||||
onDragOver={(e) => {
|
||||
e.preventDefault();
|
||||
setDragOver(true);
|
||||
|
||||
@@ -41,7 +41,7 @@ function CompCard({
|
||||
onPointerLeave={handleLeave}
|
||||
className={`w-full text-left px-2 py-1.5 flex items-center gap-2.5 transition-colors cursor-pointer ${
|
||||
isActive
|
||||
? "bg-[#3CE6AC]/10 border-l-2 border-[#3CE6AC]"
|
||||
? "bg-studio-accent/10 border-l-2 border-studio-accent"
|
||||
: "border-l-2 border-transparent hover:bg-neutral-800/50"
|
||||
}`}
|
||||
>
|
||||
|
||||
@@ -82,7 +82,7 @@ export const LeftSidebar = memo(function LeftSidebar({
|
||||
onClick={() => selectTab("code")}
|
||||
className={`flex-1 py-2 text-[11px] font-medium transition-colors ${
|
||||
tab === "code"
|
||||
? "text-neutral-200 border-b-2 border-[#3CE6AC]"
|
||||
? "text-neutral-200 border-b-2 border-studio-accent"
|
||||
: "text-neutral-500 hover:text-neutral-400"
|
||||
}`}
|
||||
>
|
||||
@@ -93,7 +93,7 @@ export const LeftSidebar = memo(function LeftSidebar({
|
||||
onClick={() => selectTab("compositions")}
|
||||
className={`flex-1 py-2 text-[11px] font-medium transition-colors ${
|
||||
tab === "compositions"
|
||||
? "text-neutral-200 border-b-2 border-blue-500"
|
||||
? "text-neutral-200 border-b-2 border-studio-accent"
|
||||
: "text-neutral-500 hover:text-neutral-400"
|
||||
}`}
|
||||
>
|
||||
@@ -104,7 +104,7 @@ export const LeftSidebar = memo(function LeftSidebar({
|
||||
onClick={() => selectTab("assets")}
|
||||
className={`flex-1 py-2 text-[11px] font-medium transition-colors ${
|
||||
tab === "assets"
|
||||
? "text-neutral-200 border-b-2 border-blue-500"
|
||||
? "text-neutral-200 border-b-2 border-studio-accent"
|
||||
: "text-neutral-500 hover:text-neutral-400"
|
||||
}`}
|
||||
>
|
||||
|
||||
@@ -105,7 +105,7 @@ Preserve all other elements and timing outside this range.`;
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between px-4 py-2.5 border-b border-neutral-800/60">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-blue-400" />
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-studio-accent" />
|
||||
<span className="text-[11px] font-medium text-neutral-300">
|
||||
{formatTime(start)} — {formatTime(end)}
|
||||
</span>
|
||||
@@ -120,7 +120,7 @@ Preserve all other elements and timing outside this range.`;
|
||||
<div className="px-4 py-2 border-b border-neutral-800/40 max-h-24 overflow-y-auto">
|
||||
{elementsInRange.map((el) => (
|
||||
<div key={el.id} className="flex items-center justify-between py-0.5">
|
||||
<span className="text-[10px] font-mono text-blue-400/80">#{el.id}</span>
|
||||
<span className="text-[10px] font-mono text-studio-accent/80">#{el.id}</span>
|
||||
<span className="text-[10px] text-neutral-600">{el.tag}</span>
|
||||
</div>
|
||||
))}
|
||||
@@ -141,7 +141,7 @@ Preserve all other elements and timing outside this range.`;
|
||||
}}
|
||||
placeholder="What should change?"
|
||||
rows={2}
|
||||
className="w-full px-3 py-2 text-xs bg-neutral-800/60 border border-neutral-700/40 rounded-lg text-neutral-200 placeholder:text-neutral-600 resize-none focus:outline-none focus:border-blue-500/40 transition-colors"
|
||||
className="w-full px-3 py-2 text-xs bg-neutral-800/60 border border-neutral-700/40 rounded-lg text-neutral-200 placeholder:text-neutral-600 resize-none focus:outline-none focus:border-studio-accent/40 transition-colors"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -152,11 +152,11 @@ Preserve all other elements and timing outside this range.`;
|
||||
className={`w-full py-1.5 text-[11px] font-medium rounded-lg transition-all ${
|
||||
copied
|
||||
? "bg-green-500/20 text-green-400 border border-green-500/30"
|
||||
: "bg-blue-500/15 text-blue-400 border border-blue-500/25 hover:bg-blue-500/25"
|
||||
: "bg-studio-accent/15 text-studio-accent border border-studio-accent/25 hover:bg-studio-accent/25"
|
||||
}`}
|
||||
>
|
||||
{copied ? "Copied!" : "Copy to Agent"}
|
||||
{!copied && <span className="text-[9px] text-blue-400/50 ml-1.5">Cmd+Enter</span>}
|
||||
{!copied && <span className="text-[9px] text-studio-accent/50 ml-1.5">Cmd+Enter</span>}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -257,7 +257,7 @@ export const PlayerControls = memo(function PlayerControls({
|
||||
onClick={onToggleTimeline}
|
||||
className={`w-7 h-7 flex items-center justify-center rounded-md border transition-colors ${
|
||||
timelineVisible
|
||||
? "text-[#3CE6AC] bg-[#3CE6AC]/10 border-[#3CE6AC]/30"
|
||||
? "text-studio-accent bg-studio-accent/10 border-studio-accent/30"
|
||||
: "border-neutral-700 text-neutral-500 hover:text-neutral-300 hover:bg-neutral-800"
|
||||
}`}
|
||||
title={timelineVisible ? "Hide timeline" : "Show timeline"}
|
||||
|
||||
@@ -429,7 +429,7 @@ export const Timeline = memo(function Timeline({
|
||||
return (
|
||||
<div
|
||||
className={`h-full border-t bg-[#0a0a0b] flex flex-col select-none transition-colors duration-150 ${
|
||||
isDragOver ? "border-blue-500/50 bg-blue-500/[0.03]" : "border-neutral-800/50"
|
||||
isDragOver ? "border-studio-accent/50 bg-studio-accent/[0.03]" : "border-neutral-800/50"
|
||||
}`}
|
||||
onDragOver={(e) => {
|
||||
e.preventDefault();
|
||||
@@ -466,7 +466,9 @@ export const Timeline = memo(function Timeline({
|
||||
<div className="flex-1 flex items-center justify-center">
|
||||
<div
|
||||
className={`flex items-center gap-3 px-6 py-3 border border-dashed rounded-lg transition-colors duration-150 ${
|
||||
isDragOver ? "border-blue-400/60 bg-blue-500/[0.06]" : "border-neutral-700/50"
|
||||
isDragOver
|
||||
? "border-studio-accent/60 bg-studio-accent/[0.06]"
|
||||
: "border-neutral-700/50"
|
||||
}`}
|
||||
>
|
||||
{isDragOver ? (
|
||||
@@ -480,13 +482,13 @@ export const Timeline = memo(function Timeline({
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="text-blue-400 flex-shrink-0"
|
||||
className="text-studio-accent flex-shrink-0"
|
||||
>
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
||||
<polyline points="7 10 12 15 17 10" />
|
||||
<line x1="12" y1="15" x2="12" y2="3" />
|
||||
</svg>
|
||||
<span className="text-[13px] text-blue-400">Drop media files to import</span>
|
||||
<span className="text-[13px] text-studio-accent">Drop media files to import</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
@@ -568,7 +570,7 @@ export const Timeline = memo(function Timeline({
|
||||
{/* Shift hint */}
|
||||
{shiftHeld && !rangeSelection && (
|
||||
<div className="absolute inset-0 flex items-center justify-center pointer-events-none z-10">
|
||||
<span className="text-[9px] text-blue-400/60 font-medium">
|
||||
<span className="text-[9px] text-studio-accent/60 font-medium">
|
||||
Drag to select range
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,7 @@ export default {
|
||||
border: "#262626",
|
||||
text: "#e5e5e5",
|
||||
muted: "#737373",
|
||||
accent: "#00E3FF",
|
||||
accent: "#3CE6AC",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user