chore: ruler files update
Signed-off-by: Dmytro Stanchiev <git@dmytros.dev>
175
.claude/skills/huashu-design/assets/android_frame.jsx
Normal file
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
340
.claude/skills/huashu-design/assets/animations.jsx
Normal file
@@ -0,0 +1,340 @@
|
||||
/**
|
||||
* 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,
|
||||
};
|
||||
}
|
||||
})();
|
||||
198
.claude/skills/huashu-design/assets/banner.svg
Normal file
@@ -0,0 +1,198 @@
|
||||
<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>
|
||||
|
After Width: | Height: | Size: 9.3 KiB |
BIN
.claude/skills/huashu-design/assets/bgm-ad.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/bgm-educational-alt.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/bgm-educational.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/bgm-tech.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/bgm-tutorial-alt.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/bgm-tutorial.mp3
Normal file
166
.claude/skills/huashu-design/assets/browser_window.jsx
Normal file
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
237
.claude/skills/huashu-design/assets/deck_index.html
Normal file
@@ -0,0 +1,237 @@
|
||||
<!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>
|
||||
420
.claude/skills/huashu-design/assets/deck_stage.js
Normal file
@@ -0,0 +1,420 @@
|
||||
/**
|
||||
* <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;
|
||||
})();
|
||||
205
.claude/skills/huashu-design/assets/design_canvas.jsx
Normal file
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
* 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 });
|
||||
}
|
||||
192
.claude/skills/huashu-design/assets/ios_frame.jsx
Normal file
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
96
.claude/skills/huashu-design/assets/macos_window.jsx
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
470
.claude/skills/huashu-design/assets/narration_stage.jsx
Normal file
@@ -0,0 +1,470 @@
|
||||
/**
|
||||
* narration_stage.jsx · 解说驱动 Stage
|
||||
*
|
||||
* ╔══════════════════════════════════════════════════════════════════╗
|
||||
* ║ 🛑 用这套工具之前必读:references/voiceover-pipeline.md ║
|
||||
* ║ ║
|
||||
* ║ 铁律 #1: 整片是一个连续的运动叙事,不是一组独立场景 ║
|
||||
* ║ You are not making 7 slides. You are directing 1 movie. ║
|
||||
* ║ ║
|
||||
* ║ 铁律 #2: 选定 hero element 跨 scene 持续存在,不要每段一个新布局║
|
||||
* ║ ║
|
||||
* ║ 铁律 #3: scene 之间禁止硬切(opacity 1→0/0→1) ║
|
||||
* ║ 要 morph,不要 cut ║
|
||||
* ║ ║
|
||||
* ║ 失败模式 #1(本 skill v1 实战踩坑): ║
|
||||
* ║ 每个 Scene 各自独立 layout + cue 用 fade-up + scene 切换║
|
||||
* ║ 整页 opacity 切换 = 带配音的 PowerPoint = 质感归零 ║
|
||||
* ║ ║
|
||||
* ║ 正确做法:把 hero 直接放在 <NarrationStage> 子级(不进 Scene) ║
|
||||
* ║ 用 useNarration() 在 hero 里读 time/scene/cue 状态 ║
|
||||
* ║ hero 自己根据当前时间决定形态 → 跨 scene 连续运动 ║
|
||||
* ╚══════════════════════════════════════════════════════════════════╝
|
||||
*
|
||||
* 用法(inline 进 HTML 的 <script type="text/babel">):
|
||||
* const { NarrationStage, Scene, Cue, useNarration } = NarrationStageLib;
|
||||
*
|
||||
* const App = () => (
|
||||
* <NarrationStage timeline={TIMELINE} audioSrc="voiceover.mp3"
|
||||
* width={1920} height={1080}>
|
||||
* <Scene id="intro">
|
||||
* <h1>什么是 token</h1>
|
||||
* <Cue id="question">
|
||||
* {(triggered) => triggered && <p>↑ 这是问题</p>}
|
||||
* </Cue>
|
||||
* </Scene>
|
||||
* <Scene id="token-2">
|
||||
* <Cue id="split">
|
||||
* {(triggered, progress) => (
|
||||
* <div style={{opacity: triggered ? 1 : 0.3}}>...</div>
|
||||
* )}
|
||||
* </Cue>
|
||||
* </Scene>
|
||||
* </NarrationStage>
|
||||
* );
|
||||
*
|
||||
* 时间源(自动二选一):
|
||||
* - 录视频模式(window.__recording === true):走 window.__time(外部 driver 推帧)
|
||||
* - 实播模式:走 <audio> 的 currentTime(用户点播放时和音频严格同步)
|
||||
*
|
||||
* 与 render-video.js 兼容:
|
||||
* - tick 第一帧设 window.__ready = true
|
||||
* - 录视频时检测 window.__recording 强制不播 audio、用 window.__time
|
||||
* - 暴露 window.__totalDuration 给 driver 算总帧数
|
||||
*
|
||||
* 依赖:React 18 + ReactDOM 18 + Babel standalone(同 animations.jsx)
|
||||
*/
|
||||
|
||||
const NarrationStageLib = (() => {
|
||||
const NarrationContext = React.createContext({
|
||||
time: 0,
|
||||
scene: null,
|
||||
sceneTime: 0,
|
||||
isCueTriggered: () => false,
|
||||
cueProgress: () => 0,
|
||||
});
|
||||
|
||||
/**
|
||||
* 主组件:吃 timeline + audio,提供 context
|
||||
*
|
||||
* Props:
|
||||
* timeline timeline.json 对象(必需)
|
||||
* audioSrc voiceover.mp3 路径(必需)
|
||||
* width/height Stage 尺寸,默认 1920x1080
|
||||
* background 默认 '#0e0e0e'
|
||||
* controls 是否显示底部播放条,默认 true
|
||||
* children 动画内容(用 <Scene>/<Cue> 组织)
|
||||
*/
|
||||
function NarrationStage({
|
||||
timeline,
|
||||
audioSrc,
|
||||
width = 1920,
|
||||
height = 1080,
|
||||
background = '#0e0e0e',
|
||||
controls = true,
|
||||
children,
|
||||
}) {
|
||||
const audioRef = React.useRef(null);
|
||||
const [time, setTime] = React.useState(0);
|
||||
const [playing, setPlaying] = React.useState(false);
|
||||
const recording = typeof window !== 'undefined' && window.__recording === true;
|
||||
|
||||
// 暴露给 render-video.js
|
||||
React.useEffect(() => {
|
||||
if (typeof window === 'undefined') return;
|
||||
window.__totalDuration = timeline.totalDuration;
|
||||
window.__ready = true;
|
||||
}, [timeline.totalDuration]);
|
||||
|
||||
// 时间 tick
|
||||
React.useEffect(() => {
|
||||
let raf;
|
||||
if (recording) {
|
||||
// 录视频模式:rAF wall-clock 自驱动从 0 开始
|
||||
// 兼容 render-video.js(它依赖动画自然推进 + window.__seek 复位)
|
||||
let startedAt = null;
|
||||
const tick = (now) => {
|
||||
if (startedAt === null) startedAt = now;
|
||||
setTime(Math.min((now - startedAt) / 1000, timeline.totalDuration));
|
||||
raf = requestAnimationFrame(tick);
|
||||
};
|
||||
raf = requestAnimationFrame(tick);
|
||||
// 暴露 __seek 给 render-video.js 在 ready 后调 __seek(0) 复位
|
||||
if (typeof window !== 'undefined') {
|
||||
window.__seek = (t) => {
|
||||
startedAt = performance.now() - t * 1000;
|
||||
setTime(t);
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// 实播模式:跟随 audio.currentTime
|
||||
const tick = () => {
|
||||
if (audioRef.current && !audioRef.current.paused) {
|
||||
setTime(audioRef.current.currentTime);
|
||||
}
|
||||
raf = requestAnimationFrame(tick);
|
||||
};
|
||||
tick();
|
||||
}
|
||||
return () => cancelAnimationFrame(raf);
|
||||
}, [recording, timeline.totalDuration]);
|
||||
|
||||
// 当前 scene
|
||||
const currentScene = React.useMemo(() => {
|
||||
if (!timeline.scenes) return null;
|
||||
// 找到 start <= time < end 的段。最后一段保留到 end
|
||||
for (let i = 0; i < timeline.scenes.length; i++) {
|
||||
const s = timeline.scenes[i];
|
||||
const next = timeline.scenes[i + 1];
|
||||
if (time >= s.start && (!next || time < next.start)) return s;
|
||||
}
|
||||
return timeline.scenes[0];
|
||||
}, [time, timeline.scenes]);
|
||||
|
||||
const sceneTime = currentScene ? Math.max(0, time - currentScene.start) : 0;
|
||||
|
||||
// 找 cue 状态(按 absoluteTime 比较,跨 scene 也能查)
|
||||
const allCues = React.useMemo(() => {
|
||||
const map = {};
|
||||
for (const s of timeline.scenes || []) {
|
||||
for (const c of s.cues || []) {
|
||||
map[c.id] = c;
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}, [timeline.scenes]);
|
||||
|
||||
const isCueTriggered = React.useCallback(
|
||||
(cueId) => {
|
||||
const c = allCues[cueId];
|
||||
if (!c) return false;
|
||||
return time >= c.absoluteTime;
|
||||
},
|
||||
[allCues, time],
|
||||
);
|
||||
|
||||
/** 触发后多少秒 0→1,>1 后保持 1。用于 cue 后做渐入动画 */
|
||||
const cueProgress = React.useCallback(
|
||||
(cueId, ramp = 0.5) => {
|
||||
const c = allCues[cueId];
|
||||
if (!c) return 0;
|
||||
const dt = time - c.absoluteTime;
|
||||
if (dt <= 0) return 0;
|
||||
if (dt >= ramp) return 1;
|
||||
return dt / ramp;
|
||||
},
|
||||
[allCues, time],
|
||||
);
|
||||
|
||||
const ctx = { time, scene: currentScene, sceneTime, isCueTriggered, cueProgress, timeline };
|
||||
|
||||
// play/pause/seek 控制
|
||||
const handlePlayPause = () => {
|
||||
if (!audioRef.current) return;
|
||||
if (audioRef.current.paused) {
|
||||
audioRef.current.play();
|
||||
setPlaying(true);
|
||||
} else {
|
||||
audioRef.current.pause();
|
||||
setPlaying(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSeek = (e) => {
|
||||
if (!audioRef.current) return;
|
||||
const t = parseFloat(e.target.value);
|
||||
audioRef.current.currentTime = t;
|
||||
setTime(t);
|
||||
};
|
||||
|
||||
const handleAudioEnded = () => setPlaying(false);
|
||||
|
||||
return (
|
||||
<NarrationContext.Provider value={ctx}>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
width,
|
||||
height,
|
||||
background,
|
||||
overflow: 'hidden',
|
||||
color: '#fff',
|
||||
fontFamily: '-apple-system, BlinkMacSystemFont, "PingFang SC", sans-serif',
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
{!recording && (
|
||||
<audio
|
||||
ref={audioRef}
|
||||
src={audioSrc}
|
||||
preload="auto"
|
||||
onEnded={handleAudioEnded}
|
||||
/>
|
||||
)}
|
||||
{!recording && controls && (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 12,
|
||||
padding: '12px 16px',
|
||||
background: '#1a1a1a',
|
||||
color: '#ddd',
|
||||
fontFamily: 'monospace',
|
||||
fontSize: 13,
|
||||
width,
|
||||
boxSizing: 'border-box',
|
||||
}}
|
||||
>
|
||||
<button
|
||||
onClick={handlePlayPause}
|
||||
style={{
|
||||
padding: '6px 14px',
|
||||
background: '#fff',
|
||||
color: '#000',
|
||||
border: 0,
|
||||
borderRadius: 4,
|
||||
cursor: 'pointer',
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
{playing ? '❚❚ Pause' : '▶ Play'}
|
||||
</button>
|
||||
<input
|
||||
type="range"
|
||||
min={0}
|
||||
max={timeline.totalDuration}
|
||||
step={0.01}
|
||||
value={time}
|
||||
onChange={handleSeek}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
<span style={{ minWidth: 110, textAlign: 'right' }}>
|
||||
{time.toFixed(2)} / {timeline.totalDuration.toFixed(2)}s
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
padding: '4px 10px',
|
||||
background: '#2a2a2a',
|
||||
borderRadius: 4,
|
||||
minWidth: 100,
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
{currentScene ? currentScene.id : '—'}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</NarrationContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scene 包裹器:只在指定 scene id 激活时渲染 children
|
||||
*
|
||||
* Props:
|
||||
* id scene id(对应 timeline.scenes[].id)
|
||||
* children 渲染内容;可以是 ReactNode 或 (sceneTime, sceneInfo) => ReactNode
|
||||
* keepMounted 默认 false。设 true 则一直挂载只切换 visibility(动画连贯需要时用)
|
||||
*/
|
||||
function Scene({ id, children, keepMounted = false }) {
|
||||
const { scene, sceneTime } = React.useContext(NarrationContext);
|
||||
const isActive = scene && scene.id === id;
|
||||
if (!isActive && !keepMounted) return null;
|
||||
const content = typeof children === 'function' ? children(sceneTime, scene) : children;
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
opacity: isActive ? 1 : 0,
|
||||
pointerEvents: isActive ? 'auto' : 'none',
|
||||
transition: keepMounted ? 'opacity 0.2s' : undefined,
|
||||
}}
|
||||
>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cue 包裹器:监听 cue 触发状态
|
||||
*
|
||||
* Props:
|
||||
* id cue id(对应 timeline.scenes[].cues[].id)
|
||||
* ramp cue 触发后 progress 0→1 的 ramp 时长(秒),默认 0.5
|
||||
* children 必须是函数:(triggered: bool, progress: 0-1) => ReactNode
|
||||
*/
|
||||
function Cue({ id, ramp = 0.5, children }) {
|
||||
const { isCueTriggered, cueProgress } = React.useContext(NarrationContext);
|
||||
const triggered = isCueTriggered(id);
|
||||
const progress = cueProgress(id, ramp);
|
||||
return children(triggered, progress);
|
||||
}
|
||||
|
||||
/** Hook:在自定义组件里直接拿 narration 状态 */
|
||||
function useNarration() {
|
||||
return React.useContext(NarrationContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* splitChunkToLines · 把一段文字按标点切成 ≤maxLen 字的短行
|
||||
*
|
||||
* 用于字幕显示——B 站标准是单行 ≤12 字便于阅读。本函数:
|
||||
* 1. 先按强标点(。!?\n)切句,绝不跨句号截断
|
||||
* 2. 每句 ≤ maxLen 直接用,否则按弱标点(,、;:)切片合并
|
||||
* 3. 中英混合:英文/数字按 0.5 字算视觉宽度
|
||||
* 4. 兜底硬切(罕见:单个标点段超 maxLen)
|
||||
*
|
||||
* @param text 原文
|
||||
* @param maxLen 单行最大视觉长度,默认 13(≈12 字 + 一个标点)
|
||||
* @returns 切好的字幕行数组
|
||||
*/
|
||||
function visualLen(s) {
|
||||
let n = 0;
|
||||
for (const ch of s) n += /[a-zA-Z0-9 .,'":;\-]/.test(ch) ? 0.5 : 1;
|
||||
return n;
|
||||
}
|
||||
function splitChunkToLines(text, maxLen = 13) {
|
||||
const lines = [];
|
||||
const sentences = [];
|
||||
let buf = '';
|
||||
for (const ch of text) {
|
||||
buf += ch;
|
||||
if ('。!?\n'.includes(ch)) { if (buf.trim()) sentences.push(buf.trim()); buf = ''; }
|
||||
}
|
||||
if (buf.trim()) sentences.push(buf.trim());
|
||||
for (const sent of sentences) {
|
||||
if (visualLen(sent) <= maxLen) { lines.push(sent); continue; }
|
||||
const parts = [];
|
||||
let pbuf = '';
|
||||
for (const ch of sent) {
|
||||
pbuf += ch;
|
||||
if (',、;:'.includes(ch)) { parts.push(pbuf); pbuf = ''; }
|
||||
}
|
||||
if (pbuf) parts.push(pbuf);
|
||||
let merged = '';
|
||||
for (const p of parts) {
|
||||
if (visualLen(merged) + visualLen(p) <= maxLen) merged += p;
|
||||
else { if (merged) lines.push(merged); merged = p; }
|
||||
}
|
||||
if (merged) {
|
||||
if (visualLen(merged) <= maxLen) lines.push(merged);
|
||||
else {
|
||||
let hbuf = '';
|
||||
for (const ch of merged) { hbuf += ch; if (visualLen(hbuf) >= maxLen) { lines.push(hbuf); hbuf = ''; } }
|
||||
if (hbuf) lines.push(hbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return lines.filter(l => l.trim());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtitles · B 站风格字幕组件(白光晕深墨字,无背景,按 chunks 时间显示)
|
||||
*
|
||||
* 自动从当前 scene.chunks 取活动 chunk,按 splitChunkToLines 切成短行,
|
||||
* 按字数比例分配 chunk 时间窗给每行显示。
|
||||
*
|
||||
* 必需:timeline.scenes[].chunks[](narrate-pipeline.mjs 已默认输出)
|
||||
*
|
||||
* Props(可覆盖默认样式):
|
||||
* bottom 距底部像素,默认 90(不贴边)
|
||||
* fontSize 字号,默认 32
|
||||
* color 字色,默认深墨 #1a1a1a(适合浅纸白底)
|
||||
* haloColor 光晕色,默认 rgba(245,241,232,0.9)(适合 #f5f1e8 底)
|
||||
* maxLen 单行最大视觉长度,默认 13
|
||||
*
|
||||
* 深底场景:把 color 改成 '#fff',haloColor 改成 'rgba(0,0,0,0.85)' 即可。
|
||||
*/
|
||||
function Subtitles({ bottom = 90, fontSize = 32, color = '#1a1a1a', haloColor = 'rgba(245,241,232,0.9)', maxLen = 13 } = {}) {
|
||||
const { time, scene } = React.useContext(NarrationContext);
|
||||
if (!scene || !scene.chunks) return null;
|
||||
const active = scene.chunks.find(c => time >= c.absoluteStart && time < c.absoluteEnd);
|
||||
if (!active) return null;
|
||||
const lines = splitChunkToLines(active.text, maxLen);
|
||||
if (lines.length === 0) return null;
|
||||
const totalLen = lines.reduce((s, l) => s + visualLen(l), 0);
|
||||
const chunkDur = active.absoluteEnd - active.absoluteStart;
|
||||
let acc = active.absoluteStart;
|
||||
let activeLine = lines[lines.length - 1];
|
||||
let lineStart = active.absoluteStart;
|
||||
for (const line of lines) {
|
||||
const dur = (visualLen(line) / totalLen) * chunkDur;
|
||||
if (time < acc + dur) { activeLine = line; lineStart = acc; break; }
|
||||
acc += dur;
|
||||
}
|
||||
const lineProg = Math.min(1, (time - lineStart) / 0.15);
|
||||
return React.createElement('div', {
|
||||
style: { position: 'absolute', left: 0, right: 0, bottom, display: 'flex', justifyContent: 'center', pointerEvents: 'none', zIndex: 50 },
|
||||
}, React.createElement('div', {
|
||||
key: lineStart,
|
||||
style: {
|
||||
fontFamily: '"PingFang SC", "Noto Sans SC", -apple-system, sans-serif',
|
||||
fontSize, fontWeight: 600, color,
|
||||
letterSpacing: '0.04em', lineHeight: 1.2, textAlign: 'center',
|
||||
textShadow: `0 0 6px ${haloColor}, 0 0 12px ${haloColor}, 0 1px 2px rgba(255,255,255,0.5)`,
|
||||
opacity: lineProg, transform: `translateY(${(1 - lineProg) * 4}px)`,
|
||||
},
|
||||
}, activeLine));
|
||||
}
|
||||
|
||||
/**
|
||||
* useSceneFade · scene 内辅助元素的软淡入淡出 helper
|
||||
*
|
||||
* 铁律第二条要求 scene 之间禁止硬切——但 scene 内辅助元素(数据卡、引用块)
|
||||
* 一旦 cue 触发后默认会一直亮到 scene 结束。如果不淡出,离开本段进入下段时
|
||||
* 这些元素会突兀地存在或瞬间消失。本 hook 提供 [入场淡入 → hold → 出场淡出] 的统一软切换。
|
||||
*
|
||||
* 用法(把 op 乘进辅助元素的 opacity):
|
||||
* const op = useSceneFade('md-side', 0.6, 0.8); // 进 0.6s, 出 0.8s
|
||||
* <Cue id="agents-md">{(t, p) => (
|
||||
* <div style={{ opacity: op * p }}>...</div>
|
||||
* )}</Cue>
|
||||
*
|
||||
* 这样数据卡片在 md-side 段开始 0.6s 内淡入,在段结束前 0.8s 开始淡出,
|
||||
* 与下一段的辅助元素淡入形成 overlap,画面不出现硬切。
|
||||
*
|
||||
* @param sceneId scene id
|
||||
* @param fadeIn 入场淡入秒数(默认 0.5)
|
||||
* @param fadeOut 出场淡出秒数(默认 0.5)
|
||||
* @returns 0-1 之间的不透明度倍率
|
||||
*/
|
||||
function useSceneFade(sceneId, fadeIn = 0.5, fadeOut = 0.5) {
|
||||
const { time, timeline } = React.useContext(NarrationContext);
|
||||
if (!timeline) return 0;
|
||||
const s = timeline.scenes.find(x => x.id === sceneId);
|
||||
if (!s) return 0;
|
||||
const inT = (time - s.start) / fadeIn;
|
||||
const outT = (s.end - time) / fadeOut;
|
||||
const v = Math.min(1, Math.min(inT, outT));
|
||||
return Math.max(0, v);
|
||||
}
|
||||
|
||||
return { NarrationStage, Scene, Cue, useNarration, useSceneFade, Subtitles, splitChunkToLines };
|
||||
})();
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
Object.assign(window, { NarrationStageLib });
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"_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/"
|
||||
}
|
||||
}
|
||||
BIN
.claude/skills/huashu-design/assets/sfx/container/card-flip.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/container/card-snap.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/container/modal-open.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/feedback/achievement.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/feedback/error-tone.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/impact/brand-stamp.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/impact/drop-thud.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/impact/logo-reveal.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/keyboard/delete-key.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/keyboard/enter.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/keyboard/space-tap.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/keyboard/type-fast.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/keyboard/type.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/magic/ai-process.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/magic/sparkle.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/magic/transform.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/transition/dissolve.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/transition/slide-in.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/transition/whoosh.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/ui/click-soft.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/ui/click.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/ui/focus.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/ui/hover-subtle.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/ui/tap-finger.mp3
Normal file
BIN
.claude/skills/huashu-design/assets/sfx/ui/toggle-on.mp3
Normal file
115
.claude/skills/huashu-design/assets/showcases/INDEX.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# 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 推荐环节
|
||||
@@ -0,0 +1,235 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 114 KiB |
@@ -0,0 +1,229 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 35 KiB |
@@ -0,0 +1,288 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 152 KiB |
@@ -0,0 +1,503 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 106 KiB |
@@ -0,0 +1,600 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 155 KiB |
@@ -0,0 +1,670 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 159 KiB |
382
.claude/skills/huashu-design/assets/showcases/ppt/ppt-build.html
Normal file
@@ -0,0 +1,382 @@
|
||||
<!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>
|
||||
BIN
.claude/skills/huashu-design/assets/showcases/ppt/ppt-build.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
@@ -0,0 +1,536 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 99 KiB |
@@ -0,0 +1,497 @@
|
||||
<!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>
|
||||
BIN
.claude/skills/huashu-design/assets/showcases/ppt/ppt-takram.png
Normal file
|
After Width: | Height: | Size: 456 KiB |
@@ -0,0 +1,385 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 83 KiB |
@@ -0,0 +1,422 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 103 KiB |
@@ -0,0 +1,499 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 119 KiB |
@@ -0,0 +1,562 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 128 KiB |
@@ -0,0 +1,548 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 147 KiB |
@@ -0,0 +1,696 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 154 KiB |
@@ -0,0 +1,372 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 67 KiB |
@@ -0,0 +1,460 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 114 KiB |
@@ -0,0 +1,494 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 109 KiB |
@@ -0,0 +1,367 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 60 KiB |
@@ -0,0 +1,368 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 56 KiB |
@@ -0,0 +1,459 @@
|
||||
<!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>
|
||||
|
After Width: | Height: | Size: 125 KiB |
@@ -0,0 +1,493 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1440">
|
||||
<title>Meridian — Business Intelligence for Modern Teams</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;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: #FAFAF8;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
/* NAV */
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 96px;
|
||||
height: 80px;
|
||||
}
|
||||
.nav-logo {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
letter-spacing: -0.3px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
.nav-logo-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: #E8E4DF;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.nav-logo-icon svg { width: 18px; height: 18px; color: #D4A574; }
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
list-style: none;
|
||||
}
|
||||
.nav-links a {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
text-decoration: none;
|
||||
color: #777;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-links a:hover { color: #1a1a1a; }
|
||||
.nav-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
}
|
||||
.nav-signin {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
text-decoration: none;
|
||||
color: #777;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-signin:hover { color: #1a1a1a; }
|
||||
.nav-cta {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
padding: 10px 24px;
|
||||
background: #1a1a1a;
|
||||
color: #FAFAF8;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.nav-cta:hover { background: #333; }
|
||||
|
||||
/* HERO LAYOUT */
|
||||
.hero {
|
||||
padding: 24px 96px 0 96px;
|
||||
display: grid;
|
||||
grid-template-columns: 480px 1fr;
|
||||
gap: 64px;
|
||||
align-items: start;
|
||||
height: calc(900px - 80px);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* LEFT TEXT */
|
||||
.hero-text {
|
||||
padding-top: 48px;
|
||||
}
|
||||
.hero-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.hero-badge-dot {
|
||||
display: none;
|
||||
}
|
||||
.hero-badge span {
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
color: #B0ACA4;
|
||||
letter-spacing: 4px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.hero-headline {
|
||||
font-size: 48px;
|
||||
font-weight: 300;
|
||||
line-height: 1.15;
|
||||
letter-spacing: -1.5px;
|
||||
margin-bottom: 24px;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
.hero-headline em {
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
.hero-subtitle {
|
||||
font-size: 17px;
|
||||
font-weight: 300;
|
||||
line-height: 1.7;
|
||||
color: #888;
|
||||
margin-bottom: 48px;
|
||||
max-width: 400px;
|
||||
}
|
||||
.hero-ctas {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-bottom: 64px;
|
||||
}
|
||||
.btn-primary {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
padding: 14px 32px;
|
||||
background: #1a1a1a;
|
||||
color: #FAFAF8;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn-primary:hover { background: #333; }
|
||||
.btn-secondary {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
padding: 14px 32px;
|
||||
background: transparent;
|
||||
color: #777;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn-secondary:hover { border-color: #aaa; color: #1a1a1a; }
|
||||
.btn-secondary svg { width: 15px; height: 15px; }
|
||||
|
||||
/* METRICS ROW */
|
||||
.metrics {
|
||||
display: flex;
|
||||
gap: 48px;
|
||||
}
|
||||
.metric {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.metric-value {
|
||||
font-size: 36px;
|
||||
font-weight: 200;
|
||||
letter-spacing: -1px;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
.metric-value span { color: #D4A574; }
|
||||
.metric-label {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #aaa;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
/* RIGHT — DASHBOARD */
|
||||
.hero-dashboard {
|
||||
position: relative;
|
||||
padding-top: 16px;
|
||||
}
|
||||
.dashboard-card {
|
||||
background: #FFFFFF;
|
||||
border-radius: 2px;
|
||||
box-shadow:
|
||||
0 1px 2px rgba(0,0,0,0.02),
|
||||
0 4px 16px rgba(0,0,0,0.04);
|
||||
padding: 28px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Dashboard header */
|
||||
.dash-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.dash-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
.dash-period {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #aaa;
|
||||
padding: 4px 12px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* KPI strip */
|
||||
.kpi-strip {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 1px;
|
||||
background: #f0eeeb;
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.kpi-item {
|
||||
background: #FAFAF8;
|
||||
padding: 18px 16px;
|
||||
text-align: center;
|
||||
}
|
||||
.kpi-item-value {
|
||||
font-size: 22px;
|
||||
font-weight: 300;
|
||||
color: #1a1a1a;
|
||||
letter-spacing: -0.5px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.kpi-item-label {
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
color: #bbb;
|
||||
letter-spacing: 0.5px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Chart */
|
||||
.chart-container {
|
||||
margin-bottom: 24px;
|
||||
position: relative;
|
||||
height: 200px;
|
||||
}
|
||||
.chart-svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Bottom section */
|
||||
.dash-bottom-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
.insight-card {
|
||||
background: #FAFAF8;
|
||||
border-radius: 2px;
|
||||
padding: 16px;
|
||||
}
|
||||
.insight-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background: #F0EBE3;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.insight-icon svg { width: 14px; height: 14px; color: #D4A574; }
|
||||
.insight-title {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.insight-desc {
|
||||
font-size: 11px;
|
||||
font-weight: 300;
|
||||
color: #999;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* TRUST BAR */
|
||||
.trust-bar {
|
||||
position: absolute;
|
||||
bottom: 24px;
|
||||
left: 96px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 40px;
|
||||
}
|
||||
.trust-label {
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
color: #ccc;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.trust-logos {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
align-items: center;
|
||||
}
|
||||
.trust-logo {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #ccc;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- NAV -->
|
||||
<nav>
|
||||
<div class="nav-logo">
|
||||
<div class="nav-logo-icon">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2"/>
|
||||
</svg>
|
||||
</div>
|
||||
Meridian
|
||||
</div>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#">Product</a></li>
|
||||
<li><a href="#">Pricing</a></li>
|
||||
<li><a href="#">Docs</a></li>
|
||||
<li><a href="#">Blog</a></li>
|
||||
</ul>
|
||||
<div class="nav-right">
|
||||
<a href="#" class="nav-signin">Sign In</a>
|
||||
<button class="nav-cta">Get Started</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- HERO -->
|
||||
<div class="hero">
|
||||
|
||||
<!-- LEFT -->
|
||||
<div class="hero-text">
|
||||
<div class="hero-badge">
|
||||
<div class="hero-badge-dot"></div>
|
||||
<span>Business Intelligence for Modern Teams</span>
|
||||
</div>
|
||||
<h1 class="hero-headline">Turn data into <em>decisions,</em> not dashboards<span style="color:#D4A574;font-weight:300;">.</span></h1>
|
||||
<p class="hero-subtitle">AI-powered analytics that tells you what matters, when it matters. Less noise, more clarity.</p>
|
||||
<div class="hero-ctas">
|
||||
<button class="btn-primary">Start Free Trial</button>
|
||||
<button class="btn-secondary">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
||||
Watch Demo
|
||||
</button>
|
||||
</div>
|
||||
<div class="metrics">
|
||||
<div class="metric">
|
||||
<div class="metric-value">3<span>x</span></div>
|
||||
<div class="metric-label">Faster insights</div>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<div class="metric-value">50<span>%</span></div>
|
||||
<div class="metric-label">Less meeting time</div>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<div class="metric-value">99.9<span>%</span></div>
|
||||
<div class="metric-label">Uptime SLA</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RIGHT — FLOATING DASHBOARD -->
|
||||
<div class="hero-dashboard">
|
||||
<div class="dashboard-card">
|
||||
<div class="dash-header">
|
||||
<div class="dash-title">Performance Overview</div>
|
||||
<div class="dash-period">Last 30 days</div>
|
||||
</div>
|
||||
|
||||
<div class="kpi-strip">
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-item-value">$2.4M</div>
|
||||
<div class="kpi-item-label">Revenue</div>
|
||||
</div>
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-item-value">84.2K</div>
|
||||
<div class="kpi-item-label">Users</div>
|
||||
</div>
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-item-value">1.2%</div>
|
||||
<div class="kpi-item-label">Churn</div>
|
||||
</div>
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-item-value">$142</div>
|
||||
<div class="kpi-item-label">ARPU</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SVG Chart -->
|
||||
<div class="chart-container">
|
||||
<svg class="chart-svg" viewBox="0 0 700 200" preserveAspectRatio="none">
|
||||
<!-- Grid lines -->
|
||||
<line x1="0" y1="50" x2="700" y2="50" stroke="#f0eeeb" stroke-width="1"/>
|
||||
<line x1="0" y1="100" x2="700" y2="100" stroke="#f0eeeb" stroke-width="1"/>
|
||||
<line x1="0" y1="150" x2="700" y2="150" stroke="#f0eeeb" stroke-width="1"/>
|
||||
|
||||
<!-- Area fill -->
|
||||
<defs>
|
||||
<linearGradient id="areaGrad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#D4A574" stop-opacity="0.15"/>
|
||||
<stop offset="100%" stop-color="#D4A574" stop-opacity="0.01"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path d="M0,160 C50,155 100,140 150,120 C200,100 250,110 300,85 C350,60 400,70 450,50 C500,30 550,45 600,35 C650,25 680,20 700,15 L700,200 L0,200 Z" fill="url(#areaGrad)"/>
|
||||
|
||||
<!-- Main line -->
|
||||
<path d="M0,160 C50,155 100,140 150,120 C200,100 250,110 300,85 C350,60 400,70 450,50 C500,30 550,45 600,35 C650,25 680,20 700,15" fill="none" stroke="#D4A574" stroke-width="2.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Secondary line -->
|
||||
<path d="M0,170 C50,165 100,158 150,150 C200,142 250,145 300,135 C350,125 400,128 450,118 C500,108 550,112 600,105 C650,98 680,95 700,90" fill="none" stroke="#e0d5c8" stroke-width="1.5" stroke-dasharray="4,4"/>
|
||||
|
||||
<!-- Data point -->
|
||||
<circle cx="600" cy="35" r="5" fill="#D4A574"/>
|
||||
<circle cx="600" cy="35" r="8" fill="none" stroke="#D4A574" stroke-width="1" opacity="0.4"/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="dash-bottom-row">
|
||||
<div class="insight-card">
|
||||
<div class="insight-icon">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
|
||||
</div>
|
||||
<div class="insight-title">AI Insight: Revenue Acceleration</div>
|
||||
<div class="insight-desc">Enterprise segment grew 23% this quarter, driven by 4 new accounts. Recommend increasing sales capacity.</div>
|
||||
</div>
|
||||
<div class="insight-card">
|
||||
<div class="insight-icon">
|
||||
<svg 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"/><polyline points="12 6 12 12 16 14"/></svg>
|
||||
</div>
|
||||
<div class="insight-title">Predicted: Q3 Target On Track</div>
|
||||
<div class="insight-desc">Based on current trajectory, 89% probability of hitting $3.2M quarterly target. Pipeline looks healthy.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TRUST BAR -->
|
||||
<div class="trust-bar">
|
||||
<span class="trust-label">Trusted by teams at</span>
|
||||
<div class="trust-logos">
|
||||
<span class="trust-logo">Stripe</span>
|
||||
<span class="trust-logo">Notion</span>
|
||||
<span class="trust-logo">Linear</span>
|
||||
<span class="trust-logo">Vercel</span>
|
||||
<span class="trust-logo">Figma</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
lucide.createIcons();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 97 KiB |