Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8e1d4bb
[refactor] Sweep raw h1-h4 tags to H1-H4 typography components
joshestein Jul 17, 2026
2578c07
[refactor] Snap arbitrary leading/tracking values to design tokens
joshestein Jul 17, 2026
d421d70
[chore] Add PR screenshots
joshestein Jul 17, 2026
28b33da
[chore] Remove PR screenshots after embedding (SHA-pinned URLs persist)
joshestein Jul 17, 2026
c2a0303
[fix] Keep Inter (font-sans) on downsized H1/H2 usages
joshestein Jul 17, 2026
aa219a0
Revert "[fix] Keep Inter (font-sans) on downsized H1/H2 usages"
joshestein Jul 17, 2026
29cc018
Merge remote-tracking branch 'origin/master' into josh/2753-sweep-raw…
joshestein Jul 21, 2026
067edb7
[refactor] Trim overrides now redundant with typography defaults
joshestein Jul 21, 2026
e509385
[refactor] Replace modal section-label H1s with paragraph labels
joshestein Jul 21, 2026
1c47d4a
[style] Unify all heroes on the display size ramp (40-72px)
joshestein Jul 21, 2026
28d63a8
[chore] Add hero ramp PR screenshots
joshestein Jul 21, 2026
750849c
[chore] Remove PR screenshots after embedding (SHA-pinned URLs persist)
joshestein Jul 21, 2026
4b7534d
[style] Keep homepage section headings on the H2 size ramp
joshestein Jul 21, 2026
b1a470a
[style] Replace token-duplicate arbitrary font sizes with size tokens
joshestein Jul 21, 2026
be58183
[fix] Pin deliberately fixed px sizes back off the responsive token ramp
joshestein Jul 21, 2026
5f048d4
Remove leftover blank
joshestein Jul 21, 2026
2cb26ec
[refactor] Consolidate hand-rolled eyebrow labels into <Eyebrow>
joshestein Jul 21, 2026
43cc9b3
[chore] Add eyebrow PR screenshots
joshestein Jul 21, 2026
fd5e470
[chore] Remove PR screenshots after embedding (SHA-pinned URLs persist)
joshestein Jul 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/availability/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { A } from '@bluedot/ui';
import { A, H1 } from '@bluedot/ui';
import Head from 'next/head';

const Home: React.FC = () => {
Expand All @@ -9,7 +9,7 @@ const Home: React.FC = () => {
<link rel="icon" href="/favicon.ico" />
</Head>
<main className="my-24 max-w-lg mx-auto">
<h1 className="text-3xl font-bold my-2">Time availability form</h1>
<H1 className="my-2">Time availability form</H1>
<p>This application collects people's availability, primarily for <A href="https://bluedot.org/">BlueDot Impact</A> related scheduling purposes.</p>
</main>
</>
Expand Down
4 changes: 2 additions & 2 deletions apps/room/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect } from 'react';
import { useRouter } from 'next/router';
import {
ClickTarget, ErrorSection, H1, withAuth,
ClickTarget, ErrorSection, H1, H2, withAuth,
} from '@bluedot/ui';
import useAxios from 'axios-hooks';
import { type Room } from '../lib/types';
Expand Down Expand Up @@ -65,7 +65,7 @@ const DashboardPage = withAuth(({ auth }) => {
{rooms.map((room) => (
<ClickTarget key={room.id} onClick={() => router.push(`/${room.id}`)} className="container-lined cursor-pointer hover:bg-cream-dark focus:bg-cream-dark p-6 transition-all">
<div className="flex items-center justify-between">
<h2 className="text-size-lg font-semibold">{room.name}</h2>
<H2 className="text-size-lg">{room.name}</H2>
<RoomHealthIndicator status={room.status} />
</div>
</ClickTarget>
Expand Down
3 changes: 2 additions & 1 deletion apps/speed-review/src/components/ApplicationCard.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { H1 } from '@bluedot/ui';
import { type Application } from '../lib/client/types';
import { SummaryCard } from './SummaryCard';
import { PreviousApplicationsCard } from './PreviousApplicationsCard';
Expand Down Expand Up @@ -40,7 +41,7 @@ export const ApplicationCard: React.FC<ApplicationCardProps> = ({ application, p
<div className="space-y-4">
<div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-2 sm:gap-4">
<div>
<h1 className="text-2xl font-bold text-stone-100">{name}</h1>
<H1 className="text-size-lg text-stone-100">{name}</H1>
{subtitle && (
<p className="text-size-sm text-stone-400 mt-0.5">{subtitle}</p>
)}
Expand Down
4 changes: 2 additions & 2 deletions apps/speed-review/src/components/RoundPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
import useAxios from 'axios-hooks';
import { CTALinkOrButton, ProgressDots } from '@bluedot/ui';
import { CTALinkOrButton, H1, ProgressDots } from '@bluedot/ui';
import { type Round } from '../lib/api/airtable';
import { type Direction } from '../lib/client/types';

Expand Down Expand Up @@ -86,7 +86,7 @@ export const RoundPicker: React.FC<RoundPickerProps> = ({ onSelect }) => {
<div className="min-h-screen bg-stone-950 flex items-center justify-center p-4 sm:p-8">
<div className="bg-stone-900 rounded-xl border border-stone-700 p-4 sm:p-8 max-w-md w-full space-y-6">
<div>
<h1 className="text-2xl font-bold text-stone-100">Speed Review</h1>
<H1 className="text-size-lg text-stone-100">Speed Review</H1>
<p className="text-size-sm text-stone-400 mt-1">Select a round to review</p>
</div>

Expand Down
13 changes: 7 additions & 6 deletions apps/speed-review/src/components/SessionComplete.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react';
import Confetti from 'react-confetti';
import { H1, H2 } from '@bluedot/ui';
import {
type RatingValue, type RatedApplication, toHumanOpinion, toDecision,
} from '../lib/client/types';
Expand Down Expand Up @@ -192,12 +193,12 @@ export const SessionComplete: React.FC<SessionCompleteProps> = ({
/>
)}
<div>
<h1 className="text-2xl font-bold text-stone-100">{(() => {
<H1 className="text-size-lg text-stone-100">{(() => {
if (roundComplete) return 'You\'ve evaluated all the applications for the round!';
if (rated.length === 0) return 'No scored applications available';
return 'Session complete';
})()}
</h1>
</H1>
<p className="text-size-sm text-stone-400 mt-1">{round}</p>
{!roundComplete && rated.length === 0 && (
<p className="text-size-sm text-stone-400 mt-2">
Expand Down Expand Up @@ -254,17 +255,17 @@ export const SessionComplete: React.FC<SessionCompleteProps> = ({

<div className="grid md:grid-cols-2 gap-6">
<div className="min-w-0">
<h2 className="text-size-sm font-semibold uppercase tracking-wide text-green-400 mb-3">
<H2 className="text-size-sm uppercase tracking-wide text-green-400 mb-3">
Accept ({accepted.length})
</h2>
</H2>
<div className="space-y-2">
{accepted.map((r) => renderRow(r, 'green'))}
</div>
</div>
<div className="min-w-0">
<h2 className="text-size-sm font-semibold uppercase tracking-wide text-red-400 mb-3">
<H2 className="text-size-sm uppercase tracking-wide text-red-400 mb-3">
Reject ({rejected.length})
</h2>
</H2>
<div className="space-y-2">
{rejected.map((r) => renderRow(r, 'red'))}
</div>
Expand Down
4 changes: 2 additions & 2 deletions apps/speed-review/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
useCallback, useEffect, useReducer, useRef, useState,
} from 'react';
import useAxios from 'axios-hooks';
import { ProgressDots, withAuth } from '@bluedot/ui';
import { H1, ProgressDots, withAuth } from '@bluedot/ui';
import {
type Application, type RatedApplication, type RatingValue, type Direction, toHumanOpinion, toDecision,
} from '../lib/client/types';
Expand Down Expand Up @@ -462,7 +462,7 @@ const SpeedReviewPage = (_props: { auth: unknown; setAuth: unknown }) => {
return (
<div className="min-h-screen bg-stone-950 flex items-center justify-center p-8">
<div className="bg-stone-900 rounded-xl border border-red-800 p-4 sm:p-8 max-w-md w-full space-y-4">
<h1 className="text-size-xl font-bold text-red-400">Save failed</h1>
<H1 className="text-size-xl text-red-400">Save failed</H1>
<p className="text-size-sm text-stone-300">
Your last rating didn&apos;t save to Airtable. Continuing would mean your reviews are lost.
</p>
Expand Down
11 changes: 7 additions & 4 deletions apps/website/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,15 @@ Import: `import { H1, H2, H3, H4, P, A } from '@bluedot/ui';`

| Component | Size | Weight | Use for |
|---|---|---|---|
| `H1`, `H2` | 32-48px | bold | Page/section titles (auto-applies Inter Display) |
| `H3` | 24px | 650 | Subsections |
| `H4` | 18px | 650 | Labels |
| `P` | 16px | normal | Body text |
| `H1` | 40-56px (`text-size-2xl`) | semibold | Page titles (auto-applies Inter Display) |
| `H2` | 32-48px (`text-size-xl`) | semibold | Section titles (auto-applies Inter Display) |
| `H3` | 24px (`text-size-lg`) | semibold | Subsections |
| `H4` | 18px (`text-size-md`) | semibold | Card titles / labels |
| `P` | 16px (`text-size-sm`) | normal | Body text (`leading-relaxed` baked in) |
| `A` | — | — | Links with proper styling |

Prefer bare components — the defaults are the design system. Override only for a genuine semantic reason (on-dark color, smaller card-title size role); don't re-add weight/leading/tracking the default already sets. Marketing heroes use `HeroH1` from `@bluedot/ui`. Leading tokens: `tight` 1.1 / `snug` 1.25 / `normal` 1.4 / `relaxed` 1.6. Tracking tokens: `tighter` -0.02em / `tight` -0.01em / `normal` 0 / `wide` 0.04em — use these, never arbitrary `leading-[...]`/`tracking-[...]` values.

### Custom text size tokens

Use these instead of Tailwind's default text sizes:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ exports[`Error404Page > should render correctly 1`] = `
</div>
</div>
<h2
class="bluedot-h2 text-cream-normal text-2xl font-normal text-center mt-4 leading-snug tracking-normal"
class="bluedot-h2 not-prose text-cream-normal text-size-lg font-normal text-center mt-4 tracking-normal"
>
Sorry, this page does not exist.
</h2>
Expand Down
24 changes: 12 additions & 12 deletions apps/website/src/__tests__/pages/__snapshots__/about.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ exports[`AboutPage > should render correctly 1`] = `
class="flex flex-col gap-6 max-w-[780px]"
>
<h1
class="bluedot-h1 text-white text-size-xl leading-tight font-normal tracking-tighter text-left"
class="bluedot-h1 text-white text-size-2xl lg:text-size-3xl xl:text-size-4xl leading-tight font-normal tracking-tighter text-left"
>
About us
</h1>
Expand Down Expand Up @@ -609,7 +609,7 @@ exports[`AboutPage > should render correctly 1`] = `
class="intro-section section section-body"
>
<h3
class="bluedot-section-heading mb-6"
class="bluedot-h3 not-prose mb-6"
>
Who we are
</h3>
Expand Down Expand Up @@ -642,7 +642,7 @@ exports[`AboutPage > should render correctly 1`] = `
class="beliefs-section section section-body"
>
<h3
class="bluedot-section-heading mb-6"
class="bluedot-h3 not-prose mb-6"
>
Core beliefs
</h3>
Expand All @@ -651,7 +651,7 @@ exports[`AboutPage > should render correctly 1`] = `
>
<div>
<h4
class="bluedot-h4 mb-2"
class="bluedot-h4 not-prose mb-2"
>
AGI could arrive soon, and society is dangerously unprepared
</h4>
Expand All @@ -663,7 +663,7 @@ exports[`AboutPage > should render correctly 1`] = `
</div>
<div>
<h4
class="bluedot-h4 mb-2"
class="bluedot-h4 not-prose mb-2"
>
People at key moments rewrite history
</h4>
Expand All @@ -675,7 +675,7 @@ exports[`AboutPage > should render correctly 1`] = `
</div>
<div>
<h4
class="bluedot-h4 mb-2"
class="bluedot-h4 not-prose mb-2"
>
We need urgency and wisdom
</h4>
Expand All @@ -691,7 +691,7 @@ exports[`AboutPage > should render correctly 1`] = `
class="values-section section section-body"
>
<h3
class="bluedot-section-heading mb-6"
class="bluedot-h3 not-prose mb-6"
>
Values
</h3>
Expand All @@ -700,7 +700,7 @@ exports[`AboutPage > should render correctly 1`] = `
>
<div>
<h4
class="bluedot-h4 mb-2"
class="bluedot-h4 not-prose mb-2"
>
Own the mission
</h4>
Expand All @@ -712,7 +712,7 @@ exports[`AboutPage > should render correctly 1`] = `
</div>
<div>
<h4
class="bluedot-h4 mb-2"
class="bluedot-h4 not-prose mb-2"
>
Think hard and move fast
</h4>
Expand All @@ -724,7 +724,7 @@ exports[`AboutPage > should render correctly 1`] = `
</div>
<div>
<h4
class="bluedot-h4 mb-2"
class="bluedot-h4 not-prose mb-2"
>
Say the uncomfortable truth
</h4>
Expand All @@ -740,7 +740,7 @@ exports[`AboutPage > should render correctly 1`] = `
class="history-section section section-body"
>
<h3
class="bluedot-section-heading mb-6"
class="bluedot-h3 not-prose mb-6"
>
Our history
</h3>
Expand Down Expand Up @@ -878,7 +878,7 @@ exports[`AboutPage > should render correctly 1`] = `
class="team-section section section-body !border-b-0"
>
<h3
class="bluedot-section-heading mb-6"
class="bluedot-h3 not-prose mb-6"
>
Our team
</h3>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ exports[`AccountSettingsPage > should render account settings page correctly 1`]
class="hidden w-[200px] shrink-0 lg:block"
>
<p
class="mb-4 text-size-xxs font-semibold uppercase tracking-wide text-bluedot-normal"
class="text-size-xxs font-medium uppercase tracking-wide text-bluedot-normal mb-4"
id="my-bluedot-nav-label"
>
My BlueDot
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ exports[`JoinUsPage > should render correctly 1`] = `
class="flex flex-col gap-6 max-w-[780px]"
>
<h1
class="bluedot-h1 text-white text-size-xl leading-tight font-normal tracking-tighter text-left"
class="bluedot-h1 text-white text-size-2xl lg:text-size-3xl xl:text-size-4xl leading-tight font-normal tracking-tighter text-left"
>
Work with us
</h1>
Expand Down Expand Up @@ -609,7 +609,7 @@ exports[`JoinUsPage > should render correctly 1`] = `
class="section section-body"
>
<h3
class="bluedot-section-heading mb-6"
class="bluedot-h3 not-prose mb-6"
>
Why us
</h3>
Expand All @@ -636,7 +636,7 @@ exports[`JoinUsPage > should render correctly 1`] = `
id="open-roles-anchor"
/>
<h3
class="bluedot-section-heading mb-6"
class="bluedot-h3 not-prose mb-6"
>
Open roles
</h3>
Expand Down Expand Up @@ -674,13 +674,13 @@ exports[`JoinUsPage > should render correctly 1`] = `
<div
class="flex flex-col gap-4 w-full"
>
<span
class="text-size-xxs leading-[14px] tracking-[0.5px] uppercase text-white opacity-70 font-medium"
<p
class="text-size-xxs font-medium uppercase tracking-wide text-white opacity-70"
>
Newsletter
</span>
</p>
<h3
class="text-2xl leading-tight text-white max-w-narrow"
class="bluedot-h3 not-prose text-white max-w-narrow"
>
Subscribe to get AI safety news and course updates delivered directly to your inbox
</h3>
Expand All @@ -698,7 +698,7 @@ exports[`JoinUsPage > should render correctly 1`] = `
Email address
</label>
<input
class="w-full h-11 px-4 bg-white rounded-md text-size-sm leading-[18.2px] tracking-[0.42px] text-bluedot-navy placeholder:text-bluedot-navy/60 border border-[rgba(0,0,0,0.1)] focus:outline-none focus:border-transparent focus:border-[3px] transition-all"
class="w-full h-11 px-4 bg-white rounded-md text-size-sm leading-tight tracking-wide text-bluedot-navy placeholder:text-bluedot-navy/60 border border-[rgba(0,0,0,0.1)] focus:outline-none focus:border-transparent focus:border-[3px] transition-all"
id="newsletter-email"
placeholder="Email"
required=""
Expand All @@ -707,7 +707,7 @@ exports[`JoinUsPage > should render correctly 1`] = `
value=""
/>
<button
class="w-full lg:w-auto h-11 px-[17px] flex items-center justify-center rounded-md text-size-sm leading-[18.2px] tracking-[0.42px] text-white bg-white/15 border border-white/15 backdrop-blur-[2px] hover:bg-white/20 hover:border-white/20 disabled:hover:bg-white/15 disabled:hover:border-white/15 transition-all cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
class="w-full lg:w-auto h-11 px-[17px] flex items-center justify-center rounded-md text-size-sm leading-tight tracking-wide text-white bg-white/15 border border-white/15 backdrop-blur-[2px] hover:bg-white/20 hover:border-white/20 disabled:hover:bg-white/15 disabled:hover:border-white/15 transition-all cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
type="submit"
>
Subscribe
Expand Down
10 changes: 4 additions & 6 deletions apps/website/src/components/PageListRow.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type React from 'react';
import clsx from 'clsx';
import Link from 'next/link';
import { CTALinkOrButton } from '@bluedot/ui';
import { CTALinkOrButton, H3 } from '@bluedot/ui';

export type PageListRowProps = {
href?: string;
Expand Down Expand Up @@ -30,9 +30,7 @@ const accentBarClassName = clsx(

const arrowCtaClassName = 'ml-5 flex shrink-0 items-center text-size-sm leading-relaxed font-medium text-bluedot-normal bd-md:ml-6 bd-md:whitespace-nowrap';

export const pageSectionHeadingClass = 'bluedot-section-heading';

const titleClassName = 'text-size-sm leading-[1.45] font-semibold text-bluedot-navy';
const titleClassName = 'text-size-sm leading-normal font-semibold text-bluedot-navy';
const summaryClassName = 'mt-1 text-size-sm leading-relaxed text-bluedot-navy/62';
const metaClassName = 'mt-1 text-size-sm leading-relaxed text-bluedot-navy/50';

Expand Down Expand Up @@ -162,9 +160,9 @@ export const PageListGroup: React.FC<PageListGroupProps> = ({ label, children, c
return (
<div className={clsx('flex flex-col gap-6', className)}>
{label && (
<h3 className={pageSectionHeadingClass}>
<H3>
{label}
</h3>
</H3>
)}

<ul className="list-none flex flex-col divide-y divide-bluedot-navy/10">
Expand Down
7 changes: 3 additions & 4 deletions apps/website/src/components/about/BeliefsSection.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { P } from '@bluedot/ui';
import { pageSectionHeadingClass } from '../PageListRow';
import { H3, H4, P } from '@bluedot/ui';

const beliefs = [
{
Expand All @@ -19,11 +18,11 @@ const beliefs = [
const BeliefsSection = () => {
return (
<section className="beliefs-section section section-body">
<h3 className={`${pageSectionHeadingClass} mb-6`}>Core beliefs</h3>
<H3 className="mb-6">Core beliefs</H3>
<div className="flex flex-col gap-6">
{beliefs.map((belief) => (
<div key={belief.title}>
<h4 className="bluedot-h4 mb-2">{belief.title}</h4>
<H4 className="mb-2">{belief.title}</H4>
<P>{belief.description}</P>
</div>
))}
Expand Down
Loading