Skip to content

Commit 60340da

Browse files
committed
docs-site: landing round 3 — brand chips, splash hamburger, cinematic scroll
- provider chips carry official simple-icons marks (Anthropic, Google, Kimi, Ollama, OpenRouter, DeepSeek); brands absent from the library stay text-only - floating pill header gains a splash-only hamburger below the nav breakpoint, opening a near-opaque glass panel with every docs section (aria-expanded, Escape/outside close); docs pages keep the native Starlight toggle - cinematic landing motion: hero copy recedes on scroll (scroll(root) timeline), hero photo settles from a slow zoom, terminal clip-path wipe, per-chip stagger, deeper slide reveals — all prefers-reduced-motion gated - fix: lightningcss merged animation-timeline into the animation shorthand and killed scroll-driven motion; build now minifies CSS with esbuild - fix: slide transforms widened the page at ~773px; .lp clips overflow-x - hero copy centered with light 440 headline; panels/buttons near-opaque; demo capture crops to bottom focus
1 parent 6535578 commit 60340da

6 files changed

Lines changed: 226 additions & 22 deletions

File tree

docs-site/astro.config.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ export default defineConfig({
3939
site: "https://lidge-jun.github.io",
4040
base: "/opencodex",
4141
trailingSlash: "ignore",
42+
// lightningcss merges animation-timeline into the `animation` shorthand,
43+
// which Chrome cannot parse — the scroll-driven animations die silently.
44+
vite: { build: { cssMinify: "esbuild" } },
4245
integrations: [
4346
starlight({
4447
title: "opencodex",

docs-site/bun.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs-site/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"@fontsource-variable/geist": "^5.2.9",
1616
"astro": "^7.0.3",
1717
"pretendard": "^1.3.9",
18-
"sharp": "^0.35.2"
18+
"sharp": "^0.35.2",
19+
"simple-icons": "^16.25.0"
1920
}
2021
}

docs-site/src/components/Header.astro

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import SocialIcons from '@astrojs/starlight/components/SocialIcons.astro';
99
import ThemeSelect from '@astrojs/starlight/components/ThemeSelect.astro';
1010
1111
const { locale } = Astro.locals.starlightRoute;
12+
// Splash pages have no Starlight sidebar/hamburger, so the pill carries its own
13+
// menu below the desktop-nav breakpoint.
14+
const isSplash = Astro.locals.starlightRoute.entry.data.template === 'splash';
1215
// Root locale is `undefined`; BASE_URL already ends with a slash.
1316
const base = import.meta.env.BASE_URL.replace(/\/?$/, '/');
1417
const prefix = locale ? `${base}${locale}/` : base;
@@ -99,6 +102,35 @@ const contributing: NavLink = {
99102
<ThemeSelect />
100103
<LanguageSelect />
101104
</div>
105+
{isSplash && (
106+
<div class="lp-menu print:hidden">
107+
<button
108+
type="button"
109+
class="lp-menu-btn"
110+
aria-haspopup="true"
111+
aria-expanded="false"
112+
aria-controls="lp-menu-panel"
113+
aria-label={t('Menu', '메뉴', '菜单')}
114+
>
115+
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" aria-hidden="true">
116+
<path d="M4 6h16M4 12h16M4 18h16" />
117+
</svg>
118+
</button>
119+
<div class="lp-menu-panel" id="lp-menu-panel">
120+
{groups.map((group) => (
121+
<div class="lp-menu-group">
122+
<span>{group.label}</span>
123+
<ul>
124+
{group.links.map((link) => (
125+
<li><a href={link.href}>{link.label}</a></li>
126+
))}
127+
</ul>
128+
</div>
129+
))}
130+
<a class="lp-menu-contrib" href={contributing.href}>{contributing.label}</a>
131+
</div>
132+
</div>
133+
)}
102134
</div>
103135

104136
<style>
@@ -243,12 +275,93 @@ const contributing: NavLink = {
243275
transition: none;
244276
}
245277
}
278+
279+
/* ---- splash hamburger (below the desktop-nav breakpoint) ---- */
280+
.lp-menu { display: none; position: relative; }
281+
@media (max-width: 71.99rem) {
282+
.lp-menu { display: block; }
283+
}
284+
.lp-menu-btn {
285+
display: inline-flex;
286+
align-items: center;
287+
justify-content: center;
288+
width: 2.25rem;
289+
height: 2.25rem;
290+
border: 0;
291+
border-radius: var(--ocx-radius-pill, 999px);
292+
background: transparent;
293+
color: var(--sl-color-gray-2);
294+
cursor: pointer;
295+
transition: background-color 0.12s, color 0.12s;
296+
}
297+
.lp-menu-btn:hover,
298+
.lp-menu-btn[aria-expanded='true'] {
299+
background-color: var(--ocx-hover, rgba(128, 128, 128, 0.1));
300+
color: var(--sl-color-white);
301+
}
302+
.lp-menu-panel {
303+
position: absolute;
304+
top: calc(100% + 0.75rem);
305+
inset-inline-end: 0;
306+
min-width: 17rem;
307+
max-height: min(72dvh, 34rem);
308+
overflow-y: auto;
309+
padding: 0.875rem;
310+
border: 1px solid var(--sl-color-gray-5);
311+
border-radius: var(--ocx-radius, 12px);
312+
background-color: var(--ocx-glass-panel, canvas);
313+
backdrop-filter: var(--ocx-glass-blur, blur(40px));
314+
-webkit-backdrop-filter: var(--ocx-glass-blur, blur(40px));
315+
box-shadow: var(--ocx-shadow, 0 10px 28px rgb(0 0 0 / 0.2));
316+
opacity: 0;
317+
visibility: hidden;
318+
translate: 0 -4px;
319+
transition: opacity 0.16s ease, visibility 0.16s, translate 0.16s ease;
320+
z-index: var(--sl-z-index-navbar);
321+
}
322+
.lp-menu:has(> .lp-menu-btn[aria-expanded='true']) .lp-menu-panel {
323+
opacity: 1;
324+
visibility: visible;
325+
translate: 0 0;
326+
}
327+
.lp-menu-group + .lp-menu-group { margin-top: 0.75rem; }
328+
.lp-menu-group > span {
329+
display: block;
330+
margin-bottom: 0.25rem;
331+
font-size: var(--sl-text-2xs);
332+
font-weight: 650;
333+
color: var(--sl-color-gray-3);
334+
}
335+
.lp-menu-group ul { list-style: none; margin: 0; padding: 0; }
336+
.lp-menu-group a,
337+
.lp-menu-contrib {
338+
display: block;
339+
padding: 0.4rem 0.5rem;
340+
border-radius: var(--ocx-radius-sm, 8px);
341+
color: var(--sl-color-gray-2);
342+
font-size: var(--sl-text-sm);
343+
text-decoration: none;
344+
transition: background-color 0.12s, color 0.12s;
345+
}
346+
.lp-menu-contrib { margin-top: 0.75rem; font-weight: 600; color: var(--sl-color-white); }
347+
.lp-menu-group a:hover,
348+
.lp-menu-group a:focus-visible,
349+
.lp-menu-contrib:hover,
350+
.lp-menu-contrib:focus-visible {
351+
background-color: var(--ocx-hover, rgba(128, 128, 128, 0.1));
352+
color: var(--sl-color-white);
353+
}
354+
@media (prefers-reduced-motion: reduce) {
355+
.lp-menu-panel { transition: none; }
356+
}
246357
</style>
247358

248359
<script>
249360
// Click/Enter/Space toggles the dropdowns (hover and focus-within still work
250361
// via CSS); Escape or an outside click closes any open menu.
251-
const buttons = Array.from(document.querySelectorAll<HTMLButtonElement>('.glass-nav .nav-link[aria-haspopup]'));
362+
const buttons = Array.from(
363+
document.querySelectorAll<HTMLButtonElement>('.glass-nav .nav-link[aria-haspopup], .lp-menu-btn'),
364+
);
252365
const closeAll = (except?: HTMLButtonElement) => {
253366
for (const b of buttons) if (b !== except) b.setAttribute('aria-expanded', 'false');
254367
};
@@ -260,7 +373,7 @@ const contributing: NavLink = {
260373
});
261374
}
262375
document.addEventListener('click', (e) => {
263-
if (!(e.target instanceof Element) || !e.target.closest('.glass-nav')) closeAll();
376+
if (!(e.target instanceof Element) || !e.target.closest('.glass-nav, .lp-menu')) closeAll();
264377
});
265378
document.addEventListener('keydown', (e) => {
266379
if (e.key === 'Escape') closeAll();

docs-site/src/components/Landing.astro

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
// media band, quickstart terminal, bento feature slab, docs link row.
55
// Styling lives in src/styles/custom.css under the `.lp` namespace.
66
import { Image } from 'astro:assets';
7+
import {
8+
siAnthropic,
9+
siDeepseek,
10+
siGoogle,
11+
siMoonshotai,
12+
siOllama,
13+
siOpenrouter,
14+
} from 'simple-icons';
715
import demo from '../assets/demo.gif';
816
import dashboard from '../assets/dashboard.png';
917
import picker from '../assets/codex-app-picker.png';
@@ -35,9 +43,19 @@ const icons: Record<string, string> = {
3543
folder: 'M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z',
3644
};
3745
38-
const providers = [
39-
'Anthropic', 'Google', 'xAI', 'Kimi', 'Ollama Cloud', 'Groq',
40-
'OpenRouter', 'Azure', 'DeepSeek', 'GLM',
46+
// Official monochrome marks from simple-icons where the brand exists in the
47+
// library; brands missing from it stay text-only (no generic substitutes).
48+
const providers: { label: string; path?: string }[] = [
49+
{ label: 'Anthropic', path: siAnthropic.path },
50+
{ label: 'Google', path: siGoogle.path },
51+
{ label: 'xAI' },
52+
{ label: 'Kimi', path: siMoonshotai.path },
53+
{ label: 'Ollama Cloud', path: siOllama.path },
54+
{ label: 'Groq' },
55+
{ label: 'OpenRouter', path: siOpenrouter.path },
56+
{ label: 'Azure' },
57+
{ label: 'DeepSeek', path: siDeepseek.path },
58+
{ label: 'GLM' },
4159
];
4260
4361
const quickstart = [
@@ -117,8 +135,17 @@ const docsMap = [
117135
</a>
118136
<a class="lp-btn-ghost" href="https://github.com/lidge-jun/opencodex">GitHub</a>
119137
</div>
120-
<ul class="lp-chips" aria-label={t('Supported providers', '지원 프로바이더', '支持的 provider')}>
121-
{providers.map((p) => <li>{p}</li>)}
138+
<ul class="lp-chips" aria-label={t('Supported providers', '지원 프로바이더', '支持的 provider')}>
139+
{providers.map((p) => (
140+
<li>
141+
{p.path && (
142+
<svg class="lp-chip-mark" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
143+
<path d={p.path} />
144+
</svg>
145+
)}
146+
{p.label}
147+
</li>
148+
))}
122149
<li class="lp-chip-more"><a href={`${prefix}guides/providers/`}>{t('40+ providers', '프로바이더 40+', '40+ providers')}</a></li>
123150
</ul>
124151
</div>

0 commit comments

Comments
 (0)