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
12 changes: 6 additions & 6 deletions src/app/contact/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ export const metadata: Metadata = {
};
export default function ContactPage() {
return (
<main className="min-h-screen bg-black text-white p-8">
<main className="min-h-screen bg-[var(--bg)] text-[var(--text)] p-8">
<div className="mb-8">
<Link
href="/"
className="inline-flex items-center text-sm opacity-70 hover:opacity-100 transition-opacity"
className="inline-flex items-center text-sm text-[var(--muted)] hover:text-[var(--text)] transition-colors"
>
&larr; Back to Reframe
</Link>
Expand All @@ -27,23 +27,23 @@ export default function ContactPage() {
href="https://github.com/magic-peach/reframe/issues"
target="_blank"
rel="noopener noreferrer"
className="text-lg font-semibold underline hover:opacity-80 transition-opacity"
className="text-lg font-semibold text-[var(--accent)] underline hover:text-[var(--accent-hover)] transition-colors"
>
GitHub Issues
</a>
<p className="opacity-70 mt-1">For bug reports and feature requests.</p>
<p className="text-[var(--muted)] mt-1">For bug reports and feature requests.</p>
</div>

<div>
<a
href="https://github.com/magic-peach/reframe/discussions"
target="_blank"
rel="noopener noreferrer"
className="text-lg font-semibold underline hover:opacity-80 transition-opacity"
className="text-lg font-semibold text-[var(--accent)] underline hover:text-[var(--accent-hover)] transition-colors"
>
GitHub Discussions
</a>
<p className="opacity-70 mt-1">For questions, ideas, and general help.</p>
<p className="text-[var(--muted)] mt-1">For questions, ideas, and general help.</p>
</div>
</div>
</main>
Expand Down
65 changes: 55 additions & 10 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
--muted: #64748b;
--accent: #3b82f6;
--accent-hover: #1d4ed8;
--accent-muted: rgba(59, 130, 246, 0.12);
--radius: 10px;
--shadow: 0 2px 12px rgba(15, 23, 42, 0.12);
--film-600: #e63946;
--film-400: #ff6b6b;
--warning: #f59e0b;
Expand All @@ -22,13 +25,16 @@

/* ── Dark mode tokens ── */
.dark {
--bg: #0f172a;
--surface: #1e293b;
--border: #334155;
--text: #f1f5f9;
--muted: #94a3b8;
--accent: #3b82f6;
--accent-hover: #2563eb;
--bg: #0f1117;
--surface: #1a1d27;
--border: #2e3147;
--text: #f0f0f5;
--muted: #8b8fa8;
--accent: #4f6ef7;
--accent-hover: #3a57d4;
--accent-muted: rgba(79, 110, 247, 0.12);
--radius: 10px;
--shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
--warning: #fbbf24;
--error: #f87171;
--error-bg: #7f1d1d;
Expand All @@ -47,6 +53,9 @@

--accent: #FFFF00;
--accent-hover: #FFFF00;
--accent-muted: rgba(255, 255, 0, 0.22);
--radius: 10px;
--shadow: none;

--error: #FF6666;
--success: #66FF66;
Expand Down Expand Up @@ -82,9 +91,45 @@
body {
background-color: var(--bg);
color: var(--text);
line-height: 1.6;
transition: background-color 0.3s ease, color 0.3s ease;
}

h1,
h2,
h3,
h4,
h5,
h6 {
color: var(--text);
font-weight: 700;
}

p,
li {
color: color-mix(in srgb, var(--text) 95%, transparent);
}

button {
transition: all 0.2s ease;
}

input,
select,
textarea {
background: var(--bg);
border: 1px solid var(--border);
color: var(--text);
}

input:focus,
select:focus,
textarea:focus {
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-muted);
outline: none;
}

/* Smooth transitions for all themed elements */
*,
*::before,
Expand All @@ -95,7 +140,7 @@ body {
}

:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
border-radius: 4px;
outline: 0;
box-shadow: 0 0 0 3px var(--accent-muted);
border-radius: var(--radius);
}
4 changes: 2 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,15 @@ export default function RootLayout({
<body className="min-h-screen bg-[var(--bg)] text-[var(--text)] antialiased">

<a href="#main-content"
className="sr-only focus:not-sr-only focus:fixed focus:top-4 focus:left-4 focus:z-50 focus:px-4 focus:py-2 focus:bg-white focus:text-black"
className="sr-only focus:not-sr-only focus:fixed focus:top-4 focus:left-4 focus:z-50 focus:rounded-[var(--radius)] focus:border focus:border-[var(--border)] focus:bg-[var(--surface)] focus:px-4 focus:py-2 focus:text-[var(--text)]"
>
Skip to main content
</a>
<ThemeProvider>
<ErrorBoundary>
<header
role="banner"
className="sticky top-0 z-50 flex items-center justify-between px-6 py-3 border-b border-[var(--border)] bg-[var(--bg)]"
className="sticky top-0 z-50 flex items-center justify-between border-b border-[var(--border)] bg-[var(--bg)]/95 px-6 py-3 backdrop-blur"
>
<div className="flex items-center gap-2">
<BrandLogo size={24} />
Expand Down
2 changes: 1 addition & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function Home() {
href="https://github.com/magic-peach/reframe"
target="_blank"
rel="noopener noreferrer"
className="hidden min-[300px]:flex fixed top-4 right-16 z-50 items-center gap-1.5 px-3 py-1.5 rounded-lg border border-[var(--border)] bg-[var(--surface)] text-[10px] font-heading font-semibold uppercase tracking-wider transition-all duration-200 ease-in-out hover:scale-105 hover:shadow-[0_0_10px_rgba(255,255,255,0.15)] hover:bg-white/10"
className="hidden min-[300px]:flex fixed top-4 right-16 z-50 items-center gap-1.5 px-3 py-1.5 rounded-lg border border-[var(--border)] bg-[var(--surface)] text-[10px] font-heading font-semibold uppercase tracking-wider transition-all duration-200 ease-in-out hover:scale-105 hover:border-[var(--accent)] hover:bg-[var(--accent-muted)] hover:shadow-[var(--shadow)]"
>
⭐ Star on GitHub
</a>
Expand Down
4 changes: 2 additions & 2 deletions src/components/AudioSpeedControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export default function AudioSpeedControl({ recipe, onChange }: Props) {
)}

{recipe.keepAudio && (recipe.trimStart !== 0 || recipe.trimEnd !== null) && (
<div role="note" className="mt-3 p-3 bg-amber-50 border border-amber-200 rounded text-sm text-amber-700 leading-relaxed flex items-start gap-2 animate-fade-in">
<div role="note" className="mt-3 p-3 bg-[var(--accent-muted)] border border-[var(--border)] rounded text-sm text-[var(--text)] leading-relaxed flex items-start gap-2 animate-fade-in">
<AlertTriangle size={12} aria-hidden="true" className="shrink-0 mt-0.5" />
<p>
Note: If audio doesn&apos;t start within the selected range, the output will be silent.
Expand All @@ -155,4 +155,4 @@ export default function AudioSpeedControl({ recipe, onChange }: Props) {
)}
</div>
);
}
}
14 changes: 7 additions & 7 deletions src/components/DownloadResult.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export default function DownloadResult({ result, onReset, soundOnCompletion, onT
<label htmlFor="filename-input" className="text-[var(--muted)] font-heading font-semibold uppercase tracking-wider">
Filename
</label>
<span className={cn("transition-colors", name.length >= 100 ? "text-red-500 font-medium" : "text-[var(--muted)]")}>
<span className={cn("transition-colors", name.length >= 100 ? "text-[var(--error)] font-medium" : "text-[var(--muted)]")}>
{100 - name.length} chars remaining
</span>
</div>
Expand All @@ -93,7 +93,7 @@ export default function DownloadResult({ result, onReset, soundOnCompletion, onT
maxLength={100}
className={cn(
"flex-1 px-3 py-2.5 bg-[var(--bg)] border rounded-lg text-sm transition-colors text-[var(--text)] placeholder:text-[var(--muted)]",
!isValid && name.length > 0 ? "border-red-500 focus:outline-red-500 focus:ring-1 focus:ring-red-500" : "border-[var(--border)] focus:outline-film-500"
!isValid && name.length > 0 ? "border-[var(--error)] focus:outline-[var(--error)] focus:ring-1 focus:ring-[var(--error)]" : "border-[var(--border)] focus:outline-[var(--accent)]"
)}
placeholder="Enter filename"
/>
Expand All @@ -102,7 +102,7 @@ export default function DownloadResult({ result, onReset, soundOnCompletion, onT
</span>
</div>
{!isValid && name.length > 0 && (
<p className="text-xs text-red-500 px-1 flex items-center gap-1.5 mt-1 animate-fade-in">
<p className="text-xs text-[var(--error)] px-1 flex items-center gap-1.5 mt-1 animate-fade-in">
<AlertCircle size={12} />
Filename contains invalid characters (\ / : * ? &quot; &lt; &gt; |)
</p>
Expand All @@ -116,7 +116,7 @@ export default function DownloadResult({ result, onReset, soundOnCompletion, onT
className={cn(
"flex-1 min-w-[10rem] flex items-center justify-center gap-2 py-3 text-sm font-heading font-bold uppercase tracking-wide rounded-lg transition-all",
isValid
? "bg-film-600 text-white hover:bg-film-700 hover:scale-[1.01] active:scale-[0.99] cursor-pointer"
? "bg-[var(--accent)] text-white hover:bg-[var(--accent-hover)] hover:scale-[1.02] active:scale-[0.99] cursor-pointer"
: "bg-[var(--border)] text-[var(--muted)] cursor-not-allowed"
)}
onClick={(e) => {
Expand All @@ -136,7 +136,7 @@ export default function DownloadResult({ result, onReset, soundOnCompletion, onT
target="_blank"
rel="noopener noreferrer"
aria-label="Preview video in new tab"
className="flex items-center justify-center gap-2 px-4 py-3 border border-[var(--border)] text-[var(--muted)] text-sm rounded-lg hover:bg-[var(--bg)] transition-colors"
className="flex items-center justify-center gap-2 px-4 py-3 border border-[var(--border)] text-[var(--muted)] text-sm rounded-lg hover:border-[var(--accent)] hover:bg-[var(--accent-muted)] hover:text-[var(--text)] transition-colors"
>
Preview
</a>
Expand All @@ -145,7 +145,7 @@ export default function DownloadResult({ result, onReset, soundOnCompletion, onT
title="Reset and upload a new video"
aria-label="Upload a new video"
onClick={handleReset}
className="flex items-center gap-2 px-4 py-3 border border-[var(--border)] text-[var(--muted)] text-sm rounded-lg hover:bg-[var(--bg)] transition-colors"
className="flex items-center gap-2 px-4 py-3 border border-[var(--border)] text-[var(--muted)] text-sm rounded-lg hover:border-[var(--accent)] hover:bg-[var(--accent-muted)] hover:text-[var(--text)] transition-colors"
>
<RotateCcw size={14} aria-hidden="true" />
New
Expand All @@ -155,7 +155,7 @@ export default function DownloadResult({ result, onReset, soundOnCompletion, onT
target="_blank"
rel="noopener noreferrer"
aria-label="Share on X (opens in a new tab)"
className="flex-1 min-w-[10rem] flex items-center justify-center gap-2 py-3 border border-[var(--border)] text-[var(--text)] text-sm font-heading font-bold uppercase tracking-wide rounded-lg hover:bg-[var(--bg)] transition-colors"
className="flex-1 min-w-[10rem] flex items-center justify-center gap-2 py-3 border border-[var(--border)] text-[var(--text)] text-sm font-heading font-bold uppercase tracking-wide rounded-lg hover:border-[var(--accent)] hover:bg-[var(--accent-muted)] transition-colors"
>
<Share2 size={15} aria-hidden="true" />
Share on X
Expand Down
4 changes: 2 additions & 2 deletions src/components/ExportSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export default function ExportSettings({
</p>

{isGif && (
<p className="text-xs text-amber-600 font-medium">
<p className="text-xs text-[var(--warning)] font-medium">
⚠ GIF files can be very large. Keep clips under 10 s for best results.
</p>
)}
Expand Down Expand Up @@ -176,7 +176,7 @@ export default function ExportSettings({
className={cn(
"text-xs",
recipe.stabilization
? "text-red-700 font-medium"
? "text-[var(--error)] font-medium"
: "text-[var(--muted)]"
)}
>
Expand Down
24 changes: 12 additions & 12 deletions src/components/FileUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export default function FileUpload({

// ── File info (shown after upload) ───────────────────
const FileInfo = () => (
<div className="px-4 py-3 bg-film-50 border border-film-200 rounded-lg">
<div className="px-4 py-3 bg-[var(--surface)] border border-[var(--border)] rounded-[var(--radius)] shadow-[var(--shadow)]">
<div className="flex flex-col lg:flex-row lg:items-center gap-3">
<div className="flex items-start gap-3 flex-1 min-w-0">
<div className="hidden lg:flex items-center justify-center w-9 h-9 rounded-lg bg-[var(--surface)] border border-[var(--border)] shrink-0">
Expand All @@ -136,18 +136,18 @@ export default function FileUpload({
<Film size={18} className="lg:hidden text-film-600 shrink-0 mt-0.5" />
<div className="flex-1 min-w-0">
<div className="flex flex-wrap items-center gap-2 mb-0.5">
<p className="text-sm font-semibold text-film-700 truncate max-w-[320px] xl:max-w-[420px]">
<p className="text-sm font-semibold text-[var(--text)] truncate max-w-[320px] xl:max-w-[420px]">
{currentFile?.name}
</p>
{currentFile && (
<span className="px-2 py-0.5 bg-gray-700 text-white font-bold tracking-wider rounded text-[10px] uppercase shrink-0">
<span className="px-2 py-0.5 bg-[var(--accent-muted)] text-[var(--text)] font-bold tracking-wider rounded text-[10px] uppercase shrink-0">
{currentFile.name.includes(".")
? currentFile.name.split(".").pop()
: "VIDEO"}
</span>
)}
</div>
<div className="text-xs text-gray-500 dark:text-gray-400 mt-1 space-y-0.5">
<div className="text-xs text-[var(--muted)] mt-1 space-y-0.5">
<p>{formatBytes(currentFile?.size ?? 0)}</p>
<p>
{duration > 0
Expand All @@ -168,12 +168,12 @@ export default function FileUpload({
</button>
</div>

<p className="text-xs text-gray-500 mt-3 break-words">
<p className="text-xs text-[var(--muted)] mt-3 break-words">
Supports: MP4, MOV, AVI, MKV, WebM, and most video formats
</p>

{fileError && (
<p className="text-xs text-red-500 mt-2 font-medium">{fileError}</p>
<p className="text-xs text-[var(--error)] mt-2 font-medium">{fileError}</p>
)}

<input
Expand Down Expand Up @@ -212,7 +212,7 @@ export default function FileUpload({
"group flex flex-col items-center justify-center gap-4 py-12 px-6",
"border-2 border-dashed rounded-xl cursor-pointer transition-all duration-300 relative overflow-hidden",
dragging
? "border-film-500 bg-film-50/50 scale-[1.02] shadow-[0_0_40px_-10px_rgba(230,57,70,0.4)] ring-4 ring-film-500/30"
? "border-[var(--accent)] bg-[var(--accent-muted)] scale-[1.02] shadow-[var(--shadow)] ring-4 ring-[var(--accent-muted)]"
: "border-[var(--border)] bg-[var(--bg)] hover:border-film-400 hover:bg-film-50/40"
)}
>
Expand All @@ -239,12 +239,12 @@ export default function FileUpload({
MP4 / MOV / AVI / WebM
</div>

<p className="text-xs text-gray-500 text-center">
<p className="text-xs text-[var(--muted)] text-center">
Supports: MP4, MOV, AVI, MKV, WebM, and most video formats up to 2GB
</p>

{fileError && (
<p className="text-sm text-red-500 text-center">{fileError}</p>
<p className="text-sm text-[var(--error)] text-center">{fileError}</p>
)}

<input
Expand Down Expand Up @@ -296,17 +296,17 @@ export default function FileUpload({
{/* ── Normal upload UI ── */}
<div className="space-y-2">
{error && (
<p role="alert" className="text-sm text-red-500">
<p role="alert" className="text-sm text-[var(--error)]">
{error}
</p>
)}
{warning && (
<p role="alert" className="text-sm text-yellow-500">
<p role="alert" className="text-sm text-[var(--warning)]">
{warning}
</p>
)}
{currentFile ? <FileInfo /> : <DropZone />}
</div>
</>
);
}
}
Loading
Loading