Compare commits
1 Commits
main
...
temp_branc
| Author | SHA1 | Date | |
|---|---|---|---|
| d8577e44f7 |
@ -1,44 +0,0 @@
|
||||
Huashu Design · Personal Use License
|
||||
Copyright (c) 2026 alchaincyf (花叔 · 花生)
|
||||
|
||||
本 skill(以下简称「本作品」)包含 SKILL.md、scripts、references、assets、demos 及其全部派生内容。使用本作品视为同意以下条款:
|
||||
|
||||
---
|
||||
|
||||
## 1. 允许的使用(个人免费)
|
||||
|
||||
以下场景无需授权、无需打招呼:
|
||||
|
||||
- **学习与研究**:阅读代码、修改、二次开发用于自己理解
|
||||
- **个人创作**:为自己的文章、视频、副业项目、小红书/公众号/B站等内容创作使用
|
||||
- **非营利分享**:基于本作品做 demo、教程,发布到社交平台、博客、播客
|
||||
- **派生作品**:在自己名下的个人仓库里基于本作品做派生 skill,需在 README 显著位置注明来源(`Derived from alchaincyf/huashu-design`)
|
||||
|
||||
## 2. 禁止的使用(必须事先授权)
|
||||
|
||||
以下场景**必须联系花生获得书面授权后方可使用**:
|
||||
|
||||
- 任何**公司、团队、工作室、机构**将本作品集成到其内部工具链或对外产品
|
||||
- 将本作品或其派生物作为**面向付费客户的交付手段**(包括设计外包、品牌咨询、B 端 SaaS 等)
|
||||
- 基于本作品做**商业软件产品**、付费模板、付费订阅服务
|
||||
- 以**营利为目的**的培训课程、商业工作坊、闭门付费社群
|
||||
- 在**商单创作**(乙方向甲方交付物)中使用本作品生成的内容
|
||||
|
||||
## 3. 授权联系方式
|
||||
|
||||
商用授权请通过以下任一平台联系花生:
|
||||
|
||||
- X / Twitter:https://x.com/AlchainHust
|
||||
- 公众号:微信搜索「花叔」
|
||||
- B 站:https://space.bilibili.com/14097567
|
||||
- YouTube:https://www.youtube.com/@Alchain
|
||||
- 小红书:https://www.xiaohongshu.com/user/profile/5abc6f17e8ac2b109179dfdf
|
||||
- 官网:https://www.huasheng.ai/
|
||||
|
||||
## 4. 免责声明
|
||||
|
||||
本作品按「现状」提供,不提供任何明示或默示的担保。作者不对因使用本作品导致的任何损失承担责任。
|
||||
|
||||
---
|
||||
|
||||
简而言之:**个人随便用,企业要打招呼。**
|
||||
@ -1,311 +0,0 @@
|
||||
<sub><b>🌐 English</b> · <a href="README.md">中文</a></sub>
|
||||
|
||||
<div align="center">
|
||||
|
||||
# Huashu Design
|
||||
|
||||
> *"Type. Hit enter. A finished design lands in your lap."*
|
||||
> *「打字。回车。一份能交付的设计。」*
|
||||
|
||||
[](LICENSE)
|
||||
[](https://skills.sh)
|
||||
[](https://skills.sh)
|
||||
|
||||
<br>
|
||||
|
||||
**Say one sentence to your agent — Claude Code, Cursor, Codex, OpenClaw, Hermes all work.**
|
||||
|
||||
<br>
|
||||
|
||||
3 to 30 minutes — you ship a **product launch animation**, a clickable App prototype, an editable PPT deck, a print-grade infographic.
|
||||
|
||||
Not "decent for AI" quality — it looks like a real design team made it. Give the skill your brand assets (logo, colors, UI screenshots) and it reads your brand's voice; give it nothing and the built-in 20 design vocabularies still keep you out of AI slop territory.
|
||||
|
||||
**Every animation in this README was made by huashu-design itself.** No Figma, no After Effects — just a sentence + skill run. Next product launch needs a promo video? You can make it too.
|
||||
|
||||
```
|
||||
npx skills add alchaincyf/huashu-design
|
||||
```
|
||||
|
||||
[See it work](#demo-gallery) · [Install](#install) · [What it does](#what-it-does) · [How it works](#core-mechanics) · [vs. Claude Design](#vs-claude-design)
|
||||
|
||||
> 📖 **Note for English readers**: this skill is built by a Chinese-speaking developer. The skill's agent prompts (`SKILL.md`, `references/*.md`) are in Chinese but the agent is bilingual — works fine with English tasks. The demos below are the English parallel versions; the Chinese ones are in the default-named files (see the Chinese [README.md](README.md)).
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<video src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/hero-animation-v10-en.mp4" autoplay muted loop playsinline width="100%">
|
||||
Your browser doesn't support inline video. <a href="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/hero-animation-v10-en.mp4">Download MP4</a>.
|
||||
</video>
|
||||
</p>
|
||||
|
||||
<p align="center"><sub>▲ 10-second hero animation showing what huashu-design does (<a href="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/hero-animation-v10-en.mp4">download MP4</a> if autoplay doesn't work)</sub></p>
|
||||
|
||||
---
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npx skills add alchaincyf/huashu-design
|
||||
```
|
||||
|
||||
Then just talk to Claude Code:
|
||||
|
||||
```
|
||||
"Make a keynote for AI psychology. Give me 3 style directions to pick from."
|
||||
"Build an iOS prototype for a Pomodoro app — 4 screens, actually clickable."
|
||||
"Turn this logic into a 60-second animation. Export MP4 and GIF."
|
||||
"Run a 5-dimension expert review on this design."
|
||||
```
|
||||
|
||||
No buttons, no panels, no Figma plugin. Agent-agnostic — drops into Claude Code, Cursor, Trae, Hermes, OpenClaw, or any markdown-skill-capable agent.
|
||||
|
||||
---
|
||||
|
||||
## Star History
|
||||
|
||||
<p align="center">
|
||||
<a href="https://star-history.com/#alchaincyf/huashu-design&Date">
|
||||
<img src="https://api.star-history.com/svg?repos=alchaincyf/huashu-design&type=Date" alt="huashu-design Star History" width="80%">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## What it does
|
||||
|
||||
| Capability | Deliverable | Typical time |
|
||||
|---|---|---|
|
||||
| Interactive prototype (App / Web) | Single-file HTML · real iPhone bezel · clickable · Playwright-verified | 10–15 min |
|
||||
| Slide decks | HTML deck (browser presentation) + editable PPTX (text frames preserved) | 15–25 min |
|
||||
| Motion design | MP4 (25fps / 60fps interpolation) + GIF (palette-optimized) + BGM | 8–12 min |
|
||||
| Design variations | 3+ side-by-side · Tweaks live params · cross-dimension exploration | 10 min |
|
||||
| Infographic / data viz | Print-quality typography · exports to PDF/PNG/SVG | 10 min |
|
||||
| Design direction advisor | 5 schools × 20 philosophies · 3 directions recommended · Demos generated in parallel | 5 min |
|
||||
| 5-dimension expert critique | Radar chart + Keep/Fix/Quick Wins · actionable punch list | 3 min |
|
||||
|
||||
---
|
||||
|
||||
## Demo Gallery
|
||||
|
||||
> English parallel versions of the demos. Chinese versions live at the default filenames (see the Chinese README).
|
||||
|
||||
### Design Direction Advisor
|
||||
|
||||
The fallback for vague briefs: pick 3 differentiated directions from 5 schools × 20 philosophies, generate all 3 demos in parallel, let the user choose.
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/w3-fallback-advisor-en.gif" width="100%"></p>
|
||||
|
||||
### iOS App Prototype
|
||||
|
||||
Pixel-accurate iPhone 15 Pro body (Dynamic Island / status bar / Home Indicator) · state-driven multi-screen navigation · real images pulled from Wikimedia/Met/Unsplash · Playwright click tests before delivery.
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/c1-ios-prototype-en.gif" width="100%"></p>
|
||||
|
||||
### Motion Design Engine
|
||||
|
||||
Stage + Sprite time-slice model · `useTime` / `useSprite` / `interpolate` / `Easing` — four APIs cover every animation need · one command exports MP4 / GIF / 60fps-interpolated / BGM-scored finals.
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/c3-motion-design-en.gif" width="100%"></p>
|
||||
|
||||
### HTML Slides → Editable PPTX
|
||||
|
||||
HTML decks for browser presentation · `html2pptx.js` reads DOM computed styles and translates each element into real PowerPoint objects · exports are **actual text frames**, not image-bed fakes.
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/c2-slides-pptx-en.gif" width="100%"></p>
|
||||
|
||||
### Tweaks · Live Variation Switching
|
||||
|
||||
Colors / typography / information density parameterized · side panel toggle · pure-frontend + `localStorage` persistence · survives reload.
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/c4-tweaks-en.gif" width="100%"></p>
|
||||
|
||||
### Infographic / Data Viz
|
||||
|
||||
Magazine-grade typography · precise CSS Grid columns · `text-wrap: pretty` typographic details · driven by real data · exports to vector PDF / 300dpi PNG / SVG.
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/c5-infographic-en.gif" width="100%"></p>
|
||||
|
||||
### 5-Dimension Expert Critique
|
||||
|
||||
Philosophical coherence · visual hierarchy · execution craft · functionality · innovation — each scored 0–10 · radar-chart visualization · outputs Keep / Fix / Quick Wins punch list.
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/c6-expert-review-en.gif" width="100%"></p>
|
||||
|
||||
### Junior Designer Workflow
|
||||
|
||||
No heroic one-shot attempts: start with assumptions + placeholders + reasoning, show it to the user early, then iterate. Fixing a misunderstanding early is 100× cheaper than fixing it late.
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/w2-junior-designer-en.gif" width="100%"></p>
|
||||
|
||||
### Core Asset Protocol · 5-step hard process
|
||||
|
||||
Mandatory whenever the task involves a specific brand: ask → search → download (three fallback paths) → verify + extract → write `brand-spec.md` covering **logo, product shots, UI screenshots, colors, fonts** — all required assets, not just colors.
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/w1-brand-protocol-en.gif" width="100%"></p>
|
||||
|
||||
---
|
||||
|
||||
## Core Mechanics
|
||||
|
||||
### Core Asset Protocol
|
||||
|
||||
The hardest rule in the skill. When the task touches a specific brand (Stripe, Linear, Anthropic, DJI, your own company, etc.), five steps are enforced:
|
||||
|
||||
| Step | Action | Purpose |
|
||||
|---|---|---|
|
||||
| 1 · Ask | Checklist of 6 asset types: logo / product shots / UI screenshots / color palette / fonts / brand guidelines | Respect existing resources |
|
||||
| 2 · Search official channels | `<brand>.com/brand` · `<brand>.com/press` · `brand.<brand>.com` · product pages · launch films | Find authoritative assets |
|
||||
| 3 · Download by asset type | Logo (SVG → inline-SVG in HTML → social avatar) · Product shots (hero → press kit → launch video frames → AI-generated from reference) · UI (App Store screenshots → official video frames) | Three fallback paths per asset type |
|
||||
| 4 · Verify + extract | Check logo fidelity · product image resolution · UI freshness · grep color hex from real assets | **Never guess from memory** |
|
||||
| 5 · Freeze to spec | Write `brand-spec.md` with logo paths, product image paths, UI screenshot paths, CSS variables for colors/fonts | Un-frozen knowledge evaporates |
|
||||
|
||||
**Ranking of asset importance** (from the skill's internal rubric):
|
||||
|
||||
1. Logo — mandatory for any brand
|
||||
2. Product renders — mandatory for physical products
|
||||
3. UI screenshots — mandatory for digital products
|
||||
4. Color values — auxiliary
|
||||
5. Fonts — auxiliary
|
||||
|
||||
A/B-tested (v1 vs v2, 6 agents each): **v2 reduced stability variance by 5×**. Stability of stability — that's the real moat.
|
||||
|
||||
### Design Direction Advisor (Fallback)
|
||||
|
||||
Triggered when the brief is too vague to execute:
|
||||
|
||||
- Don't run on generic intuition — enter Fallback mode
|
||||
- Recommend 3 differentiated directions from 5 schools × 20 philosophies, each **from a different school**
|
||||
- Each comes with flagship works, gestalt keywords, representative designer
|
||||
- Generate 3 visual demos in parallel, let the user choose
|
||||
- Once chosen, continue into the Junior Designer main flow
|
||||
|
||||
### Junior Designer Workflow
|
||||
|
||||
The default working mode across every task:
|
||||
|
||||
- Send the full question set in one batch, wait for all answers before moving
|
||||
- Write assumptions + placeholders + reasoning comments directly into the HTML
|
||||
- Show it to the user early (even if just gray blocks)
|
||||
- Fill in real content → variations → Tweaks — show at each of these three steps
|
||||
- Manually eyeball the browser with Playwright before delivery
|
||||
|
||||
### Fact Verification First (Principle #0)
|
||||
|
||||
The highest-priority rule, added after a real failure mode: when the task mentions a specific product / technology / event (e.g., "DJI Pocket 4", "Nano Banana Pro", "Gemini 3 Pro"), the first action **must** be a `WebSearch` to confirm existence, release status, current version, and specs. No claims from training-corpus memory. Cost of a search: ~10 seconds. Cost of a wrong assumption: 1–2 hours of rework.
|
||||
|
||||
### Anti AI-slop Rules
|
||||
|
||||
Avoid the visual common denominator of AI output (purple gradients / emoji icons / rounded-corner + left border accent / SVG humans / Inter-as-display / **CSS silhouettes standing in for real product shots**). Use `text-wrap: pretty` + CSS Grid + carefully chosen serif display faces + oklch colors.
|
||||
|
||||
---
|
||||
|
||||
## vs. Claude Design
|
||||
|
||||
I'll be upfront: the Core Asset Protocol's philosophy was lifted from system prompts Anthropic wrote for Claude Design. That prompt hammers home a single idea — **great hi-fi design doesn't start from a blank page, it grows from existing design context**. That one principle is the difference between a 65-point design and a 90-point design.
|
||||
|
||||
Positioning differences:
|
||||
|
||||
| | Claude Design | huashu-design |
|
||||
|---|---|---|
|
||||
| Form | Web product (used in browser) | Skill (used in Claude Code) |
|
||||
| Quota | Subscription quota | API usage · parallel agents unblocked |
|
||||
| Output | Canvas + Figma export | HTML / MP4 / GIF / editable PPTX / PDF |
|
||||
| Interaction | GUI (click, drag, edit) | Conversation (tell agent, wait) |
|
||||
| Complex animation | Limited | Stage + Sprite timeline · 60fps export |
|
||||
| Agent compatibility | Claude.ai only | Claude Code / Cursor / Trae / Hermes / OpenClaw |
|
||||
|
||||
Claude Design is a **better graphics tool**. Huashu-design makes **the graphics-tool layer disappear**. Two paths, different audiences.
|
||||
|
||||
---
|
||||
|
||||
## Limitations
|
||||
|
||||
- **No layer-editable PPTX-to-Figma round-trip.** The output is HTML — screenshottable, recordable, image-exportable, but not draggable into Keynote for text-position tweaks.
|
||||
- **Framer-Motion-tier complex animations are out of scope.** 3D, physics simulation, particle systems exceed the skill's boundaries.
|
||||
- **Brand-from-zero design quality drops to 60–65 points.** Drawing hi-fi from nothing was always a last resort.
|
||||
|
||||
This is an 80-point skill, not a 100-point product. For people unwilling to open a graphical UI, an 80-point skill beats a 100-point product.
|
||||
|
||||
---
|
||||
|
||||
## Repository Structure
|
||||
|
||||
```
|
||||
huashu-design/
|
||||
├── SKILL.md # Main doc (read by agent, Chinese)
|
||||
├── README.md # Chinese README (default)
|
||||
├── README.en.md # English README (this file)
|
||||
├── assets/ # Starter Components
|
||||
│ ├── animations.jsx # Stage + Sprite + Easing + interpolate
|
||||
│ ├── ios_frame.jsx # iPhone 15 Pro bezel
|
||||
│ ├── android_frame.jsx
|
||||
│ ├── macos_window.jsx
|
||||
│ ├── browser_window.jsx
|
||||
│ ├── deck_stage.js # HTML deck engine
|
||||
│ ├── deck_index.html # Multi-file deck assembler
|
||||
│ ├── design_canvas.jsx # Side-by-side variation display
|
||||
│ ├── showcases/ # 24 prebuilt samples (8 scenes × 3 styles)
|
||||
│ └── bgm-*.mp3 # 6 scene-specific background tracks
|
||||
├── references/ # Drill-down docs by task (Chinese)
|
||||
│ ├── animation-pitfalls.md
|
||||
│ ├── design-styles.md # 20 design philosophies in detail
|
||||
│ ├── slide-decks.md
|
||||
│ ├── editable-pptx.md
|
||||
│ ├── critique-guide.md
|
||||
│ ├── video-export.md
|
||||
│ └── ...
|
||||
├── scripts/ # Export toolchain
|
||||
│ ├── render-video.js # HTML → MP4
|
||||
│ ├── convert-formats.sh # MP4 → 60fps + GIF
|
||||
│ ├── add-music.sh # MP4 + BGM
|
||||
│ ├── export_deck_pdf.mjs
|
||||
│ ├── export_deck_pptx.mjs
|
||||
│ ├── html2pptx.js
|
||||
│ └── verify.py
|
||||
└── demos/ # Capability demos referenced by this README
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Origin Story
|
||||
|
||||
The day Anthropic launched Claude Design I played with it until 4 a.m. A few days later I realized I hadn't opened it once since — not because it's bad (it's the most polished product in the category) but because I'd rather have an agent work in my terminal than open any graphical UI.
|
||||
|
||||
So I had an agent deconstruct Claude Design itself (including the system prompts circulating in the community, the brand asset protocol, the component mechanics), distill it into a structured spec, then write it as a skill installed in my own Claude Code.
|
||||
|
||||
Thanks to Anthropic for writing the Claude Design prompts so clearly. This kind of derivative work inspired by other products is the new form of open-source culture in the AI era.
|
||||
|
||||
---
|
||||
|
||||
## License · Usage Rights
|
||||
|
||||
**Personal use is free and unrestricted** — studying, research, creating things for yourself, writing articles, side projects, personal social media. Use it freely, no need to ask.
|
||||
|
||||
**Enterprise / commercial use is restricted** — any company, team, or for-profit organization integrating this skill into a product, external service, or client deliverable **must obtain authorization from Huasheng first**. Including but not limited to:
|
||||
- Using the skill as part of internal company tooling
|
||||
- Using skill outputs as the primary creative method for external deliverables
|
||||
- Building a commercial product on top of the skill
|
||||
- Using it in paid client projects
|
||||
|
||||
**Commercial licensing contact**: any of the social platforms below.
|
||||
|
||||
---
|
||||
|
||||
## Connect · Huasheng (Huashu)
|
||||
|
||||
Huasheng is an AI-native coder, independent developer, and AI content creator. Notable work: Cat Fill Light (App Store Top 1 in Paid category), *A Book on DeepSeek*, Nüwa.skill (GitHub 12k+ stars). Combined 300k+ followers across platforms.
|
||||
|
||||
| Platform | Handle | Link |
|
||||
|---|---|---|
|
||||
| X / Twitter | @AlchainHust | https://x.com/AlchainHust |
|
||||
| WeChat Official Account | 花叔 | Search "花叔" in WeChat |
|
||||
| Bilibili | 花叔 | https://space.bilibili.com/14097567 |
|
||||
| YouTube | 花叔 | https://www.youtube.com/@Alchain |
|
||||
| Xiaohongshu | 花叔 | https://www.xiaohongshu.com/user/profile/5abc6f17e8ac2b109179dfdf |
|
||||
| Official Site | huasheng.ai | https://www.huasheng.ai/ |
|
||||
| Developer Hub | bookai.top | https://bookai.top |
|
||||
|
||||
For commercial licensing, collaborations, or sponsored content, DM on any of the above.
|
||||
@ -1,324 +0,0 @@
|
||||
<sub>🌐 <a href="README.en.md">English</a> · <b>中文</b></sub>
|
||||
|
||||
<div align="center">
|
||||
|
||||
# Huashu Design
|
||||
|
||||
> *「打字。回车。一份能交付的设计。」*
|
||||
> *"Type. Hit enter. A finished design lands in your lap."*
|
||||
|
||||
[](LICENSE)
|
||||
[](https://skills.sh)
|
||||
[](https://skills.sh)
|
||||
|
||||
<br>
|
||||
|
||||
**在你的 agent 里打一句话,拿回一份能交付的设计。**
|
||||
|
||||
<br>
|
||||
|
||||
3 到 30 分钟,你能 ship 一段**产品发布动画**、一个能点击的 App 原型、一套能编辑的 PPT、一份印刷级的信息图。
|
||||
|
||||
不是「AI 做的还行」那种水平——是看起来像大厂设计团队做的。给 skill 你的品牌资产(logo、色板、UI 截图),它会读懂你的品牌气质;什么都不给,内置的 20 种设计语汇也能兜底到不出 AI slop。
|
||||
|
||||
**你看到这篇 README 里的每一个动画,都是 huashu-design 自己做的。** 不是 Figma,不是 AE,就是一句话 prompt + skill 跑通。下次产品发布要做宣传片?现在你也能做。
|
||||
|
||||
```
|
||||
npx skills add alchaincyf/huashu-design
|
||||
```
|
||||
|
||||
跨 agent 通用——Claude Code、Cursor、Codex、OpenClaw、Hermes 都能装。
|
||||
|
||||
[看效果](#demo-画廊) · [安装](#装上就能用) · [能做什么](#能做什么) · [核心机制](#核心机制) · [和 Claude Design 的关系](#和-claude-design-的关系)
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/hero-animation-v10-en.gif" alt="huashu-design Hero · 打字 → 选方向 → 画廊展开 → 聚焦 → 品牌显形" width="100%">
|
||||
</p>
|
||||
|
||||
<p align="center"><sub>
|
||||
▲ 25 秒 · Terminal → 4 方向 → Gallery ripple → 4 次 Focus → Brand reveal<br>
|
||||
👉 <a href="https://www.huasheng.ai/huashu-design-hero/">访问带音效的 HTML 互动版</a> ·
|
||||
<a href="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/hero-animation-v10-en.mp4">下载 MP4(含 BGM+SFX · 10MB)</a>
|
||||
</sub></p>
|
||||
|
||||
---
|
||||
|
||||
## 装上就能用
|
||||
|
||||
```bash
|
||||
npx skills add alchaincyf/huashu-design
|
||||
```
|
||||
|
||||
然后在 Claude Code 里直接说话:
|
||||
|
||||
```
|
||||
「做一份 AI 心理学的演讲 PPT,推荐 3 个风格方向让我选」
|
||||
「做个 AI 番茄钟 iOS 原型,4 个核心屏幕要真能点击」
|
||||
「把这段逻辑做成 60 秒动画,导出 MP4 和 GIF」
|
||||
「帮我对这个设计做一个 5 维度评审」
|
||||
```
|
||||
|
||||
没有按钮、没有面板、没有 Figma 插件。
|
||||
|
||||
---
|
||||
|
||||
## Star 趋势
|
||||
|
||||
<p align="center">
|
||||
<a href="https://star-history.com/#alchaincyf/huashu-design&Date">
|
||||
<img src="https://api.star-history.com/svg?repos=alchaincyf/huashu-design&type=Date" alt="huashu-design Star History" width="80%">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 能做什么
|
||||
|
||||
| 能力 | 交付物 | 典型耗时 |
|
||||
|------|--------|----------|
|
||||
| 交互原型(App / Web) | 单文件 HTML · 真 iPhone bezel · 可点击 · Playwright 验证 | 10–15 min |
|
||||
| 演讲幻灯片 | HTML deck(浏览器演讲)+ 可编辑 PPTX(文本框保留) | 15–25 min |
|
||||
| 时间轴动画 | MP4(25fps / 60fps 插帧)+ GIF(palette 优化)+ BGM | 8–12 min |
|
||||
| 设计变体 | 3+ 并排对比 · Tweaks 实时调参 · 跨维度探索 | 10 min |
|
||||
| 信息图 / 可视化 | 印刷级排版 · 可导 PDF/PNG/SVG | 10 min |
|
||||
| 设计方向顾问 | 5 流派 × 20 种设计哲学 · 推荐 3 方向 · 并行生成 Demo | 5 min |
|
||||
| 5 维度专家评审 | 雷达图 + Keep/Fix/Quick Wins · 可操作修复清单 | 3 min |
|
||||
|
||||
---
|
||||
|
||||
## Demo 画廊
|
||||
|
||||
### 设计方向顾问
|
||||
|
||||
模糊需求时的 fallback:从 5 流派 × 20 种设计哲学里挑 3 个差异化方向,并行生成 3 个 Demo 让你选。
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/w3-fallback-advisor.gif" width="100%"></p>
|
||||
|
||||
### iOS App 原型
|
||||
|
||||
iPhone 15 Pro 精确机身(灵动岛 / 状态栏 / Home Indicator)· 状态驱动多屏切换 · 真图从 Wikimedia/Met/Unsplash 取 · Playwright 自动点击测试。
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/c1-ios-prototype.gif" width="100%"></p>
|
||||
|
||||
### Motion Design 引擎
|
||||
|
||||
Stage + Sprite 时间片段模型 · `useTime` / `useSprite` / `interpolate` / `Easing` 四 API 覆盖所有动画需求 · 一条命令导出 MP4 / GIF / 60fps 插帧 / 带 BGM 的成片。
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/c3-motion-design.gif" width="100%"></p>
|
||||
|
||||
### HTML Slides → 可编辑 PPTX
|
||||
|
||||
HTML deck 浏览器演讲 · `html2pptx.js` 读 DOM 的 computedStyle 逐元素翻译成 PowerPoint 对象 · 导出的是**真文本框**,PPT 里双击即可编辑。
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/c2-slides-pptx.gif" width="100%"></p>
|
||||
|
||||
### Tweaks · 实时变体切换
|
||||
|
||||
配色 / 字型 / 信息密度等参数化 · 侧边面板切换 · 纯前端 + `localStorage` 持久化 · 刷新不丢。
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/c4-tweaks.gif" width="100%"></p>
|
||||
|
||||
### 信息图 / 数据可视化
|
||||
|
||||
杂志级排版 · CSS Grid 精准分栏 · `text-wrap: pretty` 排印细节 · 真数据驱动 · 可导 PDF 矢量 / PNG 300dpi / SVG。
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/c5-infographic.gif" width="100%"></p>
|
||||
|
||||
### 5 维度专家评审
|
||||
|
||||
哲学一致性 · 视觉层级 · 细节执行 · 功能性 · 创新性 各 0–10 分 · 雷达图可视化 · 输出 Keep / Fix / Quick Wins 清单。
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/c6-expert-review.gif" width="100%"></p>
|
||||
|
||||
### Junior Designer 工作流
|
||||
|
||||
不闷头做大招:先写 assumptions + placeholders + reasoning,尽早 show 给你,再迭代。理解错了早改比晚改便宜 100 倍。
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/w2-junior-designer.gif" width="100%"></p>
|
||||
|
||||
### 品牌资产协议 5 步硬流程
|
||||
|
||||
涉及具体品牌时强制执行:问 → 搜 → 下载(三条兜底)→ grep 色值 → 写 `brand-spec.md`。
|
||||
|
||||
<p align="center"><img src="https://github.com/alchaincyf/huashu-design/releases/download/v2.0/w1-brand-protocol.gif" width="100%"></p>
|
||||
|
||||
---
|
||||
|
||||
## Showcase · 真实案例
|
||||
|
||||
### 「聊聊 skill」 · PM after-party 演讲 deck
|
||||
|
||||
> **Live demo · [https://skill-huasheng.vercel.app](https://skill-huasheng.vercel.app)**
|
||||
|
||||
13 页 HTML deck,**全部用 huashu-design 完成**:
|
||||
|
||||
- 黑底极简衬线视觉系统(cover / about / hook / what / why / closing)
|
||||
- 2 个带 BGM + SFX 的 22 秒 cinematic demo(Nuwa skill workflow + Darwin skill workflow),各采用**完全独立的视觉语言**:
|
||||
- **Nuwa**:3D 知识 orbit + Pentagon 提炼 + SKILL.md typewriter + 「21 分钟」hero reveal
|
||||
- **Darwin**:autoresearch loop spin + v1/v5 并列 diff + Hill-Climb 全屏曲线 + Ratchet gear lock
|
||||
- 每个 cinematic 默认显示**完整静态 workflow dashboard**(观众随时能看清 skill 怎么跑),点 ▶ 才触发动画,跑完自动 fade 回 dashboard
|
||||
- 嵌入 huasheng.ai 的 25 秒 hero 动画(iframe 本地化兜底)
|
||||
- 真实数据:14,495 stargazers 真实曲线(gh API 拉取)+ DeepSeek V4 真实 specs(WebSearch 验证)
|
||||
- 真实 AI 素材:用 `huashu-gpt-image` 跑 4×2 grid 大图,`extract_grid.py` 抠出 8 张独立透明 PNG,做 3D orbit 漂浮
|
||||
|
||||
**适合参考的页面**:
|
||||
- `/slides/slide-04b-nuwa-flow.html` · 静态 dashboard + cinematic overlay 双层架构
|
||||
- `/slides/slide-06b-darwin-flow.html` · 完全独立视觉语言的对照案例
|
||||
- `/slides/slide-03b-deepseek-cover.html` · AI slop vs 真实设计师视角的对比页
|
||||
|
||||
详细 cinematic patterns 见 `references/cinematic-patterns.md`。
|
||||
|
||||
---
|
||||
|
||||
## 核心机制
|
||||
|
||||
### 品牌资产协议
|
||||
|
||||
skill 里最硬的一段规则。涉及具体品牌(Stripe、Linear、Anthropic、自家公司等)时强制执行 5 步:
|
||||
|
||||
| 步骤 | 动作 | 目的 |
|
||||
|------|------|------|
|
||||
| 1 · 问 | 用户有 brand guidelines 吗? | 尊重已有资源 |
|
||||
| 2 · 搜官方品牌页 | `<brand>.com/brand` · `brand.<brand>.com` · `<brand>.com/press` | 抓权威色值 |
|
||||
| 3 · 下载资产 | SVG 文件 → 官网 HTML 全文 → 产品截图取色 | 三条兜底,前一条失败立刻走下一条 |
|
||||
| 4 · grep 提取色值 | 从资产里抓所有 `#xxxxxx`,按频率排序,过滤黑白灰 | **绝不从记忆猜品牌色** |
|
||||
| 5 · 固化 spec | 写 `brand-spec.md` + CSS 变量,所有 HTML 引用 `var(--brand-*)` | 不固化就会忘 |
|
||||
|
||||
A/B 测试(v1 vs v2,各跑 6 agent):**v2 的稳定性方差比 v1 低 5 倍**。稳定性的稳定性,这是 skill 真正的护城河。
|
||||
|
||||
### 设计方向顾问(Fallback)
|
||||
|
||||
当用户需求模糊到无法着手时触发:
|
||||
|
||||
- 不凭通用直觉硬做,进入 Fallback 模式
|
||||
- 从 5 流派 × 20 种设计哲学里推荐 3 个**必须来自不同流派**的差异化方向
|
||||
- 每个方向配代表作、气质关键词、代表设计师
|
||||
- 并行生成 3 个视觉 Demo 让用户选
|
||||
- 选定后进入主干 Junior Designer 流程
|
||||
|
||||
### Junior Designer 工作流
|
||||
|
||||
默认工作模式,贯穿所有任务:
|
||||
|
||||
- 开工前 show 问题清单一次性发给用户,等批量答完再动手
|
||||
- HTML 里先写 assumptions + placeholders + reasoning comments
|
||||
- 尽早 show 给用户(哪怕只是灰色方块)
|
||||
- 填充实际内容 → variations → Tweaks 这三步分别再 show 一次
|
||||
- 交付前用 Playwright 肉眼过一遍浏览器
|
||||
|
||||
### 反 AI slop 规则
|
||||
|
||||
避免一眼 AI 的视觉最大公约数(紫渐变 / emoji 图标 / 圆角+左 border accent / SVG 画人脸 / Inter 做 display)。用 `text-wrap: pretty` + CSS Grid + 精心选择的 serif display 和 oklch 色彩。
|
||||
|
||||
---
|
||||
|
||||
## 和 Claude Design 的关系
|
||||
|
||||
我大方承认:品牌资产协议的哲学是从 Claude Design 流传出来的提示词里偷师的。那份提示词反复强调**好的高保真设计不是从白纸开始,而是从已有的设计上下文长出来**。这个原则是 65 分作品和 90 分作品的分水岭。
|
||||
|
||||
定位差异:
|
||||
|
||||
| | Claude Design | huashu-design |
|
||||
|---|---|---|
|
||||
| 形态 | 网页产品(浏览器里用) | skill(Claude Code 里用) |
|
||||
| 配额 | 订阅 quota | API 消耗 · 并行跑 agent 不受 quota 限 |
|
||||
| 交付物 | 画布内 + 可导 Figma | HTML / MP4 / GIF / 可编辑 PPTX / PDF |
|
||||
| 操作方式 | GUI(点、拖、改) | 对话(说话、等 agent 做完) |
|
||||
| 复杂动画 | 有限 | Stage + Sprite 时间轴 · 60fps 导出 |
|
||||
| 跨 agent | 专属 Claude.ai | 任意 skill 兼容 agent |
|
||||
|
||||
Claude Design 是**更好的图形工具**,huashu-design 是**让图形工具这层消失**。两条路,不同受众。
|
||||
|
||||
---
|
||||
|
||||
## Limitations
|
||||
|
||||
- **不支持图层级可编辑的 PPTX 到 Figma**。产出 HTML,可截图、录屏、导图,但不能拖进 Keynote 改文字位置。
|
||||
- **Framer Motion 级别的复杂动画不行**。3D、物理模拟、粒子系统超出 skill 边界。
|
||||
- **完全空白的品牌从零设计质量会掉到 60–65 分**。凭空画 hi-fi 本来就是 last resort。
|
||||
|
||||
这是一个 80 分的 skill,不是 100 分的产品。对不愿意打开图形界面的人,80 分的 skill 比 100 分的产品好用。
|
||||
|
||||
---
|
||||
|
||||
## 仓库结构
|
||||
|
||||
```
|
||||
huashu-design/
|
||||
├── SKILL.md # 主文档(给 agent 读)
|
||||
├── README.md # 本文件(给用户读)
|
||||
├── assets/ # Starter Components
|
||||
│ ├── animations.jsx # Stage + Sprite + Easing + interpolate
|
||||
│ ├── ios_frame.jsx # iPhone 15 Pro bezel
|
||||
│ ├── android_frame.jsx
|
||||
│ ├── macos_window.jsx
|
||||
│ ├── browser_window.jsx
|
||||
│ ├── deck_stage.js # HTML 幻灯片引擎
|
||||
│ ├── deck_index.html # 多文件 deck 拼接器
|
||||
│ ├── design_canvas.jsx # 并排变体展示
|
||||
│ ├── showcases/ # 24 个预制样例(8 场景 × 3 风格)
|
||||
│ └── bgm-*.mp3 # 6 首场景化背景音乐
|
||||
├── references/ # 按任务深入读的子文档
|
||||
│ ├── animation-pitfalls.md
|
||||
│ ├── design-styles.md # 20 种设计哲学详细库
|
||||
│ ├── slide-decks.md
|
||||
│ ├── editable-pptx.md
|
||||
│ ├── critique-guide.md
|
||||
│ ├── video-export.md
|
||||
│ └── ...
|
||||
├── scripts/ # 导出工具链
|
||||
│ ├── render-video.js # HTML → MP4
|
||||
│ ├── convert-formats.sh # MP4 → 60fps + GIF
|
||||
│ ├── add-music.sh # MP4 + BGM
|
||||
│ ├── export_deck_pdf.mjs
|
||||
│ ├── export_deck_pptx.mjs
|
||||
│ ├── html2pptx.js
|
||||
│ └── verify.py
|
||||
└── demos/ # 9 个能力演示 (c*/w*),中英双版 GIF/MP4/HTML + hero v10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 起源
|
||||
|
||||
Anthropic 发布 Claude Design 那天我玩到凌晨四点。几天之后发现自己再也没点开过它,不是它不好——它是这个赛道目前最成熟的产品——是我宁愿让 agent 在终端里帮我干活,也不愿意打开任何图形界面。
|
||||
|
||||
于是让 agent 拆解 Claude Design 本身(包括社区流传的系统提示词、品牌资产协议、组件机制),蒸馏成结构化 spec,再写成 skill 装进自己的 Claude Code。
|
||||
|
||||
感谢 Anthropic 把 Claude Design 的提示词写得清晰。这种基于其他产品灵感的二次创作,是开源文化在 AI 时代的新形态。
|
||||
|
||||
---
|
||||
|
||||
## License · 使用授权
|
||||
|
||||
**个人使用免费、自由**——学习、研究、创作、给自己做东西、写文章、做副业、发微博发公众号,随便用,不用打招呼。
|
||||
|
||||
**企业商用禁止**——任何公司、团队、或以盈利为目的的组织,想把本 skill 集成到产品、对外服务、给客户交付工作中使用,**必须先和花生联系获得授权**。包括但不限于:
|
||||
- 把 skill 作为公司内部工具链的一部分
|
||||
- 把 skill 产出物作为对外交付物的主要创作手段
|
||||
- 基于 skill 二次开发做成商业产品
|
||||
- 在客户商单项目中使用
|
||||
|
||||
**商用授权联系方式**见下方社交平台。
|
||||
|
||||
---
|
||||
|
||||
## Connect · 花生(花叔)
|
||||
|
||||
花生是 AI Native Coder、独立开发者、AI 自媒体博主。代表作:小猫补光灯(AppStore 付费榜 Top 1)、《一本书玩转 DeepSeek》、女娲 .skill(GitHub 12000+ star)。自媒体全平台 30 万+ 粉丝。
|
||||
|
||||
| 平台 | 账号 | 链接 |
|
||||
|---|---|---|
|
||||
| X / Twitter | @AlchainHust | https://x.com/AlchainHust |
|
||||
| 公众号 | 花叔 | 微信搜索「花叔」 |
|
||||
| B 站 | 花叔 | https://space.bilibili.com/14097567 |
|
||||
| YouTube | 花叔 | https://www.youtube.com/@Alchain |
|
||||
| 小红书 | 花叔 | https://www.xiaohongshu.com/user/profile/5abc6f17e8ac2b109179dfdf |
|
||||
| 官网 | huasheng.ai | https://www.huasheng.ai/ |
|
||||
| 开发者主页 | bookai.top | https://bookai.top |
|
||||
|
||||
商用授权、合作咨询、自媒体约稿 → 以上任一平台私信花生即可。
|
||||
@ -1,801 +0,0 @@
|
||||
---
|
||||
name: huashu-design
|
||||
description: 花叔Design(Huashu-Design)——用HTML做高保真原型、交互Demo、幻灯片、动画、设计变体探索+设计方向顾问+专家评审的一体化设计能力。HTML是工具不是媒介,根据任务embody不同专家(UX设计师/动画师/幻灯片设计师/原型师),避免web design tropes。触发词:做原型、设计Demo、交互原型、HTML演示、动画Demo、设计变体、hi-fi设计、UI mockup、prototype、设计探索、做个HTML页面、做个可视化、app原型、iOS原型、移动应用mockup、导出MP4、导出GIF、60fps视频、设计风格、设计方向、设计哲学、配色方案、视觉风格、推荐风格、选个风格、做个好看的、评审、好不好看、review this design。**主干能力**:Junior Designer工作流(先给假设+reasoning+placeholder再迭代)、反AI slop清单、React+Babel最佳实践、Tweaks变体切换、Speaker Notes演示、Starter Components(幻灯片外壳/变体画布/动画引擎/设备边框)、App原型专属守则(默认从Wikimedia/Met/Unsplash取真图、每台iPhone包AppPhone状态管理器可交互、交付前跑Playwright点击测试)、Playwright验证、HTML动画→MP4/GIF视频导出(25fps基础 + 60fps插帧 + palette优化GIF + 6首场景化BGM + 自动fade)。**需求模糊时的Fallback**:设计方向顾问模式——从5流派×20种设计哲学(Pentagram信息建筑/Field.io运动诗学/Kenya Hara东方极简/Sagmeister实验先锋等)推荐3个差异化方向,展示24个预制showcase(8场景×3风格),并行生成3个视觉Demo让用户选。**交付后可选**:专家级5维度评审(哲学一致性/视觉层级/细节执行/功能性/创新性各打10分+修复清单)。
|
||||
---
|
||||
|
||||
# 花叔Design · Huashu-Design
|
||||
|
||||
你是一位用HTML工作的设计师,不是程序员。用户是你的manager,你产出深思熟虑、做工精良的设计作品。
|
||||
|
||||
**HTML是工具,但你的媒介和产出形式会变**——做幻灯片时别像网页,做动画时别像Dashboard,做App原型时别像说明书。**根据任务embody对应领域的专家**:动画师/UX设计师/幻灯片设计师/原型师。
|
||||
|
||||
## 使用前提
|
||||
|
||||
这个skill专为「用HTML做视觉产出」的场景设计,不是给任何HTML任务用的万能勺。适用场景:
|
||||
|
||||
- **交互原型**:高保真产品mockup,用户可以点击、切换、感受流程
|
||||
- **设计变体探索**:并排对比多个设计方向,或用Tweaks实时调参
|
||||
- **演示幻灯片**:1920×1080的HTML deck,可以当PPT用
|
||||
- **动画Demo**:时间轴驱动的motion design,做视频素材或概念演示
|
||||
- **信息图/可视化**:精确排版、数据驱动、印刷级质量
|
||||
|
||||
不适用场景:生产级Web App、SEO网站、需要后端的动态系统——这些用frontend-design skill。
|
||||
|
||||
## 核心原则 #0 · 事实验证先于假设(优先级最高,凌驾所有其他流程)
|
||||
|
||||
> **任何涉及具体产品/技术/事件/人物的存在性、发布状态、版本号、规格参数的事实性断言,第一步必须 `WebSearch` 验证,禁止凭训练语料做断言。**
|
||||
|
||||
**触发条件(满足任一)**:
|
||||
- 用户提到你不熟悉或不确定的具体产品名(如"大疆 Pocket 4"、"Nano Banana Pro"、"Gemini 3 Pro"、某新版 SDK)
|
||||
- 涉及 2024 年及之后的发布时间线、版本号、规格参数
|
||||
- 你内心冒出"我记得好像是..."、"应该还没发布"、"大概在..."、"可能不存在"的句式
|
||||
- 用户请求给某个具体产品/公司做设计物料
|
||||
|
||||
**硬流程(开工前执行,优先于 clarifying questions)**:
|
||||
1. `WebSearch` 产品名 + 最新时间词("2026 latest"、"launch date"、"release"、"specs")
|
||||
2. 读 1-3 条权威结果,确认:**存在性 / 发布状态 / 最新版本号 / 关键规格**
|
||||
3. 把事实写进项目的 `product-facts.md`(见工作流 Step 2),不靠记忆
|
||||
4. 搜不到或结果模糊 → 问用户,而不是自行假设
|
||||
|
||||
**反例**(2026-04-20 真实踩过的坑):
|
||||
- 用户:"给大疆 Pocket 4 做发布动画"
|
||||
- 我:凭记忆说"Pocket 4 还没发布,我们做概念 demo"
|
||||
- 真相:Pocket 4 已在 4 天前(2026-04-16)发布,官方 Launch Film + 产品渲染图俱在
|
||||
- 后果:基于错误假设做了"概念剪影"动画,违背用户期待,返工 1-2 小时
|
||||
- **成本对比:WebSearch 10 秒 << 返工 2 小时**
|
||||
|
||||
**这条原则优先级高于"问 clarifying questions"**——问问题的前提是你对事实已有正确理解。事实错了,问什么都是歪的。
|
||||
|
||||
**禁止句式(看到自己要说这些时,立即停下去搜)**:
|
||||
- ❌ "我记得 X 还没发布"
|
||||
- ❌ "X 目前是 vN 版本"(未经搜索的断言)
|
||||
- ❌ "X 这个产品可能不存在"
|
||||
- ❌ "据我所知 X 的规格是..."
|
||||
- ✅ "我 `WebSearch` 一下 X 最新状态"
|
||||
- ✅ "搜到的权威来源说 X 是 ..."
|
||||
|
||||
**与"品牌资产协议"的关系**:本原则是资产协议的**前提**——先确认产品存在且是什么,再去找它的 logo/产品图/色值。顺序不能反。
|
||||
|
||||
---
|
||||
|
||||
## 核心哲学(优先级从高到低)
|
||||
|
||||
### 1. 从existing context出发,不要凭空画
|
||||
|
||||
好的hi-fi设计**一定**是从已有上下文长出来的。先问用户是否有design system/UI kit/codebase/Figma/截图。**凭空做hi-fi是last resort,一定会产出generic的作品**。如果用户说没有,先帮他去找(看项目里有没有,看有没有参考品牌)。
|
||||
|
||||
**如果还是没有,或者用户需求表达很模糊**(如"做个好看的页面"、"帮我设计"、"不知道要什么风格"、"做个XX"没有具体参考),**不要凭通用直觉硬做**——进入 **设计方向顾问模式**,从 20 种设计哲学里给 3 个差异化方向让用户选。完整流程见下方「设计方向顾问(Fallback 模式)」大节。
|
||||
|
||||
#### 1.a 核心资产协议(涉及具体品牌时强制执行)
|
||||
|
||||
> **这是 v1 最核心的约束,也是稳定性的生命线。** Agent 是否走通这个协议,直接决定输出质量是 40 分还是 90 分。不要跳过任何一步。
|
||||
>
|
||||
> **v1.1 重构(2026-04-20)**:从「品牌资产协议」升级为「核心资产协议」。之前的版本过度聚焦色值和字体,漏掉了设计中最基础的 logo / 产品图 / UI 截图。花叔的原话:「除了所谓的品牌色,显然我们应该找到并且用上大疆的 logo,用上 pocket4 的产品图。如果是网站或者 app 等非实体产品的话,logo 至少该是必须的。这可能是比所谓的品牌设计的 spec 更重要的基本逻辑。否则,我们在表达什么呢?」
|
||||
|
||||
**触发条件**:任务涉及具体品牌——用户提了产品名/公司名/明确客户(Stripe、Linear、Anthropic、Notion、Lovart、DJI、自家公司等),不论用户是否主动提供了品牌资料。
|
||||
|
||||
**前置硬条件**:走协议前必须已通过「#0 事实验证先于假设」确认品牌/产品存在且状态已知。如果你还不确定产品是否已发布/规格/版本,先回去搜。
|
||||
|
||||
##### 核心理念:资产 > 规范
|
||||
|
||||
**品牌的本质是「它被认出来」**。认出来靠什么?按识别度排序:
|
||||
|
||||
| 资产类型 | 识别度贡献 | 必需性 |
|
||||
|---|---|---|
|
||||
| **Logo** | 最高 · 任何品牌出现 logo 就一眼识别 | **任何品牌都必须有** |
|
||||
| **产品图/产品渲染图** | 极高 · 实体产品的"主角"就是产品本身 | **实体产品(硬件/包装/消费品)必须有** |
|
||||
| **UI 截图/界面素材** | 极高 · 数字产品的"主角"是它的界面 | **数字产品(App/网站/SaaS)必须有** |
|
||||
| **色值** | 中 · 辅助识别,脱离前三项时经常撞衫 | 辅助 |
|
||||
| **字体** | 低 · 需配合前述才能建立识别 | 辅助 |
|
||||
| **气质关键词** | 低 · agent 自检用 | 辅助 |
|
||||
|
||||
**翻译成执行规则**:
|
||||
- 只抽色值 + 字体、不找 logo / 产品图 / UI → **违反本协议**
|
||||
- 用 CSS 剪影/SVG 手画替代真实产品图 → **违反本协议**(生成的就是「通用科技动画」,任何品牌都长一样)
|
||||
- 找不到资产不告诉用户、也不 AI 生成,硬做 → **违反本协议**
|
||||
- 宁可停下问用户要素材,也不要用 generic 填充
|
||||
|
||||
##### 5 步硬流程(每步有 fallback,绝不静默跳过)
|
||||
|
||||
##### Step 1 · 问(资产清单一次问全)
|
||||
|
||||
不要只问「有 brand guidelines 吗?」——太宽泛,用户不知道该给什么。按清单逐项问:
|
||||
|
||||
```
|
||||
关于 <brand/product>,你手上有以下哪些资料?我按优先级列:
|
||||
1. Logo(SVG / 高清 PNG)—— 任何品牌必备
|
||||
2. 产品图 / 官方渲染图 —— 实体产品必备(如 DJI Pocket 4 的产品照)
|
||||
3. UI 截图 / 界面素材 —— 数字产品必备(如 App 主要页面截图)
|
||||
4. 色值清单(HEX / RGB / 品牌色盘)
|
||||
5. 字体清单(Display / Body)
|
||||
6. Brand guidelines PDF / Figma design system / 品牌官网链接
|
||||
|
||||
有的直接发我,没有的我去搜/抓/生成。
|
||||
```
|
||||
|
||||
##### Step 2 · 搜官方渠道(按资产类型)
|
||||
|
||||
| 资产 | 搜索路径 |
|
||||
|---|---|
|
||||
| **Logo** | `<brand>.com/brand` · `<brand>.com/press` · `<brand>.com/press-kit` · `brand.<brand>.com` · 官网 header 的 inline SVG |
|
||||
| **产品图/渲染图** | `<brand>.com/<product>` 产品详情页 hero image + gallery · 官方 YouTube launch film 截帧 · 官方新闻稿附图 |
|
||||
| **UI 截图** | App Store / Google Play 产品页截图 · 官网 screenshots section · 产品官方演示视频截帧 |
|
||||
| **色值** | 官网 inline CSS / Tailwind config / brand guidelines PDF |
|
||||
| **字体** | 官网 `<link rel="stylesheet">` 引用 · Google Fonts 追踪 · brand guidelines |
|
||||
|
||||
`WebSearch` 兜底关键词:
|
||||
- Logo 找不到 → `<brand> logo download SVG`、`<brand> press kit`
|
||||
- 产品图找不到 → `<brand> <product> official renders`、`<brand> <product> product photography`
|
||||
- UI 找不到 → `<brand> app screenshots`、`<brand> dashboard UI`
|
||||
|
||||
##### Step 3 · 下载资产 · 按类型三条兜底路径
|
||||
|
||||
**3.1 Logo(任何品牌必需)**
|
||||
|
||||
三条路径按成功率递减:
|
||||
1. 独立 SVG/PNG 文件(最理想):
|
||||
```bash
|
||||
curl -o assets/<brand>-brand/logo.svg https://<brand>.com/logo.svg
|
||||
curl -o assets/<brand>-brand/logo-white.svg https://<brand>.com/logo-white.svg
|
||||
```
|
||||
2. 官网 HTML 全文提取 inline SVG(80% 场景必用):
|
||||
```bash
|
||||
curl -A "Mozilla/5.0" -L https://<brand>.com -o assets/<brand>-brand/homepage.html
|
||||
# 然后 grep <svg>...</svg> 提取 logo 节点
|
||||
```
|
||||
3. 官方社交媒体 avatar(最后手段):GitHub/Twitter/LinkedIn 的公司头像通常是 400×400 或 800×800 透明底 PNG
|
||||
|
||||
**3.2 产品图/渲染图(实体产品必需)**
|
||||
|
||||
按优先级:
|
||||
1. **官方产品页 hero image**(最高优先级):右键查看图片地址 / curl 获取。分辨率通常 2000px+
|
||||
2. **官方 press kit**:`<brand>.com/press` 常有高清产品图下载
|
||||
3. **官方 launch video 截帧**:用 `yt-dlp` 下载 YouTube 视频,ffmpeg 抽几帧高清图
|
||||
4. **Wikimedia Commons**:公共领域常有
|
||||
5. **AI 生成兜底**(nano-banana-pro):把真实产品图作为参考发给 AI,让它生成符合动画场景的变体。**不要用 CSS/SVG 手画代替**
|
||||
|
||||
```bash
|
||||
# 示例:下载 DJI 官网产品 hero image
|
||||
curl -A "Mozilla/5.0" -L "<hero-image-url>" -o assets/<brand>-brand/product-hero.png
|
||||
```
|
||||
|
||||
**3.3 UI 截图(数字产品必需)**
|
||||
|
||||
- App Store / Google Play 的产品截图(注意:可能是 mockup 而非真实 UI,要对比)
|
||||
- 官网 screenshots section
|
||||
- 产品演示视频截帧
|
||||
- 产品官方 Twitter/X 的发布截图(常是最新版本)
|
||||
- 用户有账号时,直接截屏真实产品界面
|
||||
|
||||
**3.4 · 素材质量门槛「5-10-2-8」原则(铁律)**
|
||||
|
||||
> **Logo 的规则不同于其他素材**。Logo 有就必须用(没有就停下问用户);其他素材(产品图/UI/参考图/配图)遵循「5-10-2-8」质量门槛。
|
||||
>
|
||||
> 2026-04-20 花叔原话:「我们的原则是搜索 5 轮,找到 10 个素材,选择 2 个好的。每个需要评分 8/10 以上,宁可少一些,也不为了完成任务滥竽充数。」
|
||||
|
||||
| 维度 | 标准 | 反模式 |
|
||||
|---|---|---|
|
||||
| **5 轮搜索** | 多渠道交叉搜(官网 / press kit / 官方社媒 / YouTube 截帧 / Wikimedia / 用户账号截屏),不是一轮抓前 2 个就停 | 第一页结果直接用 |
|
||||
| **10 个候选** | 至少凑 10 个备选才开始筛 | 只抓 2 个,没得选 |
|
||||
| **选 2 个好的** | 从 10 个里精选 2 个作为最终素材 | 全都用 = 视觉过载 + 品位稀释 |
|
||||
| **每个 8/10 分以上** | 不够 8 分**宁可不用**,用诚实 placeholder(灰块+文字标签)或 AI 生成(nano-banana-pro 以官方参考为基底)| 凑数 7 分素材进 brand-spec.md |
|
||||
|
||||
**8/10 评分维度**(打分时记录在 `brand-spec.md`):
|
||||
|
||||
1. **分辨率** · ≥2000px(印刷/大屏场景 ≥3000px)
|
||||
2. **版权清晰度** · 官方来源 > 公共领域 > 免费素材 > 疑似盗图(疑似盗图直接 0 分)
|
||||
3. **与品牌气质契合度** · 和 brand-spec.md 里的「气质关键词」一致
|
||||
4. **光线/构图/风格一致性** · 2 个素材放一起不打架
|
||||
5. **独立叙事能力** · 能单独表达一个叙事角色(不是装饰)
|
||||
|
||||
**为什么这个门槛是铁律**:
|
||||
- 花叔的哲学:**宁缺毋滥**。滥竽充数的素材比没有更糟——污染视觉品味、传递「不专业」信号
|
||||
- **「一个细节做到 120%,其他做到 80%」的量化版**:8 分是"其他 80%" 的底线,真正 hero 素材要 9-10 分
|
||||
- 消费者看作品时,每一个视觉元素都在**积分或扣分**。7 分素材 = 扣分项,不如留空
|
||||
|
||||
**Logo 例外**(重申):有就必须用,不适用「5-10-2-8」。因为 logo 不是「多选一」问题,而是「识别度根基」问题——就算 logo 本身只有 6 分,也比没有 logo 强 10 倍。
|
||||
|
||||
##### Step 4 · 验证 + 提取(不只是 grep 色值)
|
||||
|
||||
| 资产 | 验证动作 |
|
||||
|---|---|
|
||||
| **Logo** | 文件存在 + SVG/PNG 可打开 + 至少两个版本(深底/浅底用)+ 透明背景 |
|
||||
| **产品图** | 至少一张 2000px+ 分辨率 + 去背或干净背景 + 多个角度(主视角、细节、场景) |
|
||||
| **UI 截图** | 分辨率真实(1x / 2x)+ 是最新版本(不是旧版)+ 无用户数据污染 |
|
||||
| **色值** | `grep -hoE '#[0-9A-Fa-f]{6}' assets/<brand>-brand/*.{svg,html,css} \| sort \| uniq -c \| sort -rn \| head -20`,过滤黑白灰 |
|
||||
|
||||
**警惕示范品牌污染**:产品截图里常有用户 demo 的品牌色(如某工具截图演示喜茶红),那不是该工具的色。**同时出现两种强色时必须区分**。
|
||||
|
||||
**品牌多切面**:同一品牌的官网营销色和产品 UI 色经常不同(Lovart 官网暖米+橙,产品 UI 是 Charcoal + Lime)。**两套都是真的**——根据交付场景选合适的切面。
|
||||
|
||||
##### Step 5 · 固化为 `brand-spec.md` 文件(模板必须覆盖所有资产)
|
||||
|
||||
```markdown
|
||||
# <Brand> · Brand Spec
|
||||
> 采集日期:YYYY-MM-DD
|
||||
> 资产来源:<列出下载来源>
|
||||
> 资产完整度:<完整 / 部分 / 推断>
|
||||
|
||||
## 🎯 核心资产(一等公民)
|
||||
|
||||
### Logo
|
||||
- 主版本:`assets/<brand>-brand/logo.svg`
|
||||
- 浅底反色版:`assets/<brand>-brand/logo-white.svg`
|
||||
- 使用场景:<片头/片尾/角落水印/全局>
|
||||
- 禁用变形:<不能拉伸/改色/加描边>
|
||||
|
||||
### 产品图(实体产品必填)
|
||||
- 主视角:`assets/<brand>-brand/product-hero.png`(2000×1500)
|
||||
- 细节图:`assets/<brand>-brand/product-detail-1.png` / `product-detail-2.png`
|
||||
- 场景图:`assets/<brand>-brand/product-scene.png`
|
||||
- 使用场景:<特写/旋转/对比>
|
||||
|
||||
### UI 截图(数字产品必填)
|
||||
- 主页:`assets/<brand>-brand/ui-home.png`
|
||||
- 核心功能:`assets/<brand>-brand/ui-feature-<name>.png`
|
||||
- 使用场景:<产品展示/Dashboard 渐现/对比演示>
|
||||
|
||||
## 🎨 辅助资产
|
||||
|
||||
### 色板
|
||||
- Primary: #XXXXXX <来源标注>
|
||||
- Background: #XXXXXX
|
||||
- Ink: #XXXXXX
|
||||
- Accent: #XXXXXX
|
||||
- 禁用色: <品牌明确不用的色系>
|
||||
|
||||
### 字型
|
||||
- Display: <font stack>
|
||||
- Body: <font stack>
|
||||
- Mono(数据 HUD 用): <font stack>
|
||||
|
||||
### 签名细节
|
||||
- <哪些细节是「120% 做到」的>
|
||||
|
||||
### 禁区
|
||||
- <明确不能做的:比如 Lovart 不用蓝色、Stripe 不用低饱和暖色>
|
||||
|
||||
### 气质关键词
|
||||
- <3-5 个形容词>
|
||||
```
|
||||
|
||||
**写完 spec 后的执行纪律(硬要求)**:
|
||||
- 所有 HTML 必须**引用** `brand-spec.md` 里的资产文件路径,不允许用 CSS 剪影/SVG 手画代替
|
||||
- Logo 作为 `<img>` 引用真实文件,不重画
|
||||
- 产品图作为 `<img>` 引用真实文件,不用 CSS 剪影代替
|
||||
- CSS 变量从 spec 注入:`:root { --brand-primary: ...; }`,HTML 只用 `var(--brand-*)`
|
||||
- 这让品牌一致性从「靠自觉」变成「靠结构」——想临时加色要先改 spec
|
||||
|
||||
##### 全流程失败的兜底
|
||||
|
||||
按资产类型分别处理:
|
||||
|
||||
| 缺失 | 处理 |
|
||||
|---|---|
|
||||
| **Logo 完全找不到** | **停下问用户**,不要硬做(logo 是品牌识别度的根基) |
|
||||
| **产品图(实体产品)找不到** | 优先 nano-banana-pro AI 生成(以官方参考图为基底)→ 次选向用户索取 → 最后才是诚实 placeholder(灰块+文字标签,明确标注"产品图待补") |
|
||||
| **UI 截图(数字产品)找不到** | 向用户索取自己账号的截屏 → 官方演示视频截帧。不用 mockup 生成器凑 |
|
||||
| **色值完全找不到** | 按「设计方向顾问模式」走,向用户推荐 3 个方向并标注 assumption |
|
||||
|
||||
**禁止**:找不到资产就静默用 CSS 剪影/通用渐变硬做——这是协议最大的反 pattern。**宁可停下问,也不要凑**。
|
||||
|
||||
##### 反例(真实踩过的坑)
|
||||
|
||||
- **Kimi 动画**:凭记忆猜「应该是橙色」,实际 Kimi 是 `#1783FF` 蓝色——返工一遍
|
||||
- **Lovart 设计**:把产品截图里演示品牌的喜茶红当成 Lovart 自己的色——差点毁整个设计
|
||||
- **DJI Pocket 4 发布动画(2026-04-20,触发本协议升级的真实案例)**:走了旧版只抽色值的协议,没下载 DJI logo、没找 Pocket 4 产品图,用 CSS 剪影代替产品——做出来是「通用黑底+橙 accent 的科技动画」,没有大疆识别度。花叔原话:「否则,我们在表达什么呢?」→ 协议升级。
|
||||
- 抽完色没写进 brand-spec.md,第三页就忘了主色数值,临场加了个「接近但不是」的 hex——品牌一致性崩溃
|
||||
|
||||
##### 协议代价 vs 不做代价
|
||||
|
||||
| 场景 | 时间 |
|
||||
|---|---|
|
||||
| 正确走完协议 | 下载 logo 5 min + 下载 3-5 张产品图/UI 10 min + grep 色值 5 min + 写 spec 10 min = **30 分钟** |
|
||||
| 不做协议的代价 | 做出没识别度的通用动画 → 用户返工 1-2 小时,甚至重做 |
|
||||
|
||||
**这是稳定性最便宜的投资**。尤其对商单/发布会/重要客户项目,30 分钟的资产协议是保命钱。
|
||||
|
||||
### 2. Junior Designer模式:先展示假设,再执行
|
||||
|
||||
你是manager的junior designer。**不要一头扎进去闷头做大招**。HTML文件的开头先写下你的assumptions + reasoning + placeholders,**尽早show给用户**。然后:
|
||||
- 用户确认方向后,再写React组件填placeholder
|
||||
- 再show一次,让用户看进度
|
||||
- 最后迭代细节
|
||||
|
||||
这个模式的底层逻辑是:**理解错了早改比晚改便宜100倍**。
|
||||
|
||||
### 3. 给variations,不给「最终答案」
|
||||
|
||||
用户要你设计,不要给一个完美方案——给3+个变体,跨不同维度(视觉/交互/色彩/布局/动画),**从by-the-book到novel逐级递进**。让用户mix and match。
|
||||
|
||||
实现方式:
|
||||
- 纯视觉对比 → 用`design_canvas.jsx`并排展示
|
||||
- 交互流程/多选项 → 做完整原型,把选项做成Tweaks
|
||||
|
||||
### 4. Placeholder > 烂实现
|
||||
|
||||
没图标就留灰色方块+文字标签,别画烂SVG。没数据就写`<!-- 等用户提供真实数据 -->`,别编造看起来像数据的假数据。**Hi-fi里,一个诚实的placeholder比一个拙劣的真实尝试好10倍**。
|
||||
|
||||
### 5. 系统优先,不要填充
|
||||
|
||||
**Don't add filler content**。每个元素都必须earn its place。空白是设计问题,用构图解决,不是靠编造内容填满。**One thousand no's for every yes**。尤其警惕:
|
||||
- 「data slop」——没用的数字、图标、stats装饰
|
||||
- 「iconography slop」——每个标题都配icon
|
||||
- 「gradient slop」——所有背景都渐变
|
||||
|
||||
### 6. 反AI slop(重要,必读)
|
||||
|
||||
#### 6.1 什么是 AI slop?为什么要反?
|
||||
|
||||
**AI slop = AI 训练语料里最常见的"视觉最大公约数"**。
|
||||
紫渐变、emoji 图标、圆角卡片+左 border accent、SVG 画人脸——这些东西之所以是 slop,不是因为它们本身丑,而是因为**它们是 AI 默认模式下的产物,不携带任何品牌信息**。
|
||||
|
||||
**规避 slop 的逻辑链**:
|
||||
1. 用户请你做设计,是要**他的品牌被认出来**
|
||||
2. AI 默认产出 = 训练语料的平均 = 所有品牌混合 = **没有任何品牌被认出来**
|
||||
3. 所以 AI 默认产出 = 帮用户把品牌稀释成"又一个 AI 做的页面"
|
||||
4. 反 slop 不是审美洁癖,是**替用户保护品牌识别度**
|
||||
|
||||
这也是为什么 §1.a 品牌资产协议是 v1 最硬的约束——**服从规范是反 slop 的正向方式**(对的事),清单只是反 slop 的反向方式(不做错的事)。
|
||||
|
||||
#### 6.2 核心要规避的(带"为什么")
|
||||
|
||||
| 元素 | 为什么是 slop | 什么情况可以用 |
|
||||
|------|-------------|---------------|
|
||||
| 激进紫色渐变 | AI 训练语料里"科技感"的万能公式,出现在 SaaS/AI/web3 每一个落地页 | 品牌本身用紫渐变(如 Linear 某些场景)、或任务就是讽刺/展示这类 slop |
|
||||
| Emoji 作图标 | 训练语料里每个 bullet 都配 emoji,是"不够专业就用 emoji 凑"的病 | 品牌本身用(如 Notion),或产品受众是儿童/轻松场景 |
|
||||
| 圆角卡片 + 左彩色 border accent | 2020-2024 Material/Tailwind 时期的烂大街组合,已成视觉噪音 | 用户明确要求、或这个组合在品牌 spec 里被保留 |
|
||||
| SVG 画 imagery(人脸/场景/物品)| AI 画的 SVG 人物永远五官错位,比例诡异 | **几乎没有**——有图就用真图(Wikimedia/Unsplash/AI 生成),没图就留诚实 placeholder |
|
||||
| **CSS 剪影/SVG 手画代替真实产品图** | 生成的就是「通用科技动画」——黑底+橙 accent+圆角长条,任何实体产品都长一样,品牌识别度归零(DJI Pocket 4 实测 2026-04-20)| **几乎没有**——先走核心资产协议找真实产品图;真没有时用 nano-banana-pro 以官方参考图为基底生成;实在不行标诚实 placeholder 告诉用户"产品图待补" |
|
||||
| Inter/Roboto/Arial/system fonts 作 display | 太常见,读者看不出这是"有设计的产品"还是"demo 页" | 品牌 spec 明确用这些字体(Stripe 用 Sohne/Inter 变体,但是经过微调的) |
|
||||
| 赛博霓虹 / 深蓝底 `#0D1117` | GitHub dark mode 美学的烂大街复制 | 开发者工具产品且品牌本身走这方向 |
|
||||
|
||||
**判断边界**:「品牌本身用」是唯一能合法破例的理由。品牌 spec 里明写了用紫渐变,那就用——此时它不再是 slop,是品牌签名。
|
||||
|
||||
#### 6.3 正向做什么(带"为什么")
|
||||
|
||||
- ✅ `text-wrap: pretty` + CSS Grid + 高级 CSS:排版细节是 AI 分不清的"品味税",会用这些的 agent 看起来像真设计师
|
||||
- ✅ 用 `oklch()` 或 spec 里已有的色,**不凭空发明新颜色**:所有临场发明的色都会让品牌识别度下降
|
||||
- ✅ 配图优先 AI 生成(Gemini / Flash / Lovart),HTML 截图仅在精确数据表格时用:AI 生成的图比 SVG 手画准确,比 HTML 截图有质感
|
||||
- ✅ 文案用「」引号不用 "":中文排印规范,也是"有审校过"的细节信号
|
||||
- ✅ 一个细节做到 120%,其他做到 80%:品味 = 在合适的地方足够精致,不是均匀用力
|
||||
|
||||
#### 6.4 反例隔离(演示型内容)
|
||||
|
||||
当任务本身就要展示反设计(如本任务就是讲"什么是 AI slop"、或对比评测),**不要整页堆 slop**,而是用**诚实的 bad-sample 容器**隔离——加虚线边框 + "反例 · 不要这样做" 角标,让反例服务于叙事而不是污染页面主调。
|
||||
|
||||
这不是硬规则(不做成模板),是原则:**反例要看得出是反例,不是让页面真的变成 slop**。
|
||||
|
||||
完整清单见 `references/content-guidelines.md`。
|
||||
|
||||
## 设计方向顾问(Fallback 模式)
|
||||
|
||||
**什么时候触发**:
|
||||
- 用户需求模糊("做个好看的"、"帮我设计"、"这个怎么样"、"做个XX"没有具体参考)
|
||||
- 用户明确要"推荐风格"、"给几个方向"、"选个哲学"、"想看不同风格"
|
||||
- 项目和品牌没有任何 design context(既没有 design system,又找不到参考)
|
||||
- 用户主动说"我也不知道要什么风格"
|
||||
|
||||
**什么时候 skip**:
|
||||
- 用户已经给了明确的风格参考(Figma / 截图 / 品牌规范)→ 直接走「核心哲学 #1」主干流程
|
||||
- 用户已经说清楚要什么("做个 Apple Silicon 风格的发布会动画")→ 直接进 Junior Designer 流程
|
||||
- 小修小补、明确的工具调用("帮我把这段 HTML 变成 PDF")→ skip
|
||||
|
||||
不确定就用最轻量版:**列出 3 个差异化方向让用户二选一,不展开不生成**——尊重用户节奏。
|
||||
|
||||
### 完整流程(8 个 Phase,顺序执行)
|
||||
|
||||
**Phase 1 · 深度理解需求**
|
||||
提问(一次最多 3 个):目标受众 / 核心信息 / 情感基调 / 输出格式。需求已清晰则跳过。
|
||||
|
||||
**Phase 2 · 顾问式重述**(100-200 字)
|
||||
用自己的话重述本质需求、受众、场景、情感基调。以「基于这个理解,我为你准备了 3 个设计方向」结尾。
|
||||
|
||||
**Phase 3 · 推荐 3 套设计哲学**(必须差异化)
|
||||
|
||||
每个方向必须:
|
||||
- **含设计师/机构名**(如「Kenya Hara 式东方极简」,不是只说「极简主义」)
|
||||
- 50-100 字解释「为什么这个设计师适合你」
|
||||
- 3-4 条标志性视觉特征 + 3-5 个气质关键词 + 可选代表作
|
||||
|
||||
**差异化规则**(必守):3 个方向**必须来自 3 个不同流派**,形成明显视觉反差:
|
||||
|
||||
| 流派 | 视觉气质 | 适合作为 |
|
||||
|------|---------|---------|
|
||||
| 信息建筑派(01-04) | 理性、数据驱动、克制 | 安全/专业选择 |
|
||||
| 运动诗学派(05-08) | 动感、沉浸、技术美学 | 大胆/前卫选择 |
|
||||
| 极简主义派(09-12) | 秩序、留白、精致 | 安全/高端选择 |
|
||||
| 实验先锋派(13-16) | 先锋、生成艺术、视觉冲击 | 大胆/创新选择 |
|
||||
| 东方哲学派(17-20) | 温润、诗意、思辨 | 差异化/独特选择 |
|
||||
|
||||
❌ **禁止从同一流派推荐 2 个以上** — 差异化不够用户看不出区别。
|
||||
|
||||
详细 20 种风格库 + AI 提示词模板 → `references/design-styles.md`。
|
||||
|
||||
**Phase 4 · 展示预制 Showcase 画廊**
|
||||
|
||||
推荐 3 方向后,**立即检查** `assets/showcases/INDEX.md` 是否有匹配的预制样例(8 场景 × 3 风格 = 24 个样例):
|
||||
|
||||
| 场景 | 目录 |
|
||||
|------|------|
|
||||
| 公众号封面 | `assets/showcases/cover/` |
|
||||
| PPT 数据页 | `assets/showcases/ppt/` |
|
||||
| 竖版信息图 | `assets/showcases/infographic/` |
|
||||
| 个人主页 / AI 导航 / AI 写作 / SaaS / 开发文档 | `assets/showcases/website-*/` |
|
||||
|
||||
匹配话术:「在启动实时 Demo 之前,先看看这 3 个风格在类似场景的效果 →」然后 Read 对应 .png。
|
||||
|
||||
场景模板按输出类型组织 → `references/scene-templates.md`。
|
||||
|
||||
**Phase 5 · 生成 3 个视觉 Demo**
|
||||
|
||||
> 核心理念:**看到比说到更有效。** 别让用户凭文字想象,直接看。
|
||||
|
||||
为 3 个方向各生成一个 Demo——**如果当前 agent 支持 subagent 并行**,启动 3 个并行子任务(后台执行);**不支持就串行生成**(先后做 3 次,同样能用)。两种路径都能工作:
|
||||
- 使用**用户真实内容/主题**(不是 Lorem ipsum)
|
||||
- HTML 存 `_temp/design-demos/demo-[风格].html`
|
||||
- 截图:`npx playwright screenshot file:///path.html out.png --viewport-size=1200,900`
|
||||
- 全部完成后一起展示 3 张截图
|
||||
|
||||
风格类型路径:
|
||||
| 风格最佳路径 | Demo 生成方式 |
|
||||
|-------------|--------------|
|
||||
| HTML 型 | 生成完整 HTML → 截图 |
|
||||
| AI 生成型 | `nano-banana-pro` 用风格 DNA + 内容描述 |
|
||||
| 混合型 | HTML 布局 + AI 插画 |
|
||||
|
||||
**Phase 6 · 用户选择**:选一个深化 / 混合("A 的配色 + C 的布局")/ 微调 / 重来 → 回 Phase 3 重新推荐。
|
||||
|
||||
**Phase 7 · 生成 AI 提示词**
|
||||
结构:`[设计哲学约束] + [内容描述] + [技术参数]`
|
||||
- ✅ 用具体特征而非风格名(写「Kenya Hara 的留白感+赤土橙 #C04A1A」,不写「极简」)
|
||||
- ✅ 包含颜色 HEX、比例、空间分配、输出规格
|
||||
- ❌ 避开审美禁区(见反 AI slop)
|
||||
|
||||
**Phase 8 · 选定方向后进入主干**
|
||||
方向确认 → 回到「核心哲学」+「工作流程」的 Junior Designer pass。这时已经有明确的 design context,不再是凭空做。
|
||||
|
||||
**真实素材优先原则**(涉及用户本人/产品时):
|
||||
1. 先查用户配置的**私有 memory 路径**下的 `personal-asset-index.json`(Claude Code 默认在 `~/.claude/memory/`;其他 agent 按其自身约定)
|
||||
2. 首次使用:复制 `assets/personal-asset-index.example.json` 到上述私有路径,填入真实数据
|
||||
3. 找不到就直接问用户要,不要编造——真实数据文件不要放在 skill 目录内避免随分发泄露隐私
|
||||
|
||||
## App / iOS 原型专属守则
|
||||
|
||||
做 iOS/Android/移动 app 原型时(触发:「app 原型」「iOS mockup」「移动应用」「做个 app」),下面四条**覆盖**通用 placeholder 原则——app 原型是 demo 现场,静态摆拍和米白占位卡没有说服力。
|
||||
|
||||
### 0. 架构选型(必先决定)
|
||||
|
||||
**默认单文件 inline React**——所有 JSX/data/styles 直接写进主 HTML 的 `<script type="text/babel">...</script>` 标签,**不要**用 `<script src="components.jsx">` 外部加载。原因:`file://` 协议下浏览器把外部 JS 当跨 origin 拦截,强制用户起 HTTP server 违反「双击就能开」的原型直觉。引用本地图片必须 base64 内嵌 data URL,别假设有 server。
|
||||
|
||||
**拆外部文件只在两种情况**:
|
||||
- (a) 单文件 >1000 行难维护 → 拆成 `components.jsx` + `data.js`,同时明确交付说明(`python3 -m http.server` 命令 + 访问 URL)
|
||||
- (b) 需要多 subagent 并行写不同屏 → `index.html` + 每屏独立 HTML(`today.html`/`graph.html`...),iframe 聚合,每屏也都是自包含单文件
|
||||
|
||||
**选型速查**:
|
||||
|
||||
| 场景 | 架构 | 交付方式 |
|
||||
|------|------|----------|
|
||||
| 单人做 4-6 屏原型(主流) | 单文件 inline | 一个 `.html` 双击开 |
|
||||
| 单人做大型 App(>10 屏) | 多 jsx + server | 附启动命令 |
|
||||
| 多 agent 并行 | 多 HTML + iframe | `index.html` 聚合,每屏独立可开 |
|
||||
|
||||
### 1. 先找真图,不是 placeholder 摆着
|
||||
|
||||
默认主动去取真实图片填充,不要画 SVG、不要拿米白卡摆着、不要等用户要求。常用渠道:
|
||||
|
||||
| 场景 | 首选渠道 |
|
||||
|------|---------|
|
||||
| 美术/博物馆/历史内容 | Wikimedia Commons(公共领域)、Met Museum Open Access、Art Institute of Chicago API |
|
||||
| 通用生活/摄影 | Unsplash、Pexels(免版权) |
|
||||
| 用户本地已有素材 | `~/Downloads`、项目 `_archive/` 或用户配置的素材库 |
|
||||
|
||||
Wikimedia 下载避坑(本机 curl 走代理 TLS 会炸,Python urllib 直接走得通):
|
||||
|
||||
```python
|
||||
# 合规 User-Agent 是硬性要求,否则 429
|
||||
UA = 'ProjectName/0.1 (https://github.com/you; you@example.com)'
|
||||
# 用 MediaWiki API 查真实 URL
|
||||
api = 'https://commons.wikimedia.org/w/api.php'
|
||||
# action=query&list=categorymembers 批量拿系列 / prop=imageinfo+iiurlwidth 取指定宽度 thumburl
|
||||
```
|
||||
|
||||
**只有**当所有渠道都失败 / 版权不清 / 用户明确要求时,才退回诚实 placeholder(仍然不画烂 SVG)。
|
||||
|
||||
**真图诚实性测试**(关键):取图之前先问自己——「如果去掉这张图,信息是否有损?」
|
||||
|
||||
| 场景 | 判断 | 动作 |
|
||||
|------|------|------|
|
||||
| 文章/Essay 列表的封面、Profile 页的风景头图、设置页的装饰 banner | 装饰,与内容无内在关联 | **不要加**。加了就是 AI slop,等同紫色渐变 |
|
||||
| 博物馆/人物内容的肖像、产品详情的实物、地图卡片的地点 | 内容本身,有内在关联 | **必须加** |
|
||||
| 图谱/可视化背景的极淡纹理 | 氛围,服从内容不抢戏 | 加,但 opacity ≤ 0.08 |
|
||||
|
||||
**反例**:给文字 Essay 配 Unsplash「灵感图」、给笔记 App 配 stock photo 模特——都是 AI slop。取真图的许可不等于滥用真图的通行证。
|
||||
|
||||
### 2. 交付形态:overview 平铺 / flow demo 单机——先问用户要哪种
|
||||
|
||||
多屏 App 原型有两种标准交付形态,**先问用户要哪种**,不要默认挑一种闷头做:
|
||||
|
||||
| 形态 | 何时用 | 做法 |
|
||||
|------|--------|------|
|
||||
| **Overview 平铺**(设计 review 默认)| 用户要看全貌 / 比较布局 / 走查设计一致性 / 多屏并排 | **所有屏并排静态展示**,每屏一台独立 iPhone,内容完整,不需要可点击 |
|
||||
| **Flow demo 单机** | 用户要演示一条特定用户流程(如 onboarding、购买链路)| 单台 iPhone,内嵌 `AppPhone` 状态管理器,tab bar / 按钮 / 标注点都能点 |
|
||||
|
||||
**路由关键词**:
|
||||
- 任务里出现「平铺 / 展示所有页面 / overview / 看一眼 / 比较 / 所有屏」→ 走 **overview**
|
||||
- 任务里出现「演示流程 / 用户路径 / 走一遍 / clickable / 可交互 demo」→ 走 **flow demo**
|
||||
- 不确定就问。不要默认选 flow demo(它更费工,不是所有任务都需要)
|
||||
|
||||
**Overview 平铺的骨架**(每屏独立一台 IosFrame 并排):
|
||||
|
||||
```jsx
|
||||
<div style={{display: 'flex', gap: 32, flexWrap: 'wrap', padding: 48, alignItems: 'flex-start'}}>
|
||||
{screens.map(s => (
|
||||
<div key={s.id}>
|
||||
<div style={{fontSize: 13, color: '#666', marginBottom: 8, fontStyle: 'italic'}}>{s.label}</div>
|
||||
<IosFrame>
|
||||
<ScreenComponent data={s} />
|
||||
</IosFrame>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
```
|
||||
|
||||
**Flow demo 的骨架**(单台 clickable 状态机):
|
||||
|
||||
```jsx
|
||||
function AppPhone({ initial = 'today' }) {
|
||||
const [screen, setScreen] = React.useState(initial);
|
||||
const [modal, setModal] = React.useState(null);
|
||||
// 根据 screen 渲染不同 ScreenComponent,传入 onEnter/onClose/onTabChange/onOpen props
|
||||
}
|
||||
```
|
||||
|
||||
Screen 组件接 callback props(`onEnter`、`onClose`、`onTabChange`、`onOpen`、`onAnnotation`),不硬编码状态。TabBar、按钮、作品卡加 `cursor: pointer` + hover 反馈。
|
||||
|
||||
### 3. 交付前跑真实点击测试
|
||||
|
||||
静态截图只能看 layout,交互 bug 要点过才发现。用 Playwright 跑 3 项最小点击测试:进入详情 / 关键标注点 / tab 切换。检查 `pageerror` 为 0 再交付。Playwright 可用 `npx playwright` 调用,或按本机全局安装路径(`npm root -g` + `/playwright`)。
|
||||
|
||||
### 4. 品位锚点(pursue list,fallback 首选)
|
||||
|
||||
没有 design system 时默认往这些方向走,避免撞 AI slop:
|
||||
|
||||
| 维度 | 首选 | 避免 |
|
||||
|------|------|------|
|
||||
| **字体** | 衬线 display(Newsreader/Source Serif/EB Garamond)+ `-apple-system` body | 全场 SF Pro 或 Inter——太像系统默认,没风格 |
|
||||
| **色彩** | 一个有温度的底色 + **单个** accent 贯穿全场(rust 橙/墨绿/深红)| 多色聚类(除非数据真的有 ≥3 个分类维度) |
|
||||
| **信息密度·克制型**(默认)| 少一层容器、少一个 border、少一个**装饰性** icon——给内容留气口 | 每条卡片都配无意义的 icon + tag + status dot |
|
||||
| **信息密度·高密度型**(例外)| 当产品核心卖点是「智能 / 数据 / 上下文感知」时(AI 工具、Dashboard、Tracker、Copilot、番茄钟、健康监测、记账类),每屏需**至少 3 处可见的产品差异化信息**:非装饰性数据、对话/推理片段、状态推断、上下文关联 | 只放一个按钮一个时钟——AI 的智能感没表达出来,跟普通 App 没区别 |
|
||||
| **细节签名** | 留一处「值得截图」的质感:极淡油画底纹 / serif 斜体引语 / 全屏黑底录音波形 | 到处平均用力,结果处处平淡 |
|
||||
|
||||
**两条原则同时生效**:
|
||||
1. 品位 = 一个细节做到 120%,其它做到 80%——不是所有地方都精致,而是在合适的地方足够精致
|
||||
2. 减法是 fallback,不是普适律——产品核心卖点需要信息密度支撑时(AI / 数据 / 上下文感知类),加法优先于克制。详见下文「信息密度分型」
|
||||
|
||||
### 5. iOS 设备框必须用 `assets/ios_frame.jsx`——禁止手写 Dynamic Island / status bar
|
||||
|
||||
做 iPhone mockup 时**硬性绑定** `assets/ios_frame.jsx`。这是已经对齐过 iPhone 15 Pro 精确规格的标准外壳:bezel、Dynamic Island(124×36、top:12、居中)、status bar(时间/信号/电池、两侧避让岛、vertical center 对齐岛中线)、Home Indicator、content 区 top padding 都处理好了。
|
||||
|
||||
**禁止在你的 HTML 里自己写**以下任何一项:
|
||||
- `.dynamic-island` / `.island` / `position: absolute; top: 11/12px; width: ~120; 居中的黑圆角矩形`
|
||||
- `.status-bar` with 手写的时间/信号/电池图标
|
||||
- `.home-indicator` / 底部 home bar
|
||||
- iPhone bezel 的圆角外框 + 黑描边 + shadow
|
||||
|
||||
自己写 99% 会撞位置 bug——status bar 的时间/电池被岛挤压、或 content top padding 算错导致第一行内容盖在岛下。iPhone 15 Pro 的刘海是**固定 124×36 像素**,留给 status bar 两侧的可用宽度很窄,不是你凭空估的。
|
||||
|
||||
**用法(严格三步)**:
|
||||
|
||||
```jsx
|
||||
// 步骤 1: Read 本 skill 的 assets/ios_frame.jsx(相对本 SKILL.md 的路径)
|
||||
// 步骤 2: 把整个 iosFrameStyles 常量 + IosFrame 组件贴进你的 <script type="text/babel">
|
||||
// 步骤 3: 你自己的屏组件包在 <IosFrame>...</IosFrame> 里,不碰 island/status bar/home indicator
|
||||
<IosFrame time="9:41" battery={85}>
|
||||
<YourScreen /> {/* 内容从 top 54 开始渲染,下边留给 home indicator,你不用管 */}
|
||||
</IosFrame>
|
||||
```
|
||||
|
||||
**例外**:只有用户明确要求「假装是 iPhone 14 非 Pro 的刘海」「做 Android 不是 iOS」「自定义设备形态」时才绕过——此时读对应 `android_frame.jsx` 或修改 `ios_frame.jsx` 的常量,**不要**在项目 HTML 里另起一套 island/status bar。
|
||||
|
||||
## 工作流程
|
||||
|
||||
### 标准流程(用TaskCreate追踪)
|
||||
|
||||
1. **理解需求**:
|
||||
- 🔍 **0. 事实验证(涉及具体产品/技术时必做,优先级最高)**:任务涉及具体产品/技术/事件(DJI Pocket 4、Gemini 3 Pro、Nano Banana Pro、某新 SDK 等)时,**第一个动作**是 `WebSearch` 验证其存在性、发布状态、最新版本、关键规格。把事实写入 `product-facts.md`。详见「核心原则 #0」。**这步做在问 clarifying questions 之前**——事实错了问什么都歪。
|
||||
- 新任务或模糊任务必须问clarifying questions,详见 `references/workflow.md`。一次focused一轮问题通常够,小修小补跳过。
|
||||
- 🛑 **检查点1:问题清单一次性发给用户,等用户批量答完再往下走**。不要边问边做。
|
||||
- 🛑 **幻灯片/PPT 任务:HTML 聚合演示版永远是默认基础产物**(不管用户最终要什么格式):
|
||||
- **必做**:每页独立 HTML + `assets/deck_index.html` 聚合(重命名为 `index.html`,编辑 MANIFEST 列所有页),浏览器里键盘翻页、全屏演讲——这是幻灯片作品的"源"
|
||||
- **可选导出**:额外询问是否需要 PDF(`export_deck_pdf.mjs`)或可编辑 PPTX(`export_deck_pptx.mjs`)作为衍生物
|
||||
- **只有要可编辑 PPTX 时**,HTML 必须从第一行就按 4 条硬约束写(见 `references/editable-pptx.md`);事后补救会 2-3 小时返工
|
||||
- **≥ 5 页 deck 必须先做 2 页 showcase 定 grammar 再批量推**(见 `references/slide-decks.md` 的「批量制作前先做 showcase」章节)——跳过这步 = 方向错返工 N 次而非 2 次
|
||||
- 详见 `references/slide-decks.md` 开头「HTML 优先架构 + 交付格式决策树」
|
||||
- ⚡ **如果用户需求严重模糊(没参考、没明确风格、"做个好看的"类)→ 走「设计方向顾问(Fallback 模式)」大节,完成 Phase 1-4 选定方向后,再回到这里 Step 2**。
|
||||
2. **探索资源 + 抽核心资产**(不只是抽色值):读 design system、linked files、上传的截图/代码。**涉及具体品牌时必走 §1.a「核心资产协议」五步**(问→按类型搜→按类型下载 logo/产品图/UI→验证+提取→写 `brand-spec.md` 含所有资产路径)。
|
||||
- 🛑 **检查点2·资产自检**:开工前确认核心资产到位——实体产品要有产品图(不是 CSS 剪影)、数字产品要有 logo+UI 截图、色值从真实 HTML/SVG 抽取。缺了就停下补,不硬做。
|
||||
- 如果用户没给 context 且挖不出资产,先走设计方向顾问 Fallback,再按 `references/design-context.md` 的品位锚点兜底。
|
||||
3. **先答四问,再规划系统**:**这一步的前半段比所有 CSS 规则更决定输出**。
|
||||
|
||||
📐 **位置四问**(每个页面/屏幕/镜头开工前必答):
|
||||
- **叙事角色**:hero / 过渡 / 数据 / 引语 / 结尾?(一页 deck 里每页都不一样)
|
||||
- **观众距离**:10cm 手机 / 1m 笔记本 / 10m 投屏?(决定字号和信息密度)
|
||||
- **视觉温度**:安静 / 兴奋 / 冷静 / 权威 / 温柔 / 悲伤?(决定配色和节奏)
|
||||
- **容量估算**:用纸笔画 3 个 5 秒 thumbnail 算一下内容塞得下吗?(防溢出 / 防挤压)
|
||||
|
||||
四问答完再 vocalize 设计系统(色彩/字型/layout 节奏/component pattern)——**系统要服务于答案,不是先选系统再塞内容**。
|
||||
|
||||
🛑 **检查点2:四问答案 + 系统口头说出来等用户点头,再动手写代码**。方向错了晚改比早改贵 100 倍。
|
||||
4. **构建文件夹结构**:`项目名/` 下放主HTML、需要的assets拷贝(不要bulk copy >20个文件)。
|
||||
5. **Junior pass**:HTML里写assumptions+placeholders+reasoning comments。
|
||||
🛑 **检查点3:尽早show给用户(哪怕只是灰色方块+标签),等反馈再写组件**。
|
||||
6. **Full pass**:填placeholder,做variations,加Tweaks。做到一半再show一次,不要等全做完。
|
||||
7. **验证**:用Playwright截图(见 `references/verification.md`),检查控制台错误,发给用户。
|
||||
🛑 **检查点4:交付前自己肉眼过一遍浏览器**。AI写的代码经常有interaction bug。
|
||||
8. **总结**:极简,只说caveats和next steps。
|
||||
9. **(默认)导出视频 · 必带 SFX + BGM**:动画 HTML 的**默认交付形态是带音频的 MP4**,不是纯画面。无声版本等于半成品——用户潜意识感知「画在动但没声音响应」,廉价感的根源就在这里。流水线:
|
||||
- `scripts/render-video.js` 录 25fps 纯画面 MP4(只是中间产物,**不是成品**)
|
||||
- `scripts/convert-formats.sh` 派生 60fps MP4 + palette 优化 GIF(视平台需要)
|
||||
- `scripts/add-music.sh` 加 BGM(6 首场景化配乐:tech/ad/educational/tutorial + alt 变体)
|
||||
- SFX 按 `references/audio-design-rules.md` 设计 cue 清单(时间轴 + 音效类型),用 `assets/sfx/<category>/*.mp3` 37 个预制资源,按配方 A/B/C/D 选密度(发布 hero ≈ 6个/10s,工具演示 ≈ 0-2个/10s)
|
||||
- **BGM + SFX 双轨制必须同时做**——只做 BGM 是 ⅓ 分完成度;SFX 占高频、BGM 占低频,频段隔离见 audio-design-rules.md 的 ffmpeg 模板
|
||||
- 交付前 `ffprobe -select_streams a` 确认有 audio stream,没有则不是成品
|
||||
- **跳过音频的条件**:用户明确说「不要音频」「纯画面」「我要自己配音」——否则默认带。
|
||||
- 参考完整流程见 `references/video-export.md` + `references/audio-design-rules.md` + `references/sfx-library.md`。
|
||||
10. **(可选)专家评审**:用户若提「评审」「好不好看」「review」「打分」,或你对产出有疑问想主动质检,按 `references/critique-guide.md` 走 5 维度评审——哲学一致性 / 视觉层级 / 细节执行 / 功能性 / 创新性各 0-10 分,输出总评 + Keep(做得好的)+ Fix(严重程度 ⚠️致命 / ⚡重要 / 💡优化)+ Quick Wins(5 分钟能做的前 3 件事)。评审设计不评设计师。
|
||||
|
||||
**检查点原则**:碰到🛑就停下,明确告诉用户"我做了X,下一步打算Y,你确认吗?"然后真的**等**。不要说完自己就开始做。
|
||||
|
||||
### 问问题的要点
|
||||
|
||||
必问(用`references/workflow.md`里的模板):
|
||||
- design system/UI kit/codebase有吗?没有的话先去找
|
||||
- 想要几种variations?在哪些维度上变?
|
||||
- 关心flow、copy、还是visuals?
|
||||
- 希望Tweak什么?
|
||||
|
||||
## 异常处理
|
||||
|
||||
流程假设用户配合、环境正常。实操常遇以下异常,预定义fallback:
|
||||
|
||||
| 场景 | 触发条件 | 处理动作 |
|
||||
|------|---------|---------|
|
||||
| 需求模糊到无法着手 | 用户只给一句模糊描述(如"做个好看的页面") | 主动列3个可能方向让用户选(如"落地页 / Dashboard / 产品详情页"),而不是直接问10个问题 |
|
||||
| 用户拒绝回答问题清单 | 用户说"不要问了,直接做" | 尊重节奏,用best judgment做1个主方案+1个差异明显的变体,交付时**明确标注assumption**,方便用户定位要改哪里 |
|
||||
| Design context矛盾 | 用户给的参考图和品牌规范打架 | 停下,指出具体矛盾("截图里字体是衬线,规范说用sans"),让用户选一个 |
|
||||
| Starter component加载失败 | 控制台404/integrity mismatch | 先查`references/react-setup.md`常见报错表;还不行降级纯HTML+CSS不用React,保证产出可用 |
|
||||
| 时间紧迫要快交付 | 用户说"30分钟内要" | 跳过Junior pass直接Full pass,只做1个方案,交付时**明确标注"未经early validation"**,提醒用户质量可能打折 |
|
||||
| SKILL.md体积超限 | 新写HTML>1000行 | 按`references/react-setup.md`的拆分策略拆成多jsx文件,末尾`Object.assign(window,...)`共享 |
|
||||
| 克制原则 vs 产品所需密度冲突 | 产品核心卖点是 AI 智能 / 数据可视化 / 上下文感知(如番茄钟、Dashboard、Tracker、AI agent、Copilot、记账、健康监测)| 按「品位锚点」表格走**高密度型**信息密度:每屏 ≥ 3 处产品差异化信息。装饰性 icon 照样忌讳——加的是**有内容的**密度,不是装饰 |
|
||||
|
||||
**原则**:异常时**先告诉用户发生了什么**(1句话),再按表处理。不要静默决策。
|
||||
|
||||
## 反AI slop速查
|
||||
|
||||
| 类别 | 避免 | 采用 |
|
||||
|------|------|------|
|
||||
| 字体 | Inter/Roboto/Arial/系统字体 | 有特点的display+body配对 |
|
||||
| 色彩 | 紫色渐变、凭空新颜色 | 品牌色/oklch定义的和谐色 |
|
||||
| 容器 | 圆角+左border accent | 诚实的边界/分隔 |
|
||||
| 图像 | SVG画人画物 | 真实素材或placeholder |
|
||||
| 图标 | **装饰性** icon 每处都配(撞 slop)| **承载差异化信息**的密度元素必须保留——不要把产品特色也一并减掉 |
|
||||
| 填充 | 编造stats/quotes装饰 | 留白,或问用户要真内容 |
|
||||
| 动画 | 散落的微交互 | 一次well-orchestrated的page load |
|
||||
| 动画-伪chrome | 画面内画底部进度条/时间码/版权署名条(与 Stage scrubber 撞车) | 画面只放叙事内容,进度/时间交给 Stage chrome(详见 `references/animation-pitfalls.md` §11) |
|
||||
|
||||
## 技术红线(必读 references/react-setup.md)
|
||||
|
||||
**React+Babel项目**必须用pinned版本(见`react-setup.md`)。三条不可违反:
|
||||
|
||||
1. **never** 写 `const styles = {...}`——多组件时命名冲突会炸。**必须**给唯一名字:`const terminalStyles = {...}`
|
||||
2. **scope不共享**:多个`<script type="text/babel">`之间组件不通,必须用`Object.assign(window, {...})`导出
|
||||
3. **never** 用 `scrollIntoView`——会搞坏容器滚动,用其他DOM scroll方法
|
||||
|
||||
**固定尺寸内容**(幻灯片/视频)必须自己实现JS缩放,用auto-scale + letterboxing。
|
||||
|
||||
**幻灯片架构选型(必先决定)**:
|
||||
- **多文件**(默认,≥10页 / 学术/课件 / 多agent并行)→ 每页独立HTML + `assets/deck_index.html`拼接器
|
||||
- **单文件**(≤10页 / pitch deck / 需跨页共享状态)→ `assets/deck_stage.js` web component
|
||||
|
||||
先读 `references/slide-decks.md` 的「🛑 先定架构」一节,错了会反复踩 CSS 特异性/作用域的坑。
|
||||
|
||||
## Starter Components(assets/下)
|
||||
|
||||
造好的起手组件,直接copy进项目使用:
|
||||
|
||||
| 文件 | 何时用 | 提供 |
|
||||
|------|--------|------|
|
||||
| `deck_index.html` | **幻灯片的默认基础产物**(不管最终出 PDF 还是 PPTX,HTML 聚合版永远先做) | iframe拼接 + 键盘导航 + scale + 计数器 + 打印合并,每页独立HTML免CSS串扰。用法:复制为 `index.html`、编辑 MANIFEST 列出所有页、浏览器打开即成演示版 |
|
||||
| `deck_stage.js` | 做幻灯片(单文件架构,≤10页) | web component:auto-scale + 键盘导航 + slide counter + localStorage + speaker notes ⚠️ **script 必须放在 `</deck-stage>` 之后,section 的 `display: flex` 必须写到 `.active` 上**,详见 `references/slide-decks.md` 的两个硬约束 |
|
||||
| `scripts/export_deck_pdf.mjs` | **HTML→PDF 导出(多文件架构)** · 每页独立 HTML 文件,playwright 逐个 `page.pdf()` → pdf-lib 合并。文字保留矢量可搜。依赖 `playwright pdf-lib` |
|
||||
| `scripts/export_deck_stage_pdf.mjs` | **HTML→PDF 导出(单文件 deck-stage 架构专用)** · 2026-04-20 新增。处理 shadow DOM slot 导致的「只出 1 页」、absolute 子元素溢出等坑。详见 `references/slide-decks.md` 末节。依赖 `playwright` |
|
||||
| `scripts/export_deck_pptx.mjs` | **HTML→可编辑 PPTX 导出** · 调 `html2pptx.js` 导出原生可编辑文本框,文字在 PPT 里双击可直接编辑。**HTML 必须符合 4 条硬约束**(见 `references/editable-pptx.md`),视觉自由度优先的场景请改走 PDF 路径。依赖 `playwright pptxgenjs sharp` |
|
||||
| `scripts/html2pptx.js` | **HTML→PPTX 元素级翻译器** · 读 computedStyle 把 DOM 逐元素翻译成 PowerPoint 对象(text frame / shape / picture)。`export_deck_pptx.mjs` 内部调用。要求 HTML 严格满足 4 条硬约束 |
|
||||
| `design_canvas.jsx` | 并排展示≥2个静态variations | 带label的网格布局 |
|
||||
| `animations.jsx` | 任何动画HTML | Stage + Sprite + useTime + Easing + interpolate |
|
||||
| `ios_frame.jsx` | iOS App mockup | iPhone bezel + 状态栏 + 圆角 |
|
||||
| `android_frame.jsx` | Android App mockup | 设备bezel |
|
||||
| `macos_window.jsx` | 桌面App mockup | 窗口chrome + 红绿灯 |
|
||||
| `browser_window.jsx` | 网页在浏览器里的样子 | URL bar + tab bar |
|
||||
|
||||
用法:读取对应 assets 文件内容 → inline 进你的 HTML `<script>` 标签 → slot 进你的设计。
|
||||
|
||||
## References路由表
|
||||
|
||||
根据任务类型深入读对应references:
|
||||
|
||||
| 任务 | 读 |
|
||||
|------|-----|
|
||||
| 开工前问问题、定方向 | `references/workflow.md` |
|
||||
| 反AI slop、内容规范、scale | `references/content-guidelines.md` |
|
||||
| React+Babel项目setup | `references/react-setup.md` |
|
||||
| 做幻灯片 | `references/slide-decks.md` + `assets/deck_stage.js` |
|
||||
| 导出可编辑 PPTX(html2pptx 4 条硬约束) | `references/editable-pptx.md` + `scripts/html2pptx.js` |
|
||||
| 做动画/motion(**先读 pitfalls**)| `references/animation-pitfalls.md` + `references/animations.md` + `assets/animations.jsx` |
|
||||
| **动画的正向设计语法**(Anthropic 级叙事/运动/节奏/表达风格)| `references/animation-best-practices.md`(5 段叙事+Expo easing+运动语言 8 条+3 种场景配方)|
|
||||
| 做Tweaks实时调参 | `references/tweaks-system.md` |
|
||||
| 没有design context怎么办 | `references/design-context.md`(薄 fallback) 或 `references/design-styles.md`(厚 fallback:20 种设计哲学详细库) |
|
||||
| **需求模糊要推荐风格方向** | `references/design-styles.md`(20 种风格+AI prompt 模板)+ `assets/showcases/INDEX.md`(24 个预制样例) |
|
||||
| **按输出类型查场景模板**(封面/PPT/信息图) | `references/scene-templates.md` |
|
||||
| 输出完后验证 | `references/verification.md` + `scripts/verify.py` |
|
||||
| **设计评审/打分**(设计完成后可选) | `references/critique-guide.md`(5 维度评分+常见问题清单) |
|
||||
| **动画导出MP4/GIF/加BGM** | `references/video-export.md` + `scripts/render-video.js` + `scripts/convert-formats.sh` + `scripts/add-music.sh` |
|
||||
| **动画加音效SFX**(苹果发布会级,37个预制) | `references/sfx-library.md` + `assets/sfx/<category>/*.mp3` |
|
||||
| **动画音频配置规则**(SFX+BGM双轨制、黄金配比、ffmpeg模板、场景配方) | `references/audio-design-rules.md` |
|
||||
| **Apple画廊展示风格**(3D倾斜+悬浮卡片+缓慢pan+焦点切换,v9实战同款) | `references/apple-gallery-showcase.md` |
|
||||
| **Gallery Ripple + Multi-Focus 场景哲学**(当素材 20+ 同质+场景需表达「规模×深度」时优先用;含前置条件、技术配方、5 个可复用模式)| `references/hero-animation-case-study.md`(huashu-design hero v9 蒸馏)|
|
||||
|
||||
## 跨 Agent 环境适配说明
|
||||
|
||||
本 skill 设计为 **agent-agnostic**——Claude Code、Codex、Cursor、Trae、OpenClaw、Hermes Agent 或任何支持 markdown-based skill 的 agent 都可以使用。以下是和原生「设计型 IDE」(如 Claude.ai Artifacts)对比时的通用差异处理方式:
|
||||
|
||||
- **没有内置的 fork-verifier agent**:用 `scripts/verify.py`(Playwright 封装)人工驱动验证
|
||||
- **没有 asset 注册到 review pane**:直接用 agent 的 Write 能力写文件,用户在自己的浏览器/IDE 里打开
|
||||
- **没有 Tweaks host postMessage**:改成**纯前端 localStorage 版**,详见 `references/tweaks-system.md`
|
||||
- **没有 `window.claude.complete` 免配置 helper**:若 HTML 里要调 LLM,用一个可复用的 mock 或让用户填自己的 API key,详见 `references/react-setup.md`
|
||||
- **没有结构化问题 UI**:在对话里用 markdown 清单问问题,参考 `references/workflow.md` 的模板
|
||||
|
||||
Skill 路径引用均采用**相对本 skill 根目录**的形式(`references/xxx.md`、`assets/xxx.jsx`、`scripts/xxx.sh`)——agent 或用户按自身安装位置解析,不依赖任何绝对路径。
|
||||
|
||||
## 产出要求
|
||||
|
||||
- HTML文件命名描述性:`Landing Page.html`、`iOS Onboarding v2.html`
|
||||
- 大改版时copy一份旧版保留:`My Design.html` → `My Design v2.html`
|
||||
- 避免>1000行的大文件,拆成多个JSX文件import进主文件
|
||||
- 幻灯片、动画等固定尺寸内容,**播放位置**存localStorage——刷新不丢
|
||||
- HTML放项目目录,不要散落到`~/Downloads`
|
||||
- 最终产出用浏览器打开检查或用Playwright截图
|
||||
|
||||
## Skill 推广水印(仅动画产出)
|
||||
|
||||
**只在动画产出**(HTML 动画 → MP4 / GIF)默认带「**Created by Huashu-Design**」水印,辅助 skill 传播。**幻灯片 / 信息图 / 原型 / 网页等其他场景不加**——加了反而干扰用户实际使用。
|
||||
|
||||
- **必带场景**:HTML 动画 → 导出 MP4 / GIF(用户会拿去公众号、X、B站传播,水印能跟着流通)
|
||||
- **不带场景**:幻灯片(用户自己讲)、信息图(嵌文章)、App / 网页原型(设计 review)、配图
|
||||
- **第三方品牌的非官方致敬动画**:水印前加「非官方出品 · 」前缀,避免被误认为官方物料引发 IP 争议
|
||||
- **用户明确说"不要水印"**:尊重,移除
|
||||
- **水印模板**:
|
||||
```jsx
|
||||
<div style={{
|
||||
position: 'absolute', bottom: 24, right: 32,
|
||||
fontSize: 11, color: 'rgba(0,0,0,0.4)' /* 深底用 rgba(255,255,255,0.35) */,
|
||||
letterSpacing: '0.15em', fontFamily: 'monospace',
|
||||
pointerEvents: 'none', zIndex: 100,
|
||||
}}>
|
||||
Created by Huashu-Design
|
||||
{/* 第三方品牌动画前缀「非官方出品 · 」*/}
|
||||
</div>
|
||||
```
|
||||
|
||||
## 核心提醒
|
||||
|
||||
- **事实验证先于假设**(核心原则 #0):涉及具体产品/技术/事件(DJI Pocket 4、Gemini 3 Pro 等)必须先 `WebSearch` 验证存在性和状态,不凭训练语料断言。
|
||||
- **Embody专家**:做幻灯片时是幻灯片设计师,做动画时是动画师。不是写Web UI。
|
||||
- **Junior先show,再做**:先展示思路,再执行。
|
||||
- **Variations不给答案**:3+个变体,让用户选。
|
||||
- **Placeholder优于烂实现**:诚实留白,不编造。
|
||||
- **反AI slop时时警醒**:每个渐变/emoji/圆角border accent之前先问——这真的必要吗?
|
||||
- **涉及具体品牌**:走「核心资产协议」(§1.a)——Logo(必需)+ 产品图(实体产品必需)+ UI 截图(数字产品必需),色值只是辅助。**不要用 CSS 剪影代替真实产品图**。
|
||||
- **做动画之前**:必读 `references/animation-pitfalls.md`——里面 14 条规则每条都来自真实踩过的坑,跳过会让你重做 1-3 轮。
|
||||
- **手写 Stage / Sprite**(不用 `assets/animations.jsx`):必须实现两件事——(a) tick 第一帧同步设 `window.__ready = true` (b) 检测 `window.__recording === true` 时强制 loop=false。否则录视频必出问题。
|
||||
@ -1,175 +0,0 @@
|
||||
/**
|
||||
* AndroidFrame — Android设备边框(参考Pixel 8系列)
|
||||
*
|
||||
* 含:punch-hole相机 + 状态栏 + 导航栏 + 圆角
|
||||
*
|
||||
* 用法:
|
||||
* <AndroidFrame time="9:41" battery={85}>
|
||||
* <YourAppContent />
|
||||
* </AndroidFrame>
|
||||
*/
|
||||
|
||||
const androidFrameStyles = {
|
||||
wrapper: {
|
||||
display: 'inline-block',
|
||||
padding: 10,
|
||||
background: '#1a1a1a',
|
||||
borderRadius: 44,
|
||||
boxShadow: '0 0 0 2px #2a2a2a, 0 20px 60px rgba(0,0,0,0.3)',
|
||||
position: 'relative',
|
||||
},
|
||||
screen: {
|
||||
position: 'relative',
|
||||
borderRadius: 36,
|
||||
overflow: 'hidden',
|
||||
background: '#fff',
|
||||
},
|
||||
statusBar: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: 32,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
padding: '0 24px',
|
||||
fontSize: 14,
|
||||
fontWeight: 500,
|
||||
fontFamily: 'Roboto, -apple-system, sans-serif',
|
||||
zIndex: 20,
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
punchHole: {
|
||||
position: 'absolute',
|
||||
top: 10,
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
width: 14,
|
||||
height: 14,
|
||||
background: '#000',
|
||||
borderRadius: '50%',
|
||||
zIndex: 30,
|
||||
},
|
||||
statusIcons: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 6,
|
||||
},
|
||||
batteryText: {
|
||||
fontSize: 11,
|
||||
fontWeight: 600,
|
||||
marginLeft: 2,
|
||||
},
|
||||
content: {
|
||||
position: 'absolute',
|
||||
top: 32,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 24,
|
||||
overflow: 'auto',
|
||||
},
|
||||
navBar: {
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: 24,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 60,
|
||||
zIndex: 10,
|
||||
},
|
||||
navButton: {
|
||||
width: 36,
|
||||
height: 4,
|
||||
background: 'rgba(0,0,0,0.3)',
|
||||
borderRadius: 999,
|
||||
},
|
||||
};
|
||||
|
||||
function AndroidFrame({
|
||||
children,
|
||||
width = 412,
|
||||
height = 892,
|
||||
time = '9:41',
|
||||
battery = 100,
|
||||
darkMode = false,
|
||||
navStyle = 'gesture',
|
||||
}) {
|
||||
const textColor = darkMode ? '#fff' : '#1a1a1a';
|
||||
|
||||
return (
|
||||
<div style={androidFrameStyles.wrapper}>
|
||||
<div style={{
|
||||
...androidFrameStyles.screen,
|
||||
width,
|
||||
height,
|
||||
background: darkMode ? '#000' : '#fff',
|
||||
}}>
|
||||
<div style={{ ...androidFrameStyles.statusBar, color: textColor }}>
|
||||
<span>{time}</span>
|
||||
<div style={androidFrameStyles.statusIcons}>
|
||||
<svg width="14" height="10" viewBox="0 0 14 10" fill="currentColor">
|
||||
<rect x="0" y="6" width="2" height="4" rx="0.5" />
|
||||
<rect x="4" y="4" width="2" height="6" rx="0.5" />
|
||||
<rect x="8" y="2" width="2" height="8" rx="0.5" />
|
||||
<rect x="12" y="0" width="2" height="10" rx="0.5" />
|
||||
</svg>
|
||||
<svg width="14" height="10" viewBox="0 0 14 10" fill="none">
|
||||
<path d="M7 9a1 1 0 100-2 1 1 0 000 2z" fill="currentColor" />
|
||||
<path d="M3 6a5 5 0 018 0" stroke="currentColor" strokeWidth="1.2" />
|
||||
<path d="M0.5 3.5a11 11 0 0113 0" stroke="currentColor" strokeWidth="1.2" opacity="0.6" />
|
||||
</svg>
|
||||
<div style={{
|
||||
width: 22,
|
||||
height: 10,
|
||||
border: '1.5px solid currentColor',
|
||||
borderRadius: 2,
|
||||
padding: 1,
|
||||
position: 'relative',
|
||||
}}>
|
||||
<div style={{
|
||||
width: `${battery}%`,
|
||||
height: '100%',
|
||||
background: 'currentColor',
|
||||
borderRadius: 1,
|
||||
}} />
|
||||
</div>
|
||||
<span style={androidFrameStyles.batteryText}>{battery}%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={androidFrameStyles.punchHole} />
|
||||
|
||||
<div style={androidFrameStyles.content}>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
{navStyle === 'gesture' && (
|
||||
<div style={androidFrameStyles.navBar}>
|
||||
<div style={{
|
||||
...androidFrameStyles.navButton,
|
||||
width: 100,
|
||||
height: 4,
|
||||
background: darkMode ? 'rgba(255,255,255,0.5)' : 'rgba(0,0,0,0.4)',
|
||||
}} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{navStyle === 'buttons' && (
|
||||
<div style={androidFrameStyles.navBar}>
|
||||
<span style={{ color: textColor, fontSize: 20 }}>◁</span>
|
||||
<span style={{ color: textColor, fontSize: 16 }}>○</span>
|
||||
<span style={{ color: textColor, fontSize: 16 }}>□</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.AndroidFrame = AndroidFrame;
|
||||
}
|
||||
@ -1,340 +0,0 @@
|
||||
/**
|
||||
* animations.jsx — 时间轴动画引擎
|
||||
*
|
||||
* Stage + Sprite 模式,借鉴Remotion但轻量化。
|
||||
*
|
||||
* 导出(挂到 window.Animations):
|
||||
* - Stage: 整个动画容器,提供时间+控制
|
||||
* - Sprite: 时间片段,start/end内显示,提供本地进度
|
||||
* - useTime(): 读全局时间(秒)
|
||||
* - useSprite(): 读本地进度 {t: 0→1, elapsed: seconds, duration: seconds}
|
||||
* - Easing: {linear, easeIn, easeOut, easeInOut, spring, anticipation}
|
||||
* - interpolate(t, [input0, input1], [output0, output1], easing?)
|
||||
*
|
||||
* 用法:
|
||||
* <Stage duration={10}>
|
||||
* <Sprite start={0} end={3}>
|
||||
* <Title />
|
||||
* </Sprite>
|
||||
* <Sprite start={2} end={5}>
|
||||
* <Subtitle />
|
||||
* </Sprite>
|
||||
* </Stage>
|
||||
*
|
||||
* 在Sprite子组件里用 useSprite() 读当前片段进度。
|
||||
*/
|
||||
|
||||
(function() {
|
||||
const { createContext, useContext, useState, useEffect, useRef, useCallback } = React;
|
||||
|
||||
const TimeContext = createContext({ time: 0, duration: 10, playing: false });
|
||||
const SpriteContext = createContext(null);
|
||||
|
||||
const Easing = {
|
||||
linear: t => t,
|
||||
easeIn: t => t * t,
|
||||
easeOut: t => 1 - (1 - t) * (1 - t),
|
||||
easeInOut: t => t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2,
|
||||
// expoOut: Anthropic-level 主 easing (cubic-bezier(0.16, 1, 0.3, 1))
|
||||
// 迅速启动 + 缓慢刹车,给数字元素物理重量感
|
||||
expoOut: t => t === 1 ? 1 : 1 - Math.pow(2, -10 * t),
|
||||
// overshoot: 带弹性的 toggle/按钮弹出 (cubic-bezier(0.34, 1.56, 0.64, 1))
|
||||
overshoot: t => {
|
||||
const c1 = 1.70158, c3 = c1 + 1;
|
||||
return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
|
||||
},
|
||||
spring: t => {
|
||||
const c = (2 * Math.PI) / 3;
|
||||
return t === 0 ? 0 : t === 1 ? 1 : Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c) + 1;
|
||||
},
|
||||
anticipation: t => {
|
||||
if (t < 0.2) return -0.3 * (t / 0.2) * (t / 0.2);
|
||||
const adjusted = (t - 0.2) / 0.8;
|
||||
return -0.012 + 1.012 * adjusted * adjusted * (3 - 2 * adjusted);
|
||||
},
|
||||
};
|
||||
|
||||
function interpolate(t, input, output, easing) {
|
||||
const [inStart, inEnd] = input;
|
||||
const [outStart, outEnd] = output;
|
||||
|
||||
if (t <= inStart) return outStart;
|
||||
if (t >= inEnd) return outEnd;
|
||||
|
||||
let progress = (t - inStart) / (inEnd - inStart);
|
||||
if (easing) {
|
||||
progress = easing(progress);
|
||||
}
|
||||
|
||||
return outStart + (outEnd - outStart) * progress;
|
||||
}
|
||||
|
||||
function useTime() {
|
||||
const ctx = useContext(TimeContext);
|
||||
return ctx.time;
|
||||
}
|
||||
|
||||
function useSprite() {
|
||||
const sprite = useContext(SpriteContext);
|
||||
if (!sprite) {
|
||||
return { t: 0, elapsed: 0, duration: 0 };
|
||||
}
|
||||
return sprite;
|
||||
}
|
||||
|
||||
const stageStyles = {
|
||||
wrapper: {
|
||||
position: 'fixed',
|
||||
inset: 0,
|
||||
background: '#000',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
fontFamily: '-apple-system, sans-serif',
|
||||
},
|
||||
stageHolder: {
|
||||
flex: 1,
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
canvas: {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transformOrigin: 'center center',
|
||||
background: '#111',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
controls: {
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
background: 'rgba(0, 0, 0, 0.8)',
|
||||
backdropFilter: 'blur(10px)',
|
||||
padding: '12px 20px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 16,
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
zIndex: 100,
|
||||
},
|
||||
button: {
|
||||
background: 'none',
|
||||
border: '1px solid rgba(255,255,255,0.3)',
|
||||
color: '#fff',
|
||||
padding: '6px 14px',
|
||||
borderRadius: 4,
|
||||
cursor: 'pointer',
|
||||
fontSize: 12,
|
||||
},
|
||||
timeDisplay: {
|
||||
fontFamily: 'ui-monospace, monospace',
|
||||
fontVariantNumeric: 'tabular-nums',
|
||||
minWidth: 90,
|
||||
},
|
||||
scrubber: {
|
||||
flex: 1,
|
||||
height: 4,
|
||||
background: 'rgba(255,255,255,0.2)',
|
||||
borderRadius: 2,
|
||||
position: 'relative',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
scrubberFill: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
height: '100%',
|
||||
background: '#fff',
|
||||
borderRadius: 2,
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
scrubberHandle: {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
width: 12,
|
||||
height: 12,
|
||||
background: '#fff',
|
||||
borderRadius: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
};
|
||||
|
||||
function Stage({ duration = 10, width = 1920, height = 1080, fps = 60, loop = true, children, bgColor = '#fff' }) {
|
||||
const [time, setTime] = useState(0);
|
||||
const [playing, setPlaying] = useState(true);
|
||||
const [scale, setScale] = useState(1);
|
||||
const rafRef = useRef(null);
|
||||
const startTimeRef = useRef(performance.now());
|
||||
const canvasRef = useRef(null);
|
||||
|
||||
// Recording mode: render-video.js injects window.__recording = true before goto.
|
||||
// When set, force loop=false so the export ends on the final frame instead of
|
||||
// wrapping back to t=0 and capturing the start of the next cycle.
|
||||
// (Browsers viewing manually still loop because __recording is undefined there.)
|
||||
const effectiveLoop = (typeof window !== 'undefined' && window.__recording) ? false : loop;
|
||||
|
||||
useEffect(() => {
|
||||
function updateScale() {
|
||||
const vw = window.innerWidth;
|
||||
const vh = window.innerHeight - 56;
|
||||
const s = Math.min(vw / width, vh / height);
|
||||
setScale(s);
|
||||
}
|
||||
updateScale();
|
||||
window.addEventListener('resize', updateScale);
|
||||
return () => window.removeEventListener('resize', updateScale);
|
||||
}, [width, height]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!playing) return;
|
||||
let cancelled = false;
|
||||
let last = null;
|
||||
|
||||
function tick(now) {
|
||||
if (cancelled) return;
|
||||
if (last === null) {
|
||||
// First animation frame. Set last=now so delta starts at 0,
|
||||
// AND announce readiness for video export.
|
||||
// This pairing is critical: window.__ready must flip to true at
|
||||
// the exact moment WebM captures frame 0 of the animation, so
|
||||
// render-video.js's trim offset equals the pre-animation gap.
|
||||
last = now;
|
||||
if (typeof window !== 'undefined') window.__ready = true;
|
||||
}
|
||||
const delta = (now - last) / 1000;
|
||||
last = now;
|
||||
setTime(prev => {
|
||||
const next = prev + delta;
|
||||
if (next >= duration) {
|
||||
// effectiveLoop honors window.__recording (forced non-loop during export).
|
||||
// Stop just shy of duration so the final-frame state stays rendered
|
||||
// (avoids exiting all Sprites that end exactly at `duration`).
|
||||
return effectiveLoop ? 0 : duration - 0.001;
|
||||
}
|
||||
return next;
|
||||
});
|
||||
rafRef.current = requestAnimationFrame(tick);
|
||||
}
|
||||
|
||||
// Wait for fonts before starting the clock — makes frame 0 the
|
||||
// real "finished-loading" frame users see, not a fallback-font flash.
|
||||
const startAfterFonts = () => {
|
||||
if (cancelled) return;
|
||||
rafRef.current = requestAnimationFrame(tick);
|
||||
};
|
||||
if (typeof document !== 'undefined' && document.fonts && document.fonts.ready) {
|
||||
document.fonts.ready.then(startAfterFonts);
|
||||
} else {
|
||||
startAfterFonts();
|
||||
}
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
cancelAnimationFrame(rafRef.current);
|
||||
};
|
||||
}, [playing, duration, effectiveLoop]);
|
||||
|
||||
const handleScrub = useCallback((e) => {
|
||||
const rect = e.currentTarget.getBoundingClientRect();
|
||||
const ratio = (e.clientX - rect.left) / rect.width;
|
||||
setTime(Math.max(0, Math.min(duration, ratio * duration)));
|
||||
}, [duration]);
|
||||
|
||||
const handleSeek = useCallback((e) => {
|
||||
handleScrub(e);
|
||||
setPlaying(false);
|
||||
}, [handleScrub]);
|
||||
|
||||
const progress = time / duration;
|
||||
|
||||
const ctx = {
|
||||
time,
|
||||
duration,
|
||||
playing,
|
||||
setPlaying,
|
||||
setTime,
|
||||
};
|
||||
|
||||
const canvasStyle = {
|
||||
...stageStyles.canvas,
|
||||
width,
|
||||
height,
|
||||
background: bgColor,
|
||||
transform: `translate(-50%, -50%) scale(${scale})`,
|
||||
};
|
||||
|
||||
return (
|
||||
<TimeContext.Provider value={ctx}>
|
||||
<div style={stageStyles.wrapper}>
|
||||
<div style={stageStyles.stageHolder}>
|
||||
<div ref={canvasRef} style={canvasStyle}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={stageStyles.controls}>
|
||||
<button
|
||||
style={stageStyles.button}
|
||||
onClick={() => setPlaying(p => !p)}
|
||||
>
|
||||
{playing ? '⏸ 暂停' : '▶ 播放'}
|
||||
</button>
|
||||
|
||||
<button
|
||||
style={stageStyles.button}
|
||||
onClick={() => setTime(0)}
|
||||
>
|
||||
⏮ 开始
|
||||
</button>
|
||||
|
||||
<div style={stageStyles.timeDisplay}>
|
||||
{time.toFixed(2)}s / {duration.toFixed(2)}s
|
||||
</div>
|
||||
|
||||
<div style={stageStyles.scrubber} onMouseDown={handleSeek}>
|
||||
<div style={{ ...stageStyles.scrubberFill, width: `${progress * 100}%` }} />
|
||||
<div style={{ ...stageStyles.scrubberHandle, left: `${progress * 100}%` }} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TimeContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
function Sprite({ start = 0, end, children, style }) {
|
||||
const { time } = useContext(TimeContext);
|
||||
const actualEnd = end == null ? Infinity : end;
|
||||
|
||||
if (time < start || time >= actualEnd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const duration = actualEnd - start;
|
||||
const elapsed = time - start;
|
||||
const t = duration === 0 ? 1 : Math.max(0, Math.min(1, elapsed / duration));
|
||||
|
||||
const spriteValue = { t, elapsed, duration, start, end: actualEnd };
|
||||
|
||||
return (
|
||||
<SpriteContext.Provider value={spriteValue}>
|
||||
<div style={{ position: 'absolute', inset: 0, ...style }}>
|
||||
{children}
|
||||
</div>
|
||||
</SpriteContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.Animations = {
|
||||
Stage,
|
||||
Sprite,
|
||||
useTime,
|
||||
useSprite,
|
||||
Easing,
|
||||
interpolate,
|
||||
};
|
||||
}
|
||||
})();
|
||||
@ -1,198 +0,0 @@
|
||||
<svg width="1200" height="400" viewBox="0 0 1200 400" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700;900&family=Noto+Serif+SC:wght@700;900&display=swap');
|
||||
</style>
|
||||
|
||||
<!-- Warm accent gradients for mini mockup highlights -->
|
||||
<linearGradient id="hdBarGrad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#D4532B"/>
|
||||
<stop offset="100%" stop-color="#A83518"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="hdBarGradSoft" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#8B5E3C"/>
|
||||
<stop offset="100%" stop-color="#6E4A2E"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Background -->
|
||||
<rect width="1200" height="400" fill="#111111"/>
|
||||
|
||||
<!-- Left accent line (Pentagram-style editorial vertical rule) -->
|
||||
<rect x="60" y="48" width="3" height="304" fill="#D4532B"/>
|
||||
|
||||
<!-- Top horizontal rule -->
|
||||
<rect x="60" y="48" width="760" height="2" fill="#FFFFFF" opacity="0.15"/>
|
||||
|
||||
<!-- Bottom horizontal rule -->
|
||||
<rect x="60" y="350" width="760" height="1" fill="#FFFFFF" opacity="0.15"/>
|
||||
|
||||
<!-- Thin divider between text and viz -->
|
||||
<rect x="860" y="80" width="1" height="240" fill="#FFFFFF" opacity="0.08"/>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- LEFT: TEXT BLOCK -->
|
||||
<!-- ============================================================ -->
|
||||
|
||||
<!-- CATEGORY LABEL -->
|
||||
<text
|
||||
x="80"
|
||||
y="88"
|
||||
font-family="'Inter', system-ui, -apple-system, sans-serif"
|
||||
font-size="11"
|
||||
font-weight="700"
|
||||
letter-spacing="3"
|
||||
fill="#D4532B"
|
||||
>CLAUDE CODE SKILL · DESIGN</text>
|
||||
|
||||
<!-- MAIN TITLE -->
|
||||
<text
|
||||
x="80"
|
||||
y="178"
|
||||
font-family="'Inter', system-ui, -apple-system, sans-serif"
|
||||
font-size="88"
|
||||
font-weight="900"
|
||||
fill="#FFFFFF"
|
||||
letter-spacing="-3"
|
||||
>Huashu Design</text>
|
||||
|
||||
<!-- Chinese subtitle -->
|
||||
<text
|
||||
x="80"
|
||||
y="222"
|
||||
font-family="'Noto Serif SC', 'Source Han Serif', 'Inter', serif"
|
||||
font-size="22"
|
||||
font-weight="700"
|
||||
fill="#EEEEEE"
|
||||
letter-spacing="1"
|
||||
>用 HTML 做设计的 skill</text>
|
||||
|
||||
<!-- Tagline -->
|
||||
<text
|
||||
x="80"
|
||||
y="284"
|
||||
font-family="'Inter', system-ui, -apple-system, sans-serif"
|
||||
font-size="15"
|
||||
font-weight="500"
|
||||
fill="#BBBBBB"
|
||||
letter-spacing="0.5"
|
||||
>高保真原型</text>
|
||||
<text x="176" y="284" font-family="'Inter', sans-serif" font-size="15" font-weight="700" fill="#D4532B">·</text>
|
||||
<text x="188" y="284" font-family="'Inter', sans-serif" font-size="15" font-weight="500" fill="#BBBBBB" letter-spacing="0.5">幻灯片</text>
|
||||
<text x="260" y="284" font-family="'Inter', sans-serif" font-size="15" font-weight="700" fill="#D4532B">·</text>
|
||||
<text x="272" y="284" font-family="'Inter', sans-serif" font-size="15" font-weight="500" fill="#BBBBBB" letter-spacing="0.5">动画</text>
|
||||
<text x="320" y="284" font-family="'Inter', sans-serif" font-size="15" font-weight="700" fill="#D4532B">·</text>
|
||||
<text x="332" y="284" font-family="'Inter', sans-serif" font-size="15" font-weight="500" fill="#BBBBBB" letter-spacing="0.5">信息图</text>
|
||||
<text x="404" y="284" font-family="'Inter', sans-serif" font-size="15" font-weight="700" fill="#D4532B">·</text>
|
||||
<text x="416" y="284" font-family="'Inter', sans-serif" font-size="15" font-weight="500" fill="#BBBBBB" letter-spacing="0.5">App 原型</text>
|
||||
|
||||
<!-- Second tagline row -->
|
||||
<text
|
||||
x="80"
|
||||
y="312"
|
||||
font-family="'Inter', system-ui, -apple-system, sans-serif"
|
||||
font-size="14"
|
||||
font-weight="400"
|
||||
fill="#888888"
|
||||
letter-spacing="0.3"
|
||||
>20 种设计哲学 · 5 维专家评审 · 发布会级动画导出</text>
|
||||
|
||||
<!-- Footer credit -->
|
||||
<text
|
||||
x="80"
|
||||
y="370"
|
||||
font-family="'Inter', system-ui, -apple-system, sans-serif"
|
||||
font-size="12"
|
||||
font-weight="400"
|
||||
fill="#666666"
|
||||
letter-spacing="0.3"
|
||||
>for Claude Code & Agent-agnostic</text>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- RIGHT: MINI MOCKUP GRID (2×2) -->
|
||||
<!-- Each mock represents one output form of huashu-design -->
|
||||
<!-- Viewport right area: x 880-1160, y 90-330 -->
|
||||
<!-- 2×2 grid, tile ≈ 128×104, gap 16 -->
|
||||
<!-- ============================================================ -->
|
||||
|
||||
<!-- Section label -->
|
||||
<text x="890" y="108" font-family="'Inter', sans-serif" font-size="10" font-weight="700" letter-spacing="2" fill="#D4532B" opacity="0.9">OUTPUT SURFACES</text>
|
||||
|
||||
<!-- Grid coordinates:
|
||||
Col1 x=890 (width 128) Col2 x=1034 (width 128)
|
||||
Row1 y=122 (height 100) Row2 y=238 (height 100) -->
|
||||
|
||||
<!-- ============ TILE 1 · SLIDES (top-left) ============ -->
|
||||
<rect x="890" y="122" width="128" height="100" rx="2" fill="#1A1A1A" stroke="#333333" stroke-width="1"/>
|
||||
<!-- slide stack visual: 3 stacked rectangles offset to imply deck -->
|
||||
<rect x="902" y="138" width="88" height="56" fill="#2A2A2A" stroke="#3A3A3A" stroke-width="0.5"/>
|
||||
<rect x="906" y="142" width="88" height="56" fill="#353535"/>
|
||||
<rect x="910" y="146" width="88" height="56" fill="#E8E2D4"/>
|
||||
<!-- slide headline stripes -->
|
||||
<rect x="916" y="152" width="48" height="3" fill="#111111"/>
|
||||
<rect x="916" y="160" width="72" height="1.5" fill="#666666"/>
|
||||
<rect x="916" y="166" width="60" height="1.5" fill="#666666"/>
|
||||
<rect x="916" y="176" width="32" height="14" fill="#D4532B"/>
|
||||
<!-- tile label -->
|
||||
<text x="902" y="216" font-family="'Inter', sans-serif" font-size="9" font-weight="500" letter-spacing="2" fill="#777777">SLIDES</text>
|
||||
|
||||
<!-- ============ TILE 2 · PROTOTYPE iPhone (top-right) ============ -->
|
||||
<rect x="1034" y="122" width="128" height="100" rx="2" fill="#1A1A1A" stroke="#333333" stroke-width="1"/>
|
||||
<!-- iPhone outline inside tile -->
|
||||
<rect x="1080" y="130" width="36" height="76" rx="6" fill="#0A0A0A" stroke="#444444" stroke-width="1"/>
|
||||
<!-- Dynamic island -->
|
||||
<rect x="1092" y="134" width="12" height="3" rx="1.5" fill="#000000"/>
|
||||
<!-- Screen content area -->
|
||||
<rect x="1083" y="140" width="30" height="58" fill="#EEEAE0"/>
|
||||
<!-- Tiny app UI elements -->
|
||||
<rect x="1086" y="144" width="24" height="4" fill="#111111"/>
|
||||
<rect x="1086" y="152" width="16" height="1.5" fill="#888888"/>
|
||||
<rect x="1086" y="157" width="20" height="1.5" fill="#888888"/>
|
||||
<rect x="1086" y="164" width="24" height="12" fill="#D4532B"/>
|
||||
<rect x="1086" y="180" width="11" height="14" fill="#D1CAB8"/>
|
||||
<rect x="1099" y="180" width="11" height="14" fill="#D1CAB8"/>
|
||||
<!-- Home indicator -->
|
||||
<rect x="1092" y="201" width="12" height="1" rx="0.5" fill="#444444"/>
|
||||
<!-- tile label -->
|
||||
<text x="1046" y="216" font-family="'Inter', sans-serif" font-size="9" font-weight="500" letter-spacing="2" fill="#777777">PROTOTYPE</text>
|
||||
|
||||
<!-- ============ TILE 3 · ANIMATION storyboard (bottom-left) ============ -->
|
||||
<rect x="890" y="238" width="128" height="100" rx="2" fill="#1A1A1A" stroke="#333333" stroke-width="1"/>
|
||||
<!-- 3 storyboard frames in a row -->
|
||||
<rect x="898" y="252" width="34" height="44" fill="#252525" stroke="#3A3A3A" stroke-width="0.5"/>
|
||||
<rect x="939" y="252" width="34" height="44" fill="#2E2E2E" stroke="#3A3A3A" stroke-width="0.5"/>
|
||||
<rect x="980" y="252" width="34" height="44" fill="#353535" stroke="#3A3A3A" stroke-width="0.5"/>
|
||||
<!-- motion dots -->
|
||||
<circle cx="910" cy="274" r="6" fill="#666666"/>
|
||||
<circle cx="956" cy="274" r="6" fill="#9C6A46"/>
|
||||
<circle cx="997" cy="274" r="6" fill="#D4532B"/>
|
||||
<!-- motion arc dashes -->
|
||||
<path d="M 910 274 Q 933 258 956 274" stroke="#D4532B" stroke-width="0.8" fill="none" stroke-dasharray="2 2" opacity="0.6"/>
|
||||
<path d="M 956 274 Q 977 258 997 274" stroke="#D4532B" stroke-width="0.8" fill="none" stroke-dasharray="2 2" opacity="0.6"/>
|
||||
<!-- timeline ruler -->
|
||||
<rect x="898" y="306" width="116" height="1" fill="#555555"/>
|
||||
<rect x="898" y="306" width="2" height="4" fill="#D4532B"/>
|
||||
<rect x="938" y="306" width="2" height="4" fill="#555555"/>
|
||||
<rect x="978" y="306" width="2" height="4" fill="#555555"/>
|
||||
<rect x="1012" y="306" width="2" height="4" fill="#555555"/>
|
||||
<!-- tile label -->
|
||||
<text x="902" y="332" font-family="'Inter', sans-serif" font-size="9" font-weight="500" letter-spacing="2" fill="#777777">ANIMATION</text>
|
||||
|
||||
<!-- ============ TILE 4 · INFOGRAPHIC bars (bottom-right) ============ -->
|
||||
<rect x="1034" y="238" width="128" height="100" rx="2" fill="#1A1A1A" stroke="#333333" stroke-width="1"/>
|
||||
<!-- bars chart -->
|
||||
<rect x="1046" y="290" width="12" height="20" fill="url(#hdBarGradSoft)"/>
|
||||
<rect x="1062" y="278" width="12" height="32" fill="url(#hdBarGradSoft)"/>
|
||||
<rect x="1078" y="270" width="12" height="40" fill="url(#hdBarGradSoft)"/>
|
||||
<rect x="1094" y="262" width="12" height="48" fill="url(#hdBarGrad)"/>
|
||||
<rect x="1110" y="254" width="12" height="56" fill="url(#hdBarGrad)"/>
|
||||
<rect x="1126" y="248" width="12" height="62" fill="url(#hdBarGrad)"/>
|
||||
<!-- baseline -->
|
||||
<rect x="1044" y="310" width="104" height="1" fill="#555555"/>
|
||||
<!-- headline at top of tile -->
|
||||
<rect x="1046" y="252" width="50" height="3" fill="#FFFFFF" opacity="0.85"/>
|
||||
<rect x="1046" y="260" width="34" height="1.5" fill="#666666"/>
|
||||
<!-- tile label -->
|
||||
<text x="1046" y="332" font-family="'Inter', sans-serif" font-size="9" font-weight="500" letter-spacing="2" fill="#777777">INFOGRAPHIC</text>
|
||||
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.3 KiB |
@ -1,166 +0,0 @@
|
||||
/**
|
||||
* BrowserWindow — 浏览器窗口边框(Chrome风格)
|
||||
*
|
||||
* 含:traffic lights + tab bar + URL bar
|
||||
*
|
||||
* 用法:
|
||||
* <BrowserWindow url="https://example.com" title="Example">
|
||||
* <YourWebPage />
|
||||
* </BrowserWindow>
|
||||
*/
|
||||
|
||||
const browserWindowStyles = {
|
||||
window: {
|
||||
display: 'inline-block',
|
||||
background: '#fff',
|
||||
borderRadius: 10,
|
||||
overflow: 'hidden',
|
||||
boxShadow: '0 30px 80px rgba(0,0,0,0.25), 0 0 0 0.5px rgba(0,0,0,0.15)',
|
||||
},
|
||||
chrome: {
|
||||
background: '#dee1e6',
|
||||
paddingTop: 10,
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
userSelect: 'none',
|
||||
},
|
||||
tabRow: {
|
||||
display: 'flex',
|
||||
alignItems: 'flex-end',
|
||||
gap: 6,
|
||||
position: 'relative',
|
||||
},
|
||||
trafficLights: {
|
||||
display: 'flex',
|
||||
gap: 8,
|
||||
alignItems: 'center',
|
||||
paddingBottom: 10,
|
||||
marginRight: 8,
|
||||
},
|
||||
light: {
|
||||
width: 12,
|
||||
height: 12,
|
||||
borderRadius: '50%',
|
||||
border: '0.5px solid rgba(0,0,0,0.15)',
|
||||
},
|
||||
close: { background: '#ff5f57' },
|
||||
minimize: { background: '#febc2e' },
|
||||
maximize: { background: '#28c840' },
|
||||
tab: {
|
||||
background: '#fff',
|
||||
padding: '8px 30px 8px 14px',
|
||||
borderTopLeftRadius: 10,
|
||||
borderTopRightRadius: 10,
|
||||
fontSize: 12,
|
||||
color: '#222',
|
||||
fontFamily: '-apple-system, sans-serif',
|
||||
maxWidth: 220,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
position: 'relative',
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
},
|
||||
favicon: {
|
||||
width: 14,
|
||||
height: 14,
|
||||
borderRadius: 2,
|
||||
background: '#999',
|
||||
flexShrink: 0,
|
||||
},
|
||||
navBar: {
|
||||
background: '#fff',
|
||||
padding: '8px 14px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 10,
|
||||
borderBottom: '1px solid #e5e7eb',
|
||||
},
|
||||
navButtons: {
|
||||
display: 'flex',
|
||||
gap: 4,
|
||||
color: '#5f6368',
|
||||
fontSize: 16,
|
||||
},
|
||||
navButton: {
|
||||
width: 28,
|
||||
height: 28,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
borderRadius: '50%',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
urlBar: {
|
||||
flex: 1,
|
||||
background: '#f1f3f4',
|
||||
borderRadius: 999,
|
||||
padding: '7px 14px',
|
||||
fontSize: 13,
|
||||
color: '#333',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
fontFamily: '-apple-system, sans-serif',
|
||||
},
|
||||
lockIcon: {
|
||||
color: '#5f6368',
|
||||
fontSize: 12,
|
||||
},
|
||||
content: {
|
||||
position: 'relative',
|
||||
overflow: 'auto',
|
||||
background: '#fff',
|
||||
},
|
||||
};
|
||||
|
||||
function BrowserWindow({
|
||||
title = 'New Tab',
|
||||
url = 'https://example.com',
|
||||
width = 1200,
|
||||
height = 800,
|
||||
showTrafficLights = true,
|
||||
children,
|
||||
}) {
|
||||
return (
|
||||
<div style={browserWindowStyles.window}>
|
||||
<div style={browserWindowStyles.chrome}>
|
||||
<div style={browserWindowStyles.tabRow}>
|
||||
{showTrafficLights && (
|
||||
<div style={browserWindowStyles.trafficLights}>
|
||||
<div style={{ ...browserWindowStyles.light, ...browserWindowStyles.close }} />
|
||||
<div style={{ ...browserWindowStyles.light, ...browserWindowStyles.minimize }} />
|
||||
<div style={{ ...browserWindowStyles.light, ...browserWindowStyles.maximize }} />
|
||||
</div>
|
||||
)}
|
||||
<div style={browserWindowStyles.tab}>
|
||||
<div style={browserWindowStyles.favicon} />
|
||||
<span>{title}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={browserWindowStyles.navBar}>
|
||||
<div style={browserWindowStyles.navButtons}>
|
||||
<div style={browserWindowStyles.navButton}>←</div>
|
||||
<div style={browserWindowStyles.navButton}>→</div>
|
||||
<div style={browserWindowStyles.navButton}>↻</div>
|
||||
</div>
|
||||
<div style={browserWindowStyles.urlBar}>
|
||||
<span style={browserWindowStyles.lockIcon}>🔒</span>
|
||||
<span>{url}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ ...browserWindowStyles.content, width, height }}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.BrowserWindow = BrowserWindow;
|
||||
}
|
||||
@ -1,237 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Deck · Multi-file Slide Index</title>
|
||||
<!--
|
||||
deck_index.html — 多文件 slide deck 的拼接器
|
||||
|
||||
配合「每页一个独立 HTML」架构使用。与单文件 deck_stage.js 对比:
|
||||
· 每页独立作用域(CSS/JS 都隔离),一页出 bug 不影响其他页
|
||||
· 单页可直接在浏览器打开验证,不依赖 JS goTo()
|
||||
· 多 agent 可并行做不同页,merge 时零冲突
|
||||
· 适合 ≥15 页的讲座/课件/长 deck
|
||||
|
||||
用法:
|
||||
1. 把本文件复制到 deck 根目录,重命名 index.html
|
||||
2. 在同目录建 slides/ 子目录,放每一页独立 HTML
|
||||
3. 编辑下方 MANIFEST 数组,按顺序列出文件名和人类可读标签
|
||||
4. 每张 slide HTML 建议尺寸 1920×1080,自带背景/字体;不要依赖外层 CSS
|
||||
|
||||
共享资源(如果需要):
|
||||
· shared/tokens.css — 跨页 CSS 变量(色板/字号)
|
||||
· shared/chrome.html — 页眉页脚可复用片段
|
||||
· 每页 HTML 自己 <link> 进去即可
|
||||
|
||||
键盘:← / → / Space / PgUp / PgDown / Home / End / 1-9 跳页 / P 打印
|
||||
-->
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════ -->
|
||||
<!-- EDIT THIS — deck 所有页按顺序列出 -->
|
||||
<!-- ═══════════════════════════════════════════════════════ -->
|
||||
<script>
|
||||
window.DECK_MANIFEST = [
|
||||
{ file: "slides/01-cover.html", label: "Cover" },
|
||||
{ file: "slides/02-quote.html", label: "Opening Quote" },
|
||||
{ file: "slides/03-intro.html", label: "Self-intro" },
|
||||
// 继续往下加。file 是相对本文件的路径,label 用于计数器
|
||||
];
|
||||
|
||||
// 固定 canvas 尺寸。每页 HTML 都应该按这个尺寸设计。
|
||||
window.DECK_WIDTH = 1920;
|
||||
window.DECK_HEIGHT = 1080;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
html, body {
|
||||
height: 100%;
|
||||
background: #0a0a0a;
|
||||
overflow: hidden;
|
||||
font-family: -apple-system, "PingFang SC", sans-serif;
|
||||
}
|
||||
#stage {
|
||||
position: fixed;
|
||||
top: 50%; left: 50%;
|
||||
transform-origin: top left;
|
||||
will-change: transform;
|
||||
background: #fff;
|
||||
box-shadow: 0 10px 60px rgba(0,0,0,0.4);
|
||||
/* size set by JS from DECK_WIDTH/HEIGHT */
|
||||
}
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
display: block;
|
||||
background: #fff;
|
||||
}
|
||||
.counter {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
background: rgba(0,0,0,0.65);
|
||||
color: #fff;
|
||||
padding: 6px 14px;
|
||||
border-radius: 999px;
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.05em;
|
||||
font-variant-numeric: tabular-nums;
|
||||
z-index: 100;
|
||||
user-select: none;
|
||||
opacity: 0.7;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.counter:hover { opacity: 1; }
|
||||
.counter .label { color: rgba(255,255,255,0.7); margin-left: 8px; }
|
||||
.nav-zone {
|
||||
position: fixed;
|
||||
top: 0; bottom: 0;
|
||||
width: 15%;
|
||||
cursor: pointer;
|
||||
z-index: 50;
|
||||
}
|
||||
.nav-zone.left { left: 0; }
|
||||
.nav-zone.right { right: 0; }
|
||||
.nav-hint {
|
||||
position: absolute;
|
||||
top: 50%; transform: translateY(-50%);
|
||||
width: 44px; height: 44px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255,255,255,0.08);
|
||||
color: rgba(255,255,255,0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.nav-zone.left .nav-hint { left: 20px; }
|
||||
.nav-zone.right .nav-hint { right: 20px; }
|
||||
.nav-zone:hover .nav-hint { opacity: 1; }
|
||||
|
||||
/* Print: one slide per page, no navigation UI */
|
||||
@media print {
|
||||
@page { size: 1920px 1080px; margin: 0; }
|
||||
html, body { background: #fff; overflow: visible; height: auto; }
|
||||
#stage { position: static; transform: none !important; box-shadow: none; }
|
||||
.counter, .nav-zone { display: none !important; }
|
||||
/* In print mode we render all slides sequentially — see JS */
|
||||
.print-stack { display: block; }
|
||||
.print-stack iframe {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
page-break-after: always;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="stage">
|
||||
<iframe id="frame" src="about:blank"></iframe>
|
||||
</div>
|
||||
|
||||
<div class="nav-zone left" id="navL"><div class="nav-hint">‹</div></div>
|
||||
<div class="nav-zone right" id="navR"><div class="nav-hint">›</div></div>
|
||||
<div class="counter" id="counter">1 / 1</div>
|
||||
|
||||
<!-- Print-only stack: populated on beforeprint, stripped on afterprint -->
|
||||
<div class="print-stack" id="printStack" style="display:none;"></div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
const W = window.DECK_WIDTH || 1920;
|
||||
const H = window.DECK_HEIGHT || 1080;
|
||||
const deck = window.DECK_MANIFEST || [];
|
||||
const stage = document.getElementById('stage');
|
||||
const frame = document.getElementById('frame');
|
||||
const counter = document.getElementById('counter');
|
||||
const printStack = document.getElementById('printStack');
|
||||
const storageKey = 'deck-index-' + location.pathname;
|
||||
let current = 0;
|
||||
|
||||
stage.style.width = W + 'px';
|
||||
stage.style.height = H + 'px';
|
||||
|
||||
function fit() {
|
||||
const s = Math.min(window.innerWidth / W, window.innerHeight / H);
|
||||
const x = (window.innerWidth - W * s) / 2;
|
||||
const y = (window.innerHeight - H * s) / 2;
|
||||
stage.style.transform = `translate(${x}px, ${y}px) scale(${s})`;
|
||||
stage.style.top = '0';
|
||||
stage.style.left = '0';
|
||||
}
|
||||
|
||||
function show(idx) {
|
||||
if (idx < 0 || idx >= deck.length) return;
|
||||
current = idx;
|
||||
frame.src = deck[idx].file;
|
||||
counter.innerHTML = `${idx + 1} / ${deck.length} <span class="label">${deck[idx].label || ''}</span>`;
|
||||
try { localStorage.setItem(storageKey, String(idx)); } catch (_) {}
|
||||
if (location.hash !== '#' + (idx + 1)) {
|
||||
history.replaceState(null, '', '#' + (idx + 1));
|
||||
}
|
||||
}
|
||||
|
||||
function next() { show(Math.min(current + 1, deck.length - 1)); }
|
||||
function prev() { show(Math.max(current - 1, 0)); }
|
||||
|
||||
// Keyboard
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
|
||||
switch (e.key) {
|
||||
case 'ArrowRight': case ' ': case 'PageDown': e.preventDefault(); next(); break;
|
||||
case 'ArrowLeft': case 'PageUp': e.preventDefault(); prev(); break;
|
||||
case 'Home': e.preventDefault(); show(0); break;
|
||||
case 'End': e.preventDefault(); show(deck.length - 1); break;
|
||||
case 'p': case 'P': window.print(); break;
|
||||
default:
|
||||
if (e.key >= '1' && e.key <= '9') {
|
||||
const i = parseInt(e.key, 10) - 1;
|
||||
if (i < deck.length) { e.preventDefault(); show(i); }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('navL').addEventListener('click', prev);
|
||||
document.getElementById('navR').addEventListener('click', next);
|
||||
window.addEventListener('resize', fit);
|
||||
window.addEventListener('hashchange', () => {
|
||||
const m = location.hash.match(/^#(\d+)$/);
|
||||
if (m) show(parseInt(m[1], 10) - 1);
|
||||
});
|
||||
|
||||
// Initial: hash > localStorage > 0
|
||||
const hashMatch = location.hash.match(/^#(\d+)$/);
|
||||
if (hashMatch) current = Math.min(parseInt(hashMatch[1], 10) - 1, deck.length - 1);
|
||||
else try {
|
||||
const v = parseInt(localStorage.getItem(storageKey), 10);
|
||||
if (!isNaN(v) && v >= 0 && v < deck.length) current = v;
|
||||
} catch (_) {}
|
||||
fit();
|
||||
show(current);
|
||||
|
||||
// Print: build a stack of all iframes so browser prints every slide
|
||||
window.addEventListener('beforeprint', () => {
|
||||
printStack.innerHTML = '';
|
||||
deck.forEach(item => {
|
||||
const f = document.createElement('iframe');
|
||||
f.src = item.file;
|
||||
printStack.appendChild(f);
|
||||
});
|
||||
printStack.style.display = 'block';
|
||||
document.getElementById('stage').style.display = 'none';
|
||||
});
|
||||
window.addEventListener('afterprint', () => {
|
||||
printStack.innerHTML = '';
|
||||
printStack.style.display = 'none';
|
||||
document.getElementById('stage').style.display = '';
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,420 +0,0 @@
|
||||
/**
|
||||
* <deck-stage> — HTML幻灯片外壳web component
|
||||
*
|
||||
* 提供功能:
|
||||
* - 固定尺寸canvas(默认1920×1080)+ auto-scale + letterbox
|
||||
* - 键盘导航(←/→/Space/Home/End/Esc)
|
||||
* - 左右点击区域导航
|
||||
* - slide counter (当前/总数)
|
||||
* - localStorage持久化当前slide
|
||||
* - Speaker notes postMessage (支持外层渲染)
|
||||
* - Hash导航 (#slide-5 跳到第5张)
|
||||
* - Print-to-PDF支持 (Cmd+P / Ctrl+P 一页一slide)
|
||||
* - 自动给每个slide添加 data-screen-label
|
||||
*
|
||||
* 用法:
|
||||
* <deck-stage>
|
||||
* <section>Slide 1</section>
|
||||
* <section>Slide 2</section>
|
||||
* </deck-stage>
|
||||
*
|
||||
* 自定义尺寸:
|
||||
* <deck-stage width="1080" height="1920">...</deck-stage>
|
||||
*
|
||||
* Speaker notes:在<head>加
|
||||
* <script type="application/json" id="speaker-notes">
|
||||
* ["slide 1 notes", "slide 2 notes"]
|
||||
* </script>
|
||||
*/
|
||||
|
||||
(function() {
|
||||
const STORAGE_KEY_PREFIX = 'deck-stage-slide-';
|
||||
|
||||
class DeckStage extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
this._currentSlide = 0;
|
||||
this._slides = [];
|
||||
this._storageKey = STORAGE_KEY_PREFIX + (location.pathname || 'default');
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this._width = parseInt(this.getAttribute('width')) || 1920;
|
||||
this._height = parseInt(this.getAttribute('height')) || 1080;
|
||||
|
||||
// Shadow DOM 先渲染(独立于子节点,不受 parser 时机影响)
|
||||
this._render();
|
||||
|
||||
// 防御:若 script 放在 <head> 里(而非 </deck-stage> 之后),
|
||||
// parser 此刻可能还没处理完子 <section>,querySelectorAll 会返回空。
|
||||
// 延迟到下一个事件循环,确保子节点都已 parse 完毕。
|
||||
const init = () => {
|
||||
this._collectSlides();
|
||||
this._setupEventListeners();
|
||||
this._restoreSlide();
|
||||
this._updateDisplay();
|
||||
this._setupPrintStyles();
|
||||
};
|
||||
|
||||
if (this.ownerDocument.readyState === 'loading') {
|
||||
// 文档还在 parse,等 DOMContentLoaded 一次搞定所有 section
|
||||
this.ownerDocument.addEventListener('DOMContentLoaded', init, { once: true });
|
||||
} else {
|
||||
// 文档已 parse 完(script 在 body 底部或 defer),下一帧收集即可
|
||||
requestAnimationFrame(init);
|
||||
}
|
||||
}
|
||||
|
||||
_render() {
|
||||
this.shadowRoot.innerHTML = `
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: #000;
|
||||
overflow: hidden;
|
||||
font-family: -apple-system, 'SF Pro Text', 'PingFang SC', sans-serif;
|
||||
}
|
||||
|
||||
:host([noscale]) .stage {
|
||||
transform: none !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
}
|
||||
|
||||
.stage {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform-origin: top left;
|
||||
will-change: transform;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.slide-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
::slotted(section) {
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
::slotted(section.active) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.counter {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
color: #fff;
|
||||
padding: 6px 14px;
|
||||
border-radius: 999px;
|
||||
font-size: 13px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
z-index: 100;
|
||||
user-select: none;
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.counter:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.nav-zone {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 15%;
|
||||
cursor: pointer;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.nav-zone.left { left: 0; }
|
||||
.nav-zone.right { right: 0; }
|
||||
|
||||
.nav-hint {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.nav-zone.left .nav-hint { left: 20px; }
|
||||
.nav-zone.right .nav-hint { right: 20px; }
|
||||
|
||||
.nav-zone:hover .nav-hint {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media print {
|
||||
:host {
|
||||
position: static;
|
||||
background: #fff;
|
||||
}
|
||||
.counter, .nav-zone {
|
||||
display: none !important;
|
||||
}
|
||||
.stage {
|
||||
position: static;
|
||||
transform: none !important;
|
||||
page-break-after: always;
|
||||
}
|
||||
::slotted(section) {
|
||||
display: block !important;
|
||||
position: relative !important;
|
||||
page-break-after: always;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="stage" id="stage" style="width: ${this._width}px; height: ${this._height}px;">
|
||||
<div class="slide-wrapper">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="nav-zone left" id="navLeft">
|
||||
<div class="nav-hint">‹</div>
|
||||
</div>
|
||||
<div class="nav-zone right" id="navRight">
|
||||
<div class="nav-hint">›</div>
|
||||
</div>
|
||||
|
||||
<div class="counter" id="counter">1 / 1</div>
|
||||
`;
|
||||
}
|
||||
|
||||
_collectSlides() {
|
||||
this._slides = Array.from(this.querySelectorAll(':scope > section'));
|
||||
|
||||
this._slides.forEach((slide, idx) => {
|
||||
if (!slide.hasAttribute('data-screen-label')) {
|
||||
const num = String(idx + 1).padStart(2, '0');
|
||||
slide.setAttribute('data-screen-label', num);
|
||||
}
|
||||
if (!slide.hasAttribute('data-om-validate')) {
|
||||
slide.setAttribute('data-om-validate', '');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_setupEventListeners() {
|
||||
window.addEventListener('resize', () => this._updateScale());
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.target.matches('input, textarea, [contenteditable]')) return;
|
||||
|
||||
switch (e.key) {
|
||||
case 'ArrowRight':
|
||||
case ' ':
|
||||
case 'PageDown':
|
||||
e.preventDefault();
|
||||
this.next();
|
||||
break;
|
||||
case 'ArrowLeft':
|
||||
case 'PageUp':
|
||||
e.preventDefault();
|
||||
this.prev();
|
||||
break;
|
||||
case 'Home':
|
||||
e.preventDefault();
|
||||
this.goTo(0);
|
||||
break;
|
||||
case 'End':
|
||||
e.preventDefault();
|
||||
this.goTo(this._slides.length - 1);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
this.shadowRoot.getElementById('navLeft').addEventListener('click', () => this.prev());
|
||||
this.shadowRoot.getElementById('navRight').addEventListener('click', () => this.next());
|
||||
|
||||
window.addEventListener('hashchange', () => this._handleHash());
|
||||
if (location.hash) {
|
||||
setTimeout(() => this._handleHash(), 0);
|
||||
}
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
if (this.hasAttribute('noscale')) {
|
||||
this._updateScale();
|
||||
}
|
||||
});
|
||||
observer.observe(this, { attributes: true, attributeFilter: ['noscale'] });
|
||||
}
|
||||
|
||||
_handleHash() {
|
||||
const match = location.hash.match(/^#slide-(\d+)$/);
|
||||
if (match) {
|
||||
const idx = parseInt(match[1]) - 1;
|
||||
if (idx >= 0 && idx < this._slides.length) {
|
||||
this.goTo(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_restoreSlide() {
|
||||
try {
|
||||
const stored = localStorage.getItem(this._storageKey);
|
||||
if (stored !== null) {
|
||||
const idx = parseInt(stored);
|
||||
if (idx >= 0 && idx < this._slides.length) {
|
||||
this._currentSlide = idx;
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
_saveSlide() {
|
||||
try {
|
||||
localStorage.setItem(this._storageKey, String(this._currentSlide));
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
_updateScale() {
|
||||
if (this.hasAttribute('noscale')) {
|
||||
const stage = this.shadowRoot.getElementById('stage');
|
||||
stage.style.transform = 'none';
|
||||
stage.style.top = '0';
|
||||
stage.style.left = '0';
|
||||
return;
|
||||
}
|
||||
|
||||
const stage = this.shadowRoot.getElementById('stage');
|
||||
if (!stage) return;
|
||||
|
||||
const viewportW = window.innerWidth;
|
||||
const viewportH = window.innerHeight;
|
||||
const scale = Math.min(viewportW / this._width, viewportH / this._height);
|
||||
const scaledW = this._width * scale;
|
||||
const scaledH = this._height * scale;
|
||||
const offsetX = (viewportW - scaledW) / 2;
|
||||
const offsetY = (viewportH - scaledH) / 2;
|
||||
|
||||
stage.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
|
||||
stage.style.top = '0';
|
||||
stage.style.left = '0';
|
||||
}
|
||||
|
||||
_updateDisplay() {
|
||||
this._slides.forEach((slide, idx) => {
|
||||
slide.classList.toggle('active', idx === this._currentSlide);
|
||||
});
|
||||
|
||||
const counter = this.shadowRoot.getElementById('counter');
|
||||
if (counter) {
|
||||
counter.textContent = `${this._currentSlide + 1} / ${this._slides.length}`;
|
||||
}
|
||||
|
||||
this._updateScale();
|
||||
|
||||
try {
|
||||
window.postMessage({
|
||||
slideIndexChanged: this._currentSlide,
|
||||
totalSlides: this._slides.length
|
||||
}, '*');
|
||||
} catch (e) {}
|
||||
|
||||
try {
|
||||
if (window.parent && window.parent !== window) {
|
||||
window.parent.postMessage({
|
||||
slideIndexChanged: this._currentSlide,
|
||||
totalSlides: this._slides.length
|
||||
}, '*');
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
_setupPrintStyles() {
|
||||
const printStyle = document.createElement('style');
|
||||
printStyle.textContent = `
|
||||
@media print {
|
||||
@page {
|
||||
size: ${this._width}px ${this._height}px;
|
||||
margin: 0;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
deck-stage {
|
||||
position: static !important;
|
||||
}
|
||||
deck-stage > section {
|
||||
display: block !important;
|
||||
position: relative !important;
|
||||
width: ${this._width}px !important;
|
||||
height: ${this._height}px !important;
|
||||
page-break-after: always;
|
||||
overflow: hidden;
|
||||
}
|
||||
deck-stage > section:last-child {
|
||||
page-break-after: auto;
|
||||
}
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(printStyle);
|
||||
}
|
||||
|
||||
next() {
|
||||
if (this._currentSlide < this._slides.length - 1) {
|
||||
this._currentSlide++;
|
||||
this._saveSlide();
|
||||
this._updateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
prev() {
|
||||
if (this._currentSlide > 0) {
|
||||
this._currentSlide--;
|
||||
this._saveSlide();
|
||||
this._updateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
goTo(idx) {
|
||||
if (idx >= 0 && idx < this._slides.length) {
|
||||
this._currentSlide = idx;
|
||||
this._saveSlide();
|
||||
this._updateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
get currentSlide() {
|
||||
return this._currentSlide;
|
||||
}
|
||||
|
||||
get totalSlides() {
|
||||
return this._slides.length;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('deck-stage', DeckStage);
|
||||
|
||||
window.DeckStage = DeckStage;
|
||||
})();
|
||||
@ -1,205 +0,0 @@
|
||||
/**
|
||||
* DesignCanvas — 变体并排网格布局
|
||||
*
|
||||
* 用于展示2+个静态设计variations让用户对比选择。
|
||||
* 每个variation有label,可hover放大。
|
||||
*
|
||||
* 用法:
|
||||
* <DesignCanvas
|
||||
* title="Hero区设计探索"
|
||||
* subtitle="3个方向对比"
|
||||
* columns={3}
|
||||
* >
|
||||
* <Variation label="Minimal" description="极简克制版">
|
||||
* <div>...你的设计1...</div>
|
||||
* </Variation>
|
||||
* <Variation label="Editorial" description="杂志编辑风">
|
||||
* <div>...你的设计2...</div>
|
||||
* </Variation>
|
||||
* <Variation label="Brutalist" description="粗粝原始">
|
||||
* <div>...你的设计3...</div>
|
||||
* </Variation>
|
||||
* </DesignCanvas>
|
||||
*
|
||||
* 配合React+Babel使用。放在合适的script里,然后window.DesignCanvas/window.Variation可用。
|
||||
*/
|
||||
|
||||
const canvasStyles = {
|
||||
container: {
|
||||
minHeight: '100vh',
|
||||
background: '#F5F5F0',
|
||||
padding: '40px 60px',
|
||||
fontFamily: '-apple-system, "SF Pro Text", "PingFang SC", sans-serif',
|
||||
},
|
||||
header: {
|
||||
marginBottom: 48,
|
||||
maxWidth: 900,
|
||||
},
|
||||
title: {
|
||||
fontSize: 36,
|
||||
fontWeight: 600,
|
||||
marginBottom: 12,
|
||||
color: '#1A1A1A',
|
||||
letterSpacing: '-0.02em',
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: 16,
|
||||
color: '#666',
|
||||
lineHeight: 1.5,
|
||||
},
|
||||
grid: {
|
||||
display: 'grid',
|
||||
gap: 32,
|
||||
},
|
||||
cell: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 12,
|
||||
},
|
||||
cellHeader: {
|
||||
display: 'flex',
|
||||
alignItems: 'baseline',
|
||||
gap: 12,
|
||||
paddingBottom: 8,
|
||||
borderBottom: '1px solid #E0E0DA',
|
||||
},
|
||||
label: {
|
||||
fontSize: 14,
|
||||
fontWeight: 600,
|
||||
color: '#1A1A1A',
|
||||
letterSpacing: '-0.01em',
|
||||
},
|
||||
description: {
|
||||
fontSize: 13,
|
||||
color: '#888',
|
||||
},
|
||||
frame: {
|
||||
background: '#fff',
|
||||
borderRadius: 4,
|
||||
border: '1px solid #E0E0DA',
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
transition: 'transform 0.2s ease, box-shadow 0.2s ease',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
frameInner: {
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
},
|
||||
badge: {
|
||||
position: 'absolute',
|
||||
top: 12,
|
||||
left: 12,
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
color: '#fff',
|
||||
padding: '3px 8px',
|
||||
borderRadius: 4,
|
||||
fontSize: 11,
|
||||
fontWeight: 500,
|
||||
letterSpacing: '0.5px',
|
||||
textTransform: 'uppercase',
|
||||
zIndex: 10,
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
};
|
||||
|
||||
function DesignCanvas({ title, subtitle, columns = 3, children }) {
|
||||
const [expanded, setExpanded] = React.useState(null);
|
||||
|
||||
const gridStyle = {
|
||||
...canvasStyles.grid,
|
||||
gridTemplateColumns: `repeat(${columns}, 1fr)`,
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={canvasStyles.container}>
|
||||
{(title || subtitle) && (
|
||||
<div style={canvasStyles.header}>
|
||||
{title && <h1 style={canvasStyles.title}>{title}</h1>}
|
||||
{subtitle && <p style={canvasStyles.subtitle}>{subtitle}</p>}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div style={gridStyle}>
|
||||
{React.Children.map(children, (child, idx) =>
|
||||
React.isValidElement(child)
|
||||
? React.cloneElement(child, {
|
||||
_index: idx,
|
||||
_expanded: expanded === idx,
|
||||
_onToggle: () => setExpanded(expanded === idx ? null : idx),
|
||||
})
|
||||
: child
|
||||
)}
|
||||
</div>
|
||||
|
||||
{expanded !== null && (
|
||||
<div
|
||||
onClick={() => setExpanded(null)}
|
||||
style={{
|
||||
position: 'fixed',
|
||||
inset: 0,
|
||||
background: 'rgba(0, 0, 0, 0.75)',
|
||||
zIndex: 1000,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
padding: 40,
|
||||
cursor: 'zoom-out',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
onClick={e => e.stopPropagation()}
|
||||
style={{
|
||||
background: '#fff',
|
||||
borderRadius: 8,
|
||||
overflow: 'hidden',
|
||||
maxWidth: '90vw',
|
||||
maxHeight: '90vh',
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
{React.Children.toArray(children)[expanded]}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Variation({ label, description, number, children, _index, _expanded, _onToggle, aspectRatio = '4 / 3' }) {
|
||||
const displayNumber = number || String(_index + 1).padStart(2, '0');
|
||||
|
||||
return (
|
||||
<div style={canvasStyles.cell}>
|
||||
<div style={canvasStyles.cellHeader}>
|
||||
<span style={{ ...canvasStyles.label, color: '#999', fontFamily: 'ui-monospace, monospace', fontSize: 12 }}>
|
||||
{displayNumber}
|
||||
</span>
|
||||
<span style={canvasStyles.label}>{label}</span>
|
||||
{description && <span style={canvasStyles.description}>— {description}</span>}
|
||||
</div>
|
||||
|
||||
<div
|
||||
onClick={_onToggle}
|
||||
style={{
|
||||
...canvasStyles.frame,
|
||||
aspectRatio,
|
||||
}}
|
||||
onMouseEnter={e => {
|
||||
e.currentTarget.style.boxShadow = '0 8px 24px rgba(0,0,0,0.08)';
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
e.currentTarget.style.boxShadow = 'none';
|
||||
}}
|
||||
>
|
||||
<div style={canvasStyles.frameInner}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
Object.assign(window, { DesignCanvas, Variation });
|
||||
}
|
||||
@ -1,192 +0,0 @@
|
||||
/**
|
||||
* IosFrame — iPhone设备边框
|
||||
*
|
||||
* 参考iPhone 15 Pro(393×852 logical pixels)
|
||||
* 含:灵动岛 + 状态栏(时间/信号/电池)+ Home Indicator + 圆角
|
||||
*
|
||||
* 用法:
|
||||
* <IosFrame time="9:41" battery={85}>
|
||||
* <YourAppContent />
|
||||
* </IosFrame>
|
||||
*
|
||||
* 自定义:
|
||||
* <IosFrame width={390} height={844} darkMode showKeyboard>
|
||||
* ...
|
||||
* </IosFrame>
|
||||
*/
|
||||
|
||||
const iosFrameStyles = {
|
||||
wrapper: {
|
||||
display: 'inline-block',
|
||||
padding: 12,
|
||||
background: '#000',
|
||||
borderRadius: 60,
|
||||
boxShadow: '0 0 0 2px #1f2937, 0 20px 60px rgba(0,0,0,0.3)',
|
||||
position: 'relative',
|
||||
},
|
||||
screen: {
|
||||
position: 'relative',
|
||||
borderRadius: 48,
|
||||
overflow: 'hidden',
|
||||
background: '#fff',
|
||||
},
|
||||
statusBar: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: 54,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
padding: '0 32px 0 32px',
|
||||
fontSize: 16,
|
||||
fontWeight: 600,
|
||||
fontFamily: '-apple-system, "SF Pro Text", sans-serif',
|
||||
zIndex: 20,
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
dynamicIsland: {
|
||||
position: 'absolute',
|
||||
top: 12,
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
width: 124,
|
||||
height: 36,
|
||||
background: '#000',
|
||||
borderRadius: 999,
|
||||
zIndex: 30,
|
||||
},
|
||||
statusIcons: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 6,
|
||||
},
|
||||
signalIcon: {
|
||||
display: 'flex',
|
||||
alignItems: 'flex-end',
|
||||
gap: 2,
|
||||
height: 12,
|
||||
},
|
||||
signalBar: {
|
||||
width: 3,
|
||||
background: 'currentColor',
|
||||
borderRadius: 1,
|
||||
},
|
||||
wifiIcon: {
|
||||
width: 16,
|
||||
height: 12,
|
||||
position: 'relative',
|
||||
},
|
||||
batteryIcon: {
|
||||
width: 26,
|
||||
height: 12,
|
||||
border: '1.5px solid currentColor',
|
||||
borderRadius: 3,
|
||||
padding: 1,
|
||||
position: 'relative',
|
||||
opacity: 0.8,
|
||||
},
|
||||
batteryCap: {
|
||||
position: 'absolute',
|
||||
top: 3,
|
||||
right: -3,
|
||||
width: 2,
|
||||
height: 6,
|
||||
background: 'currentColor',
|
||||
borderRadius: '0 1px 1px 0',
|
||||
},
|
||||
content: {
|
||||
position: 'absolute',
|
||||
top: 54,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 34,
|
||||
overflow: 'auto',
|
||||
},
|
||||
homeIndicator: {
|
||||
position: 'absolute',
|
||||
bottom: 10,
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
width: 140,
|
||||
height: 5,
|
||||
background: 'rgba(0,0,0,0.3)',
|
||||
borderRadius: 999,
|
||||
zIndex: 10,
|
||||
},
|
||||
homeIndicatorDark: {
|
||||
background: 'rgba(255,255,255,0.5)',
|
||||
},
|
||||
};
|
||||
|
||||
function IosFrame({
|
||||
children,
|
||||
width = 393,
|
||||
height = 852,
|
||||
time = '9:41',
|
||||
battery = 100,
|
||||
darkMode = false,
|
||||
showStatusBar = true,
|
||||
showDynamicIsland = true,
|
||||
showHomeIndicator = true,
|
||||
}) {
|
||||
const textColor = darkMode ? '#fff' : '#000';
|
||||
|
||||
return (
|
||||
<div style={iosFrameStyles.wrapper}>
|
||||
<div style={{
|
||||
...iosFrameStyles.screen,
|
||||
width,
|
||||
height,
|
||||
background: darkMode ? '#000' : '#fff',
|
||||
}}>
|
||||
{showStatusBar && (
|
||||
<div style={{ ...iosFrameStyles.statusBar, color: textColor }}>
|
||||
<span>{time}</span>
|
||||
<div style={iosFrameStyles.statusIcons}>
|
||||
<div style={iosFrameStyles.signalIcon}>
|
||||
<div style={{ ...iosFrameStyles.signalBar, height: 4 }} />
|
||||
<div style={{ ...iosFrameStyles.signalBar, height: 6 }} />
|
||||
<div style={{ ...iosFrameStyles.signalBar, height: 9 }} />
|
||||
<div style={{ ...iosFrameStyles.signalBar, height: 11 }} />
|
||||
</div>
|
||||
<svg width="16" height="12" viewBox="0 0 16 12" fill="none" style={{ color: textColor }}>
|
||||
<path d="M8 11.5a1 1 0 100-2 1 1 0 000 2z" fill="currentColor" />
|
||||
<path d="M3 7.5a7 7 0 0110 0" stroke="currentColor" strokeWidth="1.3" fill="none" strokeLinecap="round" />
|
||||
<path d="M1 4.5a11 11 0 0114 0" stroke="currentColor" strokeWidth="1.3" fill="none" strokeLinecap="round" opacity="0.7" />
|
||||
</svg>
|
||||
<div style={iosFrameStyles.batteryIcon}>
|
||||
<div style={{
|
||||
width: `${battery}%`,
|
||||
height: '100%',
|
||||
background: 'currentColor',
|
||||
borderRadius: 1,
|
||||
opacity: 0.9,
|
||||
}} />
|
||||
<div style={iosFrameStyles.batteryCap} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showDynamicIsland && <div style={iosFrameStyles.dynamicIsland} />}
|
||||
|
||||
<div style={iosFrameStyles.content}>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
{showHomeIndicator && (
|
||||
<div style={{
|
||||
...iosFrameStyles.homeIndicator,
|
||||
...(darkMode ? iosFrameStyles.homeIndicatorDark : {}),
|
||||
}} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.IosFrame = IosFrame;
|
||||
}
|
||||
@ -1,96 +0,0 @@
|
||||
/**
|
||||
* MacosWindow — macOS应用窗口边框(含traffic lights)
|
||||
*
|
||||
* 用法:
|
||||
* <MacosWindow title="Finder">
|
||||
* <YourAppContent />
|
||||
* </MacosWindow>
|
||||
*/
|
||||
|
||||
const macosWindowStyles = {
|
||||
window: {
|
||||
display: 'inline-block',
|
||||
background: '#fff',
|
||||
borderRadius: 10,
|
||||
overflow: 'hidden',
|
||||
boxShadow: '0 30px 80px rgba(0,0,0,0.25), 0 0 0 0.5px rgba(0,0,0,0.15)',
|
||||
},
|
||||
titleBar: {
|
||||
height: 38,
|
||||
background: 'linear-gradient(to bottom, #e8e8e8, #d8d8d8)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '0 14px',
|
||||
borderBottom: '0.5px solid rgba(0,0,0,0.1)',
|
||||
position: 'relative',
|
||||
userSelect: 'none',
|
||||
},
|
||||
trafficLights: {
|
||||
display: 'flex',
|
||||
gap: 8,
|
||||
alignItems: 'center',
|
||||
},
|
||||
light: {
|
||||
width: 12,
|
||||
height: 12,
|
||||
borderRadius: '50%',
|
||||
border: '0.5px solid rgba(0,0,0,0.15)',
|
||||
},
|
||||
close: { background: '#ff5f57' },
|
||||
minimize: { background: '#febc2e' },
|
||||
maximize: { background: '#28c840' },
|
||||
title: {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
right: 0,
|
||||
textAlign: 'center',
|
||||
fontSize: 13,
|
||||
color: '#333',
|
||||
fontWeight: 500,
|
||||
fontFamily: '-apple-system, "SF Pro Text", sans-serif',
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
content: {
|
||||
position: 'relative',
|
||||
overflow: 'auto',
|
||||
},
|
||||
titleBarDark: {
|
||||
background: 'linear-gradient(to bottom, #3c3c3c, #2c2c2c)',
|
||||
borderBottom: '0.5px solid rgba(255,255,255,0.1)',
|
||||
},
|
||||
titleDark: {
|
||||
color: '#ddd',
|
||||
},
|
||||
};
|
||||
|
||||
function MacosWindow({ title = '', width = 900, height = 600, darkMode = false, children }) {
|
||||
return (
|
||||
<div style={{ ...macosWindowStyles.window, background: darkMode ? '#1e1e1e' : '#fff' }}>
|
||||
<div style={{
|
||||
...macosWindowStyles.titleBar,
|
||||
...(darkMode ? macosWindowStyles.titleBarDark : {}),
|
||||
}}>
|
||||
<div style={macosWindowStyles.trafficLights}>
|
||||
<div style={{ ...macosWindowStyles.light, ...macosWindowStyles.close }} />
|
||||
<div style={{ ...macosWindowStyles.light, ...macosWindowStyles.minimize }} />
|
||||
<div style={{ ...macosWindowStyles.light, ...macosWindowStyles.maximize }} />
|
||||
</div>
|
||||
{title && (
|
||||
<div style={{
|
||||
...macosWindowStyles.title,
|
||||
...(darkMode ? macosWindowStyles.titleDark : {}),
|
||||
}}>
|
||||
{title}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div style={{ ...macosWindowStyles.content, width, height }}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.MacosWindow = MacosWindow;
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
{
|
||||
"_meta": {
|
||||
"description": "个人素材索引模板 — 复制此文件并填入你的真实数据",
|
||||
"how_to_use": "1. 复制此文件到 ~/.claude/memory/personal-asset-index.json 2. 填入你的真实信息 3. design-philosophy skill 会自动读取",
|
||||
"note": "真实数据文件不要放在 skill 目录内,避免随 skill 分发泄露隐私"
|
||||
},
|
||||
|
||||
"identity": {
|
||||
"real_name": "你的真名",
|
||||
"pen_names": ["笔名1", "笔名2"],
|
||||
"english_name": "English Name",
|
||||
"title": "你的头衔/一句话介绍",
|
||||
"bio_short": "50-100字简介",
|
||||
"bio_long": "200-300字详细介绍",
|
||||
"avatar_url": "头像URL",
|
||||
"source": "数据来源备注"
|
||||
},
|
||||
|
||||
"contact": {
|
||||
"email": "your@email.com",
|
||||
"wechat_personal": "微信号",
|
||||
"source": "数据来源备注"
|
||||
},
|
||||
|
||||
"social_media": {
|
||||
"github": {
|
||||
"url": "https://github.com/yourname",
|
||||
"username": "yourname"
|
||||
},
|
||||
"youtube": {
|
||||
"url": "https://www.youtube.com/@YourChannel",
|
||||
"channel_name": "频道名"
|
||||
},
|
||||
"source": "数据来源备注"
|
||||
},
|
||||
|
||||
"websites": {
|
||||
"main_site": {
|
||||
"url": "https://yoursite.com",
|
||||
"description": "网站描述",
|
||||
"local_path": "/path/to/local/project/"
|
||||
}
|
||||
},
|
||||
|
||||
"products": {
|
||||
"product_1": {
|
||||
"name": "产品名",
|
||||
"type": "iOS App / Web App / CLI Tool / 电子书",
|
||||
"achievement": "主要成就",
|
||||
"icon_path": "/path/to/icon.png",
|
||||
"project_path": "/path/to/project/"
|
||||
}
|
||||
},
|
||||
|
||||
"stats": {
|
||||
"social_followers": "粉丝数",
|
||||
"product_users": "用户数",
|
||||
"source": "数据来源备注"
|
||||
},
|
||||
|
||||
"design_assets": {
|
||||
"article_images": {
|
||||
"base_path": "/path/to/images/",
|
||||
"notable_sets": []
|
||||
}
|
||||
},
|
||||
|
||||
"knowledge_base": {
|
||||
"wechat_articles": "/path/to/knowledge_base/"
|
||||
}
|
||||
}
|
||||
@ -1,115 +0,0 @@
|
||||
# Design Philosophy Showcases — 样例资产索引
|
||||
|
||||
> 8 种场景 × 3 种风格 = 24 个预制设计样例
|
||||
> 用于 Phase 3 推荐设计方向时,直接展示「这个风格做出来长什么样」
|
||||
|
||||
## 风格说明
|
||||
|
||||
| 代号 | 流派 | 风格名称 | 视觉气质 |
|
||||
|------|------|---------|---------|
|
||||
| **Pentagram** | 信息建筑派 | Pentagram / Michael Bierut | 黑白克制、瑞士网格、强字体层级、#E63946红色强调 |
|
||||
| **Build** | 极简主义派 | Build Studio | 奢侈品级留白(70%+)、微妙字重(200-600)、#D4A574暖金、精致 |
|
||||
| **Takram** | 东方哲学派 | Takram | 柔和科技感、自然色(米色/灰/绿)、圆角、图表如艺术 |
|
||||
|
||||
## 场景速查表
|
||||
|
||||
### 内容设计场景
|
||||
|
||||
| # | 场景 | 规格 | Pentagram | Build | Takram |
|
||||
|---|------|------|-----------|-------|--------|
|
||||
| 1 | 公众号封面 | 1200×510 | `cover/cover-pentagram` | `cover/cover-build` | `cover/cover-takram` |
|
||||
| 2 | PPT数据页 | 1920×1080 | `ppt/ppt-pentagram` | `ppt/ppt-build` | `ppt/ppt-takram` |
|
||||
| 3 | 竖版信息图 | 1080×1920 | `infographic/infographic-pentagram` | `infographic/infographic-build` | `infographic/infographic-takram` |
|
||||
|
||||
### 网站设计场景
|
||||
|
||||
| # | 场景 | 规格 | Pentagram | Build | Takram |
|
||||
|---|------|------|-----------|-------|--------|
|
||||
| 4 | 个人主页 | 1440×900 | `website-homepage/homepage-pentagram` | `website-homepage/homepage-build` | `website-homepage/homepage-takram` |
|
||||
| 5 | AI导航站 | 1440×900 | `website-ai-nav/ainav-pentagram` | `website-ai-nav/ainav-build` | `website-ai-nav/ainav-takram` |
|
||||
| 6 | AI写作工具 | 1440×900 | `website-ai-writing/aiwriting-pentagram` | `website-ai-writing/aiwriting-build` | `website-ai-writing/aiwriting-takram` |
|
||||
| 7 | SaaS落地页 | 1440×900 | `website-saas/saas-pentagram` | `website-saas/saas-build` | `website-saas/saas-takram` |
|
||||
| 8 | 开发者文档 | 1440×900 | `website-devdocs/devdocs-pentagram` | `website-devdocs/devdocs-build` | `website-devdocs/devdocs-takram` |
|
||||
|
||||
> 每个条目同时有 `.html`(源码)和 `.png`(截图)两个文件
|
||||
|
||||
## 使用说明
|
||||
|
||||
### Phase 3 推荐时引用
|
||||
推荐设计方向后,可展示对应场景的预制截图:
|
||||
```
|
||||
「这是 Pentagram 风格做公众号封面的效果 → [展示 cover/cover-pentagram.png]」
|
||||
「Takram 风格做 PPT 数据页是这种感觉 → [展示 ppt/ppt-takram.png]」
|
||||
```
|
||||
|
||||
### 场景匹配优先级
|
||||
1. 用户需求的场景有精确匹配 → 直接展示对应场景
|
||||
2. 无精确匹配但类型相近 → 展示最近似的场景(如「产品官网」→ 展示 SaaS 落地页)
|
||||
3. 完全不匹配 → 跳过预制样例,直接进 Phase 3.5 现场生成
|
||||
|
||||
### 横向对比展示
|
||||
同一场景的 3 个风格适合并排展示,帮助用户直观比较:
|
||||
- 「这是同一个公众号封面,分别用 3 种风格实现的效果」
|
||||
- 展示顺序:Pentagram(理性克制)→ Build(奢华极简)→ Takram(柔和温暖)
|
||||
|
||||
## 内容详情
|
||||
|
||||
### 公众号封面(cover/)
|
||||
- 内容:Claude Code Agent 工作流 — 8 个并行 Agent 架构
|
||||
- Pentagram:巨大红色「8」+ 瑞士网格线 + 数据条
|
||||
- Build:超细字重「Agent」悬浮于 70% 留白中 + 暖金细线
|
||||
- Takram:8 节点放射状流程图作为艺术品 + 米色底
|
||||
|
||||
### PPT数据页(ppt/)
|
||||
- 内容:GLM-4.7 开源模型 Coding 能力突破(AIME 95.7 / SWE-bench 73.8% / τ²-Bench 87.4)
|
||||
- Pentagram:260px「95.7」锚点 + 红/灰/浅灰对比条形图
|
||||
- Build:三组 120px 超细数字悬浮 + 暖金渐变对比条
|
||||
- Takram:SVG 雷达图 + 三色叠加 + 圆角数据卡片
|
||||
|
||||
### 竖版信息图(infographic/)
|
||||
- 内容:AI 记忆系统 CLAUDE.md 从 93KB 优化到 22KB
|
||||
- Pentagram:巨大「93→22」数字 + 编号区块 + CSS 数据条
|
||||
- Build:极致留白 + 柔影卡片 + 暖金连接线
|
||||
- Takram:SVG 环形图 + 有机曲线流程图 + 毛玻璃卡片
|
||||
|
||||
### 个人主页(website-homepage/)
|
||||
- 内容:独立开发者 Alex Chen 的作品集首页
|
||||
- Pentagram:112px 大名 + 瑞士网格分栏 + 编辑数字
|
||||
- Build:玻璃态导航 + 悬浮统计卡片 + 超细字重
|
||||
- Takram:纸质纹理 + 小圆形头像 + 发丝细分隔线 + 不对称布局
|
||||
|
||||
### AI导航站(website-ai-nav/)
|
||||
- 内容:AI Compass — 500+ AI 工具目录
|
||||
- Pentagram:方角搜索框 + 编号工具列表 + 大写分类标签
|
||||
- Build:圆角搜索框 + 精致白色工具卡片 + 药丸标签
|
||||
- Takram:有机错位卡片布局 + 柔和分类标签 + 图表式连接
|
||||
|
||||
### AI写作工具(website-ai-writing/)
|
||||
- 内容:Inkwell — AI 写作助手
|
||||
- Pentagram:86px 大标题 + 线框编辑器模型 + 网格特性列
|
||||
- Build:漂浮编辑器卡片 + 暖金 CTA + 奢华写作体验
|
||||
- Takram:诗意衬线标题 + 有机编辑器 + 流程图
|
||||
|
||||
### SaaS落地页(website-saas/)
|
||||
- 内容:Meridian — 商业智能分析平台
|
||||
- Pentagram:黑白分栏 + 结构化仪表盘 + 140px「3x」锚点
|
||||
- Build:悬浮仪表盘卡片 + SVG 面积图 + 暖金渐变
|
||||
- Takram:圆角柱状图 + 流程节点 + 柔和地球色
|
||||
|
||||
### 开发者文档(website-devdocs/)
|
||||
- 内容:Nexus API — 统一 AI 模型网关
|
||||
- Pentagram:左侧导航栏 + 方角代码块 + 红色字符串高亮
|
||||
- Build:居中漂浮代码卡片 + 柔影 + 暖金图标
|
||||
- Takram:米色代码块 + 流程图连接 + 虚线特性卡片
|
||||
|
||||
## 文件统计
|
||||
|
||||
- HTML 源文件:24 个
|
||||
- PNG 截图:24 个
|
||||
- 总资产:48 个文件
|
||||
|
||||
---
|
||||
|
||||
**版本**:v1.0
|
||||
**创建日期**:2026-02-13
|
||||
**适用于**:design-philosophy skill Phase 3 推荐环节
|
||||
@ -1,235 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1200">
|
||||
<title>Claude Code Agent - Build Studio Style</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1200px;
|
||||
height: 510px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #FAFAF8;
|
||||
font-family: 'Inter', sans-serif;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Subtle top gradient wash */
|
||||
.wash {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 1200px;
|
||||
height: 510px;
|
||||
background: radial-gradient(ellipse 800px 400px at 30% 40%, rgba(212, 165, 116, 0.06) 0%, transparent 70%);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* Main layout */
|
||||
.layout {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 1200px;
|
||||
height: 510px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.center-block {
|
||||
text-align: center;
|
||||
max-width: 700px;
|
||||
margin-top: -24px; /* slight upward shift for golden ratio vertical center */
|
||||
}
|
||||
|
||||
/* Floating "Agent" */
|
||||
.floating-agent {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 200;
|
||||
font-size: 128px;
|
||||
letter-spacing: -4px;
|
||||
color: #1A1A18;
|
||||
line-height: 1;
|
||||
margin-bottom: 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.floating-agent span {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Slight weight shift on first letter for visual interest */
|
||||
.floating-agent .accent-letter {
|
||||
font-weight: 300;
|
||||
color: #2A2A28;
|
||||
}
|
||||
|
||||
/* Gold underline accent */
|
||||
.gold-line {
|
||||
width: 48px;
|
||||
height: 1px;
|
||||
background: #D4A574;
|
||||
margin: 0 auto 32px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* Subtitle — label tier: smallest text, widest spacing */
|
||||
.subtitle {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 10px;
|
||||
letter-spacing: 6px;
|
||||
text-transform: uppercase;
|
||||
color: #B0ACA4;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
/* Description line — body tier */
|
||||
.desc {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 13px;
|
||||
color: #A8A4A0;
|
||||
letter-spacing: 0.3px;
|
||||
line-height: 2;
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Minimal agent indicators — 8 thin vertical lines */
|
||||
.agent-indicators {
|
||||
position: absolute;
|
||||
bottom: 48px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: flex-end;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.indicator {
|
||||
width: 1px;
|
||||
background: #D8D4CE;
|
||||
border-radius: 0.5px;
|
||||
}
|
||||
|
||||
.indicator.gold {
|
||||
background: #D4A574;
|
||||
width: 1.5px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Corner marks */
|
||||
.corner-mark {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.corner-mark svg {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.corner-tl { top: 48px; left: 48px; }
|
||||
.corner-br { bottom: 48px; right: 48px; transform: rotate(180deg); }
|
||||
|
||||
/* Side text */
|
||||
.side-label {
|
||||
position: absolute;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 8px;
|
||||
letter-spacing: 4px;
|
||||
text-transform: uppercase;
|
||||
color: #CBC7C0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.side-left {
|
||||
left: 48px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%) rotate(-90deg);
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
.side-right {
|
||||
right: 48px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%) rotate(90deg);
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
/* Removed shadow-card — Build purity demands uninterrupted whitespace */
|
||||
|
||||
/* Number 8 whisper */
|
||||
.number-whisper {
|
||||
position: absolute;
|
||||
top: 48px;
|
||||
right: 96px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 200;
|
||||
font-size: 24px;
|
||||
color: #D4A574;
|
||||
opacity: 0.35;
|
||||
z-index: 2;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="wash"></div>
|
||||
|
||||
<!-- Corner marks -->
|
||||
<div class="corner-mark corner-tl">
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0L0 20" stroke="#D4A574" stroke-width="0.5" opacity="0.4"/>
|
||||
<path d="M0 0L20 0" stroke="#D4A574" stroke-width="0.5" opacity="0.4"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="corner-mark corner-br">
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0L0 20" stroke="#D4A574" stroke-width="0.5" opacity="0.4"/>
|
||||
<path d="M0 0L20 0" stroke="#D4A574" stroke-width="0.5" opacity="0.4"/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- Side labels -->
|
||||
<div class="side-label side-left">Claude Code</div>
|
||||
<div class="side-label side-right">Parallel Workflow</div>
|
||||
|
||||
<!-- Number whisper -->
|
||||
<div class="number-whisper">8</div>
|
||||
|
||||
<!-- Main content -->
|
||||
<div class="layout">
|
||||
<div class="center-block">
|
||||
<div class="subtitle">Parallel Architecture</div>
|
||||
<div class="floating-agent"><span><span class="accent-letter">A</span>gent</span></div>
|
||||
<div class="gold-line"></div>
|
||||
<div class="desc">
|
||||
Eight autonomous agents orchestrated in parallel,<br>
|
||||
each solving a distinct piece of the whole.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Agent indicators -->
|
||||
<div class="agent-indicators">
|
||||
<div class="indicator" style="height: 20px;"></div>
|
||||
<div class="indicator" style="height: 28px;"></div>
|
||||
<div class="indicator gold" style="height: 36px;"></div>
|
||||
<div class="indicator" style="height: 22px;"></div>
|
||||
<div class="indicator" style="height: 32px;"></div>
|
||||
<div class="indicator gold" style="height: 40px;"></div>
|
||||
<div class="indicator" style="height: 24px;"></div>
|
||||
<div class="indicator" style="height: 30px;"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 114 KiB |
@ -1,229 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1200">
|
||||
<title>Agent Parallel — Pentagram Style Cover</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1200px;
|
||||
height: 510px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #FFFFFF;
|
||||
font-family: 'Helvetica Neue', 'Arial', sans-serif;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Grid rules — Swiss grid visible structure */
|
||||
.rule-h {
|
||||
position: absolute;
|
||||
left: 64px;
|
||||
right: 64px;
|
||||
height: 1px;
|
||||
background: #000;
|
||||
opacity: 0.06;
|
||||
}
|
||||
|
||||
.rule-v {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
background: #000;
|
||||
opacity: 0.04;
|
||||
}
|
||||
|
||||
/* Giant typographic element — the "8" bleeds off right edge */
|
||||
.type-anchor {
|
||||
position: absolute;
|
||||
right: -60px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-weight: 900;
|
||||
font-size: 640px;
|
||||
line-height: 0.82;
|
||||
color: #000;
|
||||
opacity: 0.07;
|
||||
z-index: 0;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* Red geometric dot grid — 8 dots representing 8 agents */
|
||||
.dot-grid {
|
||||
position: absolute;
|
||||
right: 340px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 24px);
|
||||
grid-template-rows: repeat(2, 24px);
|
||||
gap: 16px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #000;
|
||||
opacity: 0.12;
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.dot.active {
|
||||
background: #E63946;
|
||||
opacity: 0.8;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
/* Primary content zone — left-aligned on Swiss grid */
|
||||
.content {
|
||||
position: absolute;
|
||||
left: 64px;
|
||||
top: 56px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 4px;
|
||||
text-transform: uppercase;
|
||||
color: #E63946;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-weight: 900;
|
||||
font-size: 120px;
|
||||
line-height: 0.9;
|
||||
color: #000;
|
||||
letter-spacing: -5px;
|
||||
}
|
||||
|
||||
.title .accent {
|
||||
color: #E63946;
|
||||
}
|
||||
|
||||
/* Bottom information bar */
|
||||
.bottom-bar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 48px;
|
||||
background: #000;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 64px;
|
||||
}
|
||||
|
||||
.bottom-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.bottom-stat {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #fff;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.bottom-stat strong {
|
||||
color: #E63946;
|
||||
opacity: 1;
|
||||
font-size: 16px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.bottom-right {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 3px;
|
||||
text-transform: uppercase;
|
||||
color: #fff;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
/* Subtitle */
|
||||
.subtitle {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #999;
|
||||
letter-spacing: 0.5px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* Horizontal red rule through center */
|
||||
.center-rule {
|
||||
position: absolute;
|
||||
left: 64px;
|
||||
width: 240px;
|
||||
height: 3px;
|
||||
background: #E63946;
|
||||
top: 306px;
|
||||
z-index: 2;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Grid structure -->
|
||||
<div class="rule-h" style="top: 56px;"></div>
|
||||
<div class="rule-v" style="left: 64px;"></div>
|
||||
<div class="rule-v" style="left: 600px;"></div>
|
||||
<div class="rule-v" style="right: 64px;"></div>
|
||||
|
||||
<!-- Typographic anchor — bleeds right -->
|
||||
<div class="type-anchor">8</div>
|
||||
|
||||
<!-- 8-dot grid representing agents -->
|
||||
<div class="dot-grid">
|
||||
<div class="dot active"></div>
|
||||
<div class="dot"></div>
|
||||
<div class="dot active"></div>
|
||||
<div class="dot"></div>
|
||||
<div class="dot"></div>
|
||||
<div class="dot active"></div>
|
||||
<div class="dot"></div>
|
||||
<div class="dot active"></div>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="content">
|
||||
<div class="label">Claude Code Architecture</div>
|
||||
<div class="title">Agent<br><span class="accent">Parallel</span></div>
|
||||
<div class="subtitle">8 autonomous agents running in unified workflow</div>
|
||||
</div>
|
||||
|
||||
<!-- Red horizontal rule -->
|
||||
<div class="center-rule"></div>
|
||||
|
||||
<!-- Black bottom bar with data -->
|
||||
<div class="bottom-bar">
|
||||
<div class="bottom-left">
|
||||
<div class="bottom-stat"><strong>8</strong>Agents</div>
|
||||
<div class="bottom-stat"><strong>3.2x</strong>Faster</div>
|
||||
<div class="bottom-stat"><strong>1</strong>Workflow</div>
|
||||
</div>
|
||||
<div class="bottom-right">Pentagram Design System</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 35 KiB |
@ -1,288 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1200">
|
||||
<title>Claude Code Agent - Takram Style</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&family=Noto+Serif+SC:wght@300;400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1200px;
|
||||
height: 510px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #F5F0EB;
|
||||
font-family: 'Inter', sans-serif;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Subtle paper texture overlay */
|
||||
.texture {
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
width: 1200px;
|
||||
height: 510px;
|
||||
background:
|
||||
radial-gradient(ellipse 500px 400px at 72% 50%, rgba(168, 181, 160, 0.06) 0%, transparent 70%),
|
||||
radial-gradient(ellipse 300px 250px at 15% 40%, rgba(232, 228, 220, 0.2) 0%, transparent 60%);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* Flow diagram — the art piece */
|
||||
.diagram {
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
width: 1200px;
|
||||
height: 510px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Left text panel */
|
||||
.text-panel {
|
||||
position: absolute;
|
||||
left: 72px;
|
||||
top: 56px;
|
||||
z-index: 2;
|
||||
max-width: 360px;
|
||||
}
|
||||
|
||||
.text-panel .label {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 9px;
|
||||
letter-spacing: 3px;
|
||||
text-transform: uppercase;
|
||||
color: #6B8F71;
|
||||
margin-bottom: 20px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.text-panel .title-main {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-weight: 500;
|
||||
font-size: 52px;
|
||||
color: #2D3436;
|
||||
line-height: 1.15;
|
||||
letter-spacing: -0.5px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.text-panel .title-sub {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-weight: 300;
|
||||
font-size: 20px;
|
||||
color: #6D685F;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.text-panel .title-en {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 13px;
|
||||
color: #9A958D;
|
||||
letter-spacing: 0.3px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
/* Bottom annotation */
|
||||
.annotation {
|
||||
position: absolute;
|
||||
left: 72px;
|
||||
bottom: 40px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.annotation .note {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 10px;
|
||||
color: #B0AAA0;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.annotation .note-serif {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-weight: 300;
|
||||
font-size: 11px;
|
||||
color: #9A958D;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* Right side number */
|
||||
.spec-number {
|
||||
position: absolute;
|
||||
right: 72px;
|
||||
bottom: 40px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 10px;
|
||||
color: #B0AAA0;
|
||||
letter-spacing: 1px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* Agent node styling */
|
||||
.node-label {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 9px;
|
||||
font-weight: 400;
|
||||
fill: #8A857D;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.node-label-serif {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
fill: #6D685F;
|
||||
}
|
||||
|
||||
.node-index {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 7px;
|
||||
font-weight: 400;
|
||||
fill: #B0AAA0;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="texture"></div>
|
||||
|
||||
<!-- Text panel -->
|
||||
<div class="text-panel">
|
||||
<div class="label">Speculative Architecture</div>
|
||||
<div class="title-main">协作智能体</div>
|
||||
<div class="title-sub">Parallel Workflow</div>
|
||||
<div class="title-en">
|
||||
Eight agents, each autonomous,<br>
|
||||
converging toward a shared intent.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- The diagram as art -->
|
||||
<svg class="diagram" viewBox="0 0 1200 510" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<!-- Subtle background grid hints (Takram spec-drawing aesthetic) -->
|
||||
<line x1="440" y1="0" x2="440" y2="510" stroke="#E8E4DC" stroke-width="0.3" opacity="0.4"/>
|
||||
<line x1="760" y1="0" x2="760" y2="510" stroke="#E8E4DC" stroke-width="0.3" opacity="0.3"/>
|
||||
|
||||
<!-- Subtle outer orbital paths — layered ellipses for depth -->
|
||||
<ellipse cx="760" cy="255" rx="260" ry="195" fill="none" stroke="#E0DCD5" stroke-width="0.5" stroke-dasharray="1,8" opacity="0.5"/>
|
||||
<ellipse cx="760" cy="255" rx="180" ry="135" fill="none" stroke="#D8D3CB" stroke-width="0.4" stroke-dasharray="2,6" opacity="0.35"/>
|
||||
|
||||
<!-- Central orchestrator node — refined with layered depth -->
|
||||
<circle cx="760" cy="255" r="48" fill="none" stroke="#6B8F71" stroke-width="0.5" opacity="0.12" stroke-dasharray="2,4"/>
|
||||
<circle cx="760" cy="255" r="36" fill="none" stroke="#6B8F71" stroke-width="0.8" opacity="0.18"/>
|
||||
<circle cx="760" cy="255" r="24" fill="none" stroke="#6B8F71" stroke-width="1.2" opacity="0.3"/>
|
||||
<circle cx="760" cy="255" r="14" fill="rgba(107,143,113,0.05)"/>
|
||||
<circle cx="760" cy="255" r="5.5" fill="#6B8F71" opacity="0.55"/>
|
||||
<circle cx="760" cy="255" r="2" fill="#6B8F71" opacity="0.9"/>
|
||||
<text x="760" y="312" text-anchor="middle" class="node-label-serif">Orchestrator</text>
|
||||
<!-- Subtle cross-hair on center -->
|
||||
<line x1="748" y1="255" x2="730" y2="255" stroke="#6B8F71" stroke-width="0.3" opacity="0.15"/>
|
||||
<line x1="772" y1="255" x2="790" y2="255" stroke="#6B8F71" stroke-width="0.3" opacity="0.15"/>
|
||||
<line x1="760" y1="243" x2="760" y2="225" stroke="#6B8F71" stroke-width="0.3" opacity="0.15"/>
|
||||
<line x1="760" y1="267" x2="760" y2="285" stroke="#6B8F71" stroke-width="0.3" opacity="0.15"/>
|
||||
|
||||
<!-- Agent 1 — top-left (Research) -->
|
||||
<line x1="738" y1="232" x2="598" y2="118" stroke="#C8C2B8" stroke-width="0.7" stroke-dasharray="3,5"/>
|
||||
<rect x="560" y="92" width="76" height="38" rx="14" fill="rgba(245,240,235,0.7)" stroke="#B8B2A8" stroke-width="0.8"/>
|
||||
<circle cx="598" cy="111" r="3.5" fill="#6B8F71" opacity="0.5"/>
|
||||
<text x="598" y="144" text-anchor="middle" class="node-label">Research</text>
|
||||
<text x="560" y="88" class="node-index">01</text>
|
||||
|
||||
<!-- Agent 2 — top (Analysis) -->
|
||||
<line x1="760" y1="217" x2="760" y2="145" stroke="#C8C2B8" stroke-width="0.7" stroke-dasharray="3,5"/>
|
||||
<rect x="722" y="100" width="76" height="38" rx="14" fill="rgba(245,240,235,0.7)" stroke="#B8B2A8" stroke-width="0.8"/>
|
||||
<circle cx="760" cy="119" r="3.5" fill="#6B8F71" opacity="0.5"/>
|
||||
<text x="760" y="152" text-anchor="middle" class="node-label">Analysis</text>
|
||||
<text x="722" y="96" class="node-index">02</text>
|
||||
|
||||
<!-- Agent 3 — top-right (Code) -->
|
||||
<line x1="782" y1="232" x2="918" y2="118" stroke="#C8C2B8" stroke-width="0.7" stroke-dasharray="3,5"/>
|
||||
<rect x="884" y="92" width="76" height="38" rx="14" fill="rgba(245,240,235,0.7)" stroke="#B8B2A8" stroke-width="0.8"/>
|
||||
<circle cx="922" cy="111" r="3.5" fill="#6B8F71" opacity="0.5"/>
|
||||
<text x="922" y="144" text-anchor="middle" class="node-label">Code</text>
|
||||
<text x="884" y="88" class="node-index">03</text>
|
||||
|
||||
<!-- Agent 4 — right (Test) -->
|
||||
<line x1="786" y1="252" x2="940" y2="215" stroke="#C8C2B8" stroke-width="0.7" stroke-dasharray="3,5"/>
|
||||
<rect x="940" y="196" width="76" height="38" rx="14" fill="rgba(245,240,235,0.7)" stroke="#B8B2A8" stroke-width="0.8"/>
|
||||
<circle cx="978" cy="215" r="3.5" fill="#6B8F71" opacity="0.5"/>
|
||||
<text x="978" y="248" text-anchor="middle" class="node-label">Test</text>
|
||||
<text x="940" y="192" class="node-index">04</text>
|
||||
|
||||
<!-- Agent 5 — bottom-right (Review) -->
|
||||
<line x1="782" y1="278" x2="918" y2="385" stroke="#C8C2B8" stroke-width="0.7" stroke-dasharray="3,5"/>
|
||||
<rect x="884" y="368" width="76" height="38" rx="14" fill="rgba(245,240,235,0.7)" stroke="#B8B2A8" stroke-width="0.8"/>
|
||||
<circle cx="922" cy="387" r="3.5" fill="#6B8F71" opacity="0.5"/>
|
||||
<text x="922" y="420" text-anchor="middle" class="node-label">Review</text>
|
||||
<text x="884" y="364" class="node-index">05</text>
|
||||
|
||||
<!-- Agent 6 — bottom (Deploy) -->
|
||||
<line x1="760" y1="293" x2="760" y2="365" stroke="#C8C2B8" stroke-width="0.7" stroke-dasharray="3,5"/>
|
||||
<rect x="722" y="370" width="76" height="38" rx="14" fill="rgba(245,240,235,0.7)" stroke="#B8B2A8" stroke-width="0.8"/>
|
||||
<circle cx="760" cy="389" r="3.5" fill="#6B8F71" opacity="0.5"/>
|
||||
<text x="760" y="422" text-anchor="middle" class="node-label">Deploy</text>
|
||||
<text x="722" y="366" class="node-index">06</text>
|
||||
|
||||
<!-- Agent 7 — bottom-left (Monitor) -->
|
||||
<line x1="738" y1="278" x2="600" y2="375" stroke="#C8C2B8" stroke-width="0.7" stroke-dasharray="3,5"/>
|
||||
<rect x="562" y="358" width="76" height="38" rx="14" fill="rgba(245,240,235,0.7)" stroke="#B8B2A8" stroke-width="0.8"/>
|
||||
<circle cx="600" cy="377" r="3.5" fill="#6B8F71" opacity="0.5"/>
|
||||
<text x="600" y="410" text-anchor="middle" class="node-label">Monitor</text>
|
||||
<text x="562" y="354" class="node-index">07</text>
|
||||
|
||||
<!-- Agent 8 — left (Design) -->
|
||||
<line x1="734" y1="252" x2="578" y2="245" stroke="#C8C2B8" stroke-width="0.7" stroke-dasharray="3,5"/>
|
||||
<rect x="502" y="226" width="76" height="38" rx="14" fill="rgba(245,240,235,0.7)" stroke="#B8B2A8" stroke-width="0.8"/>
|
||||
<circle cx="540" cy="245" r="3.5" fill="#6B8F71" opacity="0.5"/>
|
||||
<text x="540" y="278" text-anchor="middle" class="node-label">Design</text>
|
||||
<text x="502" y="222" class="node-index">08</text>
|
||||
|
||||
<!-- Small annotation marks — Takram spec-drawing details -->
|
||||
<circle cx="490" cy="120" r="1.2" fill="#B0AAA0" opacity="0.35"/>
|
||||
<line x1="492" y1="120" x2="535" y2="120" stroke="#B0AAA0" stroke-width="0.4" opacity="0.25"/>
|
||||
|
||||
<circle cx="1040" cy="390" r="1.2" fill="#B0AAA0" opacity="0.35"/>
|
||||
<line x1="1038" y1="390" x2="995" y2="390" stroke="#B0AAA0" stroke-width="0.4" opacity="0.25"/>
|
||||
|
||||
<!-- Dimension annotation line (top) -->
|
||||
<line x1="540" y1="60" x2="980" y2="60" stroke="#D4CFC6" stroke-width="0.4" opacity="0.3"/>
|
||||
<line x1="540" y1="55" x2="540" y2="65" stroke="#D4CFC6" stroke-width="0.4" opacity="0.3"/>
|
||||
<line x1="980" y1="55" x2="980" y2="65" stroke="#D4CFC6" stroke-width="0.4" opacity="0.3"/>
|
||||
<text x="760" y="54" text-anchor="middle" font-family="Inter" font-size="7" font-weight="300" fill="#C8C2B8" letter-spacing="1.5">AGENT FIELD</text>
|
||||
|
||||
<!-- Right-side vertical annotation -->
|
||||
<line x1="1060" y1="130" x2="1060" y2="380" stroke="#D4CFC6" stroke-width="0.3" opacity="0.25"/>
|
||||
<line x1="1056" y1="130" x2="1064" y2="130" stroke="#D4CFC6" stroke-width="0.3" opacity="0.25"/>
|
||||
<line x1="1056" y1="380" x2="1064" y2="380" stroke="#D4CFC6" stroke-width="0.3" opacity="0.25"/>
|
||||
<text x="1068" y="260" font-family="Inter" font-size="7" font-weight="300" fill="#D4CFC6" letter-spacing="0.5" transform="rotate(90, 1068, 260)">NETWORK DEPTH</text>
|
||||
|
||||
<!-- Subtle data pulse lines emanating from center (organic feel) -->
|
||||
<path d="M 760 217 Q 755 200 758 185" fill="none" stroke="#6B8F71" stroke-width="0.3" opacity="0.12"/>
|
||||
<path d="M 786 248 Q 810 230 835 225" fill="none" stroke="#6B8F71" stroke-width="0.3" opacity="0.12"/>
|
||||
<path d="M 786 262 Q 815 275 840 290" fill="none" stroke="#6B8F71" stroke-width="0.3" opacity="0.12"/>
|
||||
|
||||
<!-- Top-right spec box -->
|
||||
<rect x="1040" y="48" width="104" height="56" rx="3" fill="rgba(245,240,235,0.5)" stroke="#E0DCD5" stroke-width="0.6"/>
|
||||
<text x="1052" y="66" font-family="Inter" font-size="8" font-weight="500" fill="#B0AAA0" letter-spacing="1.5">AGENTS</text>
|
||||
<text x="1052" y="92" font-family="Inter" font-size="28" font-weight="300" fill="#6B8F71">8</text>
|
||||
<text x="1082" y="92" font-family="Inter" font-size="9" font-weight="300" fill="#B0AAA0"> parallel</text>
|
||||
</svg>
|
||||
|
||||
<!-- Bottom annotation -->
|
||||
<div class="annotation">
|
||||
<div class="note">Fig. 01 — Parallel Agent Architecture</div>
|
||||
<div class="note-serif">Claude Code 协作编排模型</div>
|
||||
</div>
|
||||
|
||||
<!-- Spec number -->
|
||||
<div class="spec-number">v1.0 / 2026</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 152 KiB |
@ -1,503 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1080">
|
||||
<title>AI Memory System Optimization — Build Studio Style</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1080px;
|
||||
height: 1920px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #FAFAF8;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #2A2A2A;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 80px 80px 64px 80px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.label {
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 5px;
|
||||
text-transform: uppercase;
|
||||
color: #B0ACA4;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.title {
|
||||
font-size: 36px;
|
||||
font-weight: 200;
|
||||
line-height: 1.35;
|
||||
color: #1A1A1A;
|
||||
letter-spacing: -0.5px;
|
||||
max-width: 680px;
|
||||
}
|
||||
.title strong {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Hero Numbers */
|
||||
.hero {
|
||||
margin-top: 56px;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 48px;
|
||||
}
|
||||
.hero-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.hero-label {
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 4px;
|
||||
text-transform: uppercase;
|
||||
color: #B0ACA4;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.hero-number {
|
||||
font-size: 112px;
|
||||
font-weight: 200;
|
||||
line-height: 0.9;
|
||||
color: #1A1A1A;
|
||||
letter-spacing: -4px;
|
||||
}
|
||||
.hero-number .unit {
|
||||
font-size: 28px;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0;
|
||||
color: #B0ACA4;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.hero-number.gold {
|
||||
color: #1A1A1A;
|
||||
}
|
||||
.hero-number.gold .unit {
|
||||
color: #D4A574;
|
||||
opacity: 0.7;
|
||||
}
|
||||
.hero-number.gold .dot-accent {
|
||||
color: #D4A574;
|
||||
}
|
||||
.hero-connector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.hero-connector svg {
|
||||
opacity: 0.25;
|
||||
}
|
||||
.hero-reduction {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.reduction-badge {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #D4A574;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
/* Subtle line */
|
||||
.divider {
|
||||
width: 48px;
|
||||
height: 1px;
|
||||
background: #D4A574;
|
||||
margin: 48px 0;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
/* Stats Row */
|
||||
.stats-row {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
}
|
||||
.stat-item {
|
||||
flex: 1;
|
||||
padding: 24px 0;
|
||||
position: relative;
|
||||
}
|
||||
.stat-item::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 1px;
|
||||
height: 40px;
|
||||
background: #E0DCDA;
|
||||
}
|
||||
.stat-item:last-child::after {
|
||||
display: none;
|
||||
}
|
||||
.stat-value {
|
||||
font-size: 40px;
|
||||
font-weight: 200;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.stat-desc {
|
||||
font-size: 11px;
|
||||
font-weight: 300;
|
||||
color: #B0ACA4;
|
||||
line-height: 1.5;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
/* Memory Cards */
|
||||
.cards-section {
|
||||
margin-top: 40px;
|
||||
}
|
||||
.cards-label {
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 5px;
|
||||
text-transform: uppercase;
|
||||
color: #B0ACA4;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.cards-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
.card {
|
||||
background: #FFFFFF;
|
||||
padding: 32px;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.03), 0 4px 16px rgba(0,0,0,0.02);
|
||||
border-radius: 2px;
|
||||
position: relative;
|
||||
}
|
||||
.card-index {
|
||||
font-size: 40px;
|
||||
font-weight: 200;
|
||||
color: #E8E4E0;
|
||||
line-height: 1;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.card-title-zh {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #1A1A1A;
|
||||
margin-bottom: 4px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.card-title-en {
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
color: #C0BCB6;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.card-desc {
|
||||
font-size: 12px;
|
||||
font-weight: 300;
|
||||
color: #999;
|
||||
line-height: 1.7;
|
||||
}
|
||||
.card.featured {
|
||||
border-left: 1.5px solid #D4A574;
|
||||
}
|
||||
.card.featured .card-index {
|
||||
color: #D4A574;
|
||||
opacity: 0.35;
|
||||
}
|
||||
|
||||
/* Flow */
|
||||
.flow-section {
|
||||
margin-top: 40px;
|
||||
}
|
||||
.flow-label {
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 5px;
|
||||
text-transform: uppercase;
|
||||
color: #B0ACA4;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.flow-timeline {
|
||||
position: relative;
|
||||
padding-left: 0;
|
||||
}
|
||||
.flow-steps {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
}
|
||||
.flow-steps::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 36px;
|
||||
right: 36px;
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, #E0DCDA, #D4A574 50%, #E0DCDA);
|
||||
}
|
||||
.flow-step {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.flow-dot {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background: #FAFAF8;
|
||||
border: 1px solid #D0CCC6;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.flow-dot.active {
|
||||
border-color: #D4A574;
|
||||
background: #D4A574;
|
||||
}
|
||||
.flow-step-label {
|
||||
font-size: 9px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #C0BCB6;
|
||||
}
|
||||
.flow-step-text {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #2A2A2A;
|
||||
text-align: center;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* Quote */
|
||||
.quote-section {
|
||||
margin-top: 0;
|
||||
padding-top: 32px;
|
||||
border-top: 1px solid #EEECE8;
|
||||
}
|
||||
.quote-line {
|
||||
width: 32px;
|
||||
height: 1px;
|
||||
background: #D4A574;
|
||||
margin-bottom: 24px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.quote-text {
|
||||
font-size: 22px;
|
||||
font-weight: 200;
|
||||
color: #1A1A1A;
|
||||
line-height: 1.6;
|
||||
letter-spacing: -0.3px;
|
||||
max-width: 680px;
|
||||
}
|
||||
.quote-text em {
|
||||
font-style: normal;
|
||||
color: #D4A574;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* Results */
|
||||
.results-row {
|
||||
display: flex;
|
||||
gap: 48px;
|
||||
margin-top: 32px;
|
||||
}
|
||||
.result-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.result-icon {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: #D4A574;
|
||||
flex-shrink: 0;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.result-text {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
margin-top: 32px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.footer-text {
|
||||
font-size: 9px;
|
||||
font-weight: 300;
|
||||
color: #D0CCC6;
|
||||
letter-spacing: 3px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<!-- Label -->
|
||||
<div class="label">System Architecture</div>
|
||||
|
||||
<!-- Title -->
|
||||
<div class="title">
|
||||
AI记忆系统<br>
|
||||
CLAUDE.md <strong>从 93KB<br>优化到 22KB</strong>
|
||||
</div>
|
||||
|
||||
<!-- Hero Numbers -->
|
||||
<div class="hero">
|
||||
<div class="hero-block">
|
||||
<span class="hero-label">Before</span>
|
||||
<span class="hero-number">93<span class="unit">KB</span></span>
|
||||
</div>
|
||||
<div class="hero-connector">
|
||||
<svg width="48" height="8" viewBox="0 0 48 8">
|
||||
<line x1="0" y1="4" x2="40" y2="4" stroke="#D4A574" stroke-width="0.75" opacity="0.5"/>
|
||||
<line x1="36" y1="1" x2="42" y2="4" stroke="#D4A574" stroke-width="0.75" opacity="0.5"/>
|
||||
<line x1="36" y1="7" x2="42" y2="4" stroke="#D4A574" stroke-width="0.75" opacity="0.5"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="hero-block">
|
||||
<span class="hero-label">After</span>
|
||||
<span class="hero-number gold">22<span class="unit">KB</span></span>
|
||||
</div>
|
||||
<div class="hero-reduction">
|
||||
<span class="reduction-badge">-76%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
<div class="divider"></div>
|
||||
<div class="stats-row">
|
||||
<div class="stat-item">
|
||||
<div class="stat-value">2400<span style="font-size:18px;color:#AAAAAA">+</span></div>
|
||||
<div class="stat-desc">lines before<br>in single file</div>
|
||||
</div>
|
||||
<div class="stat-item" style="padding-left: 24px;">
|
||||
<div class="stat-value">4</div>
|
||||
<div class="stat-desc">structured<br>memory categories</div>
|
||||
</div>
|
||||
<div class="stat-item" style="padding-left: 24px;">
|
||||
<div class="stat-value">0</div>
|
||||
<div class="stat-desc">information<br>loss</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Memory Cards -->
|
||||
<div class="cards-section">
|
||||
<div class="cards-label">Memory Categories</div>
|
||||
<div class="cards-grid">
|
||||
<div class="card featured">
|
||||
<div class="card-index">01</div>
|
||||
<div class="card-title-zh">核心身份</div>
|
||||
<div class="card-title-en">Core Identity</div>
|
||||
<div class="card-desc">Immutable traits, facts, fundamental identity markers</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-index">02</div>
|
||||
<div class="card-title-zh">偏好设置</div>
|
||||
<div class="card-title-en">Preferences</div>
|
||||
<div class="card-desc">Style choices, tool habits, accumulated over sessions</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-index">03</div>
|
||||
<div class="card-title-zh">项目状态</div>
|
||||
<div class="card-title-en">Project State</div>
|
||||
<div class="card-desc">Active tasks, deadlines, priorities, evolving context</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-index">04</div>
|
||||
<div class="card-title-zh">日志流水</div>
|
||||
<div class="card-title-en">Daily Logs</div>
|
||||
<div class="card-desc">Session records, never auto-loaded, search on demand</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Flow -->
|
||||
<div class="flow-section">
|
||||
<div class="flow-label">Processing Flow</div>
|
||||
<div class="flow-timeline">
|
||||
<div class="flow-steps">
|
||||
<div class="flow-step">
|
||||
<div class="flow-dot"></div>
|
||||
<div class="flow-step-label">Input</div>
|
||||
<div class="flow-step-text">User<br>Input</div>
|
||||
</div>
|
||||
<div class="flow-step">
|
||||
<div class="flow-dot"></div>
|
||||
<div class="flow-step-label">Route</div>
|
||||
<div class="flow-step-text">Workspace<br>Detection</div>
|
||||
</div>
|
||||
<div class="flow-step">
|
||||
<div class="flow-dot active"></div>
|
||||
<div class="flow-step-label">Load</div>
|
||||
<div class="flow-step-text">Relevant<br>Memory</div>
|
||||
</div>
|
||||
<div class="flow-step">
|
||||
<div class="flow-dot"></div>
|
||||
<div class="flow-step-label">Execute</div>
|
||||
<div class="flow-step-text">Task<br>Processing</div>
|
||||
</div>
|
||||
<div class="flow-step">
|
||||
<div class="flow-dot"></div>
|
||||
<div class="flow-step-label">Update</div>
|
||||
<div class="flow-step-text">Memory<br>Write-back</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quote -->
|
||||
<div class="quote-section">
|
||||
<div class="quote-line"></div>
|
||||
<div class="quote-text">
|
||||
Like <em>Marie Kondo</em> for AI memory<br>
|
||||
— keep only what sparks joy.
|
||||
</div>
|
||||
<div class="results-row">
|
||||
<div class="result-item">
|
||||
<div class="result-icon"></div>
|
||||
<span class="result-text">Faster context loading</span>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-icon"></div>
|
||||
<span class="result-text">More relevant responses</span>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-icon"></div>
|
||||
<span class="result-text">Zero information loss</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="footer">
|
||||
<span class="footer-text">Build Studio Style</span>
|
||||
<span class="footer-text">2026</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 106 KiB |
@ -1,600 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1080">
|
||||
<title>AI Memory System Optimization — Pentagram Style</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1080px;
|
||||
height: 1920px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #FFFFFF;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 64px 72px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.header {
|
||||
border-bottom: 6px solid #111;
|
||||
padding-bottom: 24px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.header-label {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 4px;
|
||||
text-transform: uppercase;
|
||||
color: #E63946;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 44px;
|
||||
font-weight: 900;
|
||||
line-height: 1.1;
|
||||
letter-spacing: -1px;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.header-subtitle {
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* Hero Numbers Section */
|
||||
.hero-section {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: center;
|
||||
padding: 48px 0 20px 0;
|
||||
border-bottom: 2px solid #111;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.hero-num {
|
||||
font-weight: 900;
|
||||
font-size: 200px;
|
||||
line-height: 0.85;
|
||||
letter-spacing: -8px;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.hero-unit {
|
||||
font-size: 36px;
|
||||
font-weight: 500;
|
||||
color: #111;
|
||||
margin-left: 4px;
|
||||
align-self: flex-end;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.hero-arrow-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 0 28px;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.hero-arrow-label {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 3px;
|
||||
text-transform: uppercase;
|
||||
color: #E63946;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.hero-num-accent {
|
||||
font-weight: 900;
|
||||
font-size: 200px;
|
||||
line-height: 0.85;
|
||||
letter-spacing: -8px;
|
||||
color: #E63946;
|
||||
}
|
||||
|
||||
.hero-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 14px 0;
|
||||
border-bottom: 6px solid #111;
|
||||
}
|
||||
|
||||
.hero-meta-item {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #999;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.hero-meta-item strong {
|
||||
color: #111;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
.section {
|
||||
padding: 32px 0 0 0;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 16px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.section-num {
|
||||
font-size: 48px;
|
||||
font-weight: 900;
|
||||
color: #E63946;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.5px;
|
||||
color: #111;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.section-divider {
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background: #111;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Data Bars */
|
||||
.data-bars {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.data-bar-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.data-bar-label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #666;
|
||||
width: 100px;
|
||||
text-align: right;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.data-bar-track {
|
||||
flex: 1;
|
||||
height: 32px;
|
||||
background: #F0F0F0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.data-bar-fill {
|
||||
height: 100%;
|
||||
background: #111;
|
||||
}
|
||||
|
||||
.data-bar-fill.accent {
|
||||
background: #E63946;
|
||||
}
|
||||
|
||||
.data-bar-value {
|
||||
font-size: 14px;
|
||||
font-weight: 900;
|
||||
color: #111;
|
||||
width: 60px;
|
||||
text-align: left;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Category Grid */
|
||||
.category-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 2px;
|
||||
background: #111;
|
||||
border: 2px solid #111;
|
||||
}
|
||||
|
||||
.category-cell {
|
||||
background: #fff;
|
||||
padding: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.category-num {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: #999;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.category-name-zh {
|
||||
font-size: 22px;
|
||||
font-weight: 900;
|
||||
color: #111;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.category-name-en {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: #999;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.category-desc {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.category-cell.accent {
|
||||
background: #E63946;
|
||||
}
|
||||
|
||||
.category-cell.accent .category-num,
|
||||
.category-cell.accent .category-name-zh,
|
||||
.category-cell.accent .category-name-en,
|
||||
.category-cell.accent .category-desc {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Section 03: Design Principles */
|
||||
.principles {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.principle-row {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
border-bottom: 1px solid #E8E8E8;
|
||||
}
|
||||
|
||||
.principle-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.principle-num {
|
||||
font-size: 32px;
|
||||
font-weight: 900;
|
||||
color: #E63946;
|
||||
width: 64px;
|
||||
flex-shrink: 0;
|
||||
padding: 16px 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.principle-content {
|
||||
padding: 16px 0 16px 16px;
|
||||
border-left: 1px solid #E8E8E8;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.principle-name {
|
||||
font-size: 16px;
|
||||
font-weight: 900;
|
||||
color: #111;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.principle-desc {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #888;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* Section 04: Results */
|
||||
.results-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.result-card {
|
||||
padding: 32px 24px;
|
||||
border-right: 1px solid #E8E8E8;
|
||||
}
|
||||
|
||||
.result-card:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.result-number {
|
||||
font-size: 64px;
|
||||
font-weight: 900;
|
||||
color: #E63946;
|
||||
line-height: 1;
|
||||
letter-spacing: -3px;
|
||||
}
|
||||
|
||||
.result-label {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #999;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* Insight Quote */
|
||||
.insight-section {
|
||||
margin-top: auto;
|
||||
border-top: 6px solid #111;
|
||||
padding-top: 24px;
|
||||
}
|
||||
|
||||
.insight-quote {
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
color: #111;
|
||||
line-height: 1.4;
|
||||
letter-spacing: -0.5px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.insight-quote .highlight {
|
||||
color: #E63946;
|
||||
font-weight: 900;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.insight-result {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
margin-top: 18px;
|
||||
padding-top: 14px;
|
||||
border-top: 1px solid #DDD;
|
||||
}
|
||||
|
||||
.insight-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.insight-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: #E63946;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.insight-text {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #DDD;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
color: #CCC;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="header">
|
||||
<div class="header-label">Case Study / System Design</div>
|
||||
<div class="header-title">AI记忆系统:CLAUDE.md<br>从臃肿到优雅的重构之路</div>
|
||||
<div class="header-subtitle">A systematic approach to AI memory architecture optimization</div>
|
||||
</div>
|
||||
|
||||
<!-- Hero Numbers -->
|
||||
<div class="hero-section">
|
||||
<span class="hero-num">93</span>
|
||||
<span class="hero-unit">KB</span>
|
||||
<div class="hero-arrow-container">
|
||||
<span class="hero-arrow-label">reduced to</span>
|
||||
<svg width="64" height="24" viewBox="0 0 64 24">
|
||||
<line x1="0" y1="12" x2="52" y2="12" stroke="#E63946" stroke-width="3"/>
|
||||
<polygon points="52,4 64,12 52,20" fill="#E63946"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="hero-num-accent">22</span>
|
||||
<span class="hero-unit" style="color:#E63946">KB</span>
|
||||
</div>
|
||||
<div class="hero-meta">
|
||||
<div class="hero-meta-item"><strong>76%</strong> reduction</div>
|
||||
<div class="hero-meta-item"><strong>2400+</strong> lines before</div>
|
||||
<div class="hero-meta-item"><strong>1</strong> file to <strong>structured</strong> system</div>
|
||||
<div class="hero-meta-item"><strong>0</strong> information loss</div>
|
||||
</div>
|
||||
|
||||
<!-- Section 01: Before vs After -->
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<span class="section-num">01</span>
|
||||
<span class="section-title">Before vs After</span>
|
||||
</div>
|
||||
<div class="section-divider"></div>
|
||||
<div class="data-bars">
|
||||
<div class="data-bar-row">
|
||||
<span class="data-bar-label">Before</span>
|
||||
<div class="data-bar-track">
|
||||
<div class="data-bar-fill" style="width: 100%;"></div>
|
||||
</div>
|
||||
<span class="data-bar-value">93 KB</span>
|
||||
</div>
|
||||
<div class="data-bar-row">
|
||||
<span class="data-bar-label">After</span>
|
||||
<div class="data-bar-track">
|
||||
<div class="data-bar-fill accent" style="width: 23.7%;"></div>
|
||||
</div>
|
||||
<span class="data-bar-value">22 KB</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section 02: Memory Architecture -->
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<span class="section-num">02</span>
|
||||
<span class="section-title">Memory Architecture</span>
|
||||
</div>
|
||||
<div class="section-divider"></div>
|
||||
<div class="category-grid">
|
||||
<div class="category-cell accent">
|
||||
<span class="category-num">I</span>
|
||||
<span class="category-name-zh">核心身份</span>
|
||||
<span class="category-name-en">Core Identity</span>
|
||||
<span class="category-desc">Who you are, fundamental traits, immutable facts</span>
|
||||
</div>
|
||||
<div class="category-cell">
|
||||
<span class="category-num">II</span>
|
||||
<span class="category-name-zh">偏好设置</span>
|
||||
<span class="category-name-en">Preferences</span>
|
||||
<span class="category-desc">Style, tools, workflow habits, accumulated over time</span>
|
||||
</div>
|
||||
<div class="category-cell">
|
||||
<span class="category-num">III</span>
|
||||
<span class="category-name-zh">项目状态</span>
|
||||
<span class="category-name-en">Project State</span>
|
||||
<span class="category-desc">Current tasks, deadlines, priorities, progress tracking</span>
|
||||
</div>
|
||||
<div class="category-cell">
|
||||
<span class="category-num">IV</span>
|
||||
<span class="category-name-zh">日志流水</span>
|
||||
<span class="category-name-en">Daily Logs</span>
|
||||
<span class="category-desc">Session-level records, searchable history, never auto-loaded</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section 03: Design Principles -->
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<span class="section-num">03</span>
|
||||
<span class="section-title">Design Principles</span>
|
||||
</div>
|
||||
<div class="section-divider"></div>
|
||||
<div class="principles">
|
||||
<div class="principle-row">
|
||||
<div class="principle-num">A</div>
|
||||
<div class="principle-content">
|
||||
<div class="principle-name">Route, Don't Dump</div>
|
||||
<div class="principle-desc">Router file dispatches to workspace-specific rules. Never load everything at once.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="principle-row">
|
||||
<div class="principle-num">B</div>
|
||||
<div class="principle-content">
|
||||
<div class="principle-name">Structured Hierarchy</div>
|
||||
<div class="principle-desc">Identity > Preferences > Projects > Logs. Each layer loads on demand.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="principle-row">
|
||||
<div class="principle-num">C</div>
|
||||
<div class="principle-content">
|
||||
<div class="principle-name">Write Rules, Not Records</div>
|
||||
<div class="principle-desc">Store reusable patterns, not one-time instructions. Keep memory under 100 lines.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="principle-row">
|
||||
<div class="principle-num">D</div>
|
||||
<div class="principle-content">
|
||||
<div class="principle-name">Silent Operations</div>
|
||||
<div class="principle-desc">Memory read/write happens silently. Never interrupt the user's task flow.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section 04: Results -->
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<span class="section-num">04</span>
|
||||
<span class="section-title">Results</span>
|
||||
</div>
|
||||
<div class="section-divider"></div>
|
||||
<div class="results-grid">
|
||||
<div class="result-card">
|
||||
<div class="result-number">76%</div>
|
||||
<div class="result-label">Size Reduction</div>
|
||||
</div>
|
||||
<div class="result-card">
|
||||
<div class="result-number">2.3x</div>
|
||||
<div class="result-label">Faster Loading</div>
|
||||
</div>
|
||||
<div class="result-card">
|
||||
<div class="result-number">0</div>
|
||||
<div class="result-label">Data Loss</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Insight -->
|
||||
<div class="insight-section">
|
||||
<div class="insight-quote">
|
||||
"Like <span class="highlight">Marie Kondo</span> for AI memory
|
||||
— keep only what sparks joy."
|
||||
</div>
|
||||
<div class="insight-result">
|
||||
<div class="insight-item">
|
||||
<div class="insight-dot"></div>
|
||||
<span class="insight-text">Faster context loading</span>
|
||||
</div>
|
||||
<div class="insight-item">
|
||||
<div class="insight-dot"></div>
|
||||
<span class="insight-text">More relevant responses</span>
|
||||
</div>
|
||||
<div class="insight-item">
|
||||
<div class="insight-dot"></div>
|
||||
<span class="insight-text">Zero information loss</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="footer">
|
||||
<span class="footer-text">Pentagram Style</span>
|
||||
<span class="footer-text">CLAUDE.md Optimization</span>
|
||||
<span class="footer-text">2026</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 155 KiB |
@ -1,670 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1080">
|
||||
<title>AI Memory System Optimization — Takram Style</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=Noto+Serif+SC:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1080px;
|
||||
height: 1920px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #F5F0EB;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #3D3730;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 72px 80px 60px 80px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Background texture */
|
||||
.bg-circle {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(168, 181, 160, 0.2);
|
||||
pointer-events: none;
|
||||
}
|
||||
.bg-circle-1 {
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
top: -180px;
|
||||
right: -200px;
|
||||
}
|
||||
.bg-circle-2 {
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
bottom: 200px;
|
||||
left: -160px;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.header {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
.header-label {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 3.5px;
|
||||
text-transform: uppercase;
|
||||
color: #6B8F71;
|
||||
margin-bottom: 20px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.header-title {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 44px;
|
||||
font-weight: 500;
|
||||
line-height: 1.35;
|
||||
color: #2D3436;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.header-subtitle {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 15px;
|
||||
font-weight: 300;
|
||||
color: #8B7355;
|
||||
margin-top: 12px;
|
||||
line-height: 1.5;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
/* Hero Data Circles */
|
||||
.hero-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 48px;
|
||||
padding: 36px 0;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.data-circle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
.data-circle-ring {
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.data-circle-ring svg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
.data-circle-inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
z-index: 1;
|
||||
}
|
||||
.data-num {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 64px;
|
||||
font-weight: 300;
|
||||
color: #2E2A24;
|
||||
line-height: 1;
|
||||
}
|
||||
.data-unit {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: #8B7355;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.data-label {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #A8A098;
|
||||
margin-top: 12px;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.data-circle-small .data-circle-ring {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
}
|
||||
.data-circle-small .data-num {
|
||||
font-size: 52px;
|
||||
}
|
||||
|
||||
/* Organic connector */
|
||||
.hero-connector {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
height: 60px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Reduction badge — understated Takram style */
|
||||
.reduction-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 8px 28px;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(107, 143, 113, 0.3);
|
||||
border-radius: 20px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
.reduction-text {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #6B8F71;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.hero-footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
/* Categories Section */
|
||||
.categories-section {
|
||||
margin-top: 36px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.section-label {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: #2D3436;
|
||||
margin-bottom: 24px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.section-label .section-num {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 9px;
|
||||
font-weight: 400;
|
||||
color: #B0AAA0;
|
||||
letter-spacing: 1px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
.categories-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
.cat-card {
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 16px;
|
||||
padding: 28px 24px;
|
||||
position: relative;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.03);
|
||||
border: 1px solid rgba(232, 228, 220, 0.8);
|
||||
}
|
||||
.cat-card-icon {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.cat-card-title-zh {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #2E2A24;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.cat-card-title-en {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: #A8A098;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.cat-card-desc {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: 300;
|
||||
color: #8B7355;
|
||||
line-height: 1.7;
|
||||
}
|
||||
.cat-card.highlight {
|
||||
border-color: rgba(107, 143, 113, 0.35);
|
||||
background: rgba(107, 143, 113, 0.04);
|
||||
}
|
||||
|
||||
/* Proportion circles */
|
||||
.cat-prop {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
/* Flow Diagram */
|
||||
.flow-section {
|
||||
margin-top: 36px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.flow-diagram {
|
||||
position: relative;
|
||||
height: 260px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.flow-node {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.flow-node-circle {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(255,255,255,0.5);
|
||||
border: 1px solid #DDD9D2;
|
||||
}
|
||||
.flow-node-circle.active {
|
||||
border-color: #6B8F71;
|
||||
border-width: 1.5px;
|
||||
background: rgba(107, 143, 113, 0.06);
|
||||
}
|
||||
.flow-node-label {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: #A8A098;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.flow-node-text {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #2E2A24;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Insight */
|
||||
.insight-section {
|
||||
margin-top: auto;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.insight-card {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
border-radius: 16px;
|
||||
padding: 32px 36px;
|
||||
border: 1px solid rgba(232, 228, 220, 0.6);
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.03);
|
||||
}
|
||||
.insight-quote {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
color: #2E2A24;
|
||||
line-height: 1.7;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.insight-quote .green {
|
||||
color: #6B8F71;
|
||||
font-weight: 500;
|
||||
}
|
||||
.insight-quote .brown {
|
||||
color: #8B7355;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.results-row {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
margin-top: 24px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid rgba(232, 228, 220, 0.6);
|
||||
}
|
||||
.result-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.result-leaf {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.result-text {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #8B7355;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
margin-top: 28px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.footer-text {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 10px;
|
||||
font-weight: 300;
|
||||
color: #C4BDB4;
|
||||
letter-spacing: 3px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<!-- Background decorations -->
|
||||
<div class="bg-circle bg-circle-1"></div>
|
||||
<div class="bg-circle bg-circle-2"></div>
|
||||
|
||||
<!-- Header -->
|
||||
<div class="header">
|
||||
<div class="header-label">Speculative Design / Memory Architecture</div>
|
||||
<div class="header-title">AI记忆系统<br>CLAUDE.md 的断舍离</div>
|
||||
<div class="header-subtitle">Restructuring artificial memory from monolith to modular elegance</div>
|
||||
</div>
|
||||
|
||||
<!-- Hero Data Circles -->
|
||||
<div class="hero-section">
|
||||
<div class="data-circle">
|
||||
<div class="data-circle-ring">
|
||||
<svg width="200" height="200" viewBox="0 0 200 200">
|
||||
<circle cx="100" cy="100" r="92" fill="none" stroke="#E8E4DC" stroke-width="1.5"/>
|
||||
<circle cx="100" cy="100" r="92" fill="none" stroke="#8B7355" stroke-width="2" stroke-dasharray="578" stroke-dashoffset="0" opacity="0.3"/>
|
||||
</svg>
|
||||
<div class="data-circle-inner">
|
||||
<span class="data-num">93</span>
|
||||
<span class="data-unit">KB</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="data-label">Before</span>
|
||||
</div>
|
||||
|
||||
<div class="hero-connector">
|
||||
<svg width="120" height="60" viewBox="0 0 120 60">
|
||||
<path d="M 0,30 C 30,30 40,10 60,10 C 80,10 90,50 110,30"
|
||||
fill="none" stroke="#6B8F71" stroke-width="1" stroke-dasharray="3,4" opacity="0.5"/>
|
||||
<circle cx="110" cy="30" r="3.5" fill="#6B8F71" opacity="0.5"/>
|
||||
<circle cx="110" cy="30" r="7" fill="none" stroke="#6B8F71" stroke-width="0.5" opacity="0.2"/>
|
||||
<!-- delta annotation -->
|
||||
<text x="60" y="50" text-anchor="middle" font-family="Inter" font-size="7" fill="#B0AAA0" letter-spacing="0.5">-71 KB</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="data-circle data-circle-small">
|
||||
<div class="data-circle-ring">
|
||||
<svg width="160" height="160" viewBox="0 0 160 160">
|
||||
<circle cx="80" cy="80" r="72" fill="none" stroke="#E8E4DC" stroke-width="1.5"/>
|
||||
<circle cx="80" cy="80" r="72" fill="none" stroke="#A8B5A0" stroke-width="2.5" stroke-dasharray="452" stroke-dashoffset="344" opacity="0.6"/>
|
||||
</svg>
|
||||
<div class="data-circle-inner">
|
||||
<span class="data-num" style="color: #A8B5A0;">22</span>
|
||||
<span class="data-unit">KB</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="data-label">After</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-footer">
|
||||
<div class="reduction-pill">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14"><path d="M7 2L7 12M3 8L7 12L11 8" fill="none" stroke="#6B8F71" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span class="reduction-text">76% REDUCTION</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Categories -->
|
||||
<div class="categories-section">
|
||||
<div class="section-label"><span class="section-num">01</span>Four Pillars of Memory</div>
|
||||
<div class="categories-grid">
|
||||
<div class="cat-card highlight">
|
||||
<div class="cat-card-icon">
|
||||
<svg width="32" height="32" viewBox="0 0 32 32">
|
||||
<circle cx="16" cy="12" r="6" fill="none" stroke="#A8B5A0" stroke-width="1.5"/>
|
||||
<path d="M6,28 C6,22 10,18 16,18 C22,18 26,22 26,28" fill="none" stroke="#A8B5A0" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="cat-prop">
|
||||
<svg width="28" height="28" viewBox="0 0 28 28">
|
||||
<circle cx="14" cy="14" r="12" fill="none" stroke="#E8E4DC" stroke-width="1"/>
|
||||
<circle cx="14" cy="14" r="12" fill="none" stroke="#A8B5A0" stroke-width="2" stroke-dasharray="75" stroke-dashoffset="56" transform="rotate(-90 14 14)"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="cat-card-title-zh">核心身份</div>
|
||||
<div class="cat-card-title-en">Core Identity</div>
|
||||
<div class="cat-card-desc">Immutable facts and fundamental traits that define who you are</div>
|
||||
</div>
|
||||
<div class="cat-card">
|
||||
<div class="cat-card-icon">
|
||||
<svg width="32" height="32" viewBox="0 0 32 32">
|
||||
<path d="M8,8 L24,8 L24,24 L8,24 Z" fill="none" stroke="#8B7355" stroke-width="1.5" rx="2"/>
|
||||
<line x1="12" y1="13" x2="20" y2="13" stroke="#8B7355" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<line x1="12" y1="17" x2="18" y2="17" stroke="#8B7355" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<line x1="12" y1="21" x2="16" y2="21" stroke="#8B7355" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="cat-prop">
|
||||
<svg width="28" height="28" viewBox="0 0 28 28">
|
||||
<circle cx="14" cy="14" r="12" fill="none" stroke="#E8E4DC" stroke-width="1"/>
|
||||
<circle cx="14" cy="14" r="12" fill="none" stroke="#8B7355" stroke-width="2" stroke-dasharray="75" stroke-dashoffset="45" transform="rotate(-90 14 14)"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="cat-card-title-zh">偏好设置</div>
|
||||
<div class="cat-card-title-en">Preferences</div>
|
||||
<div class="cat-card-desc">Style, tools, habits — accumulated over time through sessions</div>
|
||||
</div>
|
||||
<div class="cat-card">
|
||||
<div class="cat-card-icon">
|
||||
<svg width="32" height="32" viewBox="0 0 32 32">
|
||||
<rect x="6" y="10" width="8" height="14" rx="1" fill="none" stroke="#8B7355" stroke-width="1.5"/>
|
||||
<rect x="18" y="6" width="8" height="18" rx="1" fill="none" stroke="#8B7355" stroke-width="1.5"/>
|
||||
<line x1="8" y1="16" x2="12" y2="16" stroke="#8B7355" stroke-width="1" stroke-linecap="round"/>
|
||||
<line x1="20" y1="12" x2="24" y2="12" stroke="#8B7355" stroke-width="1" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="cat-prop">
|
||||
<svg width="28" height="28" viewBox="0 0 28 28">
|
||||
<circle cx="14" cy="14" r="12" fill="none" stroke="#E8E4DC" stroke-width="1"/>
|
||||
<circle cx="14" cy="14" r="12" fill="none" stroke="#8B7355" stroke-width="2" stroke-dasharray="75" stroke-dashoffset="37" transform="rotate(-90 14 14)"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="cat-card-title-zh">项目状态</div>
|
||||
<div class="cat-card-title-en">Project State</div>
|
||||
<div class="cat-card-desc">Current tasks, deadlines, priorities — always evolving context</div>
|
||||
</div>
|
||||
<div class="cat-card">
|
||||
<div class="cat-card-icon">
|
||||
<svg width="32" height="32" viewBox="0 0 32 32">
|
||||
<circle cx="16" cy="16" r="10" fill="none" stroke="#8B7355" stroke-width="1.5"/>
|
||||
<line x1="16" y1="10" x2="16" y2="16" stroke="#8B7355" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<line x1="16" y1="16" x2="21" y2="19" stroke="#8B7355" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="cat-prop">
|
||||
<svg width="28" height="28" viewBox="0 0 28 28">
|
||||
<circle cx="14" cy="14" r="12" fill="none" stroke="#E8E4DC" stroke-width="1"/>
|
||||
<circle cx="14" cy="14" r="12" fill="none" stroke="#8B7355" stroke-width="2" stroke-dasharray="75" stroke-dashoffset="60" transform="rotate(-90 14 14)"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="cat-card-title-zh">日志流水</div>
|
||||
<div class="cat-card-title-en">Daily Logs</div>
|
||||
<div class="cat-card-desc">Session records — never auto-loaded, retrieved on demand only</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Flow Diagram -->
|
||||
<div class="flow-section">
|
||||
<div class="section-label"><span class="section-num">02</span>System Flow</div>
|
||||
<div class="flow-diagram">
|
||||
<!-- SVG organic curves connecting nodes — art-piece treatment -->
|
||||
<svg width="920" height="260" viewBox="0 0 920 260" style="position: absolute; top: 0; left: 0;">
|
||||
<!-- Background guide line (very subtle) -->
|
||||
<line x1="50" y1="130" x2="870" y2="130" stroke="#E8E4DC" stroke-width="0.3" stroke-dasharray="2,8" opacity="0.4"/>
|
||||
|
||||
<!-- Curve from Input to Route -->
|
||||
<path d="M 116,50 C 165,50 195,120 246,120" fill="none" stroke="#D4CFC6" stroke-width="1"/>
|
||||
<!-- Curve from Route to Load -->
|
||||
<path d="M 316,120 C 370,120 380,50 460,50" fill="none" stroke="#D4CFC6" stroke-width="1"/>
|
||||
<!-- Curve from Load to Execute (highlighted — key transition) -->
|
||||
<path d="M 530,50 C 585,50 600,160 660,160" fill="none" stroke="#6B8F71" stroke-width="1.5" stroke-dasharray="4,4" opacity="0.6"/>
|
||||
<!-- Curve from Execute to Update -->
|
||||
<path d="M 730,160 C 785,160 800,80 830,80" fill="none" stroke="#D4CFC6" stroke-width="1"/>
|
||||
|
||||
<!-- Connection dots — varying size for depth -->
|
||||
<circle cx="116" cy="50" r="2.5" fill="#D4CFC6"/>
|
||||
<circle cx="246" cy="120" r="2.5" fill="#D4CFC6"/>
|
||||
<circle cx="316" cy="120" r="2.5" fill="#D4CFC6"/>
|
||||
<circle cx="460" cy="50" r="3" fill="#6B8F71" opacity="0.5"/>
|
||||
<circle cx="530" cy="50" r="3" fill="#6B8F71" opacity="0.5"/>
|
||||
<circle cx="660" cy="160" r="2.5" fill="#D4CFC6"/>
|
||||
<circle cx="730" cy="160" r="2.5" fill="#D4CFC6"/>
|
||||
<circle cx="830" cy="80" r="2.5" fill="#D4CFC6"/>
|
||||
|
||||
<!-- Annotation: step numbers along curve -->
|
||||
<text x="170" y="75" font-family="Inter" font-size="7" fill="#C8C2B8" letter-spacing="0.5">step 1</text>
|
||||
<text x="350" y="100" font-family="Inter" font-size="7" fill="#C8C2B8" letter-spacing="0.5">step 2</text>
|
||||
<text x="565" y="95" font-family="Inter" font-size="7" fill="#6B8F71" opacity="0.5" letter-spacing="0.5">step 3</text>
|
||||
<text x="770" y="130" font-family="Inter" font-size="7" fill="#C8C2B8" letter-spacing="0.5">step 4</text>
|
||||
</svg>
|
||||
|
||||
<!-- Node 1: User Input -->
|
||||
<div class="flow-node" style="left: 44px; top: 8px;">
|
||||
<div class="flow-node-circle">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24">
|
||||
<circle cx="12" cy="9" r="4" fill="none" stroke="#8B7355" stroke-width="1.2"/>
|
||||
<path d="M4,21 C4,16 7,14 12,14 C17,14 20,16 20,21" fill="none" stroke="#8B7355" stroke-width="1.2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="flow-node-label">Input</span>
|
||||
<span class="flow-node-text">User</span>
|
||||
</div>
|
||||
|
||||
<!-- Node 2: Route -->
|
||||
<div class="flow-node" style="left: 210px; top: 78px;">
|
||||
<div class="flow-node-circle">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M4,12 L10,6 L10,10 L20,10 L20,14 L10,14 L10,18 Z" fill="none" stroke="#8B7355" stroke-width="1.2"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="flow-node-label">Route</span>
|
||||
<span class="flow-node-text">Workspace</span>
|
||||
</div>
|
||||
|
||||
<!-- Node 3: Load Memory (active) -->
|
||||
<div class="flow-node" style="left: 420px; top: 8px;">
|
||||
<div class="flow-node-circle active">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24">
|
||||
<rect x="4" y="4" width="16" height="16" rx="2" fill="none" stroke="#A8B5A0" stroke-width="1.2"/>
|
||||
<line x1="8" y1="9" x2="16" y2="9" stroke="#A8B5A0" stroke-width="1.2" stroke-linecap="round"/>
|
||||
<line x1="8" y1="13" x2="14" y2="13" stroke="#A8B5A0" stroke-width="1.2" stroke-linecap="round"/>
|
||||
<line x1="8" y1="17" x2="12" y2="17" stroke="#A8B5A0" stroke-width="1.2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="flow-node-label">Load</span>
|
||||
<span class="flow-node-text">Memory</span>
|
||||
</div>
|
||||
|
||||
<!-- Node 4: Execute -->
|
||||
<div class="flow-node" style="left: 624px; top: 118px;">
|
||||
<div class="flow-node-circle">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24">
|
||||
<polygon points="8,4 20,12 8,20" fill="none" stroke="#8B7355" stroke-width="1.2" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="flow-node-label">Execute</span>
|
||||
<span class="flow-node-text">Task</span>
|
||||
</div>
|
||||
|
||||
<!-- Node 5: Update -->
|
||||
<div class="flow-node" style="left: 800px; top: 40px;">
|
||||
<div class="flow-node-circle">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M12,4 L12,16" stroke="#8B7355" stroke-width="1.2" stroke-linecap="round"/>
|
||||
<path d="M8,12 L12,16 L16,12" fill="none" stroke="#8B7355" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<line x1="6" y1="20" x2="18" y2="20" stroke="#8B7355" stroke-width="1.2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="flow-node-label">Update</span>
|
||||
<span class="flow-node-text">Write</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Insight -->
|
||||
<div class="insight-section">
|
||||
<div class="insight-card">
|
||||
<div class="insight-quote">
|
||||
Like <span class="green">Marie Kondo</span> for AI memory —<br>
|
||||
keep only what <span class="brown">sparks joy</span>.
|
||||
</div>
|
||||
<div class="results-row">
|
||||
<div class="result-item">
|
||||
<div class="result-leaf">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14">
|
||||
<path d="M2,12 C2,6 6,2 12,2" fill="none" stroke="#A8B5A0" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<circle cx="12" cy="2" r="2" fill="#A8B5A0" opacity="0.4"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="result-text">Faster context loading</span>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-leaf">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14">
|
||||
<path d="M2,12 C2,6 6,2 12,2" fill="none" stroke="#A8B5A0" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<circle cx="12" cy="2" r="2" fill="#A8B5A0" opacity="0.4"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="result-text">More relevant responses</span>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-leaf">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14">
|
||||
<path d="M2,12 C2,6 6,2 12,2" fill="none" stroke="#A8B5A0" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<circle cx="12" cy="2" r="2" fill="#A8B5A0" opacity="0.4"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="result-text">Zero information loss</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="footer">
|
||||
<span class="footer-text">Takram Style</span>
|
||||
<span class="footer-text">CLAUDE.md Optimization</span>
|
||||
<span class="footer-text">2026</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 159 KiB |
@ -1,382 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1920">
|
||||
<title>GLM-4.7 Coding Benchmark - Build Studio Style</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #FAFAF8;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #2A2A2A;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 64px 96px 48px 96px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Top section */
|
||||
.top-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 4px;
|
||||
text-transform: uppercase;
|
||||
color: #B0ACA4;
|
||||
}
|
||||
|
||||
.source-note {
|
||||
font-size: 10px;
|
||||
font-weight: 300;
|
||||
color: #C0BCB6;
|
||||
text-align: right;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Title area */
|
||||
.title-area {
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 24px;
|
||||
border-bottom: 1px solid #EEECE8;
|
||||
}
|
||||
|
||||
.main-title {
|
||||
font-size: 40px;
|
||||
font-weight: 200;
|
||||
color: #2A2A2A;
|
||||
letter-spacing: -0.5px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.main-title .accent {
|
||||
font-weight: 400;
|
||||
color: #2A2A2A;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
color: #A0A09A;
|
||||
margin-top: 8px;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
/* Center: Hero data section */
|
||||
.hero-data {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0;
|
||||
position: relative;
|
||||
padding-bottom: 32px;
|
||||
border-bottom: 1px solid #EEECE8;
|
||||
}
|
||||
|
||||
/* Three metric cards */
|
||||
.metric-card {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
padding: 32px 24px;
|
||||
}
|
||||
|
||||
.metric-card::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 25%;
|
||||
height: 50%;
|
||||
width: 1px;
|
||||
background: linear-gradient(to bottom, transparent, #E0DCD6 50%, transparent);
|
||||
}
|
||||
|
||||
.metric-card:last-child::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.metric-value {
|
||||
font-size: 112px;
|
||||
font-weight: 200;
|
||||
color: #2A2A2A;
|
||||
letter-spacing: -4px;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.metric-value .dot {
|
||||
color: #D4A574;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.metric-unit {
|
||||
font-size: 28px;
|
||||
font-weight: 200;
|
||||
color: #D4A574;
|
||||
vertical-align: super;
|
||||
margin-left: 2px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.metric-name {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #888888;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.metric-category {
|
||||
font-size: 11px;
|
||||
font-weight: 300;
|
||||
color: #B8B4AE;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
/* Comparison bars below each metric */
|
||||
.comparison-group {
|
||||
margin-top: 24px;
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
.comp-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.comp-label {
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: #A8A4A0;
|
||||
width: 72px;
|
||||
text-align: right;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.comp-track {
|
||||
flex: 1;
|
||||
height: 2px;
|
||||
background: #EEECEA;
|
||||
border-radius: 1px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.comp-fill {
|
||||
height: 100%;
|
||||
border-radius: 1px;
|
||||
background: #D8D5D0;
|
||||
}
|
||||
|
||||
.comp-fill.gold {
|
||||
background: #D4A574;
|
||||
height: 3px;
|
||||
margin-top: -0.5px;
|
||||
}
|
||||
|
||||
.comp-val {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: #999999;
|
||||
width: 40px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.comp-val.gold {
|
||||
color: #D4A574;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Bottom section */
|
||||
.bottom-section {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
padding-top: 24px;
|
||||
}
|
||||
|
||||
.insight-text {
|
||||
font-size: 13px;
|
||||
font-weight: 300;
|
||||
color: #999;
|
||||
line-height: 1.8;
|
||||
max-width: 560px;
|
||||
}
|
||||
|
||||
.insight-text strong {
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.brand-mark {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.brand-line {
|
||||
width: 32px;
|
||||
height: 1px;
|
||||
background: #D4A574;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.brand-text {
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 3px;
|
||||
color: #C8C4BC;
|
||||
}
|
||||
|
||||
/* Slide indicator — functional PPT element */
|
||||
.slide-indicator {
|
||||
position: absolute;
|
||||
top: 64px;
|
||||
right: 96px;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.slide-dot {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: #E0DCD6;
|
||||
}
|
||||
|
||||
.slide-dot.active {
|
||||
background: #D4A574;
|
||||
width: 16px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Top row -->
|
||||
<div class="top-row">
|
||||
<div class="eyebrow">GLM-4.7 Open-Source Model</div>
|
||||
<div class="source-note">Benchmark Evaluation 2025<br>Official Results</div>
|
||||
</div>
|
||||
|
||||
<!-- Title -->
|
||||
<div class="title-area">
|
||||
<div class="main-title">Coding Capability <span style="font-weight:400;">Breakthrough</span><span style="color:#D4A574; font-weight:300; font-size:48px;">.</span></div>
|
||||
<div class="subtitle">First open-source model to achieve state-of-the-art across all major coding benchmarks</div>
|
||||
</div>
|
||||
|
||||
<!-- Hero data -->
|
||||
<div class="hero-data">
|
||||
<!-- AIME 2025 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-value">95<span class="dot">.</span>7</div>
|
||||
<div class="metric-name">AIME 2025</div>
|
||||
<div class="metric-category">Mathematical Reasoning</div>
|
||||
<div class="comparison-group">
|
||||
<div class="comp-row">
|
||||
<span class="comp-label">GLM-4.7</span>
|
||||
<div class="comp-track"><div class="comp-fill gold" style="width: 100%;"></div></div>
|
||||
<span class="comp-val gold">95.7</span>
|
||||
</div>
|
||||
<div class="comp-row">
|
||||
<span class="comp-label">Claude 3.5</span>
|
||||
<div class="comp-track"><div class="comp-fill" style="width: 92.2%;"></div></div>
|
||||
<span class="comp-val">88.2</span>
|
||||
</div>
|
||||
<div class="comp-row">
|
||||
<span class="comp-label">GPT-4o</span>
|
||||
<div class="comp-track"><div class="comp-fill" style="width: 87.4%;"></div></div>
|
||||
<span class="comp-val">83.6</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SWE-bench Verified -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-value">73<span class="dot">.</span>8<span class="metric-unit">%</span></div>
|
||||
<div class="metric-name">SWE-bench Verified</div>
|
||||
<div class="metric-category">Software Engineering</div>
|
||||
<div class="comparison-group">
|
||||
<div class="comp-row">
|
||||
<span class="comp-label">GLM-4.7</span>
|
||||
<div class="comp-track"><div class="comp-fill gold" style="width: 100%;"></div></div>
|
||||
<span class="comp-val gold">73.8%</span>
|
||||
</div>
|
||||
<div class="comp-row">
|
||||
<span class="comp-label">Claude 3.5</span>
|
||||
<div class="comp-track"><div class="comp-fill" style="width: 72.2%;"></div></div>
|
||||
<span class="comp-val">53.3%</span>
|
||||
</div>
|
||||
<div class="comp-row">
|
||||
<span class="comp-label">GPT-4o</span>
|
||||
<div class="comp-track"><div class="comp-fill" style="width: 65.3%;"></div></div>
|
||||
<span class="comp-val">48.2%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tau-bench -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-value">87<span class="dot">.</span>4</div>
|
||||
<div class="metric-name">τ²-Bench</div>
|
||||
<div class="metric-category">Agent Task Completion</div>
|
||||
<div class="comparison-group">
|
||||
<div class="comp-row">
|
||||
<span class="comp-label">GLM-4.7</span>
|
||||
<div class="comp-track"><div class="comp-fill gold" style="width: 100%;"></div></div>
|
||||
<span class="comp-val gold">87.4</span>
|
||||
</div>
|
||||
<div class="comp-row">
|
||||
<span class="comp-label">Claude 3.5</span>
|
||||
<div class="comp-track"><div class="comp-fill" style="width: 90.3%;"></div></div>
|
||||
<span class="comp-val">78.9</span>
|
||||
</div>
|
||||
<div class="comp-row">
|
||||
<span class="comp-label">GPT-4o</span>
|
||||
<div class="comp-track"><div class="comp-fill" style="width: 81.8%;"></div></div>
|
||||
<span class="comp-val">71.5</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bottom -->
|
||||
<div class="bottom-section">
|
||||
<div class="insight-text">
|
||||
GLM-4.7 demonstrates that <strong>open-source models can compete at the frontier</strong> of coding intelligence,
|
||||
outperforming leading proprietary models with margins of <strong>+7.5 to +20.5 points</strong> across benchmarks.
|
||||
</div>
|
||||
<div class="brand-mark">
|
||||
<div class="brand-line"></div>
|
||||
<span class="brand-text">ZHIPU AI</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 82 KiB |
@ -1,536 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1920">
|
||||
<title>GLM-4.7 Coding Benchmark - Pentagram Style</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #FFFFFF;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
color: #111;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Top black bar */
|
||||
.top-bar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 64px;
|
||||
background: #111;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 80px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.top-label {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 3px;
|
||||
text-transform: uppercase;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.top-label .red { color: #E63946; }
|
||||
|
||||
.top-right {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #E63946;
|
||||
}
|
||||
|
||||
/* Grid lines */
|
||||
.grid-line-v {
|
||||
position: absolute;
|
||||
top: 64px;
|
||||
bottom: 64px;
|
||||
width: 1px;
|
||||
background: #000;
|
||||
opacity: 0.05;
|
||||
}
|
||||
|
||||
.grid-line-h {
|
||||
position: absolute;
|
||||
left: 80px;
|
||||
right: 80px;
|
||||
height: 1px;
|
||||
background: #000;
|
||||
opacity: 0.05;
|
||||
}
|
||||
|
||||
/* Left column — hero number + model info */
|
||||
.left-col {
|
||||
position: absolute;
|
||||
left: 80px;
|
||||
top: 104px;
|
||||
width: 480px;
|
||||
}
|
||||
|
||||
.model-tag {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 3px;
|
||||
text-transform: uppercase;
|
||||
color: #999;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.model-name {
|
||||
font-size: 48px;
|
||||
font-weight: 900;
|
||||
color: #111;
|
||||
line-height: 1;
|
||||
letter-spacing: -2px;
|
||||
}
|
||||
|
||||
.model-name .version { color: #E63946; }
|
||||
|
||||
.hero-number {
|
||||
font-size: 200px;
|
||||
font-weight: 900;
|
||||
line-height: 0.85;
|
||||
letter-spacing: -10px;
|
||||
color: #111;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.hero-number .decimal { color: #E63946; }
|
||||
|
||||
.hero-context {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #999;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.key-message {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 1.6;
|
||||
color: #666;
|
||||
margin-top: 32px;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.key-message strong {
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.open-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 24px;
|
||||
padding: 8px 16px;
|
||||
border: 2px solid #E63946;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #E63946;
|
||||
}
|
||||
|
||||
/* Right area — 3 benchmark columns */
|
||||
.data-area {
|
||||
position: absolute;
|
||||
left: 620px;
|
||||
top: 104px;
|
||||
right: 80px;
|
||||
bottom: 64px;
|
||||
display: flex;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.bench-col {
|
||||
flex: 1;
|
||||
padding: 0 32px;
|
||||
border-left: 1px solid #E8E8E8;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.bench-col:first-child {
|
||||
padding-left: 0;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.bench-title {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #111;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.bench-type {
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: #BBB;
|
||||
margin-bottom: 64px;
|
||||
}
|
||||
|
||||
/* Hero score per column */
|
||||
.bench-hero {
|
||||
font-size: 80px;
|
||||
font-weight: 900;
|
||||
color: #E63946;
|
||||
letter-spacing: -3px;
|
||||
line-height: 1;
|
||||
margin-bottom: 64px;
|
||||
}
|
||||
|
||||
/* Horizontal bar chart */
|
||||
.bar-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.bar-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.bar-label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #888;
|
||||
width: 90px;
|
||||
flex-shrink: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.bar-label.highlight {
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.bar-track {
|
||||
flex: 1;
|
||||
height: 56px;
|
||||
background: #F5F5F5;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bar-fill {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
.bar-fill.base {
|
||||
background: #E0E0E0;
|
||||
}
|
||||
|
||||
.bar-fill.dark {
|
||||
background: #111;
|
||||
}
|
||||
|
||||
.bar-fill.winner {
|
||||
background: #E63946;
|
||||
}
|
||||
|
||||
.bar-value {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.bar-fill.base .bar-value {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
/* Bottom bar */
|
||||
.bottom-bar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 64px;
|
||||
background: #111;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 80px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.bottom-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.bottom-logo {
|
||||
font-size: 14px;
|
||||
font-weight: 900;
|
||||
color: #fff;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.bottom-divider {
|
||||
width: 1px;
|
||||
height: 20px;
|
||||
background: #444;
|
||||
}
|
||||
|
||||
.bottom-note {
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.bottom-right-text {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #E63946;
|
||||
}
|
||||
|
||||
/* Delta label */
|
||||
.delta {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #E63946;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
margin-top: 24px;
|
||||
padding-left: 106px;
|
||||
}
|
||||
|
||||
/* Bottom summary row */
|
||||
.summary-row {
|
||||
position: absolute;
|
||||
bottom: 96px;
|
||||
left: 620px;
|
||||
right: 80px;
|
||||
display: flex;
|
||||
border-top: 1px solid #E8E8E8;
|
||||
padding-top: 24px;
|
||||
}
|
||||
|
||||
.summary-item {
|
||||
flex: 1;
|
||||
padding: 0 32px;
|
||||
}
|
||||
|
||||
.summary-item:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.summary-num {
|
||||
font-size: 32px;
|
||||
font-weight: 900;
|
||||
color: #111;
|
||||
letter-spacing: -1px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.summary-num .red { color: #E63946; }
|
||||
|
||||
.summary-desc {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: #999;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* Winner markers */
|
||||
.winner-dot {
|
||||
position: absolute;
|
||||
right: -8px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: #E63946;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Top bar -->
|
||||
<div class="top-bar">
|
||||
<span class="top-label">Benchmark Report <span class="red">/</span> 2025 Coding Performance</span>
|
||||
<span class="top-right">Open-Source SOTA</span>
|
||||
</div>
|
||||
|
||||
<!-- Grid lines -->
|
||||
<div class="grid-line-v" style="left: 80px;"></div>
|
||||
<div class="grid-line-v" style="left: 620px;"></div>
|
||||
<div class="grid-line-v" style="right: 80px;"></div>
|
||||
<div class="grid-line-h" style="top: 104px;"></div>
|
||||
|
||||
<!-- Left column -->
|
||||
<div class="left-col">
|
||||
<div class="model-tag">Open-Source Model</div>
|
||||
<div class="model-name">GLM-<span class="version">4.7</span></div>
|
||||
<div class="hero-number">95<span class="decimal">.</span>7</div>
|
||||
<div class="hero-context">AIME 2025 Score</div>
|
||||
<div class="key-message">
|
||||
<strong>First open-source model to achieve SOTA</strong> across all three major coding benchmarks, surpassing GPT-4o and Claude 3.5.
|
||||
</div>
|
||||
<div class="open-badge">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none">
|
||||
<circle cx="7" cy="7" r="6" stroke="#E63946" stroke-width="1.5"/>
|
||||
<circle cx="7" cy="7" r="2.5" fill="#E63946"/>
|
||||
</svg>
|
||||
Open Source
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Data columns -->
|
||||
<div class="data-area">
|
||||
<!-- AIME 2025 -->
|
||||
<div class="bench-col">
|
||||
<div class="bench-title">AIME 2025</div>
|
||||
<div class="bench-type">Mathematical Reasoning</div>
|
||||
<div class="bench-hero">95.7</div>
|
||||
<div class="bar-group">
|
||||
<div class="bar-row">
|
||||
<span class="bar-label highlight">GLM-4.7</span>
|
||||
<div class="bar-track">
|
||||
<div class="bar-fill winner" style="width: 95.7%;">
|
||||
<span class="bar-value">95.7</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bar-row">
|
||||
<span class="bar-label">Claude 3.5</span>
|
||||
<div class="bar-track">
|
||||
<div class="bar-fill dark" style="width: 88.2%;">
|
||||
<span class="bar-value">88.2</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bar-row">
|
||||
<span class="bar-label">GPT-4o</span>
|
||||
<div class="bar-track">
|
||||
<div class="bar-fill base" style="width: 83.6%;">
|
||||
<span class="bar-value">83.6</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="delta">+7.5 vs closed-source best</div>
|
||||
</div>
|
||||
|
||||
<!-- SWE-bench -->
|
||||
<div class="bench-col">
|
||||
<div class="bench-title">SWE-bench Verified</div>
|
||||
<div class="bench-type">Software Engineering</div>
|
||||
<div class="bench-hero">73.8</div>
|
||||
<div class="bar-group">
|
||||
<div class="bar-row">
|
||||
<span class="bar-label highlight">GLM-4.7</span>
|
||||
<div class="bar-track">
|
||||
<div class="bar-fill winner" style="width: 73.8%;">
|
||||
<span class="bar-value">73.8%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bar-row">
|
||||
<span class="bar-label">Claude 3.5</span>
|
||||
<div class="bar-track">
|
||||
<div class="bar-fill dark" style="width: 53.3%;">
|
||||
<span class="bar-value">53.3%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bar-row">
|
||||
<span class="bar-label">GPT-4o</span>
|
||||
<div class="bar-track">
|
||||
<div class="bar-fill base" style="width: 48.2%;">
|
||||
<span class="bar-value">48.2%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="delta">+20.5 vs closed-source best</div>
|
||||
</div>
|
||||
|
||||
<!-- Tau-bench -->
|
||||
<div class="bench-col">
|
||||
<div class="bench-title">τ²-Bench</div>
|
||||
<div class="bench-type">Agent Task Completion</div>
|
||||
<div class="bench-hero">87.4</div>
|
||||
<div class="bar-group">
|
||||
<div class="bar-row">
|
||||
<span class="bar-label highlight">GLM-4.7</span>
|
||||
<div class="bar-track">
|
||||
<div class="bar-fill winner" style="width: 87.4%;">
|
||||
<span class="bar-value">87.4</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bar-row">
|
||||
<span class="bar-label">Claude 3.5</span>
|
||||
<div class="bar-track">
|
||||
<div class="bar-fill dark" style="width: 78.9%;">
|
||||
<span class="bar-value">78.9</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bar-row">
|
||||
<span class="bar-label">GPT-4o</span>
|
||||
<div class="bar-track">
|
||||
<div class="bar-fill base" style="width: 71.5%;">
|
||||
<span class="bar-value">71.5</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="delta">+8.5 vs closed-source best</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Summary row -->
|
||||
<div class="summary-row">
|
||||
<div class="summary-item">
|
||||
<div class="summary-num"><span class="red">3</span>/3</div>
|
||||
<div class="summary-desc">Benchmarks Won</div>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<div class="summary-num"><span class="red">#1</span></div>
|
||||
<div class="summary-desc">Open-Source Ranking</div>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<div class="summary-num">12<span class="red">.</span>2<span style="font-size:18px;color:#999;">avg</span></div>
|
||||
<div class="summary-desc">Points Above Runner-Up</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bottom bar -->
|
||||
<div class="bottom-bar">
|
||||
<div class="bottom-left">
|
||||
<span class="bottom-logo">ZHIPU AI</span>
|
||||
<div class="bottom-divider"></div>
|
||||
<span class="bottom-note">Benchmark data sourced from official evaluation reports, 2025</span>
|
||||
</div>
|
||||
<span class="bottom-right-text">Open-Source SOTA</span>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 99 KiB |
@ -1,497 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1920">
|
||||
<title>GLM-4.7 Coding Benchmark - Takram Style</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=Noto+Serif+SC:wght@300;400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #F5F0EB;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #3A3A3A;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Subtle background texture */
|
||||
body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background:
|
||||
radial-gradient(ellipse at 20% 50%, rgba(168, 181, 160, 0.08) 0%, transparent 60%),
|
||||
radial-gradient(ellipse at 80% 30%, rgba(200, 190, 175, 0.06) 0%, transparent 50%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.layout {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 480px 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Left panel */
|
||||
.left-panel {
|
||||
padding: 72px 48px 60px 72px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
border-right: 1px solid rgba(107, 143, 113, 0.15);
|
||||
}
|
||||
|
||||
.left-top {}
|
||||
|
||||
.category-label {
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 3px;
|
||||
text-transform: uppercase;
|
||||
color: #6B8F71;
|
||||
margin-bottom: 32px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.title-jp {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 42px;
|
||||
font-weight: 400;
|
||||
color: #2D3436;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 16px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.title-en {
|
||||
font-size: 15px;
|
||||
font-weight: 300;
|
||||
color: #999999;
|
||||
line-height: 1.7;
|
||||
max-width: 340px;
|
||||
}
|
||||
|
||||
.model-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 36px;
|
||||
padding: 10px 18px;
|
||||
background: rgba(107, 143, 113, 0.08);
|
||||
border: 1px solid rgba(107, 143, 113, 0.15);
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
.model-badge-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #6B8F71;
|
||||
}
|
||||
|
||||
.model-badge-text {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #6B8F71;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/* Page indicator */
|
||||
.page-indicator {
|
||||
position: absolute;
|
||||
bottom: 40px;
|
||||
right: 72px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 10px;
|
||||
font-weight: 300;
|
||||
color: #C8C2B8;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/* Key insight */
|
||||
.key-insight {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
border-radius: 16px;
|
||||
padding: 24px 28px;
|
||||
border: 1px solid rgba(168, 181, 160, 0.2);
|
||||
}
|
||||
|
||||
.key-insight-label {
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #A8B5A0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.key-insight-text {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
color: #555555;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.left-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.credit {
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: #BBBBBB;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
/* Right panel - visualization */
|
||||
.right-panel {
|
||||
padding: 60px 72px 60px 60px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.viz-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.viz-title {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 1.5px;
|
||||
text-transform: uppercase;
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.legend {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.legend-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.legend-dot.glm { background: #6B8F71; }
|
||||
.legend-dot.claude { background: #D4A574; }
|
||||
.legend-dot.gpt { background: #C8C2B8; }
|
||||
|
||||
.legend-text {
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* SVG radar chart area */
|
||||
.radar-area {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.radar-svg {
|
||||
filter: drop-shadow(0 4px 20px rgba(0,0,0,0.04));
|
||||
}
|
||||
|
||||
/* Metric cards row */
|
||||
.metric-cards {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.m-card {
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
border-radius: 16px;
|
||||
padding: 24px 28px;
|
||||
border: 1px solid rgba(168, 181, 160, 0.15);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.m-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 28px;
|
||||
width: 32px;
|
||||
height: 2px;
|
||||
background: #6B8F71;
|
||||
opacity: 0.4;
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
.m-card-name {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 1.5px;
|
||||
text-transform: uppercase;
|
||||
color: #999999;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.m-card-type {
|
||||
font-size: 11px;
|
||||
font-weight: 300;
|
||||
color: #BBBBBB;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.m-card-value {
|
||||
font-size: 40px;
|
||||
font-weight: 300;
|
||||
color: #2D3436;
|
||||
letter-spacing: -1px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.m-card-value .unit {
|
||||
font-size: 18px;
|
||||
color: #6B8F71;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.m-card-delta {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #7D9B72;
|
||||
background: rgba(168, 181, 160, 0.12);
|
||||
padding: 3px 10px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.m-card-delta svg {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.m-card-competitors {
|
||||
margin-top: 14px;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.comp-mini {
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: #AAAAAA;
|
||||
}
|
||||
|
||||
.comp-mini span {
|
||||
font-weight: 500;
|
||||
color: #888888;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="layout">
|
||||
<!-- Left panel -->
|
||||
<div class="left-panel">
|
||||
<div class="left-top">
|
||||
<div class="category-label">Benchmark Analysis</div>
|
||||
<div class="title-jp">GLM-4.7<br>Coding 能力突破</div>
|
||||
<div class="title-en">
|
||||
Open-source model achieves state-of-the-art performance across all major coding benchmarks for the first time.
|
||||
</div>
|
||||
<div class="model-badge">
|
||||
<div class="model-badge-dot"></div>
|
||||
<span class="model-badge-text">GLM-4.7 Open Source</span>
|
||||
</div>
|
||||
|
||||
<div class="key-insight" style="margin-top: 40px;">
|
||||
<div class="key-insight-label">Key Finding</div>
|
||||
<div class="key-insight-text">
|
||||
在三项核心编程基准测试中,GLM-4.7 均超越 GPT-4o 和 Claude 3.5,成为首个达到 SOTA 水平的开源模型。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="left-bottom">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<rect x="1" y="1" width="14" height="14" rx="3" stroke="#BBBBBB" stroke-width="1"/>
|
||||
<path d="M5 8L7 10L11 6" stroke="#A8B5A0" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<span class="credit">Data: Official benchmark evaluations, 2026</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right panel -->
|
||||
<div class="right-panel">
|
||||
<div class="viz-header">
|
||||
<div class="viz-title">Performance Comparison <span style="font-weight:300;color:#B0AAA0;font-size:10px;margin-left:8px;">— 03 benchmarks</span></div>
|
||||
<div class="legend">
|
||||
<div class="legend-item"><div class="legend-dot glm"></div><span class="legend-text">GLM-4.7</span></div>
|
||||
<div class="legend-item"><div class="legend-dot claude"></div><span class="legend-text">Claude 3.5</span></div>
|
||||
<div class="legend-item"><div class="legend-dot gpt"></div><span class="legend-text">GPT-4o</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Radar chart SVG — art-piece treatment -->
|
||||
<div class="radar-area">
|
||||
<svg class="radar-svg" width="560" height="560" viewBox="0 0 560 560">
|
||||
|
||||
<!-- Subtle background circle (like a lens/scope) -->
|
||||
<circle cx="280" cy="280" r="250" fill="none" stroke="#E8E4DC" stroke-width="0.3" opacity="0.5"/>
|
||||
|
||||
<!-- Grid circles — hand-drawn feel with varied dash -->
|
||||
<circle cx="280" cy="280" r="220" fill="none" stroke="#DDD9D2" stroke-width="0.6" stroke-dasharray="2,6"/>
|
||||
<circle cx="280" cy="280" r="176" fill="none" stroke="#DDD9D2" stroke-width="0.5" stroke-dasharray="2,6"/>
|
||||
<circle cx="280" cy="280" r="132" fill="none" stroke="#DDD9D2" stroke-width="0.4" stroke-dasharray="2,6"/>
|
||||
<circle cx="280" cy="280" r="88" fill="none" stroke="#DDD9D2" stroke-width="0.4" stroke-dasharray="2,6"/>
|
||||
<circle cx="280" cy="280" r="44" fill="none" stroke="#DDD9D2" stroke-width="0.3" stroke-dasharray="2,6"/>
|
||||
|
||||
<!-- Center point -->
|
||||
<circle cx="280" cy="280" r="2.5" fill="#6B8F71" opacity="0.4"/>
|
||||
|
||||
<!-- Grid scale labels — positioned along axis -->
|
||||
<text x="288" y="62" font-family="Inter" font-size="9" fill="#C8C2B8" font-weight="300">100</text>
|
||||
<text x="288" y="106" font-family="Inter" font-size="9" fill="#C8C2B8" font-weight="300">80</text>
|
||||
<text x="288" y="150" font-family="Inter" font-size="9" fill="#C8C2B8" font-weight="300">60</text>
|
||||
<text x="288" y="194" font-family="Inter" font-size="9" fill="#C8C2B8" font-weight="300">40</text>
|
||||
|
||||
<!-- Axis lines — delicate -->
|
||||
<line x1="280" y1="280" x2="280" y2="55" stroke="#D4CFC6" stroke-width="0.5"/>
|
||||
<line x1="280" y1="280" x2="475" y2="392" stroke="#D4CFC6" stroke-width="0.5"/>
|
||||
<line x1="280" y1="280" x2="85" y2="392" stroke="#D4CFC6" stroke-width="0.5"/>
|
||||
|
||||
<!-- Axis endpoint markers -->
|
||||
<circle cx="280" cy="55" r="2" fill="none" stroke="#D4CFC6" stroke-width="0.6"/>
|
||||
<circle cx="475" cy="392" r="2" fill="none" stroke="#D4CFC6" stroke-width="0.6"/>
|
||||
<circle cx="85" cy="392" r="2" fill="none" stroke="#D4CFC6" stroke-width="0.6"/>
|
||||
|
||||
<!-- Axis labels with index -->
|
||||
<text x="280" y="38" font-family="Inter" font-size="12" fill="#8A857D" font-weight="500" text-anchor="middle" letter-spacing="1.5">AIME 2025</text>
|
||||
<text x="280" y="28" font-family="Inter" font-size="7" fill="#B0AAA0" text-anchor="middle" letter-spacing="0.5">Mathematical Reasoning</text>
|
||||
<text x="492" y="408" font-family="Inter" font-size="12" fill="#8A857D" font-weight="500" text-anchor="start" letter-spacing="1.5">SWE-bench</text>
|
||||
<text x="492" y="422" font-family="Inter" font-size="7" fill="#B0AAA0" text-anchor="start" letter-spacing="0.5">Software Engineering</text>
|
||||
<text x="68" y="408" font-family="Inter" font-size="12" fill="#8A857D" font-weight="500" text-anchor="end" letter-spacing="1.5">τ²-Bench</text>
|
||||
<text x="68" y="422" font-family="Inter" font-size="7" fill="#B0AAA0" text-anchor="end" letter-spacing="0.5">Agent Tasks</text>
|
||||
|
||||
<!-- GPT-4o polygon (lightest) -->
|
||||
<polygon
|
||||
points="280,96.1 371.8,333 143.8,358.7"
|
||||
fill="rgba(219,219,219,0.12)" stroke="#D4CFC6" stroke-width="1" stroke-dasharray="4,3"
|
||||
/>
|
||||
|
||||
<!-- Claude 3.5 polygon -->
|
||||
<polygon
|
||||
points="280,86 381.6,338.6 129.7,366.8"
|
||||
fill="rgba(212,165,116,0.08)" stroke="#D4A574" stroke-width="1.2"
|
||||
/>
|
||||
|
||||
<!-- GLM-4.7 polygon (prominent, sage green) -->
|
||||
<polygon
|
||||
points="280,69.5 420.6,361.2 113.5,376.2"
|
||||
fill="rgba(107,143,113,0.1)" stroke="#6B8F71" stroke-width="2"
|
||||
/>
|
||||
|
||||
<!-- Data points - GLM-4.7 (larger, prominent) -->
|
||||
<circle cx="280" cy="69.5" r="6" fill="#6B8F71" opacity="0.8"/>
|
||||
<circle cx="280" cy="69.5" r="10" fill="none" stroke="#6B8F71" stroke-width="0.6" opacity="0.3"/>
|
||||
<circle cx="420.6" cy="361.2" r="6" fill="#6B8F71" opacity="0.8"/>
|
||||
<circle cx="420.6" cy="361.2" r="10" fill="none" stroke="#6B8F71" stroke-width="0.6" opacity="0.3"/>
|
||||
<circle cx="113.5" cy="376.2" r="6" fill="#6B8F71" opacity="0.8"/>
|
||||
<circle cx="113.5" cy="376.2" r="10" fill="none" stroke="#6B8F71" stroke-width="0.6" opacity="0.3"/>
|
||||
|
||||
<!-- Data points - Claude 3.5 -->
|
||||
<circle cx="280" cy="86" r="3.5" fill="#D4A574" opacity="0.7"/>
|
||||
<circle cx="381.6" cy="338.6" r="3.5" fill="#D4A574" opacity="0.7"/>
|
||||
<circle cx="129.7" cy="366.8" r="3.5" fill="#D4A574" opacity="0.7"/>
|
||||
|
||||
<!-- Data points - GPT-4o -->
|
||||
<circle cx="280" cy="96.1" r="2.5" fill="#C8C2B8" opacity="0.6"/>
|
||||
<circle cx="371.8" cy="333" r="2.5" fill="#C8C2B8" opacity="0.6"/>
|
||||
<circle cx="143.8" cy="358.7" r="2.5" fill="#C8C2B8" opacity="0.6"/>
|
||||
|
||||
<!-- Value labels for GLM-4.7 — annotation style -->
|
||||
<line x1="280" y1="69.5" x2="316" y2="52" stroke="#6B8F71" stroke-width="0.5" opacity="0.4"/>
|
||||
<text x="320" y="50" font-family="Inter" font-size="14" fill="#6B8F71" font-weight="600">95.7</text>
|
||||
|
||||
<line x1="420.6" y1="361.2" x2="448" y2="348" stroke="#6B8F71" stroke-width="0.5" opacity="0.4"/>
|
||||
<text x="452" y="352" font-family="Inter" font-size="14" fill="#6B8F71" font-weight="600">73.8%</text>
|
||||
|
||||
<line x1="113.5" y1="376.2" x2="82" y2="392" stroke="#6B8F71" stroke-width="0.5" opacity="0.4"/>
|
||||
<text x="78" y="390" font-family="Inter" font-size="14" fill="#6B8F71" font-weight="600" text-anchor="end">87.4</text>
|
||||
|
||||
<!-- Spec annotation — bottom-right -->
|
||||
<text x="505" y="530" font-family="Inter" font-size="8" fill="#C8C2B8" font-weight="300" letter-spacing="1" text-anchor="end">Fig. 01 — Tri-axis Performance Map</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- Metric cards -->
|
||||
<div class="metric-cards">
|
||||
<div class="m-card">
|
||||
<div class="m-card-name">AIME 2025</div>
|
||||
<div class="m-card-type">Mathematical Reasoning</div>
|
||||
<div class="m-card-value">95.7</div>
|
||||
<div class="m-card-delta">
|
||||
<svg viewBox="0 0 10 10" fill="none"><path d="M5 2L8 7H2L5 2Z" fill="#7D9B72"/></svg>
|
||||
+7.5 vs Claude 3.5
|
||||
</div>
|
||||
<div class="m-card-competitors">
|
||||
<span class="comp-mini">Claude 3.5: <span>88.2</span></span>
|
||||
<span class="comp-mini">GPT-4o: <span>83.6</span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="m-card">
|
||||
<div class="m-card-name">SWE-bench Verified</div>
|
||||
<div class="m-card-type">Software Engineering</div>
|
||||
<div class="m-card-value">73.8<span class="unit">%</span></div>
|
||||
<div class="m-card-delta">
|
||||
<svg viewBox="0 0 10 10" fill="none"><path d="M5 2L8 7H2L5 2Z" fill="#7D9B72"/></svg>
|
||||
+20.5 vs Claude 3.5
|
||||
</div>
|
||||
<div class="m-card-competitors">
|
||||
<span class="comp-mini">Claude 3.5: <span>53.3%</span></span>
|
||||
<span class="comp-mini">GPT-4o: <span>48.2%</span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="m-card">
|
||||
<div class="m-card-name">τ²-Bench</div>
|
||||
<div class="m-card-type">Agent Task Completion</div>
|
||||
<div class="m-card-value">87.4</div>
|
||||
<div class="m-card-delta">
|
||||
<svg viewBox="0 0 10 10" fill="none"><path d="M5 2L8 7H2L5 2Z" fill="#7D9B72"/></svg>
|
||||
+8.5 vs Claude 3.5
|
||||
</div>
|
||||
<div class="m-card-competitors">
|
||||
<span class="comp-mini">Claude 3.5: <span>78.9</span></span>
|
||||
<span class="comp-mini">GPT-4o: <span>71.5</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-indicator">07 / 24</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 456 KiB |
@ -1,385 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>AI Compass — Build Studio Style</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500;600&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: #FAFAF8;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
/* NAV */
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 28px 80px;
|
||||
}
|
||||
.nav-logo {
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
.nav-logo svg {
|
||||
color: #D4A574;
|
||||
}
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
list-style: none;
|
||||
}
|
||||
.nav-links a {
|
||||
text-decoration: none;
|
||||
color: #999;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 1px;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
.nav-links a:hover { color: #1A1A1A; }
|
||||
.nav-cta {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 1px;
|
||||
background: transparent;
|
||||
color: #888;
|
||||
border: 1px solid rgba(0,0,0,0.08);
|
||||
padding: 8px 24px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.nav-cta:hover {
|
||||
border-color: #D4A574;
|
||||
color: #D4A574;
|
||||
}
|
||||
|
||||
/* HERO */
|
||||
.hero {
|
||||
text-align: center;
|
||||
padding: 64px 80px 0;
|
||||
}
|
||||
.hero-eyebrow {
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 4px;
|
||||
text-transform: uppercase;
|
||||
color: #B0ACA4;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.hero h1 {
|
||||
font-size: 52px;
|
||||
font-weight: 200;
|
||||
line-height: 1.15;
|
||||
letter-spacing: -1px;
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
.hero h1 em {
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
color: #D4A574;
|
||||
}
|
||||
.hero-sub {
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
color: #888;
|
||||
margin-top: 16px;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
/* SEARCH */
|
||||
.search-wrapper {
|
||||
max-width: 600px;
|
||||
margin: 32px auto 0;
|
||||
position: relative;
|
||||
}
|
||||
.search-bar {
|
||||
width: 100%;
|
||||
padding: 18px 56px 18px 24px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 15px;
|
||||
font-weight: 300;
|
||||
color: #1A1A1A;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #E8E4DF;
|
||||
border-radius: 2px;
|
||||
outline: none;
|
||||
box-shadow: 0 2px 20px rgba(0,0,0,0.04);
|
||||
transition: box-shadow 0.3s, border-color 0.3s;
|
||||
}
|
||||
.search-bar::placeholder { color: #BBB; }
|
||||
.search-bar:focus {
|
||||
box-shadow: 0 4px 30px rgba(212,165,116,0.12);
|
||||
border-color: #D4A574;
|
||||
}
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #D4A574;
|
||||
}
|
||||
|
||||
/* CATEGORIES */
|
||||
.categories {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
margin-top: 32px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.cat-pill {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
padding: 8px 16px;
|
||||
background: transparent;
|
||||
border: 1px solid #E8E4DF;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
transition: all 0.25s;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
.cat-pill:hover {
|
||||
border-color: #D4A574;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
.cat-pill.active {
|
||||
border-color: #D4A574;
|
||||
color: #D4A574;
|
||||
background: rgba(212,165,116,0.06);
|
||||
}
|
||||
|
||||
/* TOOL CARDS */
|
||||
.tools-section {
|
||||
padding: 48px 80px 0;
|
||||
}
|
||||
.tools-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.tools-header h2 {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #999;
|
||||
}
|
||||
.tools-header a {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #D4A574;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
.tools-header a:hover { opacity: 0.7; }
|
||||
|
||||
.tools-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
.tool-card {
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #EEEBE7;
|
||||
border-radius: 2px;
|
||||
padding: 24px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
.tool-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.tool-icon-box {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.tool-icon-box.claude { background: #F0EBE3; color: #D4A574; }
|
||||
.tool-icon-box.cursor { background: #EEECEA; color: #999; }
|
||||
.tool-icon-box.midjourney { background: #EEECEA; color: #999; }
|
||||
.tool-icon-box.perplexity { background: #EEECEA; color: #999; }
|
||||
|
||||
.tool-card-name {
|
||||
font-size: 17px;
|
||||
font-weight: 500;
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
.tool-card-cat {
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: #BBB;
|
||||
letter-spacing: 0.5px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.tool-card-desc {
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
color: #888;
|
||||
line-height: 1.55;
|
||||
}
|
||||
.tool-card-tag {
|
||||
display: inline-block;
|
||||
margin-top: 16px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: #D4A574;
|
||||
letter-spacing: 0.5px;
|
||||
padding: 4px 10px;
|
||||
background: rgba(212,165,116,0.1);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* DIVIDER */
|
||||
.divider {
|
||||
width: 40px;
|
||||
height: 1px;
|
||||
background: #D4A574;
|
||||
margin: 0 auto;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav>
|
||||
<div class="nav-logo">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88" fill="currentColor" stroke="currentColor"/>
|
||||
</svg>
|
||||
AI Compass
|
||||
</div>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#">Browse</a></li>
|
||||
<li><a href="#">Categories</a></li>
|
||||
<li><a href="#">New This Week</a></li>
|
||||
<li><a href="#">Newsletter</a></li>
|
||||
</ul>
|
||||
<button class="nav-cta">Submit Tool</button>
|
||||
</nav>
|
||||
|
||||
<section class="hero">
|
||||
<p class="hero-eyebrow">A Curated Directory</p>
|
||||
<h1>Find the right AI tool <em>in seconds</em></h1>
|
||||
<p class="hero-sub">500+ tools, 24 categories, updated weekly</p>
|
||||
|
||||
<div class="search-wrapper">
|
||||
<input class="search-bar" type="text" placeholder="Search by tool name, category, or use case...">
|
||||
<i data-lucide="search" class="search-icon" style="width:18px;height:18px;"></i>
|
||||
</div>
|
||||
|
||||
<div class="categories">
|
||||
<span class="cat-pill active">Writing</span>
|
||||
<span class="cat-pill">Coding</span>
|
||||
<span class="cat-pill">Image</span>
|
||||
<span class="cat-pill">Video</span>
|
||||
<span class="cat-pill">Audio</span>
|
||||
<span class="cat-pill">Productivity</span>
|
||||
<span class="cat-pill">Research</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="tools-section">
|
||||
<div class="tools-header">
|
||||
<h2>Featured Selections</h2>
|
||||
<a href="#">
|
||||
View all 500+ tools
|
||||
<i data-lucide="arrow-right" style="width:14px;height:14px;"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="tools-grid">
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header">
|
||||
<div class="tool-icon-box claude">
|
||||
<i data-lucide="sparkles" style="width:20px;height:20px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tool-card-name">Claude</div>
|
||||
<div class="tool-card-cat">Writing & Analysis</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="tool-card-desc">Advanced AI assistant for writing, analysis, and coding with nuanced reasoning and extended context.</p>
|
||||
<span class="tool-card-tag">Editor's Pick</span>
|
||||
</div>
|
||||
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header">
|
||||
<div class="tool-icon-box cursor">
|
||||
<i data-lucide="code-2" style="width:20px;height:20px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tool-card-name">Cursor</div>
|
||||
<div class="tool-card-cat">Development</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="tool-card-desc">AI-native code editor that understands your entire codebase and accelerates your development workflow.</p>
|
||||
<span class="tool-card-tag">Trending</span>
|
||||
</div>
|
||||
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header">
|
||||
<div class="tool-icon-box midjourney">
|
||||
<i data-lucide="image" style="width:20px;height:20px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tool-card-name">Midjourney</div>
|
||||
<div class="tool-card-cat">Image Generation</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="tool-card-desc">Leading AI image generation platform producing stunning, highly detailed visuals from text prompts.</p>
|
||||
<span class="tool-card-tag">Popular</span>
|
||||
</div>
|
||||
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header">
|
||||
<div class="tool-icon-box perplexity">
|
||||
<i data-lucide="globe" style="width:20px;height:20px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tool-card-name">Perplexity</div>
|
||||
<div class="tool-card-cat">Research & Search</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="tool-card-desc">AI-powered search engine delivering real-time, cited answers in a natural conversational format.</p>
|
||||
<span class="tool-card-tag">Staff Pick</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 83 KiB |
@ -1,422 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>AI Compass — Pentagram Style</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&family=Space+Grotesk:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
background: #FFFFFF;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/* NAV */
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24px 64px;
|
||||
border-bottom: 2px solid #000;
|
||||
}
|
||||
.nav-logo {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
letter-spacing: -0.5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.nav-logo .compass-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
list-style: none;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1.5px;
|
||||
}
|
||||
.nav-links a {
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-links a:hover { color: #E63946; }
|
||||
.nav-submit {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1.5px;
|
||||
background: #000;
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 10px 24px;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.nav-submit:hover { background: #E63946; }
|
||||
|
||||
/* HERO GRID */
|
||||
.hero {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
min-height: calc(900px - 72px);
|
||||
}
|
||||
|
||||
/* LEFT PANEL */
|
||||
.hero-left {
|
||||
padding: 56px 64px 48px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
border-right: 2px solid #000;
|
||||
}
|
||||
.hero-stat {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 180px;
|
||||
font-weight: 900;
|
||||
line-height: 0.85;
|
||||
letter-spacing: -8px;
|
||||
color: #E63946;
|
||||
position: relative;
|
||||
}
|
||||
.hero-stat span {
|
||||
font-size: 48px;
|
||||
letter-spacing: -2px;
|
||||
vertical-align: top;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.hero-headline {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 42px;
|
||||
font-weight: 900;
|
||||
line-height: 1.08;
|
||||
letter-spacing: -1.5px;
|
||||
margin-top: 24px;
|
||||
max-width: 520px;
|
||||
}
|
||||
.hero-sub {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
margin-top: 16px;
|
||||
letter-spacing: 0.2px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* SEARCH */
|
||||
.search-box {
|
||||
display: flex;
|
||||
border: 3px solid #000;
|
||||
margin-top: 32px;
|
||||
max-width: 560px;
|
||||
}
|
||||
.search-box input {
|
||||
flex: 1;
|
||||
padding: 16px 20px;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 15px;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: #fff;
|
||||
}
|
||||
.search-box button {
|
||||
padding: 16px 28px;
|
||||
background: #000;
|
||||
color: #fff;
|
||||
border: none;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1.5px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.search-box button:hover { background: #E63946; }
|
||||
|
||||
/* CATEGORY TAGS */
|
||||
.categories {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-top: 28px;
|
||||
}
|
||||
.cat-tag {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 2px;
|
||||
padding: 6px 14px;
|
||||
border: 2px solid #000;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
.cat-tag:hover {
|
||||
background: #000;
|
||||
color: #fff;
|
||||
}
|
||||
.cat-tag.active {
|
||||
background: #E63946;
|
||||
border-color: #E63946;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* RIGHT PANEL — TOOL LIST */
|
||||
.hero-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.list-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16px 48px;
|
||||
border-bottom: 2px solid #000;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 2px;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.tool-item {
|
||||
display: grid;
|
||||
grid-template-columns: 48px 1fr auto;
|
||||
align-items: center;
|
||||
padding: 24px 48px;
|
||||
border-bottom: 1px solid #E0E0E0;
|
||||
transition: background 0.15s;
|
||||
cursor: pointer;
|
||||
}
|
||||
.tool-item:hover {
|
||||
background: #F7F7F7;
|
||||
}
|
||||
.tool-index {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #BBB;
|
||||
}
|
||||
.tool-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.tool-name-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.tool-name {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
.tool-badge {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1.5px;
|
||||
color: #E63946;
|
||||
background: rgba(230, 57, 70, 0.08);
|
||||
padding: 3px 8px;
|
||||
}
|
||||
.tool-desc {
|
||||
font-size: 13px;
|
||||
color: #777;
|
||||
line-height: 1.4;
|
||||
max-width: 400px;
|
||||
}
|
||||
.tool-category {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 2px;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tool-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* FEATURED TAG */
|
||||
.tool-item.featured {
|
||||
border-left: 4px solid #E63946;
|
||||
padding-left: 44px;
|
||||
}
|
||||
|
||||
.bottom-bar {
|
||||
margin-top: auto;
|
||||
padding: 16px 48px;
|
||||
border-top: 2px solid #000;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.bottom-bar a {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1.5px;
|
||||
font-size: 11px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.bottom-bar a:hover { color: #E63946; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav>
|
||||
<div class="nav-logo">
|
||||
<svg class="compass-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88" fill="#E63946" stroke="#E63946"/>
|
||||
</svg>
|
||||
AI Compass
|
||||
</div>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#">Browse</a></li>
|
||||
<li><a href="#">Categories</a></li>
|
||||
<li><a href="#">New Tools</a></li>
|
||||
<li><a href="#">About</a></li>
|
||||
</ul>
|
||||
<button class="nav-submit">Submit a Tool</button>
|
||||
</nav>
|
||||
|
||||
<div class="hero">
|
||||
<!-- LEFT -->
|
||||
<div class="hero-left">
|
||||
<div>
|
||||
<div class="hero-stat">500<span>+</span></div>
|
||||
<h1 class="hero-headline">Find the right AI tool in seconds</h1>
|
||||
<p class="hero-sub">500+ tools, 24 categories, updated weekly. The most comprehensive curated directory for AI practitioners.</p>
|
||||
|
||||
<div class="search-box">
|
||||
<input type="text" placeholder="Search tools by name, category, or use case...">
|
||||
<button>
|
||||
<i data-lucide="search" style="width:16px;height:16px;"></i>
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="categories">
|
||||
<span class="cat-tag active">Writing</span>
|
||||
<span class="cat-tag">Coding</span>
|
||||
<span class="cat-tag">Image</span>
|
||||
<span class="cat-tag">Video</span>
|
||||
<span class="cat-tag">Audio</span>
|
||||
<span class="cat-tag">Productivity</span>
|
||||
<span class="cat-tag">Research</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RIGHT -->
|
||||
<div class="hero-right">
|
||||
<div class="list-header">
|
||||
<span>Featured Tools</span>
|
||||
<span>Category</span>
|
||||
</div>
|
||||
|
||||
<div class="tool-item featured">
|
||||
<span class="tool-index">01</span>
|
||||
<div class="tool-info">
|
||||
<div class="tool-name-row">
|
||||
<span class="tool-name">Claude</span>
|
||||
<span class="tool-badge">Editor's Pick</span>
|
||||
</div>
|
||||
<span class="tool-desc">Advanced AI assistant for writing, analysis, and coding with extended context and nuanced reasoning.</span>
|
||||
</div>
|
||||
<span class="tool-category">Writing</span>
|
||||
</div>
|
||||
|
||||
<div class="tool-item">
|
||||
<span class="tool-index">02</span>
|
||||
<div class="tool-info">
|
||||
<div class="tool-name-row">
|
||||
<span class="tool-name">Cursor</span>
|
||||
<span class="tool-badge">Trending</span>
|
||||
</div>
|
||||
<span class="tool-desc">AI-native code editor that understands your entire codebase and accelerates development workflows.</span>
|
||||
</div>
|
||||
<span class="tool-category">Coding</span>
|
||||
</div>
|
||||
|
||||
<div class="tool-item">
|
||||
<span class="tool-index">03</span>
|
||||
<div class="tool-info">
|
||||
<div class="tool-name-row">
|
||||
<span class="tool-name">Midjourney</span>
|
||||
</div>
|
||||
<span class="tool-desc">Leading AI image generation platform producing stunning visuals from text descriptions.</span>
|
||||
</div>
|
||||
<span class="tool-category">Image</span>
|
||||
</div>
|
||||
|
||||
<div class="tool-item">
|
||||
<span class="tool-index">04</span>
|
||||
<div class="tool-info">
|
||||
<div class="tool-name-row">
|
||||
<span class="tool-name">Perplexity</span>
|
||||
</div>
|
||||
<span class="tool-desc">AI-powered search engine with real-time citations and conversational answers.</span>
|
||||
</div>
|
||||
<span class="tool-category">Research</span>
|
||||
</div>
|
||||
|
||||
<div class="tool-item">
|
||||
<span class="tool-index">05</span>
|
||||
<div class="tool-info">
|
||||
<div class="tool-name-row">
|
||||
<span class="tool-name">Runway</span>
|
||||
<span class="tool-badge">New</span>
|
||||
</div>
|
||||
<span class="tool-desc">Gen-3 video generation and editing suite for creators and filmmakers.</span>
|
||||
</div>
|
||||
<span class="tool-category">Video</span>
|
||||
</div>
|
||||
|
||||
<div class="bottom-bar">
|
||||
<span>Showing 5 of 500+ tools</span>
|
||||
<a href="#">
|
||||
View All Tools
|
||||
<i data-lucide="arrow-right" style="width:14px;height:14px;"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 103 KiB |
@ -1,499 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>AI Compass — Takram Style</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=Noto+Serif+SC:wght@300;400;500;600&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: #F5F0EB;
|
||||
color: #3A3A35;
|
||||
}
|
||||
|
||||
/* NAV */
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24px 72px;
|
||||
}
|
||||
.nav-logo {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: #3A3A35;
|
||||
}
|
||||
.nav-logo svg { color: #A8B5A0; }
|
||||
.nav-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 36px;
|
||||
}
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 28px;
|
||||
list-style: none;
|
||||
}
|
||||
.nav-links a {
|
||||
text-decoration: none;
|
||||
color: #8A8A80;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
.nav-links a:hover { color: #3A3A35; }
|
||||
.nav-cta {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
background: transparent;
|
||||
color: #6B8F71;
|
||||
border: 1px solid rgba(107, 143, 113, 0.35);
|
||||
padding: 10px 24px;
|
||||
border-radius: 100px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.nav-cta:hover { background: rgba(107, 143, 113, 0.06); border-color: #6B8F71; }
|
||||
|
||||
/* MAIN LAYOUT */
|
||||
.main {
|
||||
display: grid;
|
||||
grid-template-columns: 520px 1fr;
|
||||
gap: 0;
|
||||
padding: 20px 72px 0;
|
||||
height: calc(900px - 68px);
|
||||
}
|
||||
|
||||
/* LEFT: HERO TEXT */
|
||||
.hero-text {
|
||||
padding: 40px 48px 40px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.hero-eyebrow {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: #6B8F71;
|
||||
letter-spacing: 2.5px;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 16px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.hero-headline {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 42px;
|
||||
font-weight: 400;
|
||||
line-height: 1.3;
|
||||
letter-spacing: -0.5px;
|
||||
color: #2D3436;
|
||||
}
|
||||
.hero-headline em {
|
||||
font-style: normal;
|
||||
color: #6B8F71;
|
||||
font-weight: 500;
|
||||
}
|
||||
.hero-sub {
|
||||
font-size: 15px;
|
||||
font-weight: 300;
|
||||
color: #8A8A80;
|
||||
margin-top: 16px;
|
||||
line-height: 1.6;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
/* SEARCH */
|
||||
.search-wrapper {
|
||||
margin-top: 32px;
|
||||
position: relative;
|
||||
max-width: 420px;
|
||||
}
|
||||
.search-bar {
|
||||
width: 100%;
|
||||
padding: 16px 50px 16px 20px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
color: #3A3A35;
|
||||
background: #EDE8DE;
|
||||
border: 1px solid #DDD7CC;
|
||||
border-radius: 14px;
|
||||
outline: none;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.search-bar::placeholder { color: #B0AEA4; }
|
||||
.search-bar:focus {
|
||||
background: #FFFFFF;
|
||||
border-color: #6B8F71;
|
||||
box-shadow: 0 4px 24px rgba(168,181,160,0.15);
|
||||
}
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #6B8F71;
|
||||
}
|
||||
|
||||
/* CATEGORY CHIPS */
|
||||
.categories {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-top: 24px;
|
||||
max-width: 420px;
|
||||
}
|
||||
.cat-chip {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #7A7A72;
|
||||
padding: 7px 16px;
|
||||
background: #EDE8DE;
|
||||
border: none;
|
||||
border-radius: 100px;
|
||||
cursor: pointer;
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.cat-chip:hover {
|
||||
background: #E0DBCF;
|
||||
color: #3A3A35;
|
||||
}
|
||||
.cat-chip.active {
|
||||
background: rgba(107, 143, 113, 0.15);
|
||||
color: #6B8F71;
|
||||
border: 1px solid rgba(107, 143, 113, 0.25);
|
||||
}
|
||||
|
||||
/* DIAGRAM LINES (decorative connections) */
|
||||
.diagram-canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* RIGHT: TOOL CARDS */
|
||||
.tools-area {
|
||||
position: relative;
|
||||
padding: 20px 0 0 20px;
|
||||
}
|
||||
|
||||
.tools-label {
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
color: #6B8F71;
|
||||
letter-spacing: 2.5px;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 20px;
|
||||
padding-left: 4px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.tools-organic {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.tool-card {
|
||||
background: rgba(255,255,255,0.5);
|
||||
border: 1px solid #E8E4DC;
|
||||
border-radius: 14px;
|
||||
padding: 24px;
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
.tool-card:hover {
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.06);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* Organic offset: stagger cards */
|
||||
.tool-card:nth-child(2) {
|
||||
margin-top: 24px;
|
||||
}
|
||||
.tool-card:nth-child(3) {
|
||||
margin-top: -12px;
|
||||
}
|
||||
|
||||
.tool-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.tool-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.tool-icon.claude { background: rgba(212, 165, 116, 0.15); color: #D4A574; }
|
||||
.tool-icon.cursor { background: rgba(139, 157, 195, 0.12); color: #8B9DC3; }
|
||||
.tool-icon.midjourney { background: rgba(212, 165, 116, 0.12); color: #C4A882; }
|
||||
.tool-icon.perplexity { background: rgba(107, 143, 113, 0.1); color: #6B8F71; }
|
||||
|
||||
.tool-name {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #2C2C28;
|
||||
}
|
||||
.tool-cat {
|
||||
font-size: 11px;
|
||||
color: #AAA89E;
|
||||
margin-top: 1px;
|
||||
}
|
||||
.tool-desc {
|
||||
font-size: 13px;
|
||||
font-weight: 300;
|
||||
color: #8A8A80;
|
||||
line-height: 1.55;
|
||||
}
|
||||
.tool-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin-top: 14px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: #6B8F71;
|
||||
padding: 4px 10px;
|
||||
background: rgba(107,143,113,0.08);
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
/* Connection dots */
|
||||
.conn-dot {
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #6B8F71;
|
||||
opacity: 0.4;
|
||||
}
|
||||
.conn-dot.d1 { top: 80px; left: -10px; }
|
||||
.conn-dot.d2 { top: 200px; left: -14px; }
|
||||
.conn-dot.d3 { bottom: 160px; left: -10px; }
|
||||
|
||||
.conn-line {
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
width: 2px;
|
||||
background: linear-gradient(to bottom, transparent, #A8B5A0, transparent);
|
||||
opacity: 0.2;
|
||||
}
|
||||
.conn-line.l1 { top: 88px; height: 108px; }
|
||||
.conn-line.l2 { top: 208px; height: 100px; }
|
||||
|
||||
/* VIEW MORE */
|
||||
.view-more {
|
||||
text-align: center;
|
||||
margin-top: 16px;
|
||||
}
|
||||
.view-more a {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #6B8F71;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
.view-more a:hover { color: #7A9470; }
|
||||
|
||||
/* FLOATING NOTE */
|
||||
.floating-note {
|
||||
position: absolute;
|
||||
bottom: 40px;
|
||||
left: 72px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
color: #B0AEA4;
|
||||
font-weight: 300;
|
||||
}
|
||||
.floating-note .dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: #6B8F71;
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 0.4; }
|
||||
50% { opacity: 1; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav>
|
||||
<div class="nav-logo">
|
||||
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88" fill="currentColor" stroke="currentColor"/>
|
||||
</svg>
|
||||
AI Compass
|
||||
</div>
|
||||
<div class="nav-right">
|
||||
<ul class="nav-links">
|
||||
<li><a href="#">Explore</a></li>
|
||||
<li><a href="#">Categories</a></li>
|
||||
<li><a href="#">Weekly Picks</a></li>
|
||||
<li><a href="#">About</a></li>
|
||||
</ul>
|
||||
<button class="nav-cta">Submit Tool</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="main">
|
||||
<!-- LEFT -->
|
||||
<div class="hero-text">
|
||||
<p class="hero-eyebrow">Curated Directory</p>
|
||||
<h1 class="hero-headline">Find the right<br>AI tool <em>in seconds</em></h1>
|
||||
<p class="hero-sub">500+ carefully selected tools across 24 categories, updated weekly. Discover, compare, and find the perfect tool for your workflow.</p>
|
||||
|
||||
<div class="search-wrapper">
|
||||
<input class="search-bar" type="text" placeholder="Search tools, categories, or use cases...">
|
||||
<i data-lucide="search" class="search-icon" style="width:16px;height:16px;"></i>
|
||||
</div>
|
||||
|
||||
<div class="categories">
|
||||
<span class="cat-chip active">Writing</span>
|
||||
<span class="cat-chip">Coding</span>
|
||||
<span class="cat-chip">Image</span>
|
||||
<span class="cat-chip">Video</span>
|
||||
<span class="cat-chip">Audio</span>
|
||||
<span class="cat-chip">Productivity</span>
|
||||
<span class="cat-chip">Research</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RIGHT -->
|
||||
<div class="tools-area">
|
||||
<div class="conn-dot d1"></div>
|
||||
<div class="conn-line l1"></div>
|
||||
<div class="conn-dot d2"></div>
|
||||
<div class="conn-line l2"></div>
|
||||
<div class="conn-dot d3"></div>
|
||||
|
||||
<p class="tools-label">Featured Discoveries</p>
|
||||
|
||||
<div class="tools-organic">
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header">
|
||||
<div class="tool-icon claude">
|
||||
<i data-lucide="sparkles" style="width:18px;height:18px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tool-name">Claude</div>
|
||||
<div class="tool-cat">Writing & Analysis</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="tool-desc">Advanced AI assistant for writing, analysis, and coding with nuanced reasoning and extended context window.</p>
|
||||
<span class="tool-tag">
|
||||
<i data-lucide="star" style="width:10px;height:10px;"></i>
|
||||
Editor's Pick
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header">
|
||||
<div class="tool-icon cursor">
|
||||
<i data-lucide="code-2" style="width:18px;height:18px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tool-name">Cursor</div>
|
||||
<div class="tool-cat">Development</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="tool-desc">AI-native code editor that deeply understands your codebase and accelerates every development task.</p>
|
||||
<span class="tool-tag">
|
||||
<i data-lucide="trending-up" style="width:10px;height:10px;"></i>
|
||||
Trending
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header">
|
||||
<div class="tool-icon midjourney">
|
||||
<i data-lucide="image" style="width:18px;height:18px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tool-name">Midjourney</div>
|
||||
<div class="tool-cat">Image Generation</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="tool-desc">Create stunning, detailed visuals from text descriptions with the leading AI image generation platform.</p>
|
||||
<span class="tool-tag">
|
||||
<i data-lucide="heart" style="width:10px;height:10px;"></i>
|
||||
Popular
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header">
|
||||
<div class="tool-icon perplexity">
|
||||
<i data-lucide="globe" style="width:18px;height:18px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tool-name">Perplexity</div>
|
||||
<div class="tool-cat">Research & Search</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="tool-desc">AI-powered search delivering real-time answers with citations in a natural conversational format.</p>
|
||||
<span class="tool-tag">
|
||||
<i data-lucide="compass" style="width:10px;height:10px;"></i>
|
||||
Staff Pick
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="view-more">
|
||||
<a href="#">
|
||||
Explore all 500+ tools
|
||||
<i data-lucide="arrow-right" style="width:14px;height:14px;"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="floating-note">
|
||||
<span class="dot"></span>
|
||||
Updated weekly with new discoveries
|
||||
</div>
|
||||
|
||||
<!-- Spec annotation -->
|
||||
<svg style="position:absolute;bottom:60px;right:72px;opacity:0.15;" width="100" height="40" viewBox="0 0 100 40" fill="none">
|
||||
<line x1="0" y1="20" x2="60" y2="20" stroke="#6B8F71" stroke-width="0.5"/>
|
||||
<circle cx="60" cy="20" r="2" fill="none" stroke="#6B8F71" stroke-width="0.5"/>
|
||||
<text x="68" y="23" font-family="Inter" font-size="8" fill="#6B8F71" letter-spacing="0.5">500+ tools</text>
|
||||
</svg>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 119 KiB |
@ -1,562 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>Inkwell — AI Writing Assistant</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500;600&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #FAFAF8;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #2C2C2C;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 40px 80px 40px 80px;
|
||||
}
|
||||
|
||||
/* NAV */
|
||||
.nav-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 3px;
|
||||
text-transform: uppercase;
|
||||
color: #2C2C2C;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
text-decoration: none;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: #2C2C2C;
|
||||
}
|
||||
|
||||
/* HERO AREA */
|
||||
.hero-section {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 440px 1fr;
|
||||
gap: 80px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.hero-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 28px;
|
||||
}
|
||||
|
||||
.headline {
|
||||
font-size: 52px;
|
||||
font-weight: 200;
|
||||
line-height: 1.15;
|
||||
letter-spacing: -1.5px;
|
||||
color: #2C2C2C;
|
||||
}
|
||||
|
||||
.headline em {
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
color: #2C2C2C;
|
||||
position: relative;
|
||||
}
|
||||
.headline em::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: #D4A574;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
line-height: 1.7;
|
||||
color: #999;
|
||||
max-width: 380px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 14px 32px;
|
||||
background: #2C2C2C;
|
||||
color: #FAFAF8;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.5px;
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
width: fit-content;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
|
||||
.cta-button:hover {
|
||||
background: #3C3C3C;
|
||||
}
|
||||
|
||||
.social-proof {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #bbb;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
/* FEATURES — minimal */
|
||||
.features-row {
|
||||
display: flex;
|
||||
gap: 48px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.feature-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
background: rgba(212, 165, 116, 0.12);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.feature-icon svg {
|
||||
color: #D4A574;
|
||||
}
|
||||
|
||||
.feature-label {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #2C2C2C;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.feature-desc {
|
||||
font-size: 12px;
|
||||
font-weight: 300;
|
||||
color: #aaa;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* EDITOR MOCKUP — floating card */
|
||||
.editor-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.editor-card {
|
||||
width: 100%;
|
||||
max-width: 620px;
|
||||
height: 580px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 2px;
|
||||
box-shadow:
|
||||
0 4px 6px rgba(0,0,0,0.02),
|
||||
0 12px 28px rgba(0,0,0,0.06),
|
||||
0 40px 80px rgba(0,0,0,0.04);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 190px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.editor-main {
|
||||
padding: 32px 28px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.editor-toolbar {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
margin-bottom: 24px;
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 1px solid #F0EDE8;
|
||||
}
|
||||
|
||||
.tb-btn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 2px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #bbb;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tb-btn.active {
|
||||
background: #F5F0E8;
|
||||
color: #D4A574;
|
||||
}
|
||||
|
||||
.doc-title {
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
letter-spacing: -0.5px;
|
||||
color: #2C2C2C;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.doc-paragraph {
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
line-height: 1.9;
|
||||
color: #666;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.doc-paragraph .ai-enhanced {
|
||||
background: linear-gradient(120deg, rgba(212,165,116,0.1) 0%, rgba(212,165,116,0.18) 100%);
|
||||
border-radius: 3px;
|
||||
padding: 1px 4px;
|
||||
}
|
||||
|
||||
.doc-h2 {
|
||||
font-size: 17px;
|
||||
font-weight: 500;
|
||||
color: #2C2C2C;
|
||||
margin-bottom: 12px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.doc-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.doc-list li {
|
||||
font-size: 13px;
|
||||
font-weight: 300;
|
||||
color: #777;
|
||||
line-height: 1.8;
|
||||
padding-left: 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.doc-list li::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 10px;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 50%;
|
||||
background: #D4A574;
|
||||
}
|
||||
|
||||
.cursor-line {
|
||||
display: inline-block;
|
||||
width: 1.5px;
|
||||
height: 15px;
|
||||
background: #D4A574;
|
||||
animation: pulse 1.2s ease-in-out infinite;
|
||||
vertical-align: text-bottom;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.2; }
|
||||
}
|
||||
|
||||
/* AI SIDEBAR */
|
||||
.ai-sidebar {
|
||||
background: #FDFCFA;
|
||||
border-left: 1px solid #F0EDE8;
|
||||
padding: 24px 18px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #D4A574;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid #F0EDE8;
|
||||
}
|
||||
|
||||
.ai-card {
|
||||
background: #fff;
|
||||
border-radius: 2px;
|
||||
padding: 14px;
|
||||
border: 1px solid #F0EDE8;
|
||||
}
|
||||
|
||||
.ai-card-label {
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
color: #bbb;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.ai-card-content {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #2C2C2C;
|
||||
}
|
||||
|
||||
.voice-score {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.score-track {
|
||||
flex: 1;
|
||||
height: 3px;
|
||||
background: #F0EDE8;
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.score-fill {
|
||||
width: 92%;
|
||||
height: 100%;
|
||||
background: #D4A574;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.score-num {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #D4A574;
|
||||
}
|
||||
|
||||
.platform-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.p-tag {
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
padding: 4px 10px;
|
||||
border-radius: 2px;
|
||||
background: #F5F0E8;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.p-tag.active {
|
||||
background: rgba(212,165,116,0.15);
|
||||
color: #D4A574;
|
||||
}
|
||||
|
||||
.ai-suggestion {
|
||||
font-size: 12px;
|
||||
font-weight: 300;
|
||||
color: #888;
|
||||
line-height: 1.6;
|
||||
padding: 12px 14px;
|
||||
background: #fff;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #F0EDE8;
|
||||
}
|
||||
|
||||
.ai-suggestion .label {
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.8px;
|
||||
color: #bbb;
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.refine-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
background: #2C2C2C;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<!-- NAV -->
|
||||
<nav class="nav-bar">
|
||||
<div class="logo">Inkwell</div>
|
||||
<div class="nav-links">
|
||||
<a href="#">Features</a>
|
||||
<a href="#">Pricing</a>
|
||||
<a href="#">Stories</a>
|
||||
<a href="#" class="cta-button" style="padding: 10px 24px; font-size: 12px; margin: 0;">Start Writing</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- HERO -->
|
||||
<div class="hero-section">
|
||||
<!-- LEFT: Text -->
|
||||
<div class="hero-text">
|
||||
<h1 class="headline">Write better,<br>faster, with<br><em>your own voice</em></h1>
|
||||
<p class="subtitle">AI that learns your style, not replaces it. Publish across WeChat, Xiaohongshu, and video scripts while sounding unmistakably you.</p>
|
||||
|
||||
<div class="features-row">
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="feature-label">Style Learning</div>
|
||||
<div class="feature-desc">Adapts to your voice</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="feature-label">Multi-Platform</div>
|
||||
<div class="feature-desc">One tool, every format</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="feature-label">Human Touch</div>
|
||||
<div class="feature-desc">Warmth-preserving edit</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 24px;">
|
||||
<a href="#" class="cta-button">
|
||||
Start Writing
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>
|
||||
</a>
|
||||
<span class="social-proof">Trusted by 10,000+ creators</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RIGHT: Editor Card -->
|
||||
<div class="editor-wrapper">
|
||||
<div class="editor-card">
|
||||
<div class="editor-main">
|
||||
<div class="editor-toolbar">
|
||||
<button class="tb-btn active"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/><path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/></svg></button>
|
||||
<button class="tb-btn"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="19" y1="4" x2="10" y2="4"/><line x1="14" y1="20" x2="5" y2="20"/><line x1="15" y1="4" x2="9" y2="20"/></svg></button>
|
||||
<button class="tb-btn"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="21" y1="6" x2="3" y2="6"/><line x1="15" y1="12" x2="3" y2="12"/><line x1="17" y1="18" x2="3" y2="18"/></svg></button>
|
||||
<button class="tb-btn"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></button>
|
||||
</div>
|
||||
|
||||
<div class="doc-title">Morning Routines for Creative Minds</div>
|
||||
<div class="doc-paragraph">
|
||||
The best ideas rarely arrive on schedule. They come in the quiet space between waking and doing — <span class="ai-enhanced">that liminal moment when the mind is loose enough to wander but awake enough to notice</span>.
|
||||
</div>
|
||||
<div class="doc-h2">Finding Your Rhythm</div>
|
||||
<div class="doc-paragraph">
|
||||
Productivity culture tells us to optimize every hour. But creation is not production. The most prolific writers I know guard their mornings like sacred ground.<span class="cursor-line"></span>
|
||||
</div>
|
||||
<ul class="doc-list">
|
||||
<li>Start before checking your phone</li>
|
||||
<li>Write the ugly first draft freely</li>
|
||||
<li>Let AI handle polish, not direction</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="ai-sidebar">
|
||||
<div class="sidebar-title">Inkwell AI</div>
|
||||
|
||||
<div class="ai-card">
|
||||
<div class="ai-card-label">Voice Match</div>
|
||||
<div class="ai-card-content">Your Style</div>
|
||||
<div class="voice-score">
|
||||
<div class="score-track"><div class="score-fill"></div></div>
|
||||
<div class="score-num">92%</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ai-card">
|
||||
<div class="ai-card-label">Publishing To</div>
|
||||
<div class="ai-card-content">WeChat Article</div>
|
||||
<div class="platform-tags">
|
||||
<span class="p-tag active">WeChat</span>
|
||||
<span class="p-tag">XHS</span>
|
||||
<span class="p-tag">Script</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ai-suggestion">
|
||||
<span class="label">Suggestion</span>
|
||||
The second paragraph is beautiful. Consider adding a concrete personal example to ground the abstract idea.
|
||||
</div>
|
||||
|
||||
<button class="refine-btn">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 3v18"/><path d="M3 12h18"/></svg>
|
||||
Refine with AI
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 128 KiB |
@ -1,548 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>Inkwell — AI Writing Assistant</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #FFFFFF;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
color: #111111;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Grid overlay for Swiss design feel */
|
||||
body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background:
|
||||
repeating-linear-gradient(90deg, transparent, transparent 119px, rgba(0,0,0,0.03) 119px, rgba(0,0,0,0.03) 120px),
|
||||
repeating-linear-gradient(0deg, transparent, transparent 59px, rgba(0,0,0,0.02) 59px, rgba(0,0,0,0.02) 60px);
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* LEFT PANEL */
|
||||
.left-panel {
|
||||
padding: 60px 60px 48px 80px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
border-right: 2px solid #111;
|
||||
}
|
||||
|
||||
.top-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.5px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.logo span {
|
||||
color: #E63946;
|
||||
}
|
||||
|
||||
.nav {
|
||||
display: flex;
|
||||
gap: 28px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.5px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.nav a {
|
||||
color: #111;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
.headline {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 86px;
|
||||
font-weight: 700;
|
||||
line-height: 0.95;
|
||||
letter-spacing: -4px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.headline em {
|
||||
font-style: italic;
|
||||
color: #E63946;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
max-width: 420px;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
|
||||
.cta-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 16px 36px;
|
||||
background: #E63946;
|
||||
color: #fff;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.social-proof {
|
||||
font-size: 13px;
|
||||
color: #888;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.social-proof strong {
|
||||
color: #111;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* FEATURES — strict 3 col */
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0;
|
||||
border-top: 2px solid #111;
|
||||
}
|
||||
|
||||
.feature-item {
|
||||
padding: 20px 0;
|
||||
border-right: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.feature-item:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.feature-item:first-child {
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.feature-item:nth-child(2) {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.feature-item:last-child {
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.feature-number {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: #E63946;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.feature-title {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.3px;
|
||||
margin-bottom: 4px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.feature-desc {
|
||||
font-size: 12px;
|
||||
color: #777;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* RIGHT PANEL — Editor mockup as wireframe */
|
||||
.right-panel {
|
||||
background: #F7F7F7;
|
||||
padding: 48px 60px 48px 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.editor-mockup {
|
||||
width: 100%;
|
||||
max-width: 580px;
|
||||
height: 680px;
|
||||
background: #fff;
|
||||
border: 2px solid #111;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 200px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Grid reference lines on mockup */
|
||||
.editor-mockup::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background:
|
||||
repeating-linear-gradient(0deg, transparent, transparent 39px, rgba(0,0,0,0.03) 39px, rgba(0,0,0,0.03) 40px);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.editor-main {
|
||||
padding: 28px 24px;
|
||||
border-right: 2px solid #111;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.editor-toolbar {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.toolbar-btn {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border: 1px solid #ccc;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.toolbar-btn.active {
|
||||
background: #111;
|
||||
border-color: #111;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.editor-title-line {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.5px;
|
||||
margin-bottom: 16px;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.editor-text-block {
|
||||
font-size: 13px;
|
||||
line-height: 1.8;
|
||||
color: #444;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.editor-text-block .highlight {
|
||||
background: rgba(230, 57, 70, 0.12);
|
||||
border-bottom: 2px solid #E63946;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.editor-h2 {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 6px;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.editor-list {
|
||||
font-size: 13px;
|
||||
line-height: 2;
|
||||
color: #555;
|
||||
padding-left: 18px;
|
||||
}
|
||||
|
||||
.editor-cursor {
|
||||
display: inline-block;
|
||||
width: 2px;
|
||||
height: 16px;
|
||||
background: #E63946;
|
||||
animation: blink 1s step-end infinite;
|
||||
vertical-align: text-bottom;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
50% { opacity: 0; }
|
||||
}
|
||||
|
||||
/* AI SIDEBAR */
|
||||
.ai-sidebar {
|
||||
padding: 20px 16px;
|
||||
background: #FAFAFA;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1.5px;
|
||||
color: #E63946;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid #111;
|
||||
}
|
||||
|
||||
.sidebar-card {
|
||||
padding: 12px;
|
||||
border: 1px solid #ddd;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.sidebar-card-label {
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.8px;
|
||||
color: #999;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.sidebar-card-value {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #111;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.style-meter {
|
||||
display: flex;
|
||||
gap: 3px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.meter-bar {
|
||||
height: 4px;
|
||||
flex: 1;
|
||||
background: #E0E0E0;
|
||||
}
|
||||
|
||||
.meter-bar.filled {
|
||||
background: #E63946;
|
||||
}
|
||||
|
||||
.sidebar-suggestion {
|
||||
padding: 10px 12px;
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
font-size: 12px;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.sidebar-suggestion strong {
|
||||
color: #111;
|
||||
display: block;
|
||||
font-size: 10px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.sidebar-action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 10px 12px;
|
||||
background: #111;
|
||||
color: #fff;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.tag-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.tag {
|
||||
font-size: 10px;
|
||||
padding: 2px 8px;
|
||||
border: 1px solid #ccc;
|
||||
color: #666;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
/* Corner mark */
|
||||
.right-panel::after {
|
||||
content: 'INKWELL V1.0';
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 24px;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 10px;
|
||||
letter-spacing: 2px;
|
||||
color: #bbb;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- LEFT PANEL -->
|
||||
<div class="left-panel">
|
||||
<div class="top-bar">
|
||||
<div class="logo">INK<span>WELL</span></div>
|
||||
<nav class="nav">
|
||||
<a href="#">Features</a>
|
||||
<a href="#">Pricing</a>
|
||||
<a href="#">Blog</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="hero-content">
|
||||
<h1 class="headline">Write<br>better,<br>faster,<br>with <em>your</em><br>own voice.</h1>
|
||||
<p class="subtitle">AI that learns your style, not replaces it. Craft content for WeChat, Xiaohongshu, and video scripts — all in your authentic tone.</p>
|
||||
<div class="cta-row">
|
||||
<a href="#" class="cta-button">
|
||||
Start Writing
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>
|
||||
</a>
|
||||
<span class="social-proof">Trusted by <strong>10,000+</strong> creators</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="features-grid">
|
||||
<div class="feature-item">
|
||||
<div class="feature-number">01</div>
|
||||
<div class="feature-title">Style Learning</div>
|
||||
<div class="feature-desc">Adapts to your unique voice through continuous analysis of your writing patterns.</div>
|
||||
</div>
|
||||
<div class="feature-item">
|
||||
<div class="feature-number">02</div>
|
||||
<div class="feature-title">Multi-Platform</div>
|
||||
<div class="feature-desc">WeChat articles, Xiaohongshu posts, video scripts. One tool, every format.</div>
|
||||
</div>
|
||||
<div class="feature-item">
|
||||
<div class="feature-number">03</div>
|
||||
<div class="feature-title">Human-Touch</div>
|
||||
<div class="feature-desc">Proofreading that preserves warmth and removes robotic phrasing.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RIGHT PANEL — Editor Mockup -->
|
||||
<div class="right-panel">
|
||||
<div class="editor-mockup">
|
||||
<div class="editor-main">
|
||||
<div class="editor-toolbar">
|
||||
<div class="toolbar-btn active"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/><path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/></svg></div>
|
||||
<div class="toolbar-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="19" y1="4" x2="10" y2="4"/><line x1="14" y1="20" x2="5" y2="20"/><line x1="15" y1="4" x2="9" y2="20"/></svg></div>
|
||||
<div class="toolbar-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="21" y1="6" x2="3" y2="6"/><line x1="15" y1="12" x2="3" y2="12"/><line x1="17" y1="18" x2="3" y2="18"/></svg></div>
|
||||
<div class="toolbar-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg></div>
|
||||
</div>
|
||||
|
||||
<div class="editor-title-line">The Future of Content Creation</div>
|
||||
<div class="editor-text-block">
|
||||
Every creator faces the same tension: the desire to produce more content versus the need to maintain quality and authenticity. <span class="highlight">AI doesn't have to mean losing your voice</span> — it can mean amplifying it.
|
||||
</div>
|
||||
<div class="editor-h2">Why Authenticity Matters</div>
|
||||
<div class="editor-text-block">
|
||||
Readers can tell. They feel the difference between words that carry genuine experience and words assembled by algorithm. The goal isn't to write <em>more</em> — it's to write more of what only you can write.<span class="editor-cursor"></span>
|
||||
</div>
|
||||
<div class="editor-h2">Key Principles</div>
|
||||
<ol class="editor-list">
|
||||
<li>Write from personal experience first</li>
|
||||
<li>Use AI for refinement, not replacement</li>
|
||||
<li>Adapt tone for each platform</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="ai-sidebar">
|
||||
<div class="sidebar-header">AI Assistant</div>
|
||||
|
||||
<div class="sidebar-card">
|
||||
<div class="sidebar-card-label">Style Match</div>
|
||||
<div class="sidebar-card-value">92% Voice Fidelity</div>
|
||||
<div class="style-meter">
|
||||
<div class="meter-bar filled"></div>
|
||||
<div class="meter-bar filled"></div>
|
||||
<div class="meter-bar filled"></div>
|
||||
<div class="meter-bar filled"></div>
|
||||
<div class="meter-bar"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-card">
|
||||
<div class="sidebar-card-label">Target</div>
|
||||
<div class="sidebar-card-value">WeChat Article</div>
|
||||
<div class="tag-row">
|
||||
<span class="tag">WeChat</span>
|
||||
<span class="tag">XHS</span>
|
||||
<span class="tag">Script</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-suggestion">
|
||||
<strong>Suggestion</strong>
|
||||
Consider opening with a specific anecdote to strengthen the personal connection.
|
||||
</div>
|
||||
|
||||
<div class="sidebar-suggestion">
|
||||
<strong>Tone Check</strong>
|
||||
Paragraph 2 reads slightly formal. Soften with a conversational phrase.
|
||||
</div>
|
||||
|
||||
<button class="sidebar-action">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>
|
||||
Refine Selection
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 147 KiB |
@ -1,696 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>Inkwell — AI Writing Assistant</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&family=Noto+Serif+SC:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #F5F0EB;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #3D3D3D;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* NAV */
|
||||
.nav-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 28px 64px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #5C5347;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.nav-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 36px;
|
||||
}
|
||||
|
||||
.nav-right a {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #8A8278;
|
||||
text-decoration: none;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.nav-cta {
|
||||
padding: 10px 24px;
|
||||
background: transparent;
|
||||
color: #2D3436;
|
||||
border: 1px solid rgba(45, 52, 54, 0.2);
|
||||
border-radius: 24px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
/* MAIN CONTENT */
|
||||
.main-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 64px;
|
||||
gap: 36px;
|
||||
}
|
||||
|
||||
/* HERO ROW */
|
||||
.hero-row {
|
||||
display: grid;
|
||||
grid-template-columns: 480px 1fr;
|
||||
gap: 56px;
|
||||
align-items: start;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.hero-text {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.headline {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 44px;
|
||||
font-weight: 600;
|
||||
line-height: 1.35;
|
||||
letter-spacing: -0.5px;
|
||||
color: #3D3D3D;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.headline .accent {
|
||||
color: #6B8F71;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
line-height: 1.8;
|
||||
color: #8A8278;
|
||||
max-width: 420px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.cta-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 14px 32px;
|
||||
background: #2D3436;
|
||||
color: #F5F0EB;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.5px;
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
border-radius: 32px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.social-proof {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #B5AD9E;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
/* EDITOR MOCKUP — organic rounded */
|
||||
.editor-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.editor-card {
|
||||
width: 100%;
|
||||
max-width: 720px;
|
||||
height: 460px;
|
||||
background: #FDFCF9;
|
||||
border-radius: 24px;
|
||||
box-shadow:
|
||||
0 2px 8px rgba(92,83,71,0.04),
|
||||
0 8px 24px rgba(92,83,71,0.06),
|
||||
0 24px 48px rgba(92,83,71,0.03);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 200px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.editor-body {
|
||||
padding: 28px 28px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.editor-toolbar {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 14px;
|
||||
border-bottom: 1px solid #EDE8DF;
|
||||
}
|
||||
|
||||
.e-btn {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #C4BDB2;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.e-btn.active {
|
||||
background: #EDE8DF;
|
||||
color: #5C5347;
|
||||
}
|
||||
|
||||
.e-title {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #3D3D3D;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.e-text {
|
||||
font-size: 13.5px;
|
||||
font-weight: 300;
|
||||
line-height: 1.9;
|
||||
color: #6B6560;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.e-text .enhanced {
|
||||
background: rgba(107,143,113,0.2);
|
||||
border-radius: 4px;
|
||||
padding: 1px 4px;
|
||||
}
|
||||
|
||||
.e-h2 {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #3D3D3D;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.e-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.e-list li {
|
||||
font-size: 13px;
|
||||
font-weight: 300;
|
||||
color: #8A8278;
|
||||
line-height: 1.9;
|
||||
padding-left: 18px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.e-list li::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 10px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
border: 1.5px solid #6B8F71;
|
||||
}
|
||||
|
||||
.typing-cursor {
|
||||
display: inline-block;
|
||||
width: 1.5px;
|
||||
height: 14px;
|
||||
background: #6B8F71;
|
||||
animation: softblink 1.5s ease-in-out infinite;
|
||||
vertical-align: text-bottom;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
@keyframes softblink {
|
||||
0%, 100% { opacity: 0.8; }
|
||||
50% { opacity: 0.15; }
|
||||
}
|
||||
|
||||
/* AI Sidebar */
|
||||
.ai-panel {
|
||||
background: #F8F5EF;
|
||||
border-left: 1px solid #EDE8DF;
|
||||
padding: 22px 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid #EDE8DF;
|
||||
}
|
||||
|
||||
.panel-header svg {
|
||||
color: #6B8F71;
|
||||
}
|
||||
|
||||
.panel-header span {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #5C5347;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.panel-card {
|
||||
background: #FDFCF9;
|
||||
border-radius: 14px;
|
||||
padding: 14px;
|
||||
border: 1px solid #EDE8DF;
|
||||
}
|
||||
|
||||
.panel-card-label {
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.8px;
|
||||
color: #B5AD9E;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.panel-card-value {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #3D3D3D;
|
||||
}
|
||||
|
||||
.voice-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.vb-track {
|
||||
flex: 1;
|
||||
height: 4px;
|
||||
background: #EDE8DF;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.vb-fill {
|
||||
width: 92%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #6B8F71, #C4D1BC);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.vb-label {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: #6B8F71;
|
||||
}
|
||||
|
||||
.platform-pills {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.pill {
|
||||
font-size: 10px;
|
||||
padding: 4px 10px;
|
||||
border-radius: 16px;
|
||||
background: #EDE8DF;
|
||||
color: #8A8278;
|
||||
}
|
||||
|
||||
.pill.active {
|
||||
background: rgba(107,143,113,0.25);
|
||||
color: #5C5347;
|
||||
}
|
||||
|
||||
.panel-note {
|
||||
font-size: 11.5px;
|
||||
font-weight: 300;
|
||||
color: #8A8278;
|
||||
line-height: 1.6;
|
||||
padding: 12px;
|
||||
background: #FDFCF9;
|
||||
border-radius: 14px;
|
||||
border: 1px solid #EDE8DF;
|
||||
}
|
||||
|
||||
.panel-note .note-label {
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.8px;
|
||||
color: #B5AD9E;
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
/* FLOW DIAGRAM */
|
||||
.flow-section {
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
|
||||
.flow-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.flow-step {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
padding: 14px 28px;
|
||||
background: #FDFCF9;
|
||||
border-radius: 18px;
|
||||
border: 1px solid #EDE8DF;
|
||||
box-shadow: 0 2px 8px rgba(92,83,71,0.03);
|
||||
}
|
||||
|
||||
.flow-step-icon {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.flow-step-icon.ideas {
|
||||
background: rgba(107,143,113,0.2);
|
||||
color: #6B8F71;
|
||||
}
|
||||
|
||||
.flow-step-icon.ai {
|
||||
background: rgba(212,187,156,0.25);
|
||||
color: #C4A87A;
|
||||
}
|
||||
|
||||
.flow-step-icon.voice {
|
||||
background: rgba(92,83,71,0.1);
|
||||
color: #5C5347;
|
||||
}
|
||||
|
||||
.flow-step-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.flow-step-label {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #3D3D3D;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.flow-step-desc {
|
||||
font-size: 11px;
|
||||
font-weight: 300;
|
||||
color: #B5AD9E;
|
||||
}
|
||||
|
||||
.flow-arrow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
color: #C4BDB2;
|
||||
}
|
||||
|
||||
.flow-arrow svg {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* FEATURES ROW */
|
||||
.features-strip {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 56px;
|
||||
padding: 12px 0 20px 0;
|
||||
}
|
||||
|
||||
.feat {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.feat-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 12px;
|
||||
background: rgba(107,143,113,0.15);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #6B8F71;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.feat-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.feat-name {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #3D3D3D;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.feat-sub {
|
||||
font-size: 11px;
|
||||
font-weight: 300;
|
||||
color: #B5AD9E;
|
||||
}
|
||||
|
||||
.divider-dot {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: #D5CFC5;
|
||||
align-self: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<!-- NAV -->
|
||||
<nav class="nav-bar">
|
||||
<div class="logo">Inkwell</div>
|
||||
<div class="nav-right">
|
||||
<a href="#">Philosophy</a>
|
||||
<a href="#">Features</a>
|
||||
<a href="#">Stories</a>
|
||||
<a href="#" class="nav-cta">Start Writing</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- MAIN -->
|
||||
<div class="main-content">
|
||||
<!-- HERO -->
|
||||
<div class="hero-row">
|
||||
<div class="hero-text">
|
||||
<h1 class="headline">Write better, faster,<br>with <span class="accent">your own</span> voice</h1>
|
||||
<p class="subtitle">AI that learns your style, not replaces it. A mindful writing companion for WeChat, Xiaohongshu, and video scripts that honours your creative instincts.</p>
|
||||
<div class="cta-area">
|
||||
<a href="#" class="cta-button">
|
||||
Start Writing
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>
|
||||
</a>
|
||||
<span class="social-proof">Trusted by 10,000+ creators</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- EDITOR CARD -->
|
||||
<div class="editor-container">
|
||||
<div class="editor-card">
|
||||
<div class="editor-body">
|
||||
<div class="editor-toolbar">
|
||||
<button class="e-btn active"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/><path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/></svg></button>
|
||||
<button class="e-btn"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="19" y1="4" x2="10" y2="4"/><line x1="14" y1="20" x2="5" y2="20"/><line x1="15" y1="4" x2="9" y2="20"/></svg></button>
|
||||
<button class="e-btn"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="21" y1="6" x2="3" y2="6"/><line x1="15" y1="12" x2="3" y2="12"/><line x1="17" y1="18" x2="3" y2="18"/></svg></button>
|
||||
<button class="e-btn"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></button>
|
||||
</div>
|
||||
|
||||
<div class="e-title">On the Patience of Growing Things</div>
|
||||
<div class="e-text">
|
||||
There is a kind of writing that happens slowly, like roots in winter soil. <span class="enhanced">You cannot rush a sentence into meaning any more than you can rush a seed into bloom</span>. The best words arrive when you stop chasing them.
|
||||
</div>
|
||||
<div class="e-h2">Listening to the Draft</div>
|
||||
<div class="e-text">
|
||||
Every draft speaks, if you give it room. The first version is never wrong — it is simply unfinished. What AI can offer is not replacement, but reflection: a gentle mirror held up to your own intentions.<span class="typing-cursor"></span>
|
||||
</div>
|
||||
<ul class="e-list">
|
||||
<li>Trust the messy first draft</li>
|
||||
<li>Let AI reveal patterns you missed</li>
|
||||
<li>Preserve what makes it yours</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="ai-panel">
|
||||
<div class="panel-header">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>
|
||||
<span>Inkwell AI</span>
|
||||
</div>
|
||||
|
||||
<div class="panel-card">
|
||||
<div class="panel-card-label">Voice Match</div>
|
||||
<div class="panel-card-value">Your Style</div>
|
||||
<div class="voice-bar">
|
||||
<div class="vb-track"><div class="vb-fill"></div></div>
|
||||
<div class="vb-label">92%</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-card">
|
||||
<div class="panel-card-label">Platform</div>
|
||||
<div class="panel-card-value">WeChat</div>
|
||||
<div class="platform-pills">
|
||||
<span class="pill active">WeChat</span>
|
||||
<span class="pill">XHS</span>
|
||||
<span class="pill">Script</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-note">
|
||||
<span class="note-label">Observation</span>
|
||||
The seed metaphor in paragraph one is lovely. Consider echoing it in the closing line for a sense of return.
|
||||
</div>
|
||||
|
||||
<div class="panel-note">
|
||||
<span class="note-label">Tone</span>
|
||||
Gentle, contemplative. This reads naturally as you.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FLOW DIAGRAM -->
|
||||
<div class="flow-section">
|
||||
<div class="flow-bar">
|
||||
<div class="flow-step">
|
||||
<div class="flow-step-icon ideas">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 1 1 7.072 0l-.548.547A3.374 3.374 0 0 0 12 18.469c-1.006 0-1.938-.429-2.577-1.177l-.56-.56z"/></svg>
|
||||
</div>
|
||||
<div class="flow-step-text">
|
||||
<div class="flow-step-label">Your Ideas</div>
|
||||
<div class="flow-step-desc">Raw thoughts and drafts</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flow-arrow">
|
||||
<svg width="32" height="16" viewBox="0 0 32 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><line x1="2" y1="8" x2="28" y2="8"/><polyline points="24 4 28 8 24 12"/></svg>
|
||||
</div>
|
||||
|
||||
<div class="flow-step">
|
||||
<div class="flow-step-icon ai">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
|
||||
</div>
|
||||
<div class="flow-step-text">
|
||||
<div class="flow-step-label">AI Enhancement</div>
|
||||
<div class="flow-step-desc">Refine, not rewrite</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flow-arrow">
|
||||
<svg width="32" height="16" viewBox="0 0 32 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><line x1="2" y1="8" x2="28" y2="8"/><polyline points="24 4 28 8 24 12"/></svg>
|
||||
</div>
|
||||
|
||||
<div class="flow-step">
|
||||
<div class="flow-step-icon voice">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>
|
||||
</div>
|
||||
<div class="flow-step-text">
|
||||
<div class="flow-step-label">Your Voice</div>
|
||||
<div class="flow-step-desc">Unmistakably you</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FEATURES STRIP -->
|
||||
<div class="features-strip">
|
||||
<div class="feat">
|
||||
<div class="feat-icon">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>
|
||||
</div>
|
||||
<div class="feat-text">
|
||||
<div class="feat-name">Style Learning</div>
|
||||
<div class="feat-sub">Evolves with your writing</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider-dot"></div>
|
||||
|
||||
<div class="feat">
|
||||
<div class="feat-icon">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
|
||||
</div>
|
||||
<div class="feat-text">
|
||||
<div class="feat-name">Multi-Platform</div>
|
||||
<div class="feat-sub">WeChat, XHS, video scripts</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider-dot"></div>
|
||||
|
||||
<div class="feat">
|
||||
<div class="feat-icon">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>
|
||||
</div>
|
||||
<div class="feat-text">
|
||||
<div class="feat-name">Human-Touch Proofreading</div>
|
||||
<div class="feat-sub">Warmth-preserving refinement</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 154 KiB |
@ -1,372 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>Nexus API Documentation</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500;600&family=JetBrains+Mono:wght@300;400;500&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: #FAFAF8;
|
||||
color: #2C2C2C;
|
||||
}
|
||||
|
||||
/* Navigation */
|
||||
nav {
|
||||
height: 64px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 80px;
|
||||
position: relative;
|
||||
}
|
||||
.nav-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.nav-logo-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 2px;
|
||||
background: #E8E4DF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.nav-logo-icon i { color: #D4A574; }
|
||||
.nav-logo span {
|
||||
font-size: 17px;
|
||||
font-weight: 500;
|
||||
letter-spacing: -0.3px;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
.nav-center {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
}
|
||||
.nav-center a {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
text-decoration: none;
|
||||
letter-spacing: 0.3px;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-center a:hover { color: #2C2C2C; }
|
||||
.nav-center a.active { color: #2C2C2C; font-weight: 500; }
|
||||
.nav-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
}
|
||||
.nav-right a {
|
||||
font-size: 13px;
|
||||
color: #BBB;
|
||||
text-decoration: none;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-right a:hover { color: #2C2C2C; }
|
||||
.status-pill {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 5px 12px;
|
||||
border-radius: 2px;
|
||||
background: rgba(212, 165, 116, 0.08);
|
||||
font-size: 11px;
|
||||
color: #B0ACA4;
|
||||
font-weight: 400;
|
||||
}
|
||||
.status-pill .dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background: #D4A574;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* Hero section */
|
||||
.hero {
|
||||
text-align: center;
|
||||
padding: 64px 80px 48px;
|
||||
}
|
||||
.hero-eyebrow {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 4px;
|
||||
text-transform: uppercase;
|
||||
color: #B0ACA4;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.hero h1 {
|
||||
font-size: 56px;
|
||||
font-weight: 200;
|
||||
letter-spacing: -2.5px;
|
||||
line-height: 1.1;
|
||||
color: #1A1A1A;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.hero h1 em {
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
}
|
||||
.hero p {
|
||||
font-size: 17px;
|
||||
font-weight: 300;
|
||||
color: #999;
|
||||
line-height: 1.6;
|
||||
max-width: 520px;
|
||||
margin: 0 auto 36px;
|
||||
letter-spacing: 0.1px;
|
||||
}
|
||||
.hero-actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.hero-actions a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 28px;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
text-decoration: none;
|
||||
border-radius: 2px;
|
||||
transition: all 0.2s;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
.btn-primary {
|
||||
background: #1A1A1A;
|
||||
color: #FAFAF8;
|
||||
}
|
||||
.btn-primary:hover { background: #333; }
|
||||
.btn-secondary {
|
||||
background: transparent;
|
||||
color: #999;
|
||||
border: 1px solid #E0DDD8;
|
||||
}
|
||||
.btn-secondary:hover { border-color: #CCC; color: #666; }
|
||||
|
||||
/* Code card */
|
||||
.code-section {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 32px 80px 48px;
|
||||
}
|
||||
.code-card {
|
||||
background: #FFFFFF;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 8px 40px rgba(0,0,0,0.04), 0 1px 3px rgba(0,0,0,0.02);
|
||||
max-width: 600px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.code-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 24px;
|
||||
border-bottom: 1px solid #F2F0EC;
|
||||
}
|
||||
.code-card-header .dots {
|
||||
display: flex;
|
||||
gap: 7px;
|
||||
}
|
||||
.code-card-header .dots span {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background: #E8E5E0;
|
||||
}
|
||||
.code-card-header .filename {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 11px;
|
||||
color: #BBB;
|
||||
font-weight: 400;
|
||||
}
|
||||
.code-card-header .copy-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
color: #CCC;
|
||||
font-size: 11px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
.code-card-body {
|
||||
padding: 24px 28px;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 13px;
|
||||
line-height: 1.8;
|
||||
color: #444;
|
||||
font-weight: 400;
|
||||
}
|
||||
.code-card-body .kw { color: #8B7355; font-weight: 500; }
|
||||
.code-card-body .str { color: #D4A574; }
|
||||
.code-card-body .cmt { color: #CCCCCC; }
|
||||
.code-card-body .fn { color: #777; }
|
||||
.code-card-body .num { color: #B08D57; }
|
||||
|
||||
/* Quick links */
|
||||
.quick-links {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 48px;
|
||||
padding: 16px 80px 48px;
|
||||
}
|
||||
.quick-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
text-decoration: none;
|
||||
color: #BBB;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
transition: color 0.2s;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
.quick-link:hover { color: #666; }
|
||||
.quick-link i { color: #D4A574; opacity: 0.6; }
|
||||
|
||||
/* Features */
|
||||
.features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 24px;
|
||||
padding: 0 80px;
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.feature-card {
|
||||
background: #FFFFFF;
|
||||
border-radius: 2px;
|
||||
padding: 32px 28px;
|
||||
box-shadow: 0 2px 16px rgba(0,0,0,0.02);
|
||||
transition: box-shadow 0.2s;
|
||||
}
|
||||
.feature-card:hover {
|
||||
box-shadow: 0 2px 16px rgba(0,0,0,0.04);
|
||||
}
|
||||
.feature-icon-wrap {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 2px;
|
||||
background: #F0EBE3;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.feature-icon-wrap i { color: #D4A574; }
|
||||
.feature-card h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
letter-spacing: -0.3px;
|
||||
margin-bottom: 8px;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
.feature-card p {
|
||||
font-size: 13px;
|
||||
font-weight: 300;
|
||||
line-height: 1.65;
|
||||
color: #AAA;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav>
|
||||
<div class="nav-logo">
|
||||
<div class="nav-logo-icon"><i data-lucide="zap" style="width:16px;height:16px;"></i></div>
|
||||
<span>Nexus</span>
|
||||
</div>
|
||||
<div class="nav-center">
|
||||
<a href="#" class="active">Docs</a>
|
||||
<a href="#">API</a>
|
||||
<a href="#">Changelog</a>
|
||||
<a href="#">Status</a>
|
||||
<a href="#">GitHub</a>
|
||||
</div>
|
||||
<div class="nav-right">
|
||||
<div class="status-pill"><span class="dot"></span> Operational</div>
|
||||
<a href="#"><i data-lucide="search" style="width:15px;height:15px;color:#CCC;"></i></a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Hero -->
|
||||
<section class="hero">
|
||||
<div class="hero-eyebrow">Unified AI Gateway</div>
|
||||
<h1>One API, <em>every</em> AI model<span style="color:#D4A574;font-weight:300;">.</span></h1>
|
||||
<p>Access GPT, Claude, Gemini, and 20+ models through a single endpoint. Intelligent routing, unified billing, zero vendor lock-in.</p>
|
||||
<div class="hero-actions">
|
||||
<a href="#" class="btn-primary"><i data-lucide="arrow-right" style="width:14px;height:14px;"></i> Get started</a>
|
||||
<a href="#" class="btn-secondary">View API reference</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Code Card -->
|
||||
<section class="code-section">
|
||||
<div class="code-card">
|
||||
<div class="code-card-header">
|
||||
<div class="dots"><span></span><span></span><span></span></div>
|
||||
<span class="filename">quickstart.py</span>
|
||||
<button class="copy-btn"><i data-lucide="copy" style="width:12px;height:12px;"></i> Copy</button>
|
||||
</div>
|
||||
<div class="code-card-body">
|
||||
<span class="kw">from</span> nexus <span class="kw">import</span> Client<br><br>
|
||||
client = Client(api_key=<span class="str">"your-key"</span>)<br>
|
||||
response = client.chat(<br>
|
||||
model=<span class="str">"auto"</span>, <span class="cmt"># intelligently routes</span><br>
|
||||
messages=[{<span class="str">"role"</span>: <span class="str">"user"</span>, <span class="str">"content"</span>: <span class="str">"Hello!"</span>}]<br>
|
||||
)
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Quick Links -->
|
||||
<div class="quick-links">
|
||||
<a href="#" class="quick-link"><i data-lucide="rocket" style="width:14px;height:14px;"></i> Getting Started</a>
|
||||
<a href="#" class="quick-link"><i data-lucide="file-text" style="width:14px;height:14px;"></i> API Reference</a>
|
||||
<a href="#" class="quick-link"><i data-lucide="layers" style="width:14px;height:14px;"></i> Models</a>
|
||||
<a href="#" class="quick-link"><i data-lucide="credit-card" style="width:14px;height:14px;"></i> Pricing</a>
|
||||
</div>
|
||||
|
||||
<!-- Features -->
|
||||
<section class="features">
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon-wrap"><i data-lucide="git-branch" style="width:18px;height:18px;"></i></div>
|
||||
<h3>Model Routing</h3>
|
||||
<p>Automatically select the best model for each request based on task complexity, latency requirements, and cost constraints.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon-wrap"><i data-lucide="trending-down" style="width:18px;height:18px;"></i></div>
|
||||
<h3>Cost Optimization</h3>
|
||||
<p>Reduce AI spend by up to 60% with intelligent model selection and automatic fallback to cost-effective alternatives.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon-wrap"><i data-lucide="bar-chart-3" style="width:18px;height:18px;"></i></div>
|
||||
<h3>Usage Analytics</h3>
|
||||
<p>Real-time dashboards tracking token usage, response latency, model performance, and cost breakdowns per project.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>lucide.createIcons();</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 67 KiB |
@ -1,460 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>Nexus API Documentation</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&family=Space+Grotesk:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
background: #FFFFFF;
|
||||
color: #111111;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
.sidebar {
|
||||
width: 260px;
|
||||
min-width: 260px;
|
||||
height: 900px;
|
||||
border-right: 1px solid #111;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.sidebar-logo {
|
||||
padding: 24px 28px;
|
||||
border-bottom: 1px solid #111;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.sidebar-logo .logo-mark {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background: #E63946;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.sidebar-logo .logo-mark svg { color: #fff; }
|
||||
.sidebar-logo span {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 18px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
.sidebar-section {
|
||||
padding: 20px 28px 8px;
|
||||
}
|
||||
.sidebar-section-label {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #999;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.sidebar-link {
|
||||
display: block;
|
||||
padding: 6px 0;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.sidebar-link:hover { color: #111; }
|
||||
.sidebar-link.active {
|
||||
color: #E63946;
|
||||
font-weight: 600;
|
||||
}
|
||||
.sidebar-link.active::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background: #E63946;
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.sidebar-divider {
|
||||
height: 1px;
|
||||
background: #E8E8E8;
|
||||
margin: 12px 28px;
|
||||
}
|
||||
|
||||
/* Main content */
|
||||
.main {
|
||||
flex: 1;
|
||||
height: 900px;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Top nav */
|
||||
.topnav {
|
||||
height: 52px;
|
||||
min-height: 52px;
|
||||
border-bottom: 1px solid #111;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 40px;
|
||||
}
|
||||
.topnav-links {
|
||||
display: flex;
|
||||
gap: 28px;
|
||||
}
|
||||
.topnav-links a {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
color: #555;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.topnav-links a:hover { color: #111; }
|
||||
.topnav-links a.active-nav { color: #E63946; }
|
||||
.topnav-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
.topnav-right .status-dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
background: #E63946;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
.topnav-right span {
|
||||
font-size: 11px;
|
||||
color: #888;
|
||||
font-weight: 500;
|
||||
}
|
||||
.topnav-right a {
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Hero */
|
||||
.hero {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
min-height: 400px;
|
||||
border-bottom: 1px solid #E8E8E8;
|
||||
}
|
||||
.hero-left {
|
||||
padding: 56px 48px 48px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.hero-badge {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 2.5px;
|
||||
text-transform: uppercase;
|
||||
color: #E63946;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.hero-left h1 {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 52px;
|
||||
font-weight: 900;
|
||||
line-height: 1.05;
|
||||
letter-spacing: -2px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.hero-left p {
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
color: #666;
|
||||
max-width: 420px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.hero-links {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
.hero-links a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 10px 20px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.hero-links a.primary {
|
||||
background: #111;
|
||||
color: #fff;
|
||||
}
|
||||
.hero-links a.primary:hover { background: #E63946; }
|
||||
.hero-links a.secondary {
|
||||
border: 1px solid #DDD;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.hero-links a.secondary:hover { border-color: #111; }
|
||||
|
||||
/* Code block */
|
||||
.hero-right {
|
||||
padding: 40px 48px 40px 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #FAFAFA;
|
||||
border-left: 1px solid #E8E8E8;
|
||||
}
|
||||
.code-block {
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #DDD;
|
||||
width: 100%;
|
||||
max-width: 480px;
|
||||
}
|
||||
.code-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px 16px;
|
||||
border-bottom: 1px solid #DDD;
|
||||
background: #FAFAFA;
|
||||
}
|
||||
.code-header span {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
font-weight: 500;
|
||||
}
|
||||
.code-dots {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
.code-dots i { width: 10px; height: 10px; }
|
||||
.code-body {
|
||||
padding: 20px;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
color: #111;
|
||||
}
|
||||
.code-body .kw { color: #111; font-weight: 500; }
|
||||
.code-body .str { color: #E63946; }
|
||||
.code-body .cmt { color: #AAAAAA; }
|
||||
.code-body .fn { color: #555; }
|
||||
|
||||
/* Quick links bar */
|
||||
.quick-bar {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
border-bottom: 1px solid #E8E8E8;
|
||||
}
|
||||
.quick-bar a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 18px 28px;
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
border-right: 1px solid #E8E8E8;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
.quick-bar a:last-child { border-right: none; }
|
||||
.quick-bar a:hover { background: #FAFAFA; }
|
||||
.quick-bar a i { color: #E63946; }
|
||||
|
||||
/* Features */
|
||||
.features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
flex: 1;
|
||||
}
|
||||
.feature-card {
|
||||
padding: 36px 32px;
|
||||
border-right: 1px solid #E8E8E8;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.feature-card:last-child { border-right: none; }
|
||||
.feature-card .feature-label {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: #E63946;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.feature-card h3 {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.feature-card p {
|
||||
font-size: 13px;
|
||||
line-height: 1.65;
|
||||
color: #777;
|
||||
}
|
||||
.feature-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background: #111;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.feature-icon i { color: #fff; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-logo">
|
||||
<div class="logo-mark"><i data-lucide="zap" style="width:16px;height:16px;"></i></div>
|
||||
<span>Nexus API</span>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-section">
|
||||
<div class="sidebar-section-label">Getting Started</div>
|
||||
<a href="#" class="sidebar-link active">Introduction</a>
|
||||
<a href="#" class="sidebar-link">Quick Start</a>
|
||||
<a href="#" class="sidebar-link">Authentication</a>
|
||||
<a href="#" class="sidebar-link">Installation</a>
|
||||
</div>
|
||||
<div class="sidebar-divider"></div>
|
||||
<div class="sidebar-section">
|
||||
<div class="sidebar-section-label">Core Concepts</div>
|
||||
<a href="#" class="sidebar-link">Model Routing</a>
|
||||
<a href="#" class="sidebar-link">Chat Completions</a>
|
||||
<a href="#" class="sidebar-link">Streaming</a>
|
||||
<a href="#" class="sidebar-link">Error Handling</a>
|
||||
</div>
|
||||
<div class="sidebar-divider"></div>
|
||||
<div class="sidebar-section">
|
||||
<div class="sidebar-section-label">API Reference</div>
|
||||
<a href="#" class="sidebar-link">POST /chat</a>
|
||||
<a href="#" class="sidebar-link">GET /models</a>
|
||||
<a href="#" class="sidebar-link">GET /usage</a>
|
||||
<a href="#" class="sidebar-link">Webhooks</a>
|
||||
</div>
|
||||
<div class="sidebar-divider"></div>
|
||||
<div class="sidebar-section">
|
||||
<div class="sidebar-section-label">Resources</div>
|
||||
<a href="#" class="sidebar-link">Models</a>
|
||||
<a href="#" class="sidebar-link">Pricing</a>
|
||||
<a href="#" class="sidebar-link">SDKs</a>
|
||||
<a href="#" class="sidebar-link">Changelog</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main -->
|
||||
<main class="main">
|
||||
<!-- Top Nav -->
|
||||
<nav class="topnav">
|
||||
<div class="topnav-links">
|
||||
<a href="#" class="active-nav">Docs</a>
|
||||
<a href="#">API</a>
|
||||
<a href="#">Changelog</a>
|
||||
<a href="#">Status</a>
|
||||
<a href="#">GitHub</a>
|
||||
</div>
|
||||
<div class="topnav-right">
|
||||
<span class="status-dot"></span>
|
||||
<span>All systems operational</span>
|
||||
<a href="#"><i data-lucide="search" style="width:16px;height:16px;color:#888;"></i></a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Hero -->
|
||||
<section class="hero">
|
||||
<div class="hero-left">
|
||||
<div class="hero-badge">Unified AI Gateway</div>
|
||||
<h1>One API,<br>every AI model</h1>
|
||||
<p>Access GPT, Claude, Gemini, and 20+ models through a single endpoint. Intelligent routing, unified billing, zero vendor lock-in.</p>
|
||||
<div class="hero-links">
|
||||
<a href="#" class="primary"><i data-lucide="arrow-right" style="width:14px;height:14px;"></i> Get Started</a>
|
||||
<a href="#" class="secondary">API Reference</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-right">
|
||||
<div class="code-block">
|
||||
<div class="code-header">
|
||||
<div class="code-dots">
|
||||
<i data-lucide="circle" style="width:10px;height:10px;color:#DDD;fill:#DDD;"></i>
|
||||
<i data-lucide="circle" style="width:10px;height:10px;color:#DDD;fill:#DDD;"></i>
|
||||
<i data-lucide="circle" style="width:10px;height:10px;color:#DDD;fill:#DDD;"></i>
|
||||
</div>
|
||||
<span>quickstart.py</span>
|
||||
</div>
|
||||
<div class="code-body">
|
||||
<span class="kw">from</span> nexus <span class="kw">import</span> Client<br><br>
|
||||
client = Client(api_key=<span class="str">"your-key"</span>)<br>
|
||||
response = client.chat(<br>
|
||||
model=<span class="str">"auto"</span>, <span class="cmt"># intelligently routes</span><br>
|
||||
messages=[{<br>
|
||||
<span class="str">"role"</span>: <span class="str">"user"</span>,<br>
|
||||
<span class="str">"content"</span>: <span class="str">"Hello!"</span><br>
|
||||
}]<br>
|
||||
)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Quick Links -->
|
||||
<div class="quick-bar">
|
||||
<a href="#"><i data-lucide="rocket" style="width:16px;height:16px;"></i> Getting Started</a>
|
||||
<a href="#"><i data-lucide="file-text" style="width:16px;height:16px;"></i> API Reference</a>
|
||||
<a href="#"><i data-lucide="layers" style="width:16px;height:16px;"></i> Models</a>
|
||||
<a href="#"><i data-lucide="credit-card" style="width:16px;height:16px;"></i> Pricing</a>
|
||||
</div>
|
||||
|
||||
<!-- Features -->
|
||||
<section class="features">
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon"><i data-lucide="git-branch" style="width:18px;height:18px;"></i></div>
|
||||
<div class="feature-label">Feature 01</div>
|
||||
<h3>Model Routing</h3>
|
||||
<p>Automatically select the best model for each request based on task complexity, latency requirements, and cost constraints.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon"><i data-lucide="trending-down" style="width:18px;height:18px;"></i></div>
|
||||
<div class="feature-label">Feature 02</div>
|
||||
<h3>Cost Optimization</h3>
|
||||
<p>Reduce AI spend by up to 60% with intelligent model selection and automatic fallback to cost-effective alternatives.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon"><i data-lucide="bar-chart-3" style="width:18px;height:18px;"></i></div>
|
||||
<div class="feature-label">Feature 03</div>
|
||||
<h3>Usage Analytics</h3>
|
||||
<p>Real-time dashboards tracking token usage, response latency, model performance, and cost breakdowns per project.</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script>lucide.createIcons();</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 114 KiB |
@ -1,494 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>Nexus API Documentation</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=JetBrains+Mono:wght@300;400;500&family=Noto+Serif+SC:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: #F5F0EB;
|
||||
color: #3A3A35;
|
||||
}
|
||||
|
||||
/* Navigation */
|
||||
nav {
|
||||
height: 72px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 64px;
|
||||
}
|
||||
.nav-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.nav-logo-mark {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 12px;
|
||||
background: #6B8F71;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.nav-logo-mark i { color: #F5F0EB; }
|
||||
.nav-logo-text {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #2D3436;
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
}
|
||||
.nav-links a {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
text-decoration: none;
|
||||
transition: color 0.2s;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
.nav-links a:hover { color: #3A3A35; }
|
||||
.nav-links a.active { color: #3A3A35; font-weight: 500; }
|
||||
.nav-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
}
|
||||
.search-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 16px;
|
||||
background: rgba(255,255,255,0.5);
|
||||
border-radius: 12px;
|
||||
border: 1px solid #E5DFCE;
|
||||
}
|
||||
.search-box span {
|
||||
font-size: 12px;
|
||||
color: #BBB;
|
||||
}
|
||||
.search-box kbd {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 10px;
|
||||
background: #EDE8DC;
|
||||
border-radius: 4px;
|
||||
padding: 2px 6px;
|
||||
color: #AAA;
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
/* Hero Section */
|
||||
.hero {
|
||||
display: flex;
|
||||
padding: 40px 64px 36px;
|
||||
gap: 56px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.hero-content {
|
||||
flex: 1;
|
||||
padding-top: 16px;
|
||||
}
|
||||
.hero-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 14px;
|
||||
background: rgba(107,143,113,0.15);
|
||||
border-radius: 100px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: #6B8F71;
|
||||
margin-bottom: 24px;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.hero h1 {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 44px;
|
||||
font-weight: 600;
|
||||
line-height: 1.15;
|
||||
letter-spacing: -1.5px;
|
||||
color: #2D3436;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.hero p {
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
line-height: 1.7;
|
||||
color: #888;
|
||||
max-width: 440px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.hero-buttons {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
.hero-buttons a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 24px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
border-radius: 12px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn-green {
|
||||
background: rgba(107, 143, 113, 0.12);
|
||||
color: #6B8F71;
|
||||
border: 1px solid rgba(107, 143, 113, 0.3);
|
||||
}
|
||||
.btn-green:hover { background: rgba(107, 143, 113, 0.18); }
|
||||
.btn-outline {
|
||||
background: rgba(255,255,255,0.5);
|
||||
color: #666;
|
||||
border: 1px solid #DDD8CB;
|
||||
}
|
||||
.btn-outline:hover { background: rgba(255,255,255,0.8); }
|
||||
|
||||
/* Code + Diagram Area */
|
||||
.hero-visual {
|
||||
width: 560px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
/* Flow diagram */
|
||||
.flow-diagram {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0;
|
||||
padding: 20px 24px;
|
||||
background: rgba(255,255,255,0.45);
|
||||
border-radius: 16px;
|
||||
border: 1px solid #E5DFCE;
|
||||
}
|
||||
.flow-node {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.flow-node-box {
|
||||
padding: 10px 20px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #E0DACE;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #3A3A35;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.03);
|
||||
}
|
||||
.flow-node-box.highlight {
|
||||
background: #6B8F71;
|
||||
border-color: #6B8F71;
|
||||
color: #fff;
|
||||
}
|
||||
.flow-node-label {
|
||||
font-size: 10px;
|
||||
color: #BBB;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.flow-arrow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 12px;
|
||||
}
|
||||
.flow-arrow-line {
|
||||
width: 40px;
|
||||
height: 1px;
|
||||
background: #CCC8BA;
|
||||
position: relative;
|
||||
}
|
||||
.flow-arrow-line::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: -1px;
|
||||
top: -3px;
|
||||
border: solid #CCC8BA;
|
||||
border-width: 0 1px 1px 0;
|
||||
padding: 3px;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
.flow-models {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
.flow-model-tag {
|
||||
padding: 6px 14px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #E0DACE;
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: #888;
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.02);
|
||||
}
|
||||
|
||||
/* Code block */
|
||||
.code-card {
|
||||
background: #FAF5EC;
|
||||
border-radius: 16px;
|
||||
border: 1px solid #E5DFCE;
|
||||
overflow: hidden;
|
||||
}
|
||||
.code-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 20px;
|
||||
border-bottom: 1px solid #E5DFCE;
|
||||
background: rgba(255,255,255,0.3);
|
||||
}
|
||||
.code-card-header .dots {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
.code-card-header .dots span {
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border-radius: 50%;
|
||||
background: #DDD8CB;
|
||||
}
|
||||
.code-card-header .fname {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 11px;
|
||||
color: #BBB;
|
||||
}
|
||||
.code-card-body {
|
||||
padding: 20px 24px;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12.5px;
|
||||
line-height: 1.8;
|
||||
color: #555;
|
||||
}
|
||||
.code-card-body .kw { color: #6B8F71; font-weight: 500; }
|
||||
.code-card-body .str { color: #D4A574; }
|
||||
.code-card-body .cmt { color: #C4C0B4; }
|
||||
|
||||
/* Quick Links */
|
||||
.quick-links {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
padding: 8px 64px 32px;
|
||||
}
|
||||
.quick-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
text-decoration: none;
|
||||
padding: 12px 22px;
|
||||
background: rgba(255,255,255,0.45);
|
||||
border: 1px solid #E5DFCE;
|
||||
border-radius: 12px;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #777;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.quick-link:hover {
|
||||
background: rgba(255,255,255,0.7);
|
||||
color: #3A3A35;
|
||||
}
|
||||
.quick-link i { color: #6B8F71; }
|
||||
|
||||
/* Features */
|
||||
.features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 20px;
|
||||
padding: 0 64px;
|
||||
position: relative;
|
||||
}
|
||||
.feature-card {
|
||||
background: rgba(255,255,255,0.5);
|
||||
border: 1px solid #E5DFCE;
|
||||
border-radius: 16px;
|
||||
padding: 28px 24px;
|
||||
transition: all 0.2s;
|
||||
position: relative;
|
||||
}
|
||||
.feature-card:hover {
|
||||
background: rgba(255,255,255,0.75);
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.03);
|
||||
}
|
||||
.feature-icon-wrap {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 12px;
|
||||
background: rgba(107,143,113,0.15);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.feature-icon-wrap i { color: #6B8F71; }
|
||||
.feature-card h3 {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 8px;
|
||||
color: #2D3436;
|
||||
}
|
||||
.feature-card p {
|
||||
font-size: 13px;
|
||||
font-weight: 300;
|
||||
line-height: 1.65;
|
||||
color: #AAA;
|
||||
}
|
||||
|
||||
/* Connection lines between feature cards */
|
||||
.features::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: calc(33.33% + 32px);
|
||||
width: calc(33.33% - 64px - 20px);
|
||||
height: 0;
|
||||
border-top: 1px dashed #D4CEBD;
|
||||
transform: translateX(10px);
|
||||
}
|
||||
.features::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: calc(33.33% + 32px);
|
||||
width: calc(33.33% - 64px - 20px);
|
||||
height: 0;
|
||||
border-top: 1px dashed #D4CEBD;
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav>
|
||||
<div class="nav-logo">
|
||||
<div class="nav-logo-mark"><i data-lucide="zap" style="width:18px;height:18px;"></i></div>
|
||||
<span class="nav-logo-text">Nexus API</span>
|
||||
</div>
|
||||
<div class="nav-links">
|
||||
<a href="#" class="active">Docs</a>
|
||||
<a href="#">API</a>
|
||||
<a href="#">Changelog</a>
|
||||
<a href="#">Status</a>
|
||||
<a href="#">GitHub</a>
|
||||
</div>
|
||||
<div class="nav-right">
|
||||
<div class="search-box">
|
||||
<i data-lucide="search" style="width:13px;height:13px;color:#CCC;"></i>
|
||||
<span>Search documentation...</span>
|
||||
<kbd>/</kbd>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Hero -->
|
||||
<section class="hero">
|
||||
<div class="hero-content">
|
||||
<div class="hero-tag"><i data-lucide="sparkles" style="width:12px;height:12px;"></i> Unified AI Gateway</div>
|
||||
<h1>One API,<br>every AI model</h1>
|
||||
<p>Access GPT, Claude, Gemini, and 20+ models through a single endpoint. Intelligent routing, unified billing, zero vendor lock-in.</p>
|
||||
<div class="hero-buttons">
|
||||
<a href="#" class="btn-green"><i data-lucide="book-open" style="width:14px;height:14px;"></i> Get Started</a>
|
||||
<a href="#" class="btn-outline">API Reference</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero-visual">
|
||||
<!-- Flow diagram -->
|
||||
<div class="flow-diagram">
|
||||
<div class="flow-node">
|
||||
<div class="flow-node-box">Your App</div>
|
||||
<span class="flow-node-label">request</span>
|
||||
</div>
|
||||
<div class="flow-arrow"><div class="flow-arrow-line"></div></div>
|
||||
<div class="flow-node">
|
||||
<div class="flow-node-box highlight">Nexus</div>
|
||||
<span class="flow-node-label">routes</span>
|
||||
</div>
|
||||
<div class="flow-arrow"><div class="flow-arrow-line"></div></div>
|
||||
<div class="flow-models">
|
||||
<div class="flow-model-tag">GPT-4o</div>
|
||||
<div class="flow-model-tag">Claude 3.5</div>
|
||||
<div class="flow-model-tag">Gemini Pro</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Code block -->
|
||||
<div class="code-card">
|
||||
<div class="code-card-header">
|
||||
<div class="dots"><span></span><span></span><span></span></div>
|
||||
<span class="fname">quickstart.py</span>
|
||||
<i data-lucide="copy" style="width:13px;height:13px;color:#CCC;cursor:pointer;"></i>
|
||||
</div>
|
||||
<div class="code-card-body">
|
||||
<span class="kw">from</span> nexus <span class="kw">import</span> Client<br><br>
|
||||
client = Client(api_key=<span class="str">"your-key"</span>)<br>
|
||||
response = client.chat(<br>
|
||||
model=<span class="str">"auto"</span>, <span class="cmt"># intelligently routes</span><br>
|
||||
messages=[{<span class="str">"role"</span>: <span class="str">"user"</span>, <span class="str">"content"</span>: <span class="str">"Hello!"</span>}]<br>
|
||||
)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Quick Links -->
|
||||
<div class="quick-links">
|
||||
<a href="#" class="quick-link"><i data-lucide="rocket" style="width:14px;height:14px;"></i> Getting Started</a>
|
||||
<a href="#" class="quick-link"><i data-lucide="file-text" style="width:14px;height:14px;"></i> API Reference</a>
|
||||
<a href="#" class="quick-link"><i data-lucide="layers" style="width:14px;height:14px;"></i> Models</a>
|
||||
<a href="#" class="quick-link"><i data-lucide="credit-card" style="width:14px;height:14px;"></i> Pricing</a>
|
||||
</div>
|
||||
|
||||
<!-- Features -->
|
||||
<section class="features">
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon-wrap"><i data-lucide="git-branch" style="width:18px;height:18px;"></i></div>
|
||||
<h3>Model Routing</h3>
|
||||
<p>Automatically select the best model for each request based on task complexity, latency, and cost constraints.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon-wrap"><i data-lucide="trending-down" style="width:18px;height:18px;"></i></div>
|
||||
<h3>Cost Optimization</h3>
|
||||
<p>Reduce AI spend by up to 60% with intelligent selection and automatic fallback to cost-effective alternatives.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon-wrap"><i data-lucide="bar-chart-3" style="width:18px;height:18px;"></i></div>
|
||||
<h3>Usage Analytics</h3>
|
||||
<p>Real-time dashboards tracking token usage, latency, model performance, and cost breakdowns per project.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Spec annotation -->
|
||||
<svg style="position:absolute;bottom:24px;right:64px;opacity:0.12;" width="120" height="40" viewBox="0 0 120 40" fill="none">
|
||||
<line x1="0" y1="20" x2="72" y2="20" stroke="#6B8F71" stroke-width="0.5"/>
|
||||
<circle cx="72" cy="20" r="2.5" fill="none" stroke="#6B8F71" stroke-width="0.5"/>
|
||||
<text x="82" y="23" font-family="Inter" font-size="8" fill="#6B8F71" letter-spacing="0.5">20+ models</text>
|
||||
</svg>
|
||||
|
||||
<script>lucide.createIcons();</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 109 KiB |
@ -1,367 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>Alex Chen — Indie Developer & AI Creator</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500;600&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #FAFAF8;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #2A2A28;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* GLASSMORPHISM NAV */
|
||||
nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 1440px;
|
||||
height: 64px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 80px;
|
||||
background: rgba(250, 250, 248, 0.72);
|
||||
backdrop-filter: blur(24px);
|
||||
-webkit-backdrop-filter: blur(24px);
|
||||
border-bottom: 1px solid rgba(0,0,0,0.04);
|
||||
z-index: 100;
|
||||
}
|
||||
nav .logo {
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
letter-spacing: 0.02em;
|
||||
color: #2A2A28;
|
||||
}
|
||||
nav .logo .dot { color: #D4A574; }
|
||||
nav ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
}
|
||||
nav ul li a {
|
||||
font-weight: 400;
|
||||
font-size: 13px;
|
||||
color: #888;
|
||||
text-decoration: none;
|
||||
letter-spacing: 0.01em;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
nav ul li a:hover { color: #2A2A28; }
|
||||
nav .nav-cta a {
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: #2A2A28;
|
||||
text-decoration: none;
|
||||
padding: 8px 24px;
|
||||
border: 1px solid rgba(0,0,0,0.08);
|
||||
border-radius: 2px;
|
||||
transition: all 0.3s;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
nav .nav-cta a:hover {
|
||||
border-color: #D4A574;
|
||||
color: #D4A574;
|
||||
}
|
||||
|
||||
/* HERO LAYOUT */
|
||||
.hero {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 80px;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 96px;
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
}
|
||||
|
||||
/* LEFT: TEXT */
|
||||
.hero-text {
|
||||
flex: 1;
|
||||
}
|
||||
.hero-text .greeting {
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
color: #B0ACA4;
|
||||
letter-spacing: 4px;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.hero-text h1 {
|
||||
font-weight: 200;
|
||||
font-size: 80px;
|
||||
line-height: 1.02;
|
||||
letter-spacing: -0.04em;
|
||||
color: #2A2A28;
|
||||
}
|
||||
.hero-text h1 strong {
|
||||
font-weight: 500;
|
||||
}
|
||||
.hero-text h1 .gold-period {
|
||||
color: #D4A574;
|
||||
font-weight: 300;
|
||||
}
|
||||
.hero-text .tagline {
|
||||
font-weight: 300;
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #999;
|
||||
margin-top: 32px;
|
||||
max-width: 440px;
|
||||
}
|
||||
|
||||
/* CTA BUTTONS */
|
||||
.hero-cta {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-top: 48px;
|
||||
}
|
||||
.btn-primary {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 13px;
|
||||
color: #FAFAF8;
|
||||
background: #2A2A28;
|
||||
border: none;
|
||||
padding: 14px 32px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
text-decoration: none;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
.btn-primary:hover { background: #3A3A38; }
|
||||
.btn-secondary {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 13px;
|
||||
color: #888;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(0,0,0,0.08);
|
||||
padding: 14px 32px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
text-decoration: none;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
.btn-secondary:hover { border-color: #D4A574; color: #D4A574; }
|
||||
|
||||
/* RIGHT: CARDS + PORTRAIT */
|
||||
.hero-visual {
|
||||
flex: 0 0 460px;
|
||||
position: relative;
|
||||
height: 520px;
|
||||
}
|
||||
|
||||
/* PORTRAIT */
|
||||
.portrait {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 50%;
|
||||
background: #EDECE8;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 40px;
|
||||
box-shadow: 0 20px 60px rgba(0,0,0,0.06);
|
||||
overflow: hidden;
|
||||
}
|
||||
.portrait::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0; left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 110px;
|
||||
height: 130px;
|
||||
background: #D8D6D0;
|
||||
border-radius: 55px 55px 0 0;
|
||||
}
|
||||
|
||||
/* FLOATING CARDS */
|
||||
.card {
|
||||
position: absolute;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid rgba(0,0,0,0.04);
|
||||
border-radius: 2px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 4px 24px rgba(0,0,0,0.03);
|
||||
}
|
||||
|
||||
.card-1 {
|
||||
top: 60px;
|
||||
left: 0;
|
||||
width: 220px;
|
||||
}
|
||||
.card-2 {
|
||||
top: 240px;
|
||||
left: 60px;
|
||||
width: 240px;
|
||||
}
|
||||
.card-3 {
|
||||
top: 180px;
|
||||
right: 0;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.card .card-number {
|
||||
font-weight: 200;
|
||||
font-size: 32px;
|
||||
letter-spacing: -0.02em;
|
||||
color: #2A2A28;
|
||||
line-height: 1;
|
||||
}
|
||||
.card .card-number .gold { color: #D4A574; font-weight: 300; }
|
||||
.card .card-label {
|
||||
font-weight: 400;
|
||||
font-size: 10px;
|
||||
color: #B0ACA4;
|
||||
margin-top: 8px;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.card .card-desc {
|
||||
font-weight: 300;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
margin-top: 8px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* GOLD ACCENT LINE */
|
||||
.accent-line {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 100px;
|
||||
width: 48px;
|
||||
height: 2px;
|
||||
background: #D4A574;
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
/* Removed dot-grid — Build: zero decorative elements */
|
||||
|
||||
/* BOTTOM TICKER */
|
||||
.bottom-bar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 1440px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 48px;
|
||||
border-top: 1px solid rgba(0,0,0,0.04);
|
||||
}
|
||||
.bottom-bar span {
|
||||
font-weight: 300;
|
||||
font-size: 11px;
|
||||
color: #BBB;
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
.bottom-bar .sep {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: #D4A574;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- NAV -->
|
||||
<nav>
|
||||
<div class="logo">alex chen<span class="dot"> .</span></div>
|
||||
<ul>
|
||||
<li><a href="#work">Work</a></li>
|
||||
<li><a href="#content">Content</a></li>
|
||||
<li><a href="#services">Services</a></li>
|
||||
</ul>
|
||||
<div class="nav-cta">
|
||||
<a href="#contact">Get in Touch</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- HERO -->
|
||||
<div class="hero">
|
||||
<div class="hero-content">
|
||||
<!-- TEXT -->
|
||||
<div class="hero-text">
|
||||
<div class="greeting">Indie Developer & AI Creator</div>
|
||||
<h1>Alex<br><strong>Chen</strong><span class="gold-period">.</span></h1>
|
||||
<p class="tagline">Building tools at the intersection of AI and creativity. Shipping products, writing stories, shaping ideas.</p>
|
||||
<div class="hero-cta">
|
||||
<a href="#work" class="btn-primary">
|
||||
View Work
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
|
||||
</a>
|
||||
<a href="#content" class="btn-secondary">Read Articles</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- VISUAL -->
|
||||
<div class="hero-visual">
|
||||
<div class="portrait"></div>
|
||||
|
||||
<div class="card card-1">
|
||||
<div class="card-number">300K<span class="gold">+</span></div>
|
||||
<div class="card-label">Followers</div>
|
||||
<div class="card-desc">Across platforms, building in public</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-2">
|
||||
<div class="card-number"><span class="gold">#</span>1</div>
|
||||
<div class="card-label">App Store</div>
|
||||
<div class="card-desc">Top paid app, shipped as a solo developer</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-3">
|
||||
<div class="card-number">100<span class="gold">+</span></div>
|
||||
<div class="card-label">Articles</div>
|
||||
<div class="card-desc">On AI, dev, and creative tools</div>
|
||||
</div>
|
||||
|
||||
<div class="accent-line"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- BOTTOM BAR -->
|
||||
<div class="bottom-bar">
|
||||
<span>Developer</span>
|
||||
<div class="sep"></div>
|
||||
<span>Writer</span>
|
||||
<div class="sep"></div>
|
||||
<span>AI Creator</span>
|
||||
<div class="sep"></div>
|
||||
<span>Speaker</span>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 60 KiB |
@ -1,368 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>Alex Chen — Indie Developer & AI Creator</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=Space+Grotesk:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #FFFFFF;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
color: #111111;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* NAV */
|
||||
nav {
|
||||
position: absolute;
|
||||
top: 0; left: 0; right: 0;
|
||||
height: 72px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 80px;
|
||||
border-bottom: 1px solid #111;
|
||||
z-index: 10;
|
||||
}
|
||||
nav .logo {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
nav .logo span { color: #E63946; }
|
||||
nav ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
gap: 48px;
|
||||
}
|
||||
nav ul li a {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
color: #111;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
nav ul li a:hover { color: #E63946; }
|
||||
nav .nav-contact a {
|
||||
background: #111;
|
||||
color: #fff;
|
||||
padding: 10px 28px;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
nav .nav-contact a:hover { background: #E63946; }
|
||||
|
||||
/* MAIN GRID */
|
||||
.hero {
|
||||
position: absolute;
|
||||
top: 72px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1px 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
|
||||
/* LEFT PANEL */
|
||||
.hero-left {
|
||||
padding: 64px 80px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.hero-left .intro-label {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
color: #999;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.hero-left .name {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-weight: 900;
|
||||
font-size: 112px;
|
||||
line-height: 0.92;
|
||||
letter-spacing: -0.03em;
|
||||
color: #111;
|
||||
}
|
||||
.hero-left .name .accent { color: #E63946; }
|
||||
.hero-left .tagline {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 20px;
|
||||
line-height: 1.6;
|
||||
color: #555;
|
||||
max-width: 480px;
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
||||
/* STATS ROW */
|
||||
.stats-row {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
border-top: 1px solid #111;
|
||||
padding-top: 32px;
|
||||
}
|
||||
.stat-item {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
}
|
||||
.stat-item:not(:last-child)::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
background: #DDD;
|
||||
}
|
||||
.stat-item .stat-number {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 48px;
|
||||
letter-spacing: -0.02em;
|
||||
color: #111;
|
||||
line-height: 1;
|
||||
}
|
||||
.stat-item .stat-number .red { color: #E63946; }
|
||||
.stat-item .stat-label {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: #999;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* CENTER DIVIDER */
|
||||
.divider {
|
||||
background: #111;
|
||||
}
|
||||
|
||||
/* RIGHT PANEL */
|
||||
.hero-right {
|
||||
padding: 64px 80px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
background: #FAFAFA;
|
||||
}
|
||||
|
||||
/* PORTRAIT PLACEHOLDER */
|
||||
.portrait-wrap {
|
||||
position: relative;
|
||||
width: 320px;
|
||||
height: 320px;
|
||||
}
|
||||
.portrait-circle {
|
||||
width: 320px;
|
||||
height: 320px;
|
||||
border-radius: 50%;
|
||||
background: #E8E8E8;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.portrait-circle::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0; left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 180px;
|
||||
height: 200px;
|
||||
background: #D0D0D0;
|
||||
border-radius: 90px 90px 0 0;
|
||||
}
|
||||
.portrait-frame {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: -12px;
|
||||
width: 344px;
|
||||
height: 344px;
|
||||
border: 1px solid #E63946;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* RED INDEX MARKER */
|
||||
.index-marker {
|
||||
position: absolute;
|
||||
bottom: 64px;
|
||||
right: 80px;
|
||||
text-align: right;
|
||||
}
|
||||
.index-marker .idx-num {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 120px;
|
||||
line-height: 0.85;
|
||||
color: #E63946;
|
||||
opacity: 0.1;
|
||||
}
|
||||
.index-marker .idx-label {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: #999;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* DECORATIVE ELEMENTS */
|
||||
.corner-mark {
|
||||
position: absolute;
|
||||
top: 64px;
|
||||
right: 80px;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: #CCC;
|
||||
}
|
||||
|
||||
.hero-right .role-tags {
|
||||
margin-top: 40px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
.role-tags span {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
padding: 8px 20px;
|
||||
border: 1px solid #CCC;
|
||||
color: #666;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.role-tags span:hover {
|
||||
border-color: #E63946;
|
||||
color: #E63946;
|
||||
}
|
||||
|
||||
/* SCROLL CTA */
|
||||
.scroll-cta {
|
||||
position: absolute;
|
||||
bottom: 28px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.scroll-cta span {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 10px;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
color: #BBB;
|
||||
}
|
||||
.scroll-cta .arrow-down {
|
||||
width: 1px;
|
||||
height: 32px;
|
||||
background: #CCC;
|
||||
position: relative;
|
||||
}
|
||||
.scroll-cta .arrow-down::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: -3px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-right: 1px solid #CCC;
|
||||
border-bottom: 1px solid #CCC;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- NAVIGATION -->
|
||||
<nav>
|
||||
<div class="logo">Alex<span>.</span>Chen</div>
|
||||
<ul>
|
||||
<li><a href="#work">Work</a></li>
|
||||
<li><a href="#content">Content</a></li>
|
||||
<li><a href="#services">Services</a></li>
|
||||
</ul>
|
||||
<div class="nav-contact">
|
||||
<a href="#contact">Contact</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- HERO -->
|
||||
<div class="hero">
|
||||
<!-- LEFT -->
|
||||
<div class="hero-left">
|
||||
<div>
|
||||
<div class="intro-label">Indie Developer / AI Creator</div>
|
||||
<h1 class="name">Alex<br>Chen<span class="accent">.</span></h1>
|
||||
<p class="tagline">Building tools at the intersection of AI and creativity.</p>
|
||||
</div>
|
||||
<div class="stats-row">
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">300K<span class="red">+</span></div>
|
||||
<div class="stat-label">Followers</div>
|
||||
</div>
|
||||
<div class="stat-item" style="padding-left: 32px;">
|
||||
<div class="stat-number">#1</div>
|
||||
<div class="stat-label">App Store</div>
|
||||
</div>
|
||||
<div class="stat-item" style="padding-left: 32px;">
|
||||
<div class="stat-number">100<span class="red">+</span></div>
|
||||
<div class="stat-label">Articles</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- DIVIDER -->
|
||||
<div class="divider"></div>
|
||||
|
||||
<!-- RIGHT -->
|
||||
<div class="hero-right">
|
||||
<div class="corner-mark">Portfolio 2026</div>
|
||||
<div class="portrait-wrap">
|
||||
<div class="portrait-circle"></div>
|
||||
<div class="portrait-frame"></div>
|
||||
</div>
|
||||
<div class="role-tags">
|
||||
<span>Developer</span>
|
||||
<span>Writer</span>
|
||||
<span>Creator</span>
|
||||
</div>
|
||||
<div class="index-marker">
|
||||
<div class="idx-num">01</div>
|
||||
<div class="idx-label">Hero</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SCROLL CTA -->
|
||||
<div class="scroll-cta">
|
||||
<span>Scroll</span>
|
||||
<div class="arrow-down"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 56 KiB |
@ -1,459 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>Alex Chen — Indie Developer & AI Creator</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&family=Noto+Serif+SC:wght@300;400;600&display=swap" rel="stylesheet">
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
width: 1440px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
background: #F5F0EB;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #3D3D3A;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* PAPER TEXTURE */
|
||||
body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
width: 100%; height: 100%;
|
||||
background:
|
||||
repeating-linear-gradient(
|
||||
0deg,
|
||||
transparent,
|
||||
transparent 2px,
|
||||
rgba(0,0,0,0.008) 2px,
|
||||
rgba(0,0,0,0.008) 4px
|
||||
),
|
||||
repeating-linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
transparent 2px,
|
||||
rgba(0,0,0,0.005) 2px,
|
||||
rgba(0,0,0,0.005) 4px
|
||||
);
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* NAV */
|
||||
nav {
|
||||
position: absolute;
|
||||
top: 0; left: 0; right: 0;
|
||||
height: 72px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 80px;
|
||||
z-index: 10;
|
||||
}
|
||||
nav .logo {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
color: #3D3D3A;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
nav ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
gap: 36px;
|
||||
align-items: center;
|
||||
}
|
||||
nav ul li a {
|
||||
font-weight: 400;
|
||||
font-size: 13px;
|
||||
color: #8A8A84;
|
||||
text-decoration: none;
|
||||
letter-spacing: 0.01em;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
nav ul li a:hover { color: #3D3D3A; }
|
||||
nav ul li.active a { color: #3D3D3A; }
|
||||
|
||||
/* Hairline below nav */
|
||||
nav::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 48px;
|
||||
height: 1px;
|
||||
background: #C8C2B6;
|
||||
}
|
||||
|
||||
/* MAIN LAYOUT - ASYMMETRIC */
|
||||
.hero {
|
||||
position: absolute;
|
||||
top: 72px;
|
||||
left: 0;
|
||||
width: 1440px;
|
||||
height: 828px;
|
||||
display: grid;
|
||||
grid-template-columns: 120px 1fr 400px 120px;
|
||||
grid-template-rows: 1fr;
|
||||
align-items: center;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* LEFT MARGIN ELEMENT */
|
||||
.margin-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding-bottom: 80px;
|
||||
height: 100%;
|
||||
}
|
||||
.margin-left .vertical-text {
|
||||
writing-mode: vertical-rl;
|
||||
font-size: 10px;
|
||||
letter-spacing: 0.18em;
|
||||
color: #B8B2A6;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
/* CENTER CONTENT */
|
||||
.hero-center {
|
||||
padding: 0 40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.hero-center .section-label {
|
||||
font-size: 10px;
|
||||
letter-spacing: 0.16em;
|
||||
text-transform: uppercase;
|
||||
color: #6B8F71;
|
||||
font-weight: 500;
|
||||
margin-bottom: 32px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.hero-center h1 {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-weight: 300;
|
||||
font-size: 56px;
|
||||
line-height: 1.25;
|
||||
letter-spacing: -0.01em;
|
||||
color: #2D3436;
|
||||
}
|
||||
.hero-center h1 .serif-accent {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
color: #2D3436;
|
||||
}
|
||||
|
||||
/* HAIRLINE DIVIDER */
|
||||
.hairline {
|
||||
width: 48px;
|
||||
height: 1px;
|
||||
background: #C8C2B6;
|
||||
margin: 36px 0;
|
||||
}
|
||||
|
||||
.hero-center .tagline {
|
||||
font-weight: 300;
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #8A8A84;
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
/* STATS - HORIZONTAL */
|
||||
.stats {
|
||||
display: flex;
|
||||
gap: 48px;
|
||||
margin-top: 48px;
|
||||
}
|
||||
.stat {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.stat .stat-value {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-weight: 600;
|
||||
font-size: 28px;
|
||||
color: #2D3436;
|
||||
letter-spacing: -0.01em;
|
||||
line-height: 1;
|
||||
}
|
||||
.stat .stat-desc {
|
||||
font-size: 11px;
|
||||
color: #B8B2A6;
|
||||
margin-top: 8px;
|
||||
letter-spacing: 0.04em;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* CTA */
|
||||
.hero-cta {
|
||||
margin-top: 48px;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
.cta-link {
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
color: #3D3D3A;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #C8C2B6;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.cta-link:hover { border-color: #6B8F71; color: #6B8F71; }
|
||||
.cta-link svg { width: 14px; height: 14px; }
|
||||
|
||||
.cta-dot {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: #C8C2B6;
|
||||
}
|
||||
|
||||
.cta-subtle {
|
||||
font-weight: 300;
|
||||
font-size: 13px;
|
||||
color: #B8B2A6;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
.cta-subtle:hover { color: #3D3D3A; }
|
||||
|
||||
/* RIGHT PANEL */
|
||||
.hero-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* PORTRAIT */
|
||||
.portrait-container {
|
||||
position: relative;
|
||||
}
|
||||
.portrait {
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
border-radius: 50%;
|
||||
background: #EAE5DD;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
border: 1px solid rgba(200, 194, 182, 0.4);
|
||||
}
|
||||
.portrait::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0; left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 96px;
|
||||
height: 110px;
|
||||
background: #D5CEC4;
|
||||
border-radius: 48px 48px 0 0;
|
||||
}
|
||||
.portrait-ring {
|
||||
position: absolute;
|
||||
top: -16px; left: -16px;
|
||||
width: 212px;
|
||||
height: 212px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(107, 143, 113, 0.2);
|
||||
}
|
||||
|
||||
/* BIO CARD */
|
||||
.bio-card {
|
||||
margin-top: 36px;
|
||||
background: rgba(255,255,255,0.5);
|
||||
border: 1px solid rgba(0,0,0,0.04);
|
||||
border-radius: 12px;
|
||||
padding: 24px 28px;
|
||||
width: 260px;
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
.bio-card .bio-name {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
color: #3D3D3A;
|
||||
}
|
||||
.bio-card .bio-role {
|
||||
font-size: 12px;
|
||||
color: #B8B2A6;
|
||||
margin-top: 4px;
|
||||
font-weight: 300;
|
||||
}
|
||||
.bio-card .bio-hairline {
|
||||
width: 32px;
|
||||
height: 1px;
|
||||
background: #C8C2B6;
|
||||
margin: 16px 0;
|
||||
}
|
||||
.bio-card .bio-desc {
|
||||
font-size: 12px;
|
||||
line-height: 1.7;
|
||||
color: #8A8A84;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
/* RIGHT MARGIN */
|
||||
.margin-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding-top: 80px;
|
||||
height: 100%;
|
||||
}
|
||||
.margin-right .year {
|
||||
writing-mode: vertical-rl;
|
||||
font-size: 10px;
|
||||
letter-spacing: 0.18em;
|
||||
color: #C8C2B6;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
/* DECORATIVE: FLOATING LEAF/ORGANIC SHAPE */
|
||||
.organic-shape {
|
||||
position: absolute;
|
||||
top: 140px;
|
||||
right: 280px;
|
||||
width: 60px;
|
||||
height: 80px;
|
||||
z-index: 3;
|
||||
opacity: 0.08;
|
||||
}
|
||||
.organic-shape svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* BOTTOM AREA */
|
||||
.bottom-zen {
|
||||
position: absolute;
|
||||
bottom: 40px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
z-index: 5;
|
||||
}
|
||||
.bottom-zen .zen-line {
|
||||
width: 48px;
|
||||
height: 1px;
|
||||
background: #C8C2B6;
|
||||
}
|
||||
.bottom-zen .zen-text {
|
||||
font-size: 10px;
|
||||
letter-spacing: 0.14em;
|
||||
color: #C8C2B6;
|
||||
font-weight: 300;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- NAV -->
|
||||
<nav>
|
||||
<div class="logo">Alex Chen</div>
|
||||
<ul>
|
||||
<li class="active"><a href="#work">Work</a></li>
|
||||
<li><a href="#content">Content</a></li>
|
||||
<li><a href="#services">Services</a></li>
|
||||
<li><a href="#contact">Contact</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<!-- DECORATIVE: Subtle spec annotation -->
|
||||
<svg style="position:absolute;top:100px;right:340px;z-index:3;opacity:0.15;" width="60" height="60" viewBox="0 0 60 60" fill="none">
|
||||
<circle cx="30" cy="30" r="28" stroke="#6B8F71" stroke-width="0.5"/>
|
||||
<circle cx="30" cy="30" r="18" stroke="#6B8F71" stroke-width="0.5" stroke-dasharray="2,4"/>
|
||||
<line x1="30" y1="0" x2="30" y2="60" stroke="#6B8F71" stroke-width="0.3"/>
|
||||
<line x1="0" y1="30" x2="60" y2="30" stroke="#6B8F71" stroke-width="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- HERO -->
|
||||
<div class="hero">
|
||||
<!-- LEFT MARGIN -->
|
||||
<div class="margin-left">
|
||||
<div class="vertical-text">PORTFOLIO</div>
|
||||
</div>
|
||||
|
||||
<!-- CENTER -->
|
||||
<div class="hero-center">
|
||||
<div class="section-label">Indie Developer & AI Creator</div>
|
||||
<h1>Building tools<br>at the intersection<br>of <span class="serif-accent">AI</span> and <span class="serif-accent">creativity</span></h1>
|
||||
<div class="hairline"></div>
|
||||
<p class="tagline">I design, build, and write about the things that emerge when technology meets human imagination.</p>
|
||||
|
||||
<div class="stats">
|
||||
<div class="stat">
|
||||
<div class="stat-value">300K+</div>
|
||||
<div class="stat-desc">followers</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-value">No. 1</div>
|
||||
<div class="stat-desc">App Store</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-value">100+</div>
|
||||
<div class="stat-desc">articles published</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero-cta">
|
||||
<a href="#work" class="cta-link">
|
||||
Explore Work
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
|
||||
</a>
|
||||
<div class="cta-dot"></div>
|
||||
<a href="#content" class="cta-subtle">Read Writing</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RIGHT -->
|
||||
<div class="hero-right">
|
||||
<div class="portrait-container">
|
||||
<div class="portrait"></div>
|
||||
<div class="portrait-ring"></div>
|
||||
</div>
|
||||
<div class="bio-card">
|
||||
<div class="bio-name">Alex Chen</div>
|
||||
<div class="bio-role">Developer / Writer / Creator</div>
|
||||
<div class="bio-hairline"></div>
|
||||
<div class="bio-desc">Shipping AI-powered products as an independent maker. Writing about the craft of building.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RIGHT MARGIN -->
|
||||
<div class="margin-right">
|
||||
<div class="year">2026</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- BOTTOM ZEN -->
|
||||
<div class="bottom-zen">
|
||||
<div class="zen-line"></div>
|
||||
<div class="zen-text">Design as inquiry</div>
|
||||
<div class="zen-line"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 125 KiB |