Skip to content

Commit 35355a3

Browse files
committed
Polish PsyFlow layout and branding
1 parent 0034a38 commit 35355a3

6 files changed

Lines changed: 170 additions & 114 deletions

File tree

website/src/app/changelog/page.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,17 @@ const releaseBackgrounds = [
88
"bg-[#f4f0ff]"
99
] as const;
1010

11+
const releaseChipBackgrounds = [
12+
"bg-[#d9edf6]",
13+
"bg-[#f8d8cf]",
14+
"bg-[#dff2d7]",
15+
"bg-[#ddd7f4]",
16+
"bg-[#f3e2d5]"
17+
] as const;
18+
1119
export default function ChangelogPage() {
1220
return (
13-
<div className="space-y-8 pb-8">
21+
<div className="space-y-8 pb-8 pt-2 sm:space-y-10 sm:pt-4">
1422
<section>
1523
<h1 className="font-heading text-4xl font-bold leading-[0.95] text-[#25314d] sm:text-5xl lg:text-6xl">
1624
Changes
@@ -23,9 +31,16 @@ export default function ChangelogPage() {
2331
key={release.version}
2432
className={`pf-frame p-5 sm:p-6 ${releaseBackgrounds[index % releaseBackgrounds.length]}`}
2533
>
26-
<div className="flex flex-col gap-2 sm:flex-row sm:items-baseline sm:justify-between">
27-
<div className="text-xs font-bold uppercase tracking-[0.16em] text-slate-500">
28-
Version {release.version}
34+
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
35+
<div className="flex flex-wrap items-center gap-3">
36+
<span
37+
className={`inline-flex rounded-full border-2 border-[#25314d] px-3 py-1 text-xs font-bold uppercase tracking-[0.16em] text-[#25314d] shadow-[0_3px_0_#25314d] ${releaseChipBackgrounds[index % releaseChipBackgrounds.length]}`}
38+
>
39+
Version {release.version}
40+
</span>
41+
<span className="text-[11px] font-bold uppercase tracking-[0.18em] text-slate-500">
42+
Release Notes
43+
</span>
2944
</div>
3045
<div className="text-sm font-medium text-slate-600">{release.date}</div>
3146
</div>

website/src/app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default function RootLayout({ children }: Readonly<{ children: React.Reac
1919
<body>
2020
<div className="pf-grid-bg min-h-screen">
2121
<SiteHeader />
22-
<main className="mx-auto w-full max-w-7xl px-4 pb-12 pt-28 sm:px-6 sm:pt-32 lg:px-8">{children}</main>
22+
<main className="mx-auto w-full max-w-7xl px-4 pb-12 pt-32 sm:px-6 sm:pt-36 lg:px-8">{children}</main>
2323
<SiteFooter />
2424
</div>
2525
</body>

website/src/app/page.tsx

Lines changed: 94 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2,68 +2,60 @@ import Link from "next/link";
22
import Image from "next/image";
33
import { CommandCard } from "@/components/command-card";
44
import { ResourceCard } from "@/components/resource-card";
5-
import { changelog, siteData } from "@/lib/generated";
5+
import { changelog } from "@/lib/generated";
66
import { withBasePath } from "@/lib/base-path";
77
import { chineseTutorials, englishTutorials, type TutorialEntry } from "@/lib/content";
88
import { routes } from "@/lib/routes";
99

1010
function TapsDiagram() {
1111
return (
1212
<div className="pf-frame bg-[#fffdf9] p-4 sm:p-5">
13-
<div className="grid gap-3">
14-
<div className="grid gap-3 sm:grid-cols-[1.05fr_0.95fr]">
15-
<div className="rounded-[22px] border-2 border-[#25314d] bg-[#eef8ff] p-4 shadow-[0_4px_0_#25314d]">
16-
<div className="text-[11px] font-bold uppercase tracking-[0.16em] text-slate-500">
17-
Entry layer
18-
</div>
19-
<div className="mt-2 font-heading text-2xl font-bold text-[#25314d]">
20-
README + taskbeacon.yaml
21-
</div>
13+
<div className="rounded-[26px] border-2 border-dashed border-[#5cabc0] bg-[#f8fcfe] p-4 sm:p-6">
14+
<div className="grid gap-3 lg:grid-cols-4">
15+
<div className="rounded-[20px] border-2 border-[#25314d] bg-[#eef8ff] p-4 shadow-[0_4px_0_#25314d]">
16+
<div className="text-[11px] font-bold uppercase tracking-[0.16em] text-slate-500">Docs</div>
17+
<div className="mt-2 font-heading text-xl font-bold text-[#25314d]">README</div>
2218
<div className="mt-2 text-sm leading-6 text-slate-700">
23-
Public description plus machine-readable metadata.
19+
Human-readable task purpose, setup, and review context.
2420
</div>
2521
</div>
26-
<div className="rounded-[22px] border-2 border-[#25314d] bg-[#fff3ed] p-4 shadow-[0_4px_0_#25314d]">
27-
<div className="text-[11px] font-bold uppercase tracking-[0.16em] text-slate-500">
28-
Runtime layer
29-
</div>
30-
<div className="mt-2 font-heading text-2xl font-bold text-[#25314d]">
31-
config + src + assets
32-
</div>
22+
<div className="rounded-[20px] border-2 border-[#25314d] bg-[#fff3ed] p-4 shadow-[0_4px_0_#25314d]">
23+
<div className="text-[11px] font-bold uppercase tracking-[0.16em] text-slate-500">Metadata</div>
24+
<div className="mt-2 font-heading text-xl font-bold text-[#25314d]">taskbeacon.yaml</div>
3325
<div className="mt-2 text-sm leading-6 text-slate-700">
34-
Keep config, task code, and participant-facing assets separate.
26+
Machine-readable IDs, maturity, preview links, and release state.
3527
</div>
3628
</div>
37-
</div>
38-
39-
<div className="grid gap-3 sm:grid-cols-[0.92fr_1.08fr]">
40-
<div className="rounded-[22px] border-2 border-[#25314d] bg-[#efffe9] p-4 shadow-[0_4px_0_#25314d]">
41-
<div className="text-[11px] font-bold uppercase tracking-[0.16em] text-slate-500">
42-
Review layer
43-
</div>
44-
<div className="mt-2 font-heading text-2xl font-bold text-[#25314d]">
45-
references + outputs
46-
</div>
29+
<div className="rounded-[20px] border-2 border-[#25314d] bg-[#efffe9] p-4 shadow-[0_4px_0_#25314d]">
30+
<div className="text-[11px] font-bold uppercase tracking-[0.16em] text-slate-500">Runtime</div>
31+
<div className="mt-2 font-heading text-xl font-bold text-[#25314d]">config + src + assets</div>
4732
<div className="mt-2 text-sm leading-6 text-slate-700">
48-
QA artifacts, references, and logs remain attached to the same package.
33+
Separate task code, participant-facing assets, and local runtime settings.
4934
</div>
5035
</div>
51-
<div className="rounded-[22px] border-2 border-[#25314d] bg-white p-4 shadow-[0_4px_0_#25314d]">
52-
<div className="text-[11px] font-bold uppercase tracking-[0.16em] text-slate-500">
53-
TAPS result
54-
</div>
55-
<div className="mt-2 font-heading text-2xl font-bold text-[#25314d]">
56-
One task package that stays readable across runtime, docs, and QA.
36+
<div className="rounded-[20px] border-2 border-[#25314d] bg-[#f4f0ff] p-4 shadow-[0_4px_0_#25314d]">
37+
<div className="text-[11px] font-bold uppercase tracking-[0.16em] text-slate-500">Review</div>
38+
<div className="mt-2 font-heading text-xl font-bold text-[#25314d]">references + outputs</div>
39+
<div className="mt-2 text-sm leading-6 text-slate-700">
40+
Keep QA artifacts, reference files, and release evidence attached to the task.
5741
</div>
5842
</div>
5943
</div>
44+
45+
<div className="mt-4 flex items-center justify-center">
46+
<div className="h-0.5 w-full max-w-[110px] bg-[#5cabc0]" />
47+
<div className="mx-3 rounded-full border-2 border-[#25314d] bg-white px-4 py-2 text-xs font-bold uppercase tracking-[0.16em] text-[#25314d] shadow-[0_4px_0_#25314d]">
48+
One Auditable Task Package
49+
</div>
50+
<div className="h-0.5 w-full max-w-[110px] bg-[#5cabc0]" />
51+
</div>
6052
</div>
6153
</div>
6254
);
6355
}
6456

6557
export default function HomePage() {
66-
const latest = changelog[0] ?? siteData.latest_release;
58+
const latest = changelog[0] ?? null;
6759
const tutorialCards = [
6860
englishTutorials.find((entry) => entry.slug === "getting-started"),
6961
englishTutorials.find((entry) => entry.slug === "trigger-io"),
@@ -146,64 +138,89 @@ export default function HomePage() {
146138
</div>
147139
</section>
148140

149-
<section id="taps" className="grid gap-8 lg:grid-cols-[0.9fr_1.1fr] lg:items-center">
150-
<div>
141+
<section id="taps" className="space-y-8">
142+
<div className="mx-auto max-w-4xl text-center">
151143
<div className="pf-section-chip">TAPS</div>
152144
<h2 className="mt-5 font-heading text-3xl font-bold text-[#25314d] sm:text-4xl">
153-
A task package structure, not just another label.
145+
TAPS keeps the full task structure readable.
154146
</h2>
155147
<p className="mt-4 text-base leading-8 text-slate-700">
156-
TAPS keeps the local runtime, config, metadata, references, and outputs inside one package
157-
that stays easier to review across development, QA, and release.
148+
Instead of scattering docs, config, runtime code, and QA artifacts across unrelated places,
149+
TAPS keeps them attached to the same task package.
158150
</p>
159-
<div className="mt-5 space-y-3 text-sm leading-6 text-slate-700">
160-
<div className="rounded-[18px] border-2 border-[#25314d] bg-white px-4 py-3 shadow-[0_4px_0_#25314d]">
161-
PsyFlow handles the local runtime inside the package.
162-
</div>
163-
<div className="rounded-[18px] border-2 border-[#25314d] bg-white px-4 py-3 shadow-[0_4px_0_#25314d]">
164-
taskbeacon metadata and README describe the task from outside the code.
165-
</div>
166-
<div className="rounded-[18px] border-2 border-[#25314d] bg-white px-4 py-3 shadow-[0_4px_0_#25314d]">
167-
QA outputs and references stay attached to the same source of truth.
168-
</div>
169-
</div>
170151
</div>
171152

172153
<TapsDiagram />
154+
155+
<div className="grid gap-4 md:grid-cols-3">
156+
<div className="pf-frame-soft bg-white p-5">
157+
<div className="font-heading text-[1.5rem] font-bold text-[#25314d]">Readable by humans</div>
158+
<p className="mt-3 text-sm leading-7 text-slate-700">
159+
README carries the task story, setup notes, and review context without forcing readers into the code.
160+
</p>
161+
</div>
162+
<div className="pf-frame-soft bg-white p-5">
163+
<div className="font-heading text-[1.5rem] font-bold text-[#25314d]">Readable by tooling</div>
164+
<p className="mt-3 text-sm leading-7 text-slate-700">
165+
Metadata and config stay structured, so QA, previews, and downstream tooling can reason over the task.
166+
</p>
167+
</div>
168+
<div className="pf-frame-soft bg-white p-5">
169+
<div className="font-heading text-[1.5rem] font-bold text-[#25314d]">Readable over time</div>
170+
<p className="mt-3 text-sm leading-7 text-slate-700">
171+
Outputs, references, and release evidence remain beside the source package instead of drifting away.
172+
</p>
173+
</div>
174+
</div>
173175
</section>
174176

175-
<section id="framework" className="grid gap-8 lg:grid-cols-[minmax(0,520px)_minmax(0,1fr)] lg:items-center">
176-
<div className="pf-frame bg-[#fffdf9] p-4">
177-
<Image
178-
src={withBasePath("/images/framework/flowchart.png")}
179-
alt="PsyFlow framework flowchart"
180-
width={1600}
181-
height={1200}
182-
className="w-full rounded-[24px] border-2 border-[#25314d] bg-white shadow-[0_5px_0_#25314d]"
183-
/>
177+
<section id="framework" className="space-y-8">
178+
<div className="grid gap-6 xl:grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)] xl:items-end">
179+
<div>
180+
<div className="pf-section-chip bg-[#f5c1b5]">Framework</div>
181+
<h2 className="mt-5 font-heading text-3xl font-bold text-[#25314d] sm:text-4xl">
182+
Keep the framework opinionated where reviewability matters.
183+
</h2>
184+
<p className="mt-4 text-base leading-8 text-slate-700">
185+
PsyFlow is designed around a few stable primitives: `BlockUnit`, `StimBank`, `StimUnit`,
186+
`SubInfo`, and `TaskSettings`. The goal is not abstraction for its own sake, but a task
187+
runtime that stays readable when the paradigm grows.
188+
</p>
189+
</div>
190+
191+
<div className="pf-frame-soft bg-[#eef8ff] p-5">
192+
<div className="text-[11px] font-bold uppercase tracking-[0.18em] text-slate-500">
193+
Framework idea
194+
</div>
195+
<p className="mt-3 text-sm leading-7 text-slate-700">
196+
Keep generic runtime work inside the framework, but keep paradigm logic close to the task.
197+
That split is what makes larger tasks easier to test, localize, and review.
198+
</p>
199+
</div>
184200
</div>
185201

186-
<div>
187-
<div className="pf-section-chip bg-[#f5c1b5]">Framework</div>
188-
<h2 className="mt-5 font-heading text-3xl font-bold text-[#25314d] sm:text-4xl">
189-
Keep the framework opinionated where reviewability matters.
190-
</h2>
191-
<p className="mt-4 text-base leading-8 text-slate-700">
192-
PsyFlow is designed around a few stable primitives: `BlockUnit`, `StimBank`, `StimUnit`,
193-
`SubInfo`, and `TaskSettings`. The goal is not abstraction for its own sake, but a task
194-
runtime that stays readable when the paradigm grows.
195-
</p>
196-
<div className="mt-5 grid gap-3 sm:grid-cols-2">
197-
<div className="rounded-[18px] border-2 border-[#25314d] bg-[#eef8ff] px-4 py-4 text-sm leading-6 text-slate-700 shadow-[0_4px_0_#25314d]">
202+
<div className="grid gap-6 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)] xl:items-stretch">
203+
<div className="pf-frame bg-[#fffdf9] p-4">
204+
<Image
205+
src={withBasePath("/images/framework/flowchart.png")}
206+
alt="PsyFlow framework flowchart"
207+
width={1600}
208+
height={1200}
209+
className="w-full rounded-[24px] border-2 border-[#25314d] bg-white shadow-[0_5px_0_#25314d]"
210+
/>
211+
</div>
212+
213+
<div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-2">
214+
<div className="rounded-[18px] border-2 border-[#25314d] bg-[#eef8ff] px-4 py-4 text-sm leading-7 text-slate-700 shadow-[0_4px_0_#25314d]">
198215
Use config and settings for reusable runtime state.
199216
</div>
200-
<div className="rounded-[18px] border-2 border-[#25314d] bg-[#fff3ed] px-4 py-4 text-sm leading-6 text-slate-700 shadow-[0_4px_0_#25314d]">
217+
<div className="rounded-[18px] border-2 border-[#25314d] bg-[#fff3ed] px-4 py-4 text-sm leading-7 text-slate-700 shadow-[0_4px_0_#25314d]">
201218
Keep `main.py` orchestration separate from `run_trial.py`.
202219
</div>
203-
<div className="rounded-[18px] border-2 border-[#25314d] bg-[#efffe9] px-4 py-4 text-sm leading-6 text-slate-700 shadow-[0_4px_0_#25314d]">
220+
<div className="rounded-[18px] border-2 border-[#25314d] bg-[#efffe9] px-4 py-4 text-sm leading-7 text-slate-700 shadow-[0_4px_0_#25314d]">
204221
Let framework helpers absorb generic boilerplate, not paradigm logic.
205222
</div>
206-
<div className="rounded-[18px] border-2 border-[#25314d] bg-[#f4f0ff] px-4 py-4 text-sm leading-6 text-slate-700 shadow-[0_4px_0_#25314d]">
223+
<div className="rounded-[18px] border-2 border-[#25314d] bg-[#f4f0ff] px-4 py-4 text-sm leading-7 text-slate-700 shadow-[0_4px_0_#25314d]">
207224
Keep outputs and validation artifacts tied to the same local package.
208225
</div>
209226
</div>

website/src/components/psyflow-logo.tsx

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,54 @@
1-
import Image from "next/image";
21
import clsx from "@/components/utils/clsx";
3-
import { withBasePath } from "@/lib/base-path";
42

5-
type PsyFlowLogoProps = {
6-
className?: string;
7-
imageClassName?: string;
8-
alt?: string;
9-
variant?: "black" | "white";
10-
};
3+
export function PsyFlowMark({ className }: { className?: string }) {
4+
return (
5+
<svg
6+
viewBox="0 0 126 86"
7+
role="img"
8+
aria-label="PsyFlow mark"
9+
className={clsx("h-auto w-[92px] sm:w-[104px]", className)}
10+
>
11+
<g fill="none" stroke="#0f2d57" strokeWidth="3.4" strokeLinecap="round" strokeLinejoin="round">
12+
<rect x="6" y="13" width="44" height="36" rx="10" fill="#44b7b2" />
13+
<rect x="35" y="7" width="52" height="40" rx="12" fill="#1f7398" />
14+
<rect x="72" y="17" width="44" height="36" rx="10" fill="#44b7b2" />
15+
<path d="M14 61l92 12" />
16+
<path d="M95 64l15 10-18 3" />
17+
<path d="M24 26v10" />
18+
<path d="M19 31h10" />
19+
<path d="M93 30v10" />
20+
<path d="M88 35h10" />
21+
<path d="M58 21v15" stroke="#69d7c0" />
22+
<path d="M50 23c0-5 16-5 16 0" stroke="#69d7c0" />
23+
</g>
24+
</svg>
25+
);
26+
}
1127

1228
export function PsyFlowLogo({
1329
className,
14-
imageClassName,
15-
alt = "PsyFlow logo",
16-
variant = "black"
17-
}: PsyFlowLogoProps) {
18-
const src =
19-
variant === "white"
20-
? withBasePath("/images/branding/psyflow-logo-white.png")
21-
: withBasePath("/images/branding/psyflow-logo-black.png");
22-
30+
markClassName,
31+
wordmarkClassName,
32+
showWordmark = true
33+
}: {
34+
className?: string;
35+
markClassName?: string;
36+
wordmarkClassName?: string;
37+
showWordmark?: boolean;
38+
}) {
2339
return (
24-
<Image
25-
src={src}
26-
alt={alt}
27-
width={472}
28-
height={287}
29-
priority
30-
className={clsx("h-auto w-[150px] sm:w-[176px]", imageClassName, className)}
31-
/>
40+
<span className={clsx("inline-flex items-center gap-3", className)}>
41+
<PsyFlowMark className={markClassName} />
42+
{showWordmark ? (
43+
<span
44+
className={clsx(
45+
"font-heading text-[1.9rem] leading-none text-[#25314d] sm:text-[2.2rem]",
46+
wordmarkClassName
47+
)}
48+
>
49+
PsyFlow
50+
</span>
51+
) : null}
52+
</span>
3253
);
3354
}
34-
35-
export function PsyFlowMark(props: PsyFlowLogoProps) {
36-
return <PsyFlowLogo {...props} />;
37-
}

website/src/components/site-footer.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ export function SiteFooter() {
1010
<div className="pf-frame bg-[#fff8f0] px-5 py-7 sm:px-6 sm:py-8">
1111
<div className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_320px] lg:items-center">
1212
<div className="text-center lg:text-left">
13-
<PsyFlowLogo className="mx-auto lg:mx-0" imageClassName="w-[148px] sm:w-[176px]" />
13+
<PsyFlowLogo
14+
className="mx-auto lg:mx-0"
15+
markClassName="w-[86px] sm:w-[96px]"
16+
wordmarkClassName="text-[2rem] sm:text-[2.2rem]"
17+
/>
1418
<p className="mt-4 max-w-2xl text-sm leading-7 text-slate-700 lg:max-w-xl">
1519
PsyFlow keeps the local task runtime, trigger model, QA flow, and validation path inside
1620
one auditable package.
@@ -24,7 +28,10 @@ export function SiteFooter() {
2428

2529
<div className="lg:justify-self-end">
2630
<div className="pf-frame-soft flex items-center justify-center bg-[#eef8ff] px-4 py-5 sm:px-6 sm:py-6">
27-
<PsyFlowLogo imageClassName="w-[194px] sm:w-[228px]" />
31+
<PsyFlowLogo
32+
markClassName="w-[96px] sm:w-[110px]"
33+
wordmarkClassName="text-[2.1rem] sm:text-[2.45rem]"
34+
/>
2835
</div>
2936
</div>
3037
</div>

website/src/components/site-header.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export function SiteHeader() {
4848
<div className="pf-frame bg-[#fffdf9] px-3 py-3 sm:px-4">
4949
<div className="flex items-center justify-between gap-3">
5050
<Link href={routes.home} className="pf-focus-ring rounded-xl" onClick={() => setOpen(false)}>
51-
<PsyFlowLogo imageClassName="w-[126px] sm:w-[162px]" />
51+
<PsyFlowLogo markClassName="w-[74px] sm:w-[82px]" wordmarkClassName="text-[1.65rem] sm:text-[1.85rem]" />
5252
</Link>
5353

5454
<nav className="hidden items-center gap-1 xl:flex">

0 commit comments

Comments
 (0)