Tier 2 refactor: theming, CI, responsive typography#66
Merged
felipebalbi merged 16 commits intoMay 15, 2026
Conversation
wasm-bindgen and web-sys are already declared as runtime dependencies, and wasm-bindgen-test is unused (no #[wasm_bindgen_test] in the tree). Removing the duplicates keeps a single source of truth for the WASM bindings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three typography classes were referenced from .rs sources but never defined in style/tailwind.css, so they silently fell back to no styling: - announce_banner.rs used .p3 -> replaced with the defined .p body class. - documentation_training.rs used .link_large_mobile (mobile twin of .link_large) -> replaced with the defined .link_mobile. - project_introduction.rs used .p3_mobile -> replaced with the defined .p2_mobile, matching the desktop .p1 it was paired with. No new classes are introduced; this only swaps in existing definitions so the affected text actually picks up the intended typography on mobile. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a header comment in style/tailwind.css describing the naming
convention (.hN / .hN_mobile, .pN, .link*, .background_*) and inline
comments above each class explaining its role and any known issues:
- .h2_mobile (50px) is larger than .h2 (30px) — the pair is likely
swapped.
- .p_mobile (10px) is below the legibility floor on phones.
- .p1 / .p1_mobile and .h3 / .h3_mobile are identical (no mobile
shrink today).
- .p_mono, .mono, .link_large, .icon, .odp-btn-text, and
.odp-header-btn-text have no mobile twin.
Also groups classes into logical sections (Surfaces, Headings, Body,
Links, Misc) with separator comments. No font-size, padding, or color
values are changed — this is a documentation-only commit so a sibling
follow-up can adjust the bogus sizes with reviewable, isolated diffs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mobile font sizes should never grow past their desktop counterparts, and no body text should fall below the practical legibility floor on phones. Three of the .hN_mobile/.pN_mobile classes violated one of those rules and one was identical to its desktop sibling, defeating the purpose of the responsive split. Changes (mobile-only; desktop sizes are untouched): .h2_mobile : 50px -> 28px (was LARGER than desktop 30px) .h3_mobile : 25px -> 20px (was identical to desktop) .p_mobile : 10px -> 16px (was unreadable; below ~12px floor) .p1_mobile : 30px -> 22px (was identical to desktop) Also drop the matching BUG/NOTE markers from the doc comments added in the previous commit, since the issues are now resolved, and trim the "known issues" header block to only the still-outstanding item (several classes lack a mobile twin entirely). Visual impact: phone-width viewports will see smaller, properly proportioned section headings and paragraphs. Desktop and tablet (>=768px) layouts are unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The same five-entry vector of DocLinks (Why ODP?, Getting Started, Tutorials, Specifications, Contributing) was duplicated byte-for-byte in five page files (home, boot_firmware, embedded_controller, projects, unified_ec_services). Editing it required touching every page and was an obvious source of drift. Promote the vector to `pub const DEFAULT_DOC_LINKS: &[DocLink]` in components/documentation_training.rs and make the `links` prop on `DocumentationTraining` default to that constant (instead of the empty `vec![]` it defaulted to before, which would have rendered an empty <ul> if any caller forgot the prop). Pages now render `<DocumentationTraining />` with no prop. The `DocLink` symbol is no longer needed in the page imports and is dropped from each `use` line. No visual change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Every page-level SVG icon was rendered with the same hand-written
boilerplate:
<picture>
<source srcset="/images/dark/X.svg"
media="(prefers-color-scheme: dark)" />
<img src="/images/light/X.svg" alt="..." class="..." style="..." />
</picture>
Seventeen copies of that block were spread across header, footer,
landing_page, main, documentation_training, community_teams, and the
three team_* pages.
Introduce components/themed_icon.rs which exposes:
<ThemedIcon name="X" alt="..." class="..." style="..." />
The component derives the dark and light asset paths from a single
`name` prop and forwards `class` / `style` to the underlying `<img>`,
so callers keep the exact sizing they had before. Every existing
call site is converted; a final grep confirms the only remaining
reference to `prefers-color-scheme` is in themed_icon.rs itself.
No visual change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Strip inline `style="display: block; text-align: left;"` (and the `word-break: break-word`, `overflow-wrap: break-word`, `margin: 0`, `padding: 0` variants) from elements that paired them with a `class="..."` attribute. Each property is replaced by its Tailwind equivalent (`block`, `text-left`, `break-words`, `m-0`, `p-0`) appended to the existing class list, deduplicated against utilities that were already present. Inline `style` attributes that carry properties Tailwind does not trivially express (e.g. `color: white;`, `padding-top: 80px;`, `max-width: 100%;`) are left untouched. No visual changes expected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add `components::page_layout::PageLayout` that wraps every standard page in: * an `ErrorBoundary` with the existing generic fallback, * the outer `w-full min-h-screen` container, * the site `<Header/>`, * the page `children`, * the site `<Footer/>`. Pages that previously used `style=overflow-x: auto;` opt in via `scrollable_x=true`; the default is `overflow-x-hidden`, matching what every other page already had. Migrated 10 pages: home, community, getting_started, projects, boot_firmware, embedded_controller, unified_ec_services, team_ec, team_patina, team_ec_services. Each loses ~20 lines of boilerplate. The announcements page keeps its bespoke shell because it customizes the Header background and renders content between the header and footer that does not fit the simple slot model. The not_found page intentionally has no chrome. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move the nine brand hex codes out of the @apply chains in `style/tailwind.css` and into `theme.extend.colors` in `tailwind.config.js` as semantic tokens: surface.primary / primary-dark (#FFFFFF / #171717) surface.secondary / secondary-dark (#F1F1F1 / #3B3B3B) surface.tertiary / tertiary-dark (#E2E2E2 / #595959) surface.quaternary / quaternary-dark (#CACACA / #797979) surface.announcement / announcement-dark (#FEEED6 / #FEEED6) The `.background_*`, `.header_background`, and the `.background_quaternary .odp-header-btn` overrides now read `bg-surface-N dark:bg-surface-N-dark` instead of literal `bg-[#FFFFFF] dark:bg-[#171717]` chains. Custom utility class names are unchanged so no call site needs to be touched. Tailwind compiles to identical output -- the @apply expansion produces the same hex codes. No visual change expected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds `.github/workflows/ci.yaml` with three jobs that run on every
pull request to `main` (and on direct pushes to `main`):
* line-endings -- installs `dos2unix` and runs `dos2unix -ic`
over every file tracked by git. `-ic` is the canonical "info /
converted" check: it prints the names of files that contain CR
characters, so a non-empty result fails the job.
* formatting -- installs `leptosfmt` 0.1.33 (cached across runs)
and runs `leptosfmt --check src` to verify all Leptos `view!`
blocks are formatted consistently.
* build -- installs nightly Rust + the `wasm32-unknown-unknown`
target, downloads Trunk 0.21.14 (matching the Cloudflare deploy
workflow), and runs `trunk build --release` so we know the site
actually compiles before merging.
Concurrency is keyed per-ref so superseded PR pushes cancel the
in-flight run. The deploy workflow on `main` is unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Page rhythm in this site is built on five recurring spacing values: 32, 40, 60, 80, and 120 px. Tailwind's default 4-px scale already covers three of them (8 = 32, 10 = 40, 20 = 80), but the 60 and 120 px steps were spelled as `[60px]` / `[120px]` arbitrary-value escapes at every call site -- ~30 instances across the landing page, headers, footers, team pages, partners and projects components. Add two extension keys to `theme.extend.spacing` in `tailwind.config.js`: '15': '60px' -> used as `gap-15`, `mb-15`, `md:py-15` etc. '30': '120px' -> used as `md:px-30`, `py-30`, `pb-30` etc. Naming follows Tailwind's "1 unit = 4 px" mental model so the new classes look native. All call sites swap their arbitrary brackets for the tokens; defaults (8/10/20) replace `[32px]` / `[40px]` / `[80px]` straight up. While here, fix three style attributes that t02 missed and that mixed spacing with other declarations is now unnecessary -- they were pure padding/margin, so they collapse into `py-20`, `py-30`, `pb-30`, and `mb-20`. Also fix `md:[120px]` (a no-op class missing the `px-` prefix) on the community-teams `<section>` -- it now correctly applies the page-x token like its siblings. Compiled output is unchanged: `15` and `30` resolve to 60 px / 120 px exactly as the bracket escapes did. No visual change expected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…eparators
Two cleanups on top of t10:
1. Replace the custom `spacing.15 = 60px` and `spacing.30 = 120px`
tokens with the nearest Tailwind defaults: `16` (64 px) and `32`
(128 px). The custom extension is removed from
`tailwind.config.js` entirely. This trades 4 px of vertical /
horizontal breathing room per occurrence for staying inside the
stock 4-px scale -- no theme bookkeeping, full IDE autocomplete,
and the spacing rhythm still doubles cleanly (32 = 2 * 16).
2. Drop the `{}` empty-block separators that the leptosfmt cleanup in
Tier 1 left behind in `view!` macros. They evaluate to `()`,
which Leptos renders as nothing, but they make the views noisier
to read. Removed across all components / pages touched in t10.
Verified that no real `format!("...{}...", arg)` placeholders
were swept up by the regex (those live inside string literals).
No visual change beyond the ~4 px snap noted above.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the static `.h1` (100 px desktop) + `.h1_mobile` (60 px
mobile) pair with a single fluid `.h1` rule:
font-size: clamp(2.25rem, 1.33rem + 4.58vw, 5rem);
Linear interpolation between the two endpoints lands exactly on:
* 36 px at <= 320 px viewport (smallest phones)
* 80 px at >= 1280 px viewport (desktop)
Mid-range viewports get a smooth transition instead of a hard
`md:` breakpoint flip. The desktop max is also dropped from 100 px
to 80 px so very wide screens don't dominate the page with the
hero headline.
Sweep call sites:
h1_mobile md:h1 -> h1
across community_teams, main (the "Building the Future..." hero
headline that motivated this), partners_grid, projects_component,
and the three team pages. The `.h1_mobile` rule is removed from
`style/tailwind.css` -- it has no remaining users.
Sites that intentionally use a smaller mobile heading
(`h2_mobile md:h1` on landing_page, announcements,
project_introduction) are left alone -- those express a different
design intent (secondary headline) and the now-fluid `.h1` still
behaves correctly above the `md` breakpoint.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Apply the same clamp() treatment used for .h1 in t11 to the rest of the typography scale, retiring four `_mobile` companion rules: .h2 : clamp(1.75rem, 1.71rem + 0.21vw, 1.875rem) /* 28 -> 30 */ .h3 : clamp(1.25rem, 1.15rem + 0.52vw, 1.5625rem) /* 20 -> 25 */ .p1 : clamp(1.375rem, 1.21rem + 0.83vw, 1.875rem) /* 22 -> 30 */ .p2 : clamp(1.125rem, 0.98rem + 0.73vw, 1.5625rem) /* 18 -> 25 */ Each clamp linearly interpolates between the previous mobile and desktop pixel sizes between 320 px and 1280 px viewports. The static values were spelled out as `.h2/.h2_mobile` / `.h3/.h3_mobile` / `.p1/.p1_mobile` / `.p2/.p2_mobile` pairs and required call sites to write `hN_mobile md:hN` to opt into the responsive flip; with the fluid clamp a single class covers every viewport smoothly. `.p` and `.p_mobile` are intentionally retained: the footer deliberately renders smaller copy on mobile via `p_mobile md:p` and the spread (16 -> 20 px) is large enough that a hard breakpoint reads better than a fluid interpolation. Comment in the CSS notes this. Sweep call sites: hN_mobile md:hN -> hN pN_mobile md:pN -> pN h2_mobile md:h1 -> h1 (cross-class downgrade, .h1 fluid covers it) p2_mobile md:p1 -> p1 (cross-class downgrade, .p1 fluid covers it) The two cross-class downgrades collapse into the larger fluid class because that class already shrinks to a reasonable mobile size. Headlines that previously dropped to 28 px on mobile now sit at the fluid h1 minimum of 36 px; lead paragraphs that previously dropped to 18 px now sit at the fluid p1 minimum of 22 px. Both increases keep visual hierarchy clear and remove a hard breakpoint flip. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on #65
Six commits, each independently reviewable, layered on top of the Tier 1 cleanup PR (#65). Until that lands, this PR's diff will also show the eight Tier 1 commits; GitHub will auto-recompute the diff once #65 merges.
Commits
Verification