feat: rebrand to website design, Apple HIG icons, ASCII onboarding animation
Build & Release / Lint & Typecheck (push) Successful in 38s
Build & Release / Unit Tests (push) Successful in 31s
Build & Release / Windows (arm64) (push) Failing after 11s
Build & Release / Windows (x64) (push) Failing after 27s
Build & Release / Linux (arm64) (push) Canceled after 0s
Build & Release / Linux (x64) (push) Canceled after 0s
Build & Release / Publish Release (push) Canceled after 0s
Build & Release / macOS (arm64) (push) Canceled after 0s
Build & Release / macOS (x64) (push) Canceled after 0s
Build & Release / Lint & Typecheck (push) Successful in 38s
Build & Release / Unit Tests (push) Successful in 31s
Build & Release / Windows (arm64) (push) Failing after 11s
Build & Release / Windows (x64) (push) Failing after 27s
Build & Release / Linux (arm64) (push) Canceled after 0s
Build & Release / Linux (x64) (push) Canceled after 0s
Build & Release / Publish Release (push) Canceled after 0s
Build & Release / macOS (arm64) (push) Canceled after 0s
Build & Release / macOS (x64) (push) Canceled after 0s
- Align Electron CSS with website design schema (Inter font, #FBFAF5/#191919 palette, #213448/#94B4C1 accent) - Generate proper app icons from logo.svg via cairosvg (no more Pillow ladder) - Square bg icons for Electron/tray (Apple HIG — OS applies squircle mask) - Circle bg icons for website favicon only - Add scrolling ASCII agent-activity animation to onboarding hero left panel - Remove dock.setIcon() — let macOS use bundle .icns with system mask - Fix goal title overflow with min-w-0 for flex truncation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
273244817a
commit
eda0e26adb
18 files changed
+337
-237
No files matched your search
@@ -0,0 +1,85 @@
|
||||
import { memo } from "react";
|
||||
|
||||
/**
|
||||
* Scrolling ASCII agent-activity backdrop for the onboarding hero panel.
|
||||
* Pure CSS animation (translateY on compositor thread) — no JS ticks.
|
||||
* Content is doubled for seamless looping.
|
||||
*/
|
||||
|
||||
const LINES = [
|
||||
"",
|
||||
" ╭──────────╮",
|
||||
" │ CEO │",
|
||||
" ╰────┬─────╯",
|
||||
" ┌────┴─────┐",
|
||||
" ╭──┴──╮ ╭──┴──╮",
|
||||
" │ CTO │ │ CMO │",
|
||||
" ╰──┬──╯ ╰──┬──╯",
|
||||
" ╭──┴──╮ ╭──┴──╮",
|
||||
" │ Eng │ │ Mkt │",
|
||||
" ╰─────╯ ╰─────╯",
|
||||
"",
|
||||
" $ deploy --agents 12",
|
||||
" ████████████████████ 100%",
|
||||
" [OK] all agents online",
|
||||
"",
|
||||
" CEO │ analyzing requirements",
|
||||
" CEO │ identifying deliverables",
|
||||
" CEO │ delegating to leads",
|
||||
"",
|
||||
" CTO │ reviewing architecture",
|
||||
" CTO │ → Dev.01: auth module",
|
||||
" CTO │ → Dev.02: API layer",
|
||||
" CTO │ → QA: test strategy",
|
||||
"",
|
||||
" CMO │ go-to-market strategy",
|
||||
" CMO │ → Mkt.01: launch copy",
|
||||
" CMO │ → Mkt.02: social plan",
|
||||
"",
|
||||
" ┌─ SPRINT 1 ────────────────┐",
|
||||
" │ tasks ████████░░ 80% │",
|
||||
" │ agents 12 active │",
|
||||
" │ tests 128 passing │",
|
||||
" └──────────────────────────┘",
|
||||
"",
|
||||
" Dev.01 │ scaffolding auth",
|
||||
" Dev.02 │ REST endpoints",
|
||||
" Design │ component library",
|
||||
" QA │ integration tests",
|
||||
" Mkt.01 │ blog post drafted",
|
||||
"",
|
||||
" CEO │ sprint review: ✓",
|
||||
" CTO │ code review: merged",
|
||||
" Dev.01 │ PR #12 → main",
|
||||
" QA │ all tests green",
|
||||
" CMO │ brief approved",
|
||||
"",
|
||||
" [INFO] Sprint 1 complete",
|
||||
" [INFO] Advancing to Sprint 2",
|
||||
"",
|
||||
];
|
||||
|
||||
const BLOCK = LINES.join("\n");
|
||||
|
||||
export const AsciiAnimation = memo(function AsciiAnimation() {
|
||||
return (
|
||||
<div className="pointer-events-none absolute inset-0 select-none overflow-hidden">
|
||||
{/* Fade masks */}
|
||||
<div
|
||||
className="absolute inset-x-0 top-0 z-10 h-32"
|
||||
style={{ background: "linear-gradient(to bottom, var(--bg), transparent)" }}
|
||||
/>
|
||||
<div
|
||||
className="absolute inset-x-0 bottom-0 z-10 h-32"
|
||||
style={{ background: "linear-gradient(to top, var(--bg), transparent)" }}
|
||||
/>
|
||||
|
||||
{/* Scrolling track — doubled for seamless loop */}
|
||||
<div className="ascii-scroll-track whitespace-pre font-mono text-[11px] leading-[1.8] text-[color:var(--accent)] opacity-[0.08]">
|
||||
{BLOCK}
|
||||
{"\n"}
|
||||
{BLOCK}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
import type { ProfileSnapshot } from "@shared/types";
|
||||
import type { AppLocale } from "@shared/locale";
|
||||
import { ConnectorReadiness } from "./ConnectorReadiness";
|
||||
import { AsciiAnimation } from "./AsciiAnimation";
|
||||
|
||||
type Step = "language" | "company" | "mission" | "launch";
|
||||
|
||||
@@ -57,6 +58,9 @@ export function OnboardingHero({
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* ASCII agent activity backdrop */}
|
||||
<AsciiAnimation />
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 24 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
|
||||
@@ -22,12 +22,12 @@ export function GoalProgress({ goals, tasks, onNavigate }: { goals: GoalRecord[]
|
||||
onClick={() => onNavigate("goals")}
|
||||
className="focus-ring w-full rounded-[8px] border border-[color:var(--line)] bg-[color:var(--panel)] px-4 py-3.5 text-left transition hover:border-[color:var(--line-strong)] hover:shadow-sm"
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<Target size={15} weight="fill" className="text-[color:var(--accent)]" />
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div className="flex min-w-0 items-center gap-2">
|
||||
<Target size={15} weight="fill" className="shrink-0 text-[color:var(--accent)]" />
|
||||
<span className="truncate text-[13px] font-medium text-[color:var(--text)]">{goal.title}</span>
|
||||
</div>
|
||||
<span className="whitespace-nowrap text-[13px] font-bold tabular-nums text-[color:var(--accent)]">{pct}%</span>
|
||||
<span className="shrink-0 whitespace-nowrap text-[13px] font-bold tabular-nums text-[color:var(--accent)]">{pct}%</span>
|
||||
</div>
|
||||
<div className="mt-2.5 h-2 w-full overflow-hidden rounded-full bg-[color:var(--panel-soft)]">
|
||||
<div
|
||||
|
||||
@@ -32,10 +32,10 @@ export function GoalList({
|
||||
onClick={() => onSelect(goal.id)}
|
||||
className={`cursor-pointer transition-colors duration-100 ${isSelected ? "bg-[color:var(--accent-soft)]" : "hover:bg-[color:var(--panel-soft)]"}`}
|
||||
>
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="mb-2 flex items-center justify-between gap-3">
|
||||
<div className="flex min-w-0 items-center gap-2">
|
||||
{isSelected && (
|
||||
<CheckCircle size={16} weight="fill" className="text-[color:var(--accent)]" />
|
||||
<CheckCircle size={16} weight="fill" className="shrink-0 text-[color:var(--accent)]" />
|
||||
)}
|
||||
<div className="truncate text-[14px] font-semibold text-[color:var(--text)]">{goal.title}</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user