diff --git a/docs/theme-assets.md b/docs/theme-assets.md
new file mode 100644
index 00000000..f68af4f2
--- /dev/null
+++ b/docs/theme-assets.md
@@ -0,0 +1,61 @@
+# Theme assets and Tailwind tokens
+
+Legacy source ref: `origin/main` at `93d55c91102b75174a3b078e707767d602f8a5db`. Files were read with `git show`; the working tree was not switched to the legacy branch.
+
+## Static asset provenance
+
+| New path | Legacy path | SHA-256 | Git blob |
+| --- | --- | --- | --- |
+| `static/css/fonts/WOFF2/VAR/SourceSansVariable-Italic.ttf.woff2` | `SgfDevs/wwwroot/css/fonts/WOFF2/VAR/SourceSansVariable-Italic.ttf.woff2` | `2bfce090130cd2878715edf9479f449d01e3733283d31bc7673fc4e9def59f3f` | `13bcc865e392ae54da7eb4d20e18ed8cd7c78e9b` |
+| `static/css/fonts/WOFF2/VAR/SourceSansVariable-Roman.ttf.woff2` | `SgfDevs/wwwroot/css/fonts/WOFF2/VAR/SourceSansVariable-Roman.ttf.woff2` | `e27286b157603ed26dcc4dda11861c101ee00a27791f49e7d9473772d3579d93` | `b60988fe2e9dfa71c4e6acfc6c99ed9f6ff6b7ca` |
+| `static/images/checkbox_checked.svg` | `SgfDevs/wwwroot/images/checkbox_checked.svg` | `79a2b4bcc5daadf226690c81046bcecf65ecff8e0e59b015c9b63e9e22b91a8e` | `0f7d89b0a76eb5f034bbc912c5772da182dd3fd7` |
+| `static/images/checkbox_unchecked.svg` | `SgfDevs/wwwroot/images/checkbox_unchecked.svg` | `f86e2d82fec93aedb72739e063f13777049e1c7a75dae3123ebb7486768f89ad` | `534cd955fb288a675c2c0ad7c1b05611d01dc7bf` |
+| `static/images/circuit_line.svg` | `SgfDevs/wwwroot/images/circuit_line.svg` | `4c9698986cdd0fe96d82968be5b8591dde68fb8ec1254bacfdaeed9188bd2e15` | `17ab7407c58facf1334a99d27230523d972b3176` |
+| `static/images/circuit_oval.svg` | `SgfDevs/wwwroot/images/circuit_oval.svg` | `651ba148e53f8c30d1dd66fb75ef7bae28e2f08c4c61661ed56c1c5b992ed9c0` | `1ff0a2505a2dec38c0cd1e9f2d3b2c6dae3ad67c` |
+| `static/images/circuitry/circuit_graphic.svg` | `SgfDevs/wwwroot/images/circuitry/circuit_graphic.svg` | `b4005e1b1e13924960c27265891dad4724539a90622cac75df5be6df30076dd3` | `571cb3c7d882be1942096b64798338db2d807b22` |
+| `static/images/circuitry/header.svg` | `SgfDevs/wwwroot/images/circuitry/header.svg` | `88cc974e2c2d53759f96d64bdc00fb7572f1bf2bcd186cc74b82dd461df96e56` | `46cdc79e0a966ad138e745c898fcb075487c3ff9` |
+| `static/images/circuitry/mobile_lines_bottom_left.svg` | `SgfDevs/wwwroot/images/circuitry/mobile_lines_bottom_left.svg` | `327709be4928312387b66a04906bd5953764d66397f8f85a33014feaecec06be` | `b4f8ac1d23ae5b35d14e8748effb3ed31be50fe4` |
+| `static/images/circuitry/mobile_lines_bottom_right.svg` | `SgfDevs/wwwroot/images/circuitry/mobile_lines_bottom_right.svg` | `565a2bb2293efbfb1b1bcca934cae2d88e681a74eec50c398759c529e3c88abe` | `27cd4012f6ac7e31e5c7114066ee2f1c4026a6a7` |
+| `static/images/circuitry/mobile_lines_mid_right.svg` | `SgfDevs/wwwroot/images/circuitry/mobile_lines_mid_right.svg` | `c2061183847bae3eb5f78c7e7a9bde15646e1529d9f427f08b8d348813ae93a1` | `f4ec7be6c85525380f61383d2476811ccbe30d97` |
+| `static/images/circuitry/mobile_lines_top_left.svg` | `SgfDevs/wwwroot/images/circuitry/mobile_lines_top_left.svg` | `ffed1980f4d63e22c0ff8aebed6031a183f7899ad9319ec6804fd0d3b22e6f82` | `d66fdd1965c653a0b87291c8c8896f80c6bd0308` |
+| `static/images/circuitry/sponsor_lower_left.svg` | `SgfDevs/wwwroot/images/circuitry/sponsor_lower_left.svg` | `03bfae86c4ca7b6ea91bdca850a5376a81744969d864a3252871fe822011273f` | `a0ac95815c01481d1af07789939200c72b259db8` |
+| `static/images/circuitry/sponsor_lower_left_2.svg` | `SgfDevs/wwwroot/images/circuitry/sponsor_lower_left_2.svg` | `9a4562405cf5d63e68eecbf9553935f5b6fafdfc08df73ec0a4a908aa85984fd` | `599837a562ac4d2f1fe358fb6d8637274bbeffd1` |
+| `static/images/circuitry/sponsor_lower_right.svg` | `SgfDevs/wwwroot/images/circuitry/sponsor_lower_right.svg` | `71be86b67c8ea89de3dc4dfce53f4f35b8d1bef8abb3a62628d6d872776c8879` | `7143c4209d2e8a27112d099e1d87324fff533571` |
+| `static/images/circuitry/sponsor_upper_left.svg` | `SgfDevs/wwwroot/images/circuitry/sponsor_upper_left.svg` | `7655c4f13e6ac7691b98deb161ca273e0009524c2086bb329648dba8110e4cfb` | `03bdf0184e8384fe251d8d439ef73d3d26d3bf31` |
+| `static/images/circuitry/sponsor_upper_right.svg` | `SgfDevs/wwwroot/images/circuitry/sponsor_upper_right.svg` | `696bf6f94878e0c170759ee845bf2447463997b8a8a389799d9b4f6fbd387841` | `224ff1277d0c3c25479eee58849fe9a0c31f5b93` |
+| `static/images/headlines/dev_night.svg` | `SgfDevs/wwwroot/images/headlines/dev_night.svg` | `1ad1682e0645bdcbc0e204a0ca011cd48b4527d7b6e23bdfff84304094555317` | `9f26c4aac14265e26d636185814750e59ab9e407` |
+| `static/images/headlines/directory.svg` | `SgfDevs/wwwroot/images/headlines/directory.svg` | `01e88e2e3e0c9cba62fcc8bf8b0da27909d36026b896551b8cb19264842bcf74` | `1e824ab689fd76ab3f60efbcb726e07a019e315a` |
+| `static/images/headlines/events.svg` | `SgfDevs/wwwroot/images/headlines/events.svg` | `a30b40479b46b985c3b1558136df0a2d259496acdd9eb55b2ebf4cd16dc96a3e` | `218f0ff5a2c752b31276ca8b4863226d709dfc81` |
+| `static/images/headlines/groups.svg` | `SgfDevs/wwwroot/images/headlines/groups.svg` | `fd0267553d6496b88dcd745ec8a2d6632b293645202beed0ad3517c64fa4969f` | `b406f9588726e6635c1a7d67761d256f530ae768` |
+| `static/images/headlines/history.svg` | `SgfDevs/wwwroot/images/headlines/history.svg` | `6e0c5ac0f33ede148c1bae6f04410179d3bec0de6c09f7157f50b6fd2e29ac53` | `ba76cda9e172a28cb183ff7b927752a8a04b7707` |
+| `static/images/headlines/jobs.svg` | `SgfDevs/wwwroot/images/headlines/jobs.svg` | `f279786ab136903c1a65a6d092a5b61bfc5efbb21c33d2dadb60299bb669b563` | `4d92ad266085fbf7397b8f31ae0b37215d3e57cb` |
+| `static/images/headlines/leadership_bg.svg` | `SgfDevs/wwwroot/images/headlines/leadership_bg.svg` | `f48c92fcc5c6e0d1055584814270841d7e9960e8e6211a218ba7a27a9b97139e` | `15c53ad527124bb6cd1713fdb1c76ebd2c5f70bf` |
+| `static/images/headlines/leadership_bg_3.svg` | `SgfDevs/wwwroot/images/headlines/leadership_bg_3.svg` | `efc077f7438536725d3df0e0e5fd406db6c00e52ee21c3ae1fcd66f5bd5fe2f9` | `f0186834229ab4dc835947ffbe31d108f8418a8c` |
+| `static/images/headlines/sponsor.svg` | `SgfDevs/wwwroot/images/headlines/sponsor.svg` | `92b8787b7e9e6ca41a1d485d7bfade439c344ddfd0daf8e1b3ab505c271ffbb9` | `b9ed91bc1305f2abbd8ce47d3adfbfe7ad0acff9` |
+| `static/images/logo.svg` | `SgfDevs/wwwroot/images/logo.svg` | `5688153712b0c190e999fe99c35cf81ebda65fc819bc4b43f1f64924c52edce0` | `f1a254b7904c212910c4bc945cc79095ac948152` |
+| `static/images/logo_short.svg` | `SgfDevs/wwwroot/images/logo_short.svg` | `412071cfbf8c17742d78a6b65fcdd0fa2c2570ec5005a20f5a02467a4e6ad87a` | `01f3e5d66c9d5ca9ac7839e342a02e93237bd1a1` |
+| `static/images/og.jpg` | `SgfDevs/wwwroot/images/og.jpg` | `dcff27f11ba8fbb91793dcf7206332750b8f36e4deccc46bfa5fe74349f90524` | `52074adaa715dff39cca42b9af103a214cd82d6c` |
+| `static/images/pipey.jpg` | `SgfDevs/wwwroot/images/pipey.jpg` | `5896fa9c0319265a88521e23e54b96aa4e7d7f44d16cb2228c7e01c20c46ee49` | `df956e25c528ab0806824f3648a470dc6d971009` |
+| `static/images/radio_checked.svg` | `SgfDevs/wwwroot/images/radio_checked.svg` | `1b60ed2ac74beb50e148b33da191eea0ae1e524bff08ad8fde5e8ab3258471b1` | `f9b1499d4c87de1d220f6d1902e3244c99a24144` |
+| `static/images/radio_unchecked.svg` | `SgfDevs/wwwroot/images/radio_unchecked.svg` | `a23a5085702a9d09ec16351fc98912bcd5e5d5772f2585144ae5cffc89f0706b` | `ef20a3f971bc24fcf0b3ead5c3221ff19580137c` |
+
+## Font license
+
+`static/licenses/source-sans-variable-OFL-1.1.txt` is the Adobe Source Sans 3.006R SIL Open Font License 1.1 notice fetched from `https://raw.githubusercontent.com/adobe-fonts/source-sans/3.006R/LICENSE.md`; SHA-256 `f698b3361368a7ad7cf77234e58bc7a8502bf9fe0678f8e30a67d593f47206c2`.
+
+The copied Roman and Italic variable WOFF2 files match Adobe's `source-sans-pro-3.006R.zip` release asset at `https://github.com/adobe-fonts/source-sans/releases/tag/3.006R`, paths `WOFF2/VAR/SourceSansVariable-Roman.ttf.woff2` and `WOFF2/VAR/SourceSansVariable-Italic.ttf.woff2`. Only those two legacy Source Sans Variable WOFF2 files were copied. Font Awesome 5 Pro, `fa-light`, and `fa-duotone` files were not copied because their licensing is not verified for redistribution in this frontend layer.
+
+## Tailwind 4 theme tokens
+
+- Colors: `sgf-dark-blue` `#153557`, `sgf-light-blue` `#619ECE`, `sgf-grey`/`sgf-gray` `#e6e6e6`, `sgf-light-grey`/`sgf-light-gray` `#f3f3f3`, `sgf-text` `rgb(37 65 81)`.
+- Font: `font-sans` maps to `Source Sans Variable`, then `Open Sans`, then `sans-serif`.
+- Body base: 18px, weight 400, line-height 1.666, text color `rgb(37 65 81)`.
+- Breakpoint tokens: `sgf-480`, `sgf-700`, `sgf-768`, `sgf-950`, `sgf-1024`, `sgf-1060`, `sgf-1400`, all in px to avoid mixed-unit ordering surprises.
+- Legacy max-width variants: `sgf-max-480`, `sgf-max-700`, `sgf-max-768`, `sgf-max-950`, `sgf-max-1024`, `sgf-max-1060`, `sgf-max-1400`; plus `sgf-min-951` for the legacy greater-than-small-desktop case. The source declares max variants from largest to smallest so narrower max-width utilities win in Tailwind's compiled CSS. `sgf-min-951` sits between `sgf-max-1024` and `sgf-max-950`, matching the legacy `951px` split.
+- Radius and sizing: `radius-sgf-card` 27px, `radius-sgf-button` 25.5px, `radius-sgf-button-tall` 33px, `spacing-sgf-button` 40px, `spacing-sgf-button-tall` 64px.
+
+## Intentional gaps
+
+- No header, footer, menu, page migration, API/auth behavior, CI, Docker, release, or icon-system work belongs to this layer.
+- The root route remains a minimal placeholder. Full site visual parity should not be claimed until the next shell and page layers are implemented and captured against the baseline matrix.
+- Upcoming shell work still needs an icon plan. Do not add Font Awesome Pro webfonts or a public CDN until the project confirms licensing, or replace each needed glyph with a known-licensed SVG.
diff --git a/package.json b/package.json
index a8159f72..5ec3d9e7 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,8 @@
"api:generate": "tsx scripts/generate-sgf-api.ts",
"api:check": "tsx scripts/generate-sgf-api.ts --check",
"api:schema:fetch": "tsx scripts/fetch-sgf-api-schema.ts",
- "test:api": "svelte-kit sync && tsc --noEmit --project tsconfig.test.json && node --test --import tsx tests/api/*.test.ts"
+ "test:api": "svelte-kit sync && tsc --noEmit --project tsconfig.test.json && node --test --import tsx tests/api/*.test.ts",
+ "test:theme": "node --test --import tsx tests/theme/*.test.ts"
},
"devDependencies": {
"@sveltejs/adapter-node": "6.0.0",
diff --git a/src/app.css b/src/app.css
index d4b50785..2928cd0a 100644
--- a/src/app.css
+++ b/src/app.css
@@ -1 +1,74 @@
@import 'tailwindcss';
+
+@font-face {
+ font-family: 'Source Sans Variable';
+ font-style: normal;
+ font-stretch: normal;
+ font-weight: 200 900;
+ src: url('/css/fonts/WOFF2/VAR/SourceSansVariable-Roman.ttf.woff2') format('woff2');
+}
+
+@font-face {
+ font-family: 'Source Sans Variable';
+ font-style: italic;
+ font-stretch: normal;
+ font-weight: 200 900;
+ src: url('/css/fonts/WOFF2/VAR/SourceSansVariable-Italic.ttf.woff2') format('woff2');
+}
+
+@theme {
+ --font-sans: 'Source Sans Variable', 'Open Sans', sans-serif;
+
+ --color-sgf-dark-blue: #153557;
+ --color-sgf-light-blue: #619ECE;
+ --color-sgf-grey: #e6e6e6;
+ --color-sgf-gray: #e6e6e6;
+ --color-sgf-light-grey: #f3f3f3;
+ --color-sgf-light-gray: #f3f3f3;
+ --color-sgf-text: rgb(37 65 81);
+
+ --breakpoint-sgf-480: 480px;
+ --breakpoint-sgf-700: 700px;
+ --breakpoint-sgf-768: 768px;
+ --breakpoint-sgf-950: 950px;
+ --breakpoint-sgf-1024: 1024px;
+ --breakpoint-sgf-1060: 1060px;
+ --breakpoint-sgf-1400: 1400px;
+
+ --radius-sgf-card: 27px;
+ --radius-sgf-button: 25.5px;
+ --radius-sgf-button-tall: 33px;
+
+ --spacing-sgf-button: 40px;
+ --spacing-sgf-button-tall: 64px;
+
+ --text-sgf-body: 18px;
+ --leading-sgf-body: 1.666;
+}
+
+@custom-variant sgf-max-1400 (@media (width <= 1400px));
+@custom-variant sgf-max-1060 (@media (width <= 1060px));
+@custom-variant sgf-max-1024 (@media (width <= 1024px));
+/* Keep the legacy 951px desktop split between 1024px and 950px max variants. */
+@custom-variant sgf-min-951 (@media (width >= 951px));
+@custom-variant sgf-max-950 (@media (width <= 950px));
+@custom-variant sgf-max-768 (@media (width <= 768px));
+@custom-variant sgf-max-700 (@media (width <= 700px));
+@custom-variant sgf-max-480 (@media (width <= 480px));
+
+@layer base {
+ html {
+ font-family: var(--font-sans);
+ color: var(--color-sgf-text);
+ background: white;
+ }
+
+ body {
+ font-family: var(--font-sans);
+ font-size: var(--text-sgf-body);
+ font-weight: 400;
+ line-height: var(--leading-sgf-body);
+ color: var(--color-sgf-text);
+ background: white;
+ }
+}
diff --git a/static/css/fonts/WOFF2/VAR/SourceSansVariable-Italic.ttf.woff2 b/static/css/fonts/WOFF2/VAR/SourceSansVariable-Italic.ttf.woff2
new file mode 100644
index 00000000..13bcc865
Binary files /dev/null and b/static/css/fonts/WOFF2/VAR/SourceSansVariable-Italic.ttf.woff2 differ
diff --git a/static/css/fonts/WOFF2/VAR/SourceSansVariable-Roman.ttf.woff2 b/static/css/fonts/WOFF2/VAR/SourceSansVariable-Roman.ttf.woff2
new file mode 100644
index 00000000..b60988fe
Binary files /dev/null and b/static/css/fonts/WOFF2/VAR/SourceSansVariable-Roman.ttf.woff2 differ
diff --git a/static/images/checkbox_checked.svg b/static/images/checkbox_checked.svg
new file mode 100644
index 00000000..0f7d89b0
--- /dev/null
+++ b/static/images/checkbox_checked.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/static/images/checkbox_unchecked.svg b/static/images/checkbox_unchecked.svg
new file mode 100644
index 00000000..534cd955
--- /dev/null
+++ b/static/images/checkbox_unchecked.svg
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuit_line.svg b/static/images/circuit_line.svg
new file mode 100644
index 00000000..17ab7407
--- /dev/null
+++ b/static/images/circuit_line.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuit_oval.svg b/static/images/circuit_oval.svg
new file mode 100644
index 00000000..1ff0a250
--- /dev/null
+++ b/static/images/circuit_oval.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuitry/circuit_graphic.svg b/static/images/circuitry/circuit_graphic.svg
new file mode 100644
index 00000000..571cb3c7
--- /dev/null
+++ b/static/images/circuitry/circuit_graphic.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuitry/header.svg b/static/images/circuitry/header.svg
new file mode 100644
index 00000000..46cdc79e
--- /dev/null
+++ b/static/images/circuitry/header.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuitry/mobile_lines_bottom_left.svg b/static/images/circuitry/mobile_lines_bottom_left.svg
new file mode 100644
index 00000000..b4f8ac1d
--- /dev/null
+++ b/static/images/circuitry/mobile_lines_bottom_left.svg
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuitry/mobile_lines_bottom_right.svg b/static/images/circuitry/mobile_lines_bottom_right.svg
new file mode 100644
index 00000000..27cd4012
--- /dev/null
+++ b/static/images/circuitry/mobile_lines_bottom_right.svg
@@ -0,0 +1,16 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuitry/mobile_lines_mid_right.svg b/static/images/circuitry/mobile_lines_mid_right.svg
new file mode 100644
index 00000000..f4ec7be6
--- /dev/null
+++ b/static/images/circuitry/mobile_lines_mid_right.svg
@@ -0,0 +1,20 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuitry/mobile_lines_top_left.svg b/static/images/circuitry/mobile_lines_top_left.svg
new file mode 100644
index 00000000..d66fdd19
--- /dev/null
+++ b/static/images/circuitry/mobile_lines_top_left.svg
@@ -0,0 +1,20 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuitry/sponsor_lower_left.svg b/static/images/circuitry/sponsor_lower_left.svg
new file mode 100644
index 00000000..a0ac9581
--- /dev/null
+++ b/static/images/circuitry/sponsor_lower_left.svg
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuitry/sponsor_lower_left_2.svg b/static/images/circuitry/sponsor_lower_left_2.svg
new file mode 100644
index 00000000..599837a5
--- /dev/null
+++ b/static/images/circuitry/sponsor_lower_left_2.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuitry/sponsor_lower_right.svg b/static/images/circuitry/sponsor_lower_right.svg
new file mode 100644
index 00000000..7143c420
--- /dev/null
+++ b/static/images/circuitry/sponsor_lower_right.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuitry/sponsor_upper_left.svg b/static/images/circuitry/sponsor_upper_left.svg
new file mode 100644
index 00000000..03bdf018
--- /dev/null
+++ b/static/images/circuitry/sponsor_upper_left.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/static/images/circuitry/sponsor_upper_right.svg b/static/images/circuitry/sponsor_upper_right.svg
new file mode 100644
index 00000000..224ff127
--- /dev/null
+++ b/static/images/circuitry/sponsor_upper_right.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/static/images/headlines/dev_night.svg b/static/images/headlines/dev_night.svg
new file mode 100644
index 00000000..9f26c4aa
--- /dev/null
+++ b/static/images/headlines/dev_night.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/static/images/headlines/directory.svg b/static/images/headlines/directory.svg
new file mode 100644
index 00000000..1e824ab6
--- /dev/null
+++ b/static/images/headlines/directory.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/static/images/headlines/events.svg b/static/images/headlines/events.svg
new file mode 100644
index 00000000..218f0ff5
--- /dev/null
+++ b/static/images/headlines/events.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/static/images/headlines/groups.svg b/static/images/headlines/groups.svg
new file mode 100644
index 00000000..b406f958
--- /dev/null
+++ b/static/images/headlines/groups.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/static/images/headlines/history.svg b/static/images/headlines/history.svg
new file mode 100644
index 00000000..ba76cda9
--- /dev/null
+++ b/static/images/headlines/history.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/static/images/headlines/jobs.svg b/static/images/headlines/jobs.svg
new file mode 100644
index 00000000..4d92ad26
--- /dev/null
+++ b/static/images/headlines/jobs.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/static/images/headlines/leadership_bg.svg b/static/images/headlines/leadership_bg.svg
new file mode 100644
index 00000000..15c53ad5
--- /dev/null
+++ b/static/images/headlines/leadership_bg.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/static/images/headlines/leadership_bg_3.svg b/static/images/headlines/leadership_bg_3.svg
new file mode 100644
index 00000000..f0186834
--- /dev/null
+++ b/static/images/headlines/leadership_bg_3.svg
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/static/images/headlines/sponsor.svg b/static/images/headlines/sponsor.svg
new file mode 100644
index 00000000..b9ed91bc
--- /dev/null
+++ b/static/images/headlines/sponsor.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/static/images/logo.svg b/static/images/logo.svg
new file mode 100644
index 00000000..f1a254b7
--- /dev/null
+++ b/static/images/logo.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/static/images/logo_short.svg b/static/images/logo_short.svg
new file mode 100644
index 00000000..01f3e5d6
--- /dev/null
+++ b/static/images/logo_short.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/static/images/og.jpg b/static/images/og.jpg
new file mode 100644
index 00000000..52074ada
Binary files /dev/null and b/static/images/og.jpg differ
diff --git a/static/images/pipey.jpg b/static/images/pipey.jpg
new file mode 100644
index 00000000..df956e25
Binary files /dev/null and b/static/images/pipey.jpg differ
diff --git a/static/images/radio_checked.svg b/static/images/radio_checked.svg
new file mode 100644
index 00000000..f9b1499d
--- /dev/null
+++ b/static/images/radio_checked.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/static/images/radio_unchecked.svg b/static/images/radio_unchecked.svg
new file mode 100644
index 00000000..ef20a3f9
--- /dev/null
+++ b/static/images/radio_unchecked.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/static/licenses/source-sans-variable-OFL-1.1.txt b/static/licenses/source-sans-variable-OFL-1.1.txt
new file mode 100644
index 00000000..3079b6db
--- /dev/null
+++ b/static/licenses/source-sans-variable-OFL-1.1.txt
@@ -0,0 +1,93 @@
+Copyright 2010-2018 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+
+This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/tests/theme/breakpoint-variants.test.ts b/tests/theme/breakpoint-variants.test.ts
new file mode 100644
index 00000000..aaaf1991
--- /dev/null
+++ b/tests/theme/breakpoint-variants.test.ts
@@ -0,0 +1,139 @@
+import assert from 'node:assert/strict';
+import { readFile } from 'node:fs/promises';
+import test from 'node:test';
+
+import { compile } from 'tailwindcss';
+
+type Rule = {
+ marker: 'max' | 'split';
+ variant: string;
+ condition: string;
+ value: number;
+ position: number;
+};
+
+const root = new URL('../..', import.meta.url);
+const appCssUrl = new URL('src/app.css', root);
+
+const maxProbeClasses = [
+ 'sgf-max-1400:[--sgf-max-probe:1400]',
+ 'sgf-max-1060:[--sgf-max-probe:1060]',
+ 'sgf-max-1024:[--sgf-max-probe:1024]',
+ 'sgf-max-950:[--sgf-max-probe:950]',
+ 'sgf-max-768:[--sgf-max-probe:768]',
+ 'sgf-max-700:[--sgf-max-probe:700]',
+ 'sgf-max-480:[--sgf-max-probe:480]'
+];
+
+const splitProbeClasses = [
+ 'sgf-max-1024:[--sgf-split-probe:1024]',
+ 'sgf-min-951:[--sgf-split-probe:951]',
+ 'sgf-max-950:[--sgf-split-probe:950]'
+];
+
+const expectedMaxValues = new Map([
+ [400, 480],
+ [480, 480],
+ [700, 700],
+ [950, 950],
+ [951, 1024],
+ [1024, 1024],
+ [1400, 1400]
+]);
+
+const expectedSplitValues = new Map([
+ [400, 950],
+ [480, 950],
+ [700, 950],
+ [950, 950],
+ [951, 951],
+ [1024, 951],
+ [1400, 951]
+]);
+
+test('SGF breakpoint variants compile in legacy cascade order', async () => {
+ const compiledCss = await compileProbeCss([...maxProbeClasses, ...splitProbeClasses]);
+ const rules = extractProbeRules(compiledCss);
+
+ assertRuleOrder(
+ rules.filter((rule) => rule.marker === 'max'),
+ ['sgf-max-1400', 'sgf-max-1060', 'sgf-max-1024', 'sgf-max-950', 'sgf-max-768', 'sgf-max-700', 'sgf-max-480']
+ );
+ assertRuleOrder(
+ rules.filter((rule) => rule.marker === 'split'),
+ ['sgf-max-1024', 'sgf-min-951', 'sgf-max-950']
+ );
+
+ for (const [width, value] of expectedMaxValues) {
+ assert.equal(cascadeValue(rules, 'max', width), value, `max-only cascade at ${width}px`);
+ }
+
+ for (const [width, value] of expectedSplitValues) {
+ assert.equal(cascadeValue(rules, 'split', width), value, `950/951 split cascade at ${width}px`);
+ }
+});
+
+async function compileProbeCss(classes: string[]) {
+ const appCss = await readFile(appCssUrl, 'utf8');
+ const probeCss = appCss.replace("@import 'tailwindcss';", '@tailwind utilities;');
+ const compiler = await compile(probeCss, {
+ base: root.pathname,
+ from: appCssUrl.pathname
+ });
+
+ return compiler.build(classes);
+}
+
+function extractProbeRules(compiledCss: string): Rule[] {
+ const rules: Rule[] = [];
+ const mediaRule = /@media \((width [<>]= (\d+)px)\) \{([\s\S]*?)\n\}/g;
+ let match: RegExpExecArray | null;
+
+ while ((match = mediaRule.exec(compiledCss)) !== null) {
+ const [, condition, , block] = match;
+ for (const marker of ['max', 'split'] as const) {
+ const valueMatch = block.match(new RegExp(`--sgf-${marker}-probe: (\\d+);`));
+ if (!valueMatch) continue;
+
+ rules.push({
+ marker,
+ variant: variantFromBlock(block),
+ condition,
+ value: Number(valueMatch[1]),
+ position: match.index
+ });
+ }
+ }
+
+ return rules.sort((left, right) => left.position - right.position);
+}
+
+function variantFromBlock(block: string) {
+ const classMatch = block.match(/\.(sgf-(?:max|min)-\d+)\\:/);
+ assert.ok(classMatch, `Expected SGF variant class in block: ${block}`);
+ return classMatch[1];
+}
+
+function assertRuleOrder(rules: Rule[], expectedOrder: string[]) {
+ assert.deepEqual(
+ rules.map((rule) => rule.variant),
+ expectedOrder
+ );
+}
+
+function cascadeValue(rules: Rule[], marker: Rule['marker'], width: number) {
+ let value: number | undefined;
+
+ for (const rule of rules) {
+ if (rule.marker !== marker || !mediaMatches(rule.condition, width)) continue;
+ value = rule.value;
+ }
+
+ return value;
+}
+
+function mediaMatches(condition: string, width: number) {
+ const [, operator, value] = condition.match(/width ([<>]=) (\d+)px/) ?? [];
+ assert.ok(operator && value, `Unsupported media condition: ${condition}`);
+ return operator === '<=' ? width <= Number(value) : width >= Number(value);
+}