Editorial portfolio
Static React portfolio skill for Claude Code / Codex — turn your context into a deployable personal site in editorial bilingual style. Zero build step.
npx -y skills add wilson534/editorial-portfolioAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Generate a Claude-designed personal portfolio website in editorial bilingual (中/英) dark-mode style. Single-page React app with hero / methodology / timeline / awards / press / inputs / agent chat / contact sections. Trigger when the user asks to build their personal website / portfolio / 个人网站, or wants a Claude-quality "looks-like-Peng-Zhiwei's-site". Reads user context (chat, attached docs, GitHub, prior bio) and produces a deployable codebase, ideally one-shot.
SKILL.md
7.9 KB, ~2.0k tokens by cl100k_base, as published. Nobody here has run it
Editorial Portfolio
A static React SPA personal portfolio in editorial bilingual style — dark mode, serif headings, mono accents, custom cursor ring (desktop), mobile bottom action bar, AI chat agent, scroll-driven reveals. Designed for fresh-grad / IC / founder profiles. Zero build step — Babel-standalone in the browser. Deploys to Vercel in 30 seconds.
Reference live site (built by 彭智炜 / @wilson534): https://pengzhiwei.vercel.app
When to use
- User asks "帮我做个人网站 / build my portfolio / 给我做个像彭智炜那样的站"
- User has a resume / GitHub profile / LinkedIn dump and wants a polished personal site
- User wants something deployable to Vercel today, not a Next.js project that takes a week
What you do
End-to-end ownership: codebase generation → local preview → deploy. The user should not have to learn React, CSS, or Vercel.
Step 1 — Gather information from context
Mine the conversation history, attached files, GitHub repo, prior resume for these fields. Most map 1:1 to data.js:
| Field | Where to find it | data.js key |
|---|---|---|
| Name (Zh + En) | first message, signature, GitHub | profile.nameZh / nameEn |
| Role | job title or self-described | profile.role / roleEn |
| Tagline | one-liner of what they ship | profile.tagline |
| Statement | 1-sentence philosophy | profile.statement |
| Location | city or "X → Y" if relocating | profile.location |
| Status | hiring / open-to-work / busy state | profile.status |
| Photo | portrait image path or URL | profile.photo (drop into assets/portrait.png) |
| Contact links | GitHub / 小红书 / Email / WeChat / Linkedin etc. | profile.links array |
| Hero figures | 3-4 numbers + labels (e.g. "12 awards · 7 hackathons") | profile.figures |
| Internships | dated work entries | timeline items with kind: "internship" |
| Projects | independent shipped projects | timeline items with kind: "project" |
| Hackathons | competition / showcase entries | timeline items with kind: "hackathon" or "showcase" |
| Awards | competition wins, scholarships | awards array |
| Press | interviews, articles, videos | press array |
| Skills | grouped chips: tools / stack / methods / domain | skills array of {group, items} |
| Inputs | what they're listening / reading / using right now | inputs |
If a section is genuinely missing from context, omit it cleanly:
- For top-level sections (press, inputs, agent chat) you can drop the entire
<section>block inapp.jsx - For timeline, just have fewer entries — the section auto-handles empty kinds
If critical fields are missing (name, no work history at all), ask once in a single bundled message.
Step 2 — Lay down the template
Copy the entire templates/ directory to a new working directory (e.g. user's ~/portfolio/ or wherever they want). The structure is:
portfolio/
├── index.html # root HTML — loads React + Babel from CDN
├── styles.css # all design tokens + responsive layout
├── app.jsx # React app (no build step needed)
├── tweaks-panel.jsx # dev-only edit-mode panel (safe to leave)
├── data.js # ← THE FILE YOU EDIT
├── .vercelignore # excludes dev artifacts from deploy
└── assets/
└── portrait.png # ← REPLACE with user's photo
Step 3 — Edit data.js only (DO NOT touch CSS or JSX)
data.js is the single source of truth for content. Replace every field under window.PZW_DATA = { ... } with the user's data. The existing values are 彭智炜's — use them as format reference only, then overwrite.
The structure with example shape:
window.PZW_DATA = {
profile: {
nameZh: "彭智炜", // → user's Chinese name
nameEn: "Musketeer", // → user's English name / nickname
role: "技术型 AI 产品工程师", // → user's role
roleEn: "Technical AI Product Engineer",
tagline: "...", // one-liner
statement: "...", // 1-2 sentence philosophy
location: "Shanghai → Beijing",
status: "summer 2026 · 开放合作 / 实习",
photo: "assets/portrait.png",
links: [ { label, handle, href }, ... ],
figures: [ { label, value }, ... ]
},
timeline: [ { kind, date, year, org, title, ... }, ... ],
awards: [ { year, name, prize, sub }, ... ],
press: [ { outlet, title, sub, kind, href }, ... ],
skills: [ { group, items: [...] }, ... ],
inputs: { listening: [...], reading: [...], using: [...] },
};
Step 4 — Replace placeholders in app.jsx
A few strings outside data.js use {{...}} placeholders. Replace these directly in app.jsx:
| Placeholder | Replace with |
|---|---|
{{NAME_ZH}} | user's Chinese name (multiple occurrences) |
{{NAME_EN}} | user's English name |
{{FIRST_NAME_ZH}} | first name only (e.g. "智炜" → use last 2 chars of nameZh) |
{{GITHUB_USERNAME}} | GitHub handle (no @) |
{{YEAR}} | current year for footer copyright (e.g. 2026) |
Search-and-replace with sed -i '' 's/{{NAME_ZH}}/...//g' style.
Step 5 — Drop in the portrait photo
Replace assets/portrait.png with the user's photo. Recommended:
- portrait orientation (taller than wide)
- crop ratio approximately 3:4
- 1000px+ on the long edge
If the user hasn't provided one, leave a note in the README and skip — site will display a broken image but everything else works.
Step 6 — Local preview
Start a static server in the working directory and tell the user the URL:
cd portfolio/
python3 -m http.server 5173
# → open http://localhost:5173
Verify:
- Hero loads, name/role/tagline correct
- Timeline shows correct entries
- Mobile viewport (375px) works — no horizontal scroll, bottom action bar visible
- Chat agent responds (or doesn't crash if no API set)
Step 7 — Deploy to Vercel
cd portfolio/
vercel link --yes --project <user-handle> # one-time link, e.g. "wilson534"
vercel --prod --yes # deploy
Output: https://<user-handle>.vercel.app
If user doesn't have Vercel CLI: npm i -g vercel && vercel login.
Style rules baked in (don't alter)
- Editorial dark mode (default):
bg #0d0c0a+fg #ede7dc+ accentoklch(0.85 0.16 118)lime - Three direction modes user can toggle:
editorial / paper / terminal(the tweaks panel exposes this) - Bilingual: Chinese for sections + 大字, English for tech terms + small caps + mono labels
- Single-column mobile, max 1100px breakpoint folds nav into FAB stack
- Custom cursor ring on desktop, native cursor on touch
SUMMER 2026style chip in hero — auto-update season per user's launch context
Customization
Most users won't touch CSS. If they want to:
- Accent color:
--accent-huein:root(try 30 = orange, 280 = violet) - Direction default: change
tw.directioninitial in app.jsx - Font:
--serifand--monoin:root
Files
templates/— full deployable static site, drop in and gotemplates/data.js— single content source, contains 彭智炜's data as format referencetemplates/assets/— placeholder portrait. Replace before deploy.
Companion skill
Pair with editorial-resume — generates the matching single-page A4 PDF resume that the portfolio's mobile RESUME button links to.
What ships with it: 10 files
112.2 KB alongside SKILL.md, 1 of them executable
templates/
- app.jsx36.5 KB
- assets/portrait.svg1002 B
- data.jsruns15.0 KB
- index.html1.3 KB
- styles.css35.9 KB
- tweaks-panel.jsx17.7 KB
- .vercelignore117 B
- .gitignore38 B
- LICENSE1.1 KB
- README.md3.6 KB