Skip to content

Commit aa343d3

Browse files
thebuilderclaude
andcommitted
fix(docs): make landing panels theme-aware + tighten the headline
The code, instrument, install, HUD, and tile panels were fixed dark in both color modes, so in light mode they clashed with the page. Make every panel follow the theme: - Panel surfaces, text, hairlines, inset, and the focal highlight derive from the --color-* theme tokens (light surfaces in light mode, dark in dark). - Syntax highlighting moves from inline colors to `.rio-tok--*` classes with a light palette by default and a dark override under `:root[data-theme="dark"]`, so code stays readable in both modes. Also shorten the hero headline to "Know when an element meets the viewport." (H1 + the OG card) so it wraps tighter. Verified light and dark via computed styles + screenshots: light mode now shows light panels with dark, high-contrast syntax; dark mode is unchanged. biome clean, fallow exits 0, typecheck 0 errors, build OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent aed6bf7 commit aa343d3

5 files changed

Lines changed: 97 additions & 39 deletions

File tree

‎apps/docs/pages/_home/Landing.tsx‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ function Hero() {
6868
<header className="rio-section rio-hero" ref={ref}>
6969
<div className="rio-hero__grid">
7070
<div className="rio-hero__copy">
71-
<h1 className="rio-h1">
72-
Know the moment an element meets the viewport.
73-
</h1>
71+
<h1 className="rio-h1">Know when an element meets the viewport.</h1>
7472
<p className="rio-lead">
7573
A tiny, fully-typed React adapter for the Intersection Observer API.
7674
Reveal on scroll, lazy-load, track impressions, and build infinite

‎apps/docs/pages/_home/home.css‎

Lines changed: 89 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
/* ============================================================== */
22
/* Landing page — React Intersection Observer */
3-
/* Page chrome follows Blume's theme; code + instrument panels are */
4-
/* a deliberate dark instrument surface in both color modes. */
3+
/* Everything follows Blume's theme: chrome, panels, code, and */
4+
/* instrument all adapt to light and dark. Tokens derive from the */
5+
/* --color-* theme vars; the few that can't (code syntax, focal */
6+
/* highlight) get an explicit dark override below. */
57
/* ============================================================== */
68

79
.rio-home {
@@ -12,18 +14,51 @@
1214
--rio-line-2: color-mix(in srgb, var(--color-foreground) 22%, transparent);
1315
--rio-surface: color-mix(in srgb, var(--color-foreground) 3.5%, transparent);
1416
--rio-surface-2: color-mix(in srgb, var(--color-foreground) 7%, transparent);
15-
--rio-panel: #0d0d15;
16-
--rio-panel-2: #14141f;
17-
--rio-panel-fg: #ece9f8;
18-
--rio-panel-muted: #a6a3be;
19-
--rio-panel-line: color-mix(in srgb, #a78bfa 24%, transparent);
17+
18+
/* Panels: light surface in light mode, dark in dark, derived from theme. */
19+
--rio-panel: color-mix(
20+
in srgb,
21+
var(--color-foreground) 4%,
22+
var(--color-background)
23+
);
24+
--rio-panel-2: color-mix(
25+
in srgb,
26+
var(--color-foreground) 8%,
27+
var(--color-background)
28+
);
29+
--rio-panel-inset: color-mix(
30+
in srgb,
31+
var(--color-foreground) 7%,
32+
var(--color-background)
33+
);
34+
--rio-panel-fg: var(--color-foreground);
35+
--rio-panel-muted: var(--color-muted-foreground);
36+
--rio-panel-line: color-mix(in srgb, var(--rio-accent) 30%, transparent);
37+
--rio-panel-hair: color-mix(in srgb, var(--color-foreground) 9%, transparent);
38+
2039
--rio-violet: #a78bfa;
2140
--rio-emerald: #34d399;
2241
/* Dedicated button violet: darker/more saturated than the theme accent so
2342
white label text stays high-contrast in both light and dark modes. */
2443
--rio-btn: oklch(0.56 0.18 290);
2544
--rio-btn-hover: oklch(0.62 0.17 290);
26-
--rio-focal: linear-gradient(135deg, #241f47 0%, #16294a 100%);
45+
46+
/* Focal highlight (target chip, logged tiles) and its text. */
47+
--rio-focal: linear-gradient(
48+
135deg,
49+
color-mix(in srgb, #8b5cf6 16%, var(--color-background)),
50+
color-mix(in srgb, #22d3ee 13%, var(--color-background))
51+
);
52+
--rio-focal-fg: var(--color-foreground);
53+
54+
/* Code syntax palette (light-mode values; dark overridden below). */
55+
--rio-code-fg: #37324a;
56+
--rio-code-k: #7c3aed;
57+
--rio-code-f: #7c3aed;
58+
--rio-code-s: #0f7a4d;
59+
--rio-code-c: #86829a;
60+
--rio-code-p: #0b6bb3;
61+
2762
--rio-mono: var(
2863
--blume-font-mono,
2964
ui-monospace,
@@ -38,6 +73,18 @@
3873
overflow-x: clip;
3974
}
4075

76+
:root[data-theme="dark"] .rio-home {
77+
--rio-panel-line: color-mix(in srgb, #a78bfa 24%, transparent);
78+
--rio-focal: linear-gradient(135deg, #241f47 0%, #16294a 100%);
79+
--rio-focal-fg: #f4f2ff;
80+
--rio-code-fg: #d7d4e6;
81+
--rio-code-k: #c4b5fd;
82+
--rio-code-f: #a78bfa;
83+
--rio-code-s: #8ee7a6;
84+
--rio-code-c: #948fb0;
85+
--rio-code-p: #7cc7ff;
86+
}
87+
4188
.rio-home ::selection {
4289
background: color-mix(in srgb, var(--rio-accent) 32%, transparent);
4390
color: var(--rio-fg);
@@ -282,7 +329,7 @@
282329
align-items: center;
283330
gap: 0.5rem;
284331
padding: 0.7rem 0.7rem 0.7rem 0.9rem;
285-
border-top: 1px solid color-mix(in srgb, #ffffff 6%, transparent);
332+
border-top: 1px solid var(--rio-panel-hair);
286333
}
287334

288335
.rio-install__cmd {
@@ -313,7 +360,7 @@
313360
height: 2.1rem;
314361
flex: none;
315362
border-radius: 8px;
316-
border: 1px solid color-mix(in srgb, #ffffff 10%, transparent);
363+
border: 1px solid var(--rio-panel-hair);
317364
background: var(--rio-panel-2);
318365
color: var(--rio-panel-muted);
319366
cursor: pointer;
@@ -428,10 +475,8 @@
428475
position: relative;
429476
height: 8.5rem;
430477
border-radius: 12px;
431-
border: 1px solid color-mix(in srgb, #ffffff 8%, transparent);
432-
background:
433-
linear-gradient(color-mix(in srgb, #ffffff 3%, transparent), transparent),
434-
#0a0a11;
478+
border: 1px solid var(--rio-panel-hair);
479+
background: var(--rio-panel-inset);
435480
overflow: hidden;
436481
margin-bottom: 1rem;
437482
}
@@ -476,7 +521,7 @@
476521
top: -1.5rem;
477522
font-family: var(--rio-mono);
478523
font-size: 0.62rem;
479-
color: color-mix(in srgb, var(--rio-violet) 80%, white);
524+
color: color-mix(in srgb, var(--rio-accent) 72%, var(--rio-panel-fg));
480525
}
481526

482527
.rio-instrument__target {
@@ -493,7 +538,7 @@
493538
font-size: 0.78rem;
494539
border: 1px solid color-mix(in srgb, var(--rio-violet) 45%, transparent);
495540
background: var(--rio-focal);
496-
color: #f4f2ff;
541+
color: var(--rio-focal-fg);
497542
transition:
498543
box-shadow 0.3s ease,
499544
border-color 0.3s ease;
@@ -519,7 +564,7 @@
519564
gap: 0.5rem;
520565
font-family: var(--rio-mono);
521566
font-size: 0.76rem;
522-
border-bottom: 1px solid color-mix(in srgb, #ffffff 6%, transparent);
567+
border-bottom: 1px solid var(--rio-panel-hair);
523568
padding-bottom: 0.3rem;
524569
}
525570

@@ -541,14 +586,14 @@
541586
color: var(--rio-emerald);
542587
}
543588
.rio-readout dd[data-tone="off"] {
544-
color: color-mix(in srgb, var(--rio-panel-muted) 85%, white);
589+
color: var(--rio-panel-muted);
545590
}
546591

547592
.rio-instrument__bar,
548593
.rio-hud__bar {
549594
height: 5px;
550595
border-radius: 999px;
551-
background: color-mix(in srgb, #ffffff 8%, transparent);
596+
background: var(--rio-panel-hair);
552597
overflow: hidden;
553598
}
554599

@@ -774,7 +819,7 @@
774819
font-size: 0.72rem;
775820
color: var(--rio-panel-muted);
776821
padding: 0.55rem 0.9rem;
777-
border-bottom: 1px solid color-mix(in srgb, #ffffff 6%, transparent);
822+
border-bottom: 1px solid var(--rio-panel-hair);
778823
background: var(--rio-panel-2);
779824
}
780825

@@ -785,7 +830,7 @@
785830
font-family: var(--rio-mono);
786831
font-size: 0.82rem;
787832
line-height: 1.65;
788-
color: #d7d4e6;
833+
color: var(--rio-code-fg);
789834
tab-size: 2;
790835
}
791836

@@ -798,10 +843,30 @@
798843
height: 8px;
799844
}
800845
.rio-code__pre::-webkit-scrollbar-thumb {
801-
background: color-mix(in srgb, #ffffff 14%, transparent);
846+
background: color-mix(in srgb, var(--color-foreground) 22%, transparent);
802847
border-radius: 999px;
803848
}
804849

850+
/* Syntax token colors — theme-aware (values set on .rio-home + dark override). */
851+
.rio-tok--t {
852+
color: var(--rio-code-fg);
853+
}
854+
.rio-tok--k {
855+
color: var(--rio-code-k);
856+
}
857+
.rio-tok--f {
858+
color: var(--rio-code-f);
859+
}
860+
.rio-tok--s {
861+
color: var(--rio-code-s);
862+
}
863+
.rio-tok--c {
864+
color: var(--rio-code-c);
865+
}
866+
.rio-tok--p {
867+
color: var(--rio-code-p);
868+
}
869+
805870
/* ------------------------------------------------------------- */
806871
/* Impression strip */
807872
/* ------------------------------------------------------------- */
@@ -839,7 +904,7 @@
839904
.rio-tile[data-logged="true"] {
840905
border-color: color-mix(in srgb, var(--rio-emerald) 50%, transparent);
841906
background: var(--rio-focal);
842-
color: #f2f1ff;
907+
color: var(--rio-focal-fg);
843908
}
844909

845910
.rio-tile__id {
@@ -872,7 +937,7 @@
872937
}
873938

874939
.rio-tile[data-logged="true"] .rio-tile__index {
875-
color: color-mix(in srgb, #ffffff 45%, transparent);
940+
color: color-mix(in srgb, var(--rio-focal-fg) 55%, transparent);
876941
}
877942

878943
.rio-impr__panel {

‎apps/docs/pages/_home/primitives.tsx‎

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -318,20 +318,15 @@ export function Icon({
318318
}
319319

320320
/* ------------------------------------------------------------------ */
321-
/* Code rendering — minimal, deliberate token colors on the dark panel */
321+
/* Code rendering — token kinds map to theme-aware colors in home.css */
322+
/* (`.rio-tok--*`), so syntax stays readable in light and dark. */
322323
/* ------------------------------------------------------------------ */
323324

324-
const CODE_COLOR = {
325-
t: "#d7d4e6", // plain text
326-
k: "#c4b5fd", // keyword
327-
f: "#a78bfa", // function / hook
328-
s: "#8ee7a6", // string
329-
c: "#948fb0", // comment
330-
p: "#7cc7ff", // property / jsx attr
331-
} as const;
325+
// t: plain · k: keyword · f: function/hook · s: string · c: comment · p: prop
326+
type TokenKind = "t" | "k" | "f" | "s" | "c" | "p";
332327

333328
/** A single token: [kind, value]. */
334-
export type Tk = [kind: keyof typeof CODE_COLOR, value: string];
329+
export type Tk = [kind: TokenKind, value: string];
335330

336331
/** One line of code is a list of tokens. Convenience token builders: */
337332
export const c = {
@@ -365,9 +360,9 @@ export function Code({
365360
{line.length === 0 ? "​" : null}
366361
{line.map((token, j) => (
367362
<span
363+
className={`rio-tok rio-tok--${token[0]}`}
368364
// biome-ignore lint/suspicious/noArrayIndexKey: static tokens
369365
key={j}
370-
style={{ color: CODE_COLOR[token[0]] }}
371366
>
372367
{token[1]}
373368
</span>

‎apps/docs/public/og-home.png‎

-1.05 KB
Loading

‎apps/docs/scripts/generate-og.mjs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ async function main() {
158158
style: { display: "flex", flexDirection: "column", maxWidth: 560 },
159159
children: [
160160
brand,
161-
text("Know the moment an element meets the viewport.", {
161+
text("Know when an element meets the viewport.", {
162162
color: FG,
163163
fontFamily: f.display,
164164
fontSize: 58,

0 commit comments

Comments
 (0)