From 305278a84697fdf4b8661cb5272ed0c3cea9f97d Mon Sep 17 00:00:00 2001 From: Leon Serfaty <80597822+silkoserfo@users.noreply.github.com> Date: Mon, 8 Jun 2026 04:37:10 -0400 Subject: [PATCH] Add comprehensive /features page + allow Unsplash imagery --- DESIGN.md | 46 +- app/(marketing)/about/page.tsx | 196 +++++++ app/(marketing)/features/page.tsx | 763 +++++++++++++++++++++++++++ app/globals.css | 21 +- components/admin/cost-chart.tsx | 4 +- components/admin/ui/chart-theme.ts | 10 +- components/app/team-client.tsx | 2 +- components/app/waveform-player.tsx | 2 +- components/marketing/site-footer.tsx | 1 + components/marketing/site-header.tsx | 3 +- next.config.mjs | 4 +- 11 files changed, 1008 insertions(+), 44 deletions(-) create mode 100644 app/(marketing)/about/page.tsx create mode 100644 app/(marketing)/features/page.tsx diff --git a/DESIGN.md b/DESIGN.md index d4083ad..df59302 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -15,8 +15,8 @@ Reference: [Wix Design Assets & Guidelines](https://www.wix.com/about/design-ass 1. **Confident & editorial.** Big, bold, tightly‑tracked headlines. Generous whitespace. Let one idea own each section. Marketing reads like a magazine, not a SaaS dashboard. 2. **High contrast, mostly monochrome.** Near‑black on white is the base. Color is used - deliberately — almost always the single **Wix Blue** accent — never decoratively. -3. **Black is the primary action.** Primary buttons are solid black pills. Blue is the + deliberately — almost always the single **orange** accent — never decoratively. +3. **Black is the primary action.** Primary buttons are solid black pills. Orange is the *interactive / accent* color (links, focus rings, active nav, highlights). This is the defining Wix.com marketing combination. 4. **Soft, rounded, friendly.** Pill buttons, large card radii, gentle shadows. Nothing @@ -36,8 +36,8 @@ Reference: [Wix Design Assets & Guidelines](https://www.wix.com/about/design-ass | ---------------- | ---------- | ------------------ | --- | | **Ink / black** | `#0B0B0B` | `0 0% 5%` | Primary buttons, headlines, default text | | **White** | `#FFFFFF` | `0 0% 100%` | Page background, cards | -| **Wix Blue** | `#116DFF` | `217 100% 53%` | Links, focus rings, active states, highlights, brand mark | -| **Blue (hover)** | `#0B57E0` | `219 90% 46%` | Blue hover / pressed | +| **Brand Orange** | `#E65100` | `21 100% 45%` | Links, focus rings, active states, highlights, brand mark | +| **Orange (hover)**| `#B84500` | `21 100% 39%` | Orange hover / pressed | | **Surface** | `#F4F4F4` | `0 0% 96%` | Section backgrounds, muted fills, inputs‑on‑white | | **Border** | `#E4E4E4` | `0 0% 89%` | Hairline dividers, card borders, input borders | | **Muted text** | `#6A6A6A` | `0 0% 42%` | Secondary / supporting copy | @@ -65,7 +65,7 @@ status, and small decorative moments — never for primary UI chrome. --card-foreground 0 0% 7% --primary 0 0% 5% /* INK — black buttons */ --primary-foreground 0 0% 100% ---brand 217 100% 53% /* WIX BLUE — links, accents, active */ +--brand 21 100% 45% /* ORANGE — links, accents, active */ --brand-foreground 0 0% 100% --secondary 0 0% 96% /* surface gray fill */ --secondary-foreground 0 0% 7% @@ -78,14 +78,14 @@ status, and small decorative moments — never for primary UI chrome. --warning 24 100% 50% --border 0 0% 89% --input 0 0% 89% ---ring 217 100% 53% /* focus ring = Wix Blue */ +--ring 21 100% 45% /* focus ring = brand orange */ ``` **Rules** - Default text = `foreground`. Secondary text = `muted-foreground`. Never lighter than `#6A6A6A` on white. -- Links and any "interactive accent" = **Wix Blue** (`text-brand`). Hover → underline or darker blue. -- Primary CTA = **black** pill. Never blue and black competing in the same button group. -- Focus is always a **2px Wix‑Blue ring** with a 2px offset. No exceptions. +- Links and any "interactive accent" = **orange** (`text-brand`). Hover → underline or darker orange. +- Primary CTA = **black** pill. Never orange and black competing in the same button group. +- Focus is always a **2px orange ring** with a 2px offset. No exceptions. --- @@ -108,7 +108,7 @@ System fallback stack: `ui-sans-serif, system-ui, -apple-system, "Segoe UI", san | Lead paragraph | `1.125–1.25rem` (18–20px)| 400 | normal | `text-muted-foreground` | | Body | `1rem` (16px) | 400 | normal | base UI = 14–16px | | Small / meta | `0.875rem` (14px) | 500 | normal | | -| Eyebrow / label | `0.8125rem` (13px) | 600 | `0.04em` UPPERCASE | Use **Wix Blue** or muted | +| Eyebrow / label | `0.8125rem` (13px) | 600 | `0.04em` UPPERCASE | Use **orange** or muted | **Rules** - Headlines are tight: always pair big display sizes with `tracking-tight` and `leading-[1.05–1.1]`. @@ -154,14 +154,14 @@ Pill shape, Madefor, weight 600, `transition`. Sizes: `sm h-9`, `default h-11`, | Variant | Style | | ------------ | ----- | | `default` | **Black** fill, white text, `rounded-full`, `hover:bg-black/85`, soft shadow. Primary CTA. | -| `brand` | **Wix Blue** fill, white text, `rounded-full`, `hover:bg-[#0B57E0]`. Use for the single hero/marketing accent action when black isn't wanted. | +| `brand` | **orange** fill, white text, `rounded-full`, `hover:bg-brand-hover`. Use for the single hero/marketing accent action when black isn't wanted. | | `secondary` | `secondary` gray fill, ink text, `rounded-full`, `hover:bg-black/[.06]`. | | `outline` | White fill, `border` (1.5px) ink/border color, ink text, `rounded-full`, hover gray fill. | | `ghost` | Transparent, ink text, `hover:bg-secondary`. | -| `link` | Wix‑Blue text, underline on hover, no padding. | +| `link` | orange text, underline on hover, no padding. | | `destructive`| `destructive` fill, white text, `rounded-full`. | -Icon buttons: `rounded-full`, square. Always include the blue focus ring. +Icon buttons: `rounded-full`, square. Always include the orange focus ring. ### Cards (``) `rounded-2xl border bg-card shadow-sm`. Interactive cards add `transition hover:shadow-md hover:-translate-y-0.5`. @@ -174,22 +174,22 @@ Focus: `ring-2 ring-brand border-transparent`. Labels: 14px weight 600, `mb-2`. ### Badges / chips `rounded-full px-3 py-1 text-xs font-semibold`. - `default` → ink fill / white text. -- `brand` → blue tint `bg-brand/10 text-brand`. +- `brand` → orange tint `bg-brand/10 text-brand`. - `secondary` → gray fill. - `success / warning / destructive` → tinted (`bg-x/12 text-x`). -Eyebrow chips on marketing: `bg-secondary` pill with a blue dot/`Sparkles` and uppercase label. +Eyebrow chips on marketing: `bg-secondary` pill with an orange dot/`Sparkles` and uppercase label. ### Navigation - **Marketing header:** white, hairline bottom border, `backdrop-blur`. Black wordmark - with blue mic mark. Nav links muted → ink on hover. Right side: `ghost` "Log in" + + with orange mic mark. Nav links muted → ink on hover. Right side: `ghost` "Log in" + black pill "Get Started". - **App sidebar:** white, hairline right border. Item = `rounded-full px-4 py-2.5`. Active = `bg-brand/10 text-brand font-semibold`; idle = muted, `hover:bg-secondary`. -- **Active link accent is always Wix Blue.** +- **Active link accent is always orange.** ### Pricing cards White cards, big display price (weight 800). Highlighted plan: `ring-2 ring-brand` + -floating blue "Most popular" pill + `shadow-lg`. Feature list uses blue `Check` icons. +floating orange "Most popular" pill + `shadow-lg`. Feature list uses orange `Check` icons. ### Footer `bg-secondary` (`#F4F4F4`), hairline top border, multi‑column link lists, muted labels, @@ -198,10 +198,10 @@ ink wordmark. Calm and quiet. --- ## 6. Iconography & imagery -- **Icons:** `lucide-react`, `1.5` stroke, `size-4`/`size-5`. Inherit text color; use blue +- **Icons:** `lucide-react`, `1.5` stroke, `size-4`/`size-5`. Inherit text color; use orange only for accent/active. Icon "chips" = `rounded-2xl bg-secondary` (neutral) or `bg-brand/10 text-brand` (accent) tile. -- **Brand mark:** mic glyph in a `rounded-2xl` tile — blue tile / white glyph on light, or +- **Brand mark:** mic glyph in a `rounded-2xl` tile — orange tile / white glyph on light, or black tile on accent surfaces. - **Imagery:** large, rounded (`rounded-3xl`), full‑bleed where possible. Generous. @@ -215,9 +215,9 @@ ink wordmark. Calm and quiet. --- ## 8. Do / Don't -- ✅ Black primary pill + Wix‑Blue accents. ❌ Purple/gradient primary buttons. -- ✅ One blue accent per view. ❌ Rainbow of brand colors in core UI. +- ✅ Black primary pill + orange accents. ❌ Purple/gradient primary buttons. +- ✅ One orange accent per view. ❌ Rainbow of brand colors in core UI. - ✅ Big tight headlines in Madefor Display. ❌ Small timid headings. - ✅ Hairline borders + soft shadows + whitespace. ❌ Heavy borders, boxes‑in‑boxes. - ✅ Pill buttons & chips, `rounded-2xl` cards. ❌ Sharp corners / `rounded-md` chrome. -- ✅ Blue focus ring everywhere. ❌ Default browser outline or no focus state. +- ✅ Orange focus ring everywhere. ❌ Default browser outline or no focus state. diff --git a/app/(marketing)/about/page.tsx b/app/(marketing)/about/page.tsx new file mode 100644 index 0000000..8b121ac --- /dev/null +++ b/app/(marketing)/about/page.tsx @@ -0,0 +1,196 @@ +import type { Metadata } from "next"; +import Link from "next/link"; +import { + Sparkles, + Wand2, + ShieldCheck, + Globe, + Zap, + HeartHandshake, + ArrowRight, +} from "lucide-react"; +import { Button } from "@/components/ui/button"; + +export const metadata: Metadata = { + title: "About", + description: + "PodcastYes is an AI studio that turns a single idea into a finished, publishable podcast — script, voices, and cover art — in minutes. Learn why we built it and what we believe.", +}; + +const STATS = [ + { value: "3", label: "AI models in one workflow" }, + { value: "14+", label: "Realistic narrator voices" }, + { value: "13+", label: "Languages supported" }, + { value: "Minutes", label: "From idea to finished episode" }, +]; + +const VALUES = [ + { + icon: Sparkles, + title: "Creativity for everyone", + body: "Powerful production shouldn't require gear, a budget, or technical skill. If you can describe an idea, you can turn it into a finished episode.", + }, + { + icon: Wand2, + title: "Quality you'd actually publish", + body: "AI drafts are a starting point, not the finish line. Every script and voice is editable, so the final cut always sounds like you.", + }, + { + icon: ShieldCheck, + title: "Built responsibly", + body: "We screen content against a clear policy, never use your private work to train our models, and make sure you own everything you create.", + }, + { + icon: Globe, + title: "Global from day one", + body: "Stories aren't only told in English. With 13+ languages, you can produce for an audience anywhere — no re-recording required.", + }, + { + icon: Zap, + title: "Fast, but never careless", + body: "Minutes from idea to episode, with the controls to get the details right before you hit publish. Speed and craft aren't a trade-off.", + }, + { + icon: HeartHandshake, + title: "Honest and transparent", + body: "Simple plans, clear limits, cancel anytime. No dark patterns and no surprises — just a tool that respects your time and your work.", + }, +]; + +export default function AboutPage() { + return ( + <> + {/* Hero */} +
+
+

About us

+

+ Making great podcasts possible for everyone +

+

+ PodcastYes is an AI studio that turns a single idea into a finished, publishable episode — + script, voices, and cover art — in minutes. No microphone, no editing suite, no production + budget. +

+
+
+ + {/* Stats */} +
+
+ {STATS.map((s) => ( +
+

+ {s.value} +

+

{s.label}

+
+ ))} +
+
+ + {/* Mission */} +
+
+

Our mission

+

+ To remove every barrier between a great idea and a published podcast — so anyone with + something to say can be{" "} + heard. +

+
+
+ + {/* Story */} +
+
+

Our story

+

+ Why we built PodcastYes +

+
+

+ Podcasting is one of the most personal ways to reach an audience — and one of the + hardest to start. Scripting, recording, editing, designing artwork, and publishing can + take days and a stack of tools and skills most people simply don't have. Brilliant + ideas die in that gap between “I should make a podcast” and actually + shipping one. +

+

+ We thought the modern AI stack could collapse all of that into a single workflow. GPT-4 + can write a tight, on-brand script. ElevenLabs can voice it with realistic, multi-speaker + narration. DALL·E can design cover art that matches the topic. Stitched together, they + turn “I have a topic” into “I have an episode.” +

+

+ So we built PodcastYes: a studio that lives in your browser. Describe an idea, fine-tune + the result in a real editor, download the MP3 — then repurpose it into a blog post, a + social thread, or a newsletter. We're a small team of engineers, audio nerds, and + storytellers obsessed with making production effortless without making it feel generic. +

+
+
+
+ + {/* Values */} +
+
+
+

+ What we believe +

+

+ The principles behind the product +

+
+
+ {VALUES.map((v) => ( +
+ + + +

{v.title}

+

{v.body}

+
+ ))} +
+
+
+ + {/* CTA */} +
+
+
+
+
+

+ Come make something worth listening to +

+

+ Spin up a fully produced episode on the free plan in a couple of minutes — then decide. +

+
+ + +
+
+
+
+
+ + ); +} diff --git a/app/(marketing)/features/page.tsx b/app/(marketing)/features/page.tsx new file mode 100644 index 0000000..558f492 --- /dev/null +++ b/app/(marketing)/features/page.tsx @@ -0,0 +1,763 @@ +import type { Metadata } from "next"; +import Link from "next/link"; +import { + ArrowRight, + FileText, + AudioLines, + ImageIcon, + Languages, + Repeat, + ListMusic, + Share2, + Users, + KeyRound, + CreditCard, + Edit3, + Download, + Sparkles, + Mic2, + Radio, + MessagesSquare, + Palette, + Globe2, + Workflow, + Gauge, + ShieldCheck, + Wand2, + Mail, + Hash, + Clock, + Check, + Rocket, +} from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; + +export const metadata: Metadata = { + title: "Features", + description: + "Everything PodcastYes does — AI scriptwriting, realistic multi-voice audio, cover art, repurposing, a season generator, 13+ languages, team white-label, an API, and more.", +}; + +const HERO_IMG = + "https://images.unsplash.com/photo-1590602847861-f357a9332bbc?auto=format&fit=crop&w=1600&q=80"; +const AUDIO_IMG = + "https://images.unsplash.com/photo-1598488035139-bdbb2231ce04?auto=format&fit=crop&w=1400&q=80"; +const TEAM_IMG = + "https://images.unsplash.com/photo-1521737604893-d14cc237f11d?auto=format&fit=crop&w=1400&q=80"; + +export default function FeaturesPage() { + return ( + <> + {/* 1 — Hero */} +
+
+
+ Every feature, one workflow +

+ The entire podcast studio, powered by AI +

+

+ Write, narrate, illustrate, edit, repurpose, and publish — PodcastYes replaces a + writer, a voice actor, an editor, and a designer with one clean, end-to-end workflow. + No microphone, no software, no skills required. +

+
+ + +
+

+ Free plan — 3 scripts & 1 audio generation / month. No card required. +

+
+
+
+ {/* eslint-disable-next-line @next/next/no-img-element */} + Studio condenser microphone +
+
+
+ + + +
+

Topic → episode

+

in minutes, not hours

+
+
+
+
+
+
+ + {/* 2 — Model strip */} +
+
+

+ Best-in-class AI, stitched into one product +

+
+ + + +
+
+
+ + {/* 3 — AI script generation */} + + + {/* 4 — Multi-voice audio (with image) */} + + + {/* 5 — Formats */} +
+
+ +
+ + + +
+
+
+ + {/* 6 — Cover art */} + } + /> + + {/* 7 — Languages */} +
+
+ +
+ {[ + "English", + "Spanish", + "French", + "German", + "Italian", + "Portuguese", + "Dutch", + "Polish", + "Hindi", + "Japanese", + "Korean", + "Chinese", + "Arabic", + "Turkish", + "Russian", + ].map((l) => ( + + + {l} + + ))} +
+
+
+ + {/* 8 — Workflow */} +
+
+ +
+ + + +
+
+
+ + {/* 9 — Script editor */} + + + {/* 10 — Player & downloads */} + } + /> + + {/* 11 — Repurposing */} +
+
+ +
+ + + +
+
+
+ + {/* 12 — Series generator */} + + + {/* 13 — Share & publish */} + } + /> + + {/* 14 — Teams / white-label (with image) */} + + + {/* 15 — API */} + } + /> + + {/* 16 — Plans, usage & billing */} +
+
+
+ Transparent & flexible +

+ Clear limits, your choice of payment +

+

+ Start free and upgrade as you grow. A live usage dashboard shows exactly where you + stand against your plan, with friendly nudges before you hit a limit. Pay with a card + via Stripe or with PayPal — whichever you prefer. +

+
+ + + +
+ +
+
+ + + + +
+
+
+ + {/* 17 — Everything included grid */} +
+
+ +
+ {EVERYTHING.map((f) => ( +
+ + + +
+

{f.title}

+

{f.body}

+
+
+ ))} +
+
+
+ + {/* 18 — CTA */} +
+
+
+

+ See it produce your first episode +

+

+ Spin up a fully produced episode on the free plan in a couple of minutes — then decide. +

+
+ + +
+
+
+
+ + ); +} + +/* ─────────────────────────── helpers ─────────────────────────── */ + +function Eyebrow({ children }: { children: React.ReactNode }) { + return

{children}

; +} + +function SectionHeading({ + eyebrow, + title, + subtitle, +}: { + eyebrow: string; + title: string; + subtitle: string; +}) { + return ( +
+ {eyebrow} +

{title}

+

{subtitle}

+
+ ); +} + +function FeatureBand({ + eyebrow, + icon: Icon, + title, + body, + bullets, + image, + imageAlt, + visual, + reverse, + tinted, +}: { + eyebrow: string; + icon: React.ComponentType<{ className?: string }>; + title: string; + body: string; + bullets?: string[]; + image?: string; + imageAlt?: string; + visual?: React.ReactNode; + reverse?: boolean; + tinted?: boolean; +}) { + return ( +
+
+
+ + + + {eyebrow} +

{title}

+

{body}

+ {bullets && ( +
    + {bullets.map((b) => ( +
  • + + + + {b} +
  • + ))} +
+ )} +
+
+ {image ? ( +
+ {/* eslint-disable-next-line @next/next/no-img-element */} + {imageAlt +
+ ) : ( + visual + )} +
+
+
+ ); +} + +function ModelChip({ + icon: Icon, + name, + role, +}: { + icon: React.ComponentType<{ className?: string }>; + name: string; + role: string; +}) { + return ( +
+ + + +
+

{name}

+

{role}

+
+
+ ); +} + +function FormatCard({ + icon: Icon, + title, + body, +}: { + icon: React.ComponentType<{ className?: string }>; + title: string; + body: string; +}) { + return ( + + + + + +

{title}

+

{body}

+
+
+ ); +} + +function StepCard({ + n, + icon: Icon, + title, + body, +}: { + n: string; + icon: React.ComponentType<{ className?: string }>; + title: string; + body: string; +}) { + return ( + + +
+ + + + {n} +
+

{title}

+

{body}

+
+
+ ); +} + +function FeatureChip({ + icon: Icon, + label, +}: { + icon: React.ComponentType<{ className?: string }>; + label: string; +}) { + return ( + + {label} + + ); +} + +function MiniStat({ value, label }: { value: string; label: string }) { + return ( +
+

{value}

+

{label}

+
+ ); +} + +/* lightweight, dependency-free "product" visuals for image-less bands */ + +function ArtVisual() { + return ( +
+ {["from-brand/30 to-brand/5", "from-foreground/20 to-foreground/5", "from-amber-400/30 to-amber-400/5", "from-emerald-400/30 to-emerald-400/5"].map( + (g, i) => ( +
+ +
+ ) + )} +
+ ); +} + +function PlayerVisual() { + return ( +
+
+ + + +
+

The history of coffee, ep. 1

+

12:04 · solo · EN

+
+
+
+ {Array.from({ length: 48 }).map((_, i) => ( + + ))} +
+
+ + +
+
+ ); +} + +function ShareVisual() { + return ( +
+
+ + + + + podcastyes.app/p/aZ9k… + +
+
+
+ +
+
+ + Public + +

Your episode, live for anyone

+

+ no login required +

+
+
+
+ ); +} + +function ApiVisual() { + return ( +
+
+ + POST /api/v1/episodes +
+
+        {`curl -X POST https://podcastyes.app/api/v1/episodes \\
+  -H "Authorization: Bearer pky_live_…" \\
+  -d '{
+    "topic": "Why deep work matters",
+    "format": "SOLO",
+    "language": "en"
+  }'
+
+→ 201  { "id": "ep_8fk2…", "status": "QUEUED" }`}
+      
+
+ ); +} + +const EVERYTHING = [ + { icon: FileText, title: "GPT-4 scripts", body: "Structured, spoken-word scripts in seconds." }, + { icon: AudioLines, title: "Multi-voice audio", body: "14+ realistic voices, multi-speaker." }, + { icon: ImageIcon, title: "AI cover art", body: "Bespoke DALL·E artwork per episode." }, + { icon: Languages, title: "13+ languages", body: "Native scripts and narration." }, + { icon: Edit3, title: "Script editor", body: "Edit, regenerate sections, re-record." }, + { icon: Download, title: "MP3 + ZIP export", body: "Audio, art, transcript & notes." }, + { icon: Repeat, title: "Repurposing", body: "Blog, social thread, newsletter." }, + { icon: ListMusic, title: "Series generator", body: "Plan whole seasons from one prompt." }, + { icon: Share2, title: "Public share pages", body: "No-login listen links, branded." }, + { icon: Users, title: "Team workspace", body: "5 seats, invitations, roles." }, + { icon: Palette, title: "White-label", body: "Your brand color, logo, no PodcastYes." }, + { icon: KeyRound, title: "Developer API", body: "Generate episodes programmatically." }, + { icon: Gauge, title: "Usage dashboard", body: "Live meters and limit nudges." }, + { icon: CreditCard, title: "Stripe & PayPal", body: "Pay your way; cancel anytime." }, + { icon: Sparkles, title: "Live generation", body: "Watch each stage stream in real time." }, + { icon: ShieldCheck, title: "Yours to keep", body: "Download and publish anywhere." }, +]; diff --git a/app/globals.css b/app/globals.css index be2ff35..f833836 100644 --- a/app/globals.css +++ b/app/globals.css @@ -4,7 +4,7 @@ @layer base { :root { - /* Wix-inspired: white base, near-black ink, single Wix-Blue accent */ + /* White base, near-black ink, single ORANGE accent */ --background: 0 0% 100%; --foreground: 0 0% 7%; --card: 0 0% 100%; @@ -16,10 +16,10 @@ --primary: 0 0% 5%; --primary-foreground: 0 0% 100%; - /* WIX BLUE — links, focus, active states, accents */ - --brand: 217 100% 53%; + /* ORANGE — links, focus, active states, accents (#E65100) */ + --brand: 21 100% 45%; --brand-foreground: 0 0% 100%; - --brand-hover: 219 90% 46%; + --brand-hover: 21 100% 39%; --secondary: 0 0% 96%; --secondary-foreground: 0 0% 7%; @@ -31,11 +31,12 @@ --destructive: 4 86% 58%; --destructive-foreground: 0 0% 100%; --success: 157 100% 30%; - --warning: 24 100% 50%; + /* amber — kept distinct from the orange brand accent */ + --warning: 38 100% 50%; --border: 0 0% 89%; --input: 0 0% 89%; - --ring: 217 100% 53%; + --ring: 21 100% 45%; --radius: 0.875rem; } @@ -50,9 +51,9 @@ --primary: 0 0% 100%; --primary-foreground: 0 0% 5%; - --brand: 217 100% 60%; + --brand: 24 100% 58%; --brand-foreground: 0 0% 100%; - --brand-hover: 217 100% 66%; + --brand-hover: 24 100% 64%; --secondary: 0 0% 13%; --secondary-foreground: 0 0% 98%; @@ -64,11 +65,11 @@ --destructive: 4 80% 58%; --destructive-foreground: 0 0% 100%; --success: 157 70% 45%; - --warning: 24 100% 55%; + --warning: 40 100% 55%; --border: 0 0% 16%; --input: 0 0% 16%; - --ring: 217 100% 60%; + --ring: 24 100% 58%; } } diff --git a/components/admin/cost-chart.tsx b/components/admin/cost-chart.tsx index 082805d..beb38e0 100644 --- a/components/admin/cost-chart.tsx +++ b/components/admin/cost-chart.tsx @@ -29,8 +29,8 @@ export function CostChart({ data }: { data: CostPoint[] }) { contentStyle={{ fontSize: 12, borderRadius: 8 }} /> - {/* Wix-palette data series: Wix Blue + Deep Purple */} - + {/* Data series: brand orange + deep purple */} + diff --git a/components/admin/ui/chart-theme.ts b/components/admin/ui/chart-theme.ts index 5473b43..0ca14c4 100644 --- a/components/admin/ui/chart-theme.ts +++ b/components/admin/ui/chart-theme.ts @@ -1,11 +1,11 @@ -// Wix-aligned chart palette. Series 1 = Wix Blue, series 2 = deep purple, -// plus success/warning for status-coded series. Kept hex (Recharts needs concrete +// Chart palette. Series 1 = brand orange, series 2 = deep purple, plus +// success/amber for status-coded series. Kept hex (Recharts needs concrete // colors), mirroring the design tokens in app/globals.css. export const CHART = { - brand: "#116DFF", + brand: "#E65100", brand2: "#3910ED", success: "#00C271", - warning: "#FF5500", + warning: "#F59E0B", ink: "#0B0B0B", muted: "#6A6A6A", grid: "#E4E4E4", @@ -14,7 +14,7 @@ export const CHART = { // Tier colors for the plan-distribution donut. export const TIER_COLORS: Record = { free: "#9AA0A6", - creator: "#116DFF", + creator: "#E65100", pro: "#3910ED", agency: "#0B0B0B", }; diff --git a/components/app/team-client.tsx b/components/app/team-client.tsx index df7d228..adedcf0 100644 --- a/components/app/team-client.tsx +++ b/components/app/team-client.tsx @@ -290,7 +290,7 @@ function BrandingCard({ orgId, branding }: { orgId: string; branding: Branding | {primaryColor.trim() && !previewHsl && ( -

Enter a 6-digit hex colour (e.g. #116DFF).

+

Enter a 6-digit hex colour (e.g. #E65100).

)}
diff --git a/components/app/waveform-player.tsx b/components/app/waveform-player.tsx index d684d67..26902a1 100644 --- a/components/app/waveform-player.tsx +++ b/components/app/waveform-player.tsx @@ -85,7 +85,7 @@ export function WaveformPlayer({ ctx.clearRect(0, 0, w, h); const styles = getComputedStyle(canvas); - const played = `hsl(${styles.getPropertyValue("--brand").trim() || "217 100% 53%"})`; + const played = `hsl(${styles.getPropertyValue("--brand").trim() || "21 100% 45%"})`; const unplayed = `hsl(${styles.getPropertyValue("--border").trim() || "0 0% 89%"})`; const n = waveform.length; diff --git a/components/marketing/site-footer.tsx b/components/marketing/site-footer.tsx index 6ee1103..6873ab0 100644 --- a/components/marketing/site-footer.tsx +++ b/components/marketing/site-footer.tsx @@ -26,6 +26,7 @@ export function SiteFooter() { ["Features", "/#features"], ["Pricing", "/pricing"], ["FAQ", "/faq"], + ["About", "/about"], ]} /> How it works - Features + Features Pricing FAQ + About
diff --git a/next.config.mjs b/next.config.mjs index e001e4d..9a97256 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -12,6 +12,8 @@ const nextConfig = { // DALL·E asset URLs (OpenAI blob storage) used before they are persisted to local disk. // Scoped to the single OpenAI host actually used — no broad *.blob.core.windows.net wildcard. { protocol: "https", hostname: "oaidalleapiprodscus.blob.core.windows.net" }, + // Marketing imagery (features/about pages). + { protocol: "https", hostname: "images.unsplash.com" }, ], }, // Server-only packages that should be required at runtime, not bundled by webpack. @@ -24,7 +26,7 @@ const nextConfig = { // to per-request nonces (and drop 'unsafe-*') once the app is migrated. const csp = [ "default-src 'self'", - "img-src 'self' data: https://*.blob.core.windows.net", + "img-src 'self' data: https://*.blob.core.windows.net https://images.unsplash.com", "media-src 'self'", "style-src 'self' 'unsafe-inline'", "script-src 'self' 'unsafe-inline' 'unsafe-eval'",