Skip to content

Commit b9627b0

Browse files
Merge pull request #520 from open-element/dev
feat(www): implement the v4 view-source editorial design across the site
2 parents a933a56 + aeac3ef commit b9627b0

111 files changed

Lines changed: 1995 additions & 1391 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/ui/src/open-code-block.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ sheet.replaceSync(`
3939
padding: var(--size-5);
4040
background: var(--bg-code);
4141
border: var(--border-size-1) solid var(--code-border);
42-
border-radius: var(--radius-3);
42+
border-radius: var(--radius-2);
4343
overflow-x: auto;
4444
font-family: var(--font-mono);
4545
font-size: var(--font-size-0);
@@ -56,7 +56,7 @@ sheet.replaceSync(`
5656
padding: var(--size-5);
5757
background: var(--bg-code);
5858
border: var(--border-size-1) solid var(--code-border);
59-
border-radius: var(--radius-3);
59+
border-radius: var(--radius-2);
6060
overflow-x: auto;
6161
font-family: var(--font-mono);
6262
font-size: var(--font-size-0);

packages/ui/src/open-props-tokens.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
═══════════════════════════════════════════════ */
7272
--font-sans: 'JetBrains Mono', monospace;
7373
--font-mono: 'JetBrains Mono', monospace;
74+
--font-serif: 'Instrument Serif', serif;
7475
--font-size-00: 0.75rem;
7576
--font-size-0: 0.875rem;
7677
--font-size-1: 1rem;
@@ -172,7 +173,7 @@
172173
--ui-control-bg: color-mix(in srgb, var(--bg-elevated) 78%, transparent);
173174
--ui-control-border: color-mix(in srgb, var(--border) 72%, var(--brand));
174175
--ui-control-border-hover: color-mix(in srgb, var(--brand-light) 74%, var(--border));
175-
--ui-control-radius: var(--radius-round);
176+
--ui-control-radius: var(--radius-1);
176177
--ui-control-highlight: inset 0 1px 0 color-mix(in srgb, white 12%, transparent);
177178
--surface-glass: linear-gradient(145deg, color-mix(in srgb, var(--brand) 9%, var(--bg-card)), color-mix(in srgb, var(--bg-card) 90%, transparent));
178179
--surface-overlay: color-mix(in srgb, var(--bg-elevated) 92%, transparent);

packages/ui/src/open-props-tokens.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export const OPEN_PROPS_TOKEN_CSS = `/**
8585
═══════════════════════════════════════════════ */
8686
--font-sans: 'JetBrains Mono', monospace;
8787
--font-mono: 'JetBrains Mono', monospace;
88+
--font-serif: 'Instrument Serif', serif;
8889
--font-size-00: 0.75rem;
8990
--font-size-0: 0.875rem;
9091
--font-size-1: 1rem;
@@ -186,7 +187,7 @@ export const OPEN_PROPS_TOKEN_CSS = `/**
186187
--ui-control-bg: color-mix(in srgb, var(--bg-elevated) 78%, transparent);
187188
--ui-control-border: color-mix(in srgb, var(--border) 72%, var(--brand));
188189
--ui-control-border-hover: color-mix(in srgb, var(--brand-light) 74%, var(--border));
189-
--ui-control-radius: var(--radius-round);
190+
--ui-control-radius: var(--radius-1);
190191
--ui-control-highlight: inset 0 1px 0 color-mix(in srgb, white 12%, transparent);
191192
--surface-glass: linear-gradient(145deg, color-mix(in srgb, var(--brand) 9%, var(--bg-card)), color-mix(in srgb, var(--bg-card) 90%, transparent));
192193
--surface-overlay: color-mix(in srgb, var(--bg-elevated) 92%, transparent);

tools/check-www-current-truth.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,10 @@ await checkFile('www/vite.config.ts');
119119

120120
if (Deno.args.includes('--artifacts')) {
121121
for await (const file of walk('www/dist', { skip: ['blog'] })) {
122-
// The root-level history indexes are emitted as blog.html/changelog.html;
123-
// their historical copy is intentionally outside the current-surface rule.
124-
if (/(?:^|\/)(?:blog|changelog)\.html$/.test(file)) continue;
122+
// The root-level history indexes (blog.html, changelog.html or their
123+
// /blog//changelog route index.html) hold historical copy that is
124+
// intentionally outside the current-surface rule.
125+
if (/(?:^|\/)(?:blog|changelog)(?:\.html|\/index\.html)$/.test(file)) continue;
125126
if (/\.html$/.test(file)) await checkFile(file);
126127
}
127128
}

www/app/routes/404.tsx

Lines changed: 130 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,135 +1,180 @@
11
/**
2-
* 404 Not Found Page - with search, helpful links, and old URL redirects
2+
* 404 Not Found Page - v4 recovery scene: outlined giant code with one solid
3+
* digit, serif accent line, square actions, and a standards marquee.
34
*/
45
import { OpenElement } from '@openelement/element';
56
import { StyleSheet } from '@openelement/element';
67
import '@openelement/ui/open-button';
7-
import '@openelement/ui/open-input';
8-
import '@openelement/site-ui/open-brand-mark.tsx';
9-
import '@openelement/site-ui/open-page-hero.tsx';
10-
11-
const POPULAR_LINKS = [
12-
{ href: '/guide/getting-started', label: 'Getting Started' },
13-
{ href: '/guide/core-concepts', label: 'Core Concepts' },
14-
{ href: '/architecture/dsd', label: 'DSD Rendering' },
15-
{ href: '/apilist', label: 'API Reference' },
16-
{ href: '/architecture/architecture', label: 'Architecture' },
17-
{ href: '/architecture/comparison', label: 'Framework Comparison' },
18-
{ href: '/roadmap', label: 'Roadmap' },
19-
];
8+
9+
const marqueeText =
10+
'CUSTOM ELEMENTS ✳ SHADOW DOM ✳ DECLARATIVE SHADOW DOM ✳ ES MODULES ✳ SIGNALS ✳ HTML FIRST ✳ 404 ✳ ';
2011

2112
const styles = new StyleSheet();
2213
styles.replaceSync(`
2314
:host {
2415
display: block;
2516
color: var(--text-primary);
17+
background: var(--bg-base);
18+
}
19+
20+
* {
21+
box-sizing: border-box;
22+
}
23+
24+
h1,
25+
p {
26+
margin: 0;
2627
}
27-
.container {
28+
29+
.stage {
30+
position: relative;
31+
isolation: isolate;
2832
display: grid;
2933
justify-items: center;
30-
max-width: none;
31-
min-height: min(700px, calc(100svh - var(--nav-height)));
32-
margin: 0 auto;
33-
padding: var(--size-16) var(--size-6);
34+
align-content: center;
35+
gap: var(--size-5);
36+
min-height: calc(100svh - var(--nav-height) - var(--size-12));
37+
padding: clamp(3rem, 8vh, 6rem) var(--size-6);
3438
text-align: center;
3539
background:
36-
radial-gradient(circle at 50% 22%, color-mix(in srgb, var(--brand-pale) 46%, transparent), transparent 34%),
40+
radial-gradient(circle at 50% 42%, color-mix(in srgb, var(--violet-5) 18%, transparent), transparent 55%),
3741
var(--bg-base);
3842
}
39-
.title {
40-
font-size: calc(var(--font-size-8) * 1.35);
41-
font-weight: var(--font-weight-9);
42-
color: var(--text-primary);
43-
letter-spacing: 0;
44-
margin: 0;
45-
line-height: 1;
43+
44+
.stage::before {
45+
content: "";
46+
position: absolute;
47+
inset: 0;
48+
z-index: -1;
49+
background-image:
50+
linear-gradient(color-mix(in srgb, var(--violet-6) 7%, transparent) 1px, transparent 1px),
51+
linear-gradient(90deg, color-mix(in srgb, var(--violet-6) 7%, transparent) 1px, transparent 1px);
52+
background-size: 72px 72px;
53+
mask-image: radial-gradient(circle at 50% 45%, black, transparent 75%);
4654
}
47-
.mark { width:clamp(5rem,12vw,9rem); margin-bottom:var(--size-6); filter:drop-shadow(0 0 44px color-mix(in srgb,var(--brand) 42%,transparent)); }
48-
.subtitle {
49-
font-size: var(--font-size-4);
50-
font-weight: var(--font-weight-8);
51-
margin: var(--size-3) 0 0;
55+
56+
.code {
57+
display: flex;
58+
font-family: var(--font-mono);
59+
font-size: clamp(9rem, 26vw, 24rem);
60+
font-weight: 800;
61+
line-height: 0.9;
62+
letter-spacing: -0.06em;
63+
color: transparent;
64+
-webkit-text-stroke: 1.5px color-mix(in srgb, var(--violet-5) 55%, transparent);
65+
user-select: none;
66+
}
67+
68+
.code .solid {
5269
color: var(--text-primary);
70+
-webkit-text-stroke: 0;
5371
}
54-
.description {
55-
max-width: 520px;
56-
font-size: var(--font-size-1);
57-
color: var(--text-secondary);
58-
margin: var(--size-2) 0 var(--size-7);
59-
line-height: var(--font-lineheight-3);
72+
73+
.serif-line {
74+
font-family: var(--font-serif);
75+
font-style: italic;
76+
font-weight: 400;
77+
font-size: clamp(2rem, 5vw, 4rem);
78+
letter-spacing: -0.01em;
79+
color: var(--violet-8);
6080
}
61-
.search-wrapper {
62-
max-width: 400px;
63-
width: 100%;
64-
margin: 0 auto var(--size-8);
81+
82+
.lede {
83+
max-width: 34rem;
84+
color: var(--text-secondary);
85+
font-family: var(--font-mono);
86+
font-size: var(--font-size-0);
87+
line-height: 1.75;
6588
}
66-
.popular-label {
89+
90+
.requested {
91+
color: var(--text-muted);
6792
font-family: var(--font-mono);
6893
font-size: var(--font-size-00);
69-
font-weight: var(--font-weight-8);
70-
text-transform: uppercase;
71-
color: var(--brand);
72-
margin-bottom: var(--size-3);
73-
letter-spacing: 0;
7494
}
75-
.links-grid {
95+
96+
.requested code {
97+
padding: 0.125rem 0.375rem;
98+
border: 0.5px solid var(--border);
99+
border-radius: var(--radius-1);
100+
background: var(--bg-surface);
101+
color: var(--text-secondary);
102+
}
103+
104+
.actions {
76105
display: flex;
77106
flex-wrap: wrap;
78-
gap: var(--size-2);
79107
justify-content: center;
80-
margin-bottom: var(--size-8);
108+
gap: var(--size-3);
109+
margin-block-start: var(--size-3);
81110
}
82-
@media (max-width: 600px) {
83-
.container {
84-
padding: 80px 20px 64px;
85-
}
86-
.title {
87-
font-size: var(--font-size-7);
111+
112+
.marquee {
113+
overflow: hidden;
114+
white-space: nowrap;
115+
border-block: 1px solid var(--border);
116+
background: var(--surface-1);
117+
}
118+
119+
.marquee span {
120+
display: inline-block;
121+
padding: var(--size-3) 0;
122+
color: var(--brand);
123+
font-family: var(--font-mono);
124+
font-size: var(--font-size-0);
125+
font-weight: var(--font-weight-5);
126+
letter-spacing: 0.12em;
127+
animation: marquee 36s linear infinite;
128+
}
129+
130+
@keyframes marquee {
131+
to {
132+
transform: translateX(-50%);
88133
}
89-
.subtitle {
90-
font-size: var(--font-size-2);
134+
}
135+
136+
@media (prefers-reduced-motion: reduce) {
137+
.marquee span {
138+
animation: none;
91139
}
92140
}
93141
`);
94142

95143
export default class Page404 extends OpenElement {
96144
static override styles = [styles];
97145
override render() {
98-
const locale = this._getLocale('zh');
146+
const locale = this._getLocale('en');
99147
const homeHref = locale === 'en' ? '/' : '/zh/';
148+
const docsHref = locale === 'en' ? '/docs' : '/zh/docs';
100149
const requestedPath = typeof globalThis.location === 'undefined'
101150
? '/404'
102151
: globalThis.location.pathname;
103152
return (
104-
<main>
105-
<open-page-hero variant='error'>
106-
<span slot='eyebrow'>Recovery scene</span>
107-
<span slot='title'>404</span>
108-
<span slot='lede'>The requested route is not part of the current public map.</span>
109-
</open-page-hero>
110-
<div class='container'>
111-
<open-brand-mark class='mark' size='xl'></open-brand-mark>
112-
<p class='subtitle'>Page not found</p>
113-
<p class='description'>
114-
The page you are looking for doesn't exist or has been moved.
153+
<main class='notfound'>
154+
<section class='stage'>
155+
<h1 class='code' aria-label='404'>
156+
<span aria-hidden='true'>4</span>
157+
<span class='solid' aria-hidden='true'>0</span>
158+
<span aria-hidden='true'>4</span>
159+
</h1>
160+
<p class='serif-line'>Lost in the shadow DOM.</p>
161+
<p class='lede'>
162+
This route never mounted. The page you want is probably one declarative template away.
115163
</p>
116-
<p class='description'>
164+
<p class='requested'>
117165
Requested path: <code>{requestedPath}</code>
118166
</p>
119-
<div class='search-wrapper'>
120-
<open-input placeholder='Search docs and API'></open-input>
121-
</div>
122-
<p class='popular-label'>Popular pages</p>
123-
<div class='links-grid'>
124-
{POPULAR_LINKS.map((l) => (
125-
<open-button size='sm' href={l.href}>
126-
{l.label}
127-
</open-button>
128-
))}
167+
<div class='actions'>
168+
<open-button variant='primary' href={homeHref}>
169+
Back home
170+
</open-button>
171+
<open-button href={docsHref}>
172+
Read the docs
173+
</open-button>
129174
</div>
130-
<open-button variant='primary' href={homeHref}>
131-
Go home
132-
</open-button>
175+
</section>
176+
<div class='marquee' aria-hidden='true'>
177+
<span>{marqueeText + marqueeText}</span>
133178
</div>
134179
</main>
135180
);

0 commit comments

Comments
 (0)