Skip to content

Commit 5e01235

Browse files
committed
docs: simplify portfolio README
1 parent 9f9a24c commit 5e01235

1 file changed

Lines changed: 3 additions & 135 deletions

File tree

‎README.md‎

Lines changed: 3 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,137 +1,5 @@
1-
# code-tomato.github.io
1+
# Nathan Lemma
22

3-
Nathan Lemma's portfolio. ECE at UT Austin — GPU inference serving in the
4-
systems-for-ML group, firmware and data infrastructure at Caterpillar.
5-
Third author on EnerTune (SOSP '26).
3+
My personal portfolio, featuring my work in computer engineering, research, and software.
64

7-
**Live:** [code-tomato.github.io](https://code-tomato.github.io)
8-
9-
## Résumé
10-
11-
`public/NathanLemmaPublicResume.pdf` is the public variant of the one-page
12-
résumé (no phone or email), built in the private résumé repo by
13-
`./build.sh public`. To update it, rebuild there, check the PDF (one page, no
14-
contact details), and copy only `NathanLemmaPublicResume.pdf` into `public/`.
15-
Never copy the private PDFs or any `.typ` sources here.
16-
17-
## Design
18-
19-
The site is one screen in a physical set (a bezel, a chin, and a power button
20-
in that chin) and the page scrolls inside it. Two designs, both available in
21-
every browser: a CRT (blue-black tube, cream and amber phosphor, one tomato
22-
accent) and an iPad (cool light canvas, white cards, dot grid, no glow). The
23-
CRT has effects that can be turned off separately: scanlines, a refresh sweep,
24-
heading flicker, and a live barrel warp on Chromium at ≥900px (the only part
25-
tied to a browser engine). Behind both is a field of hand-drawn doodles tiled
26-
from a single SVG. Type is IBM Plex Mono and Reddit Sans, self-hosted; nothing
27-
loads at runtime.
28-
29-
Built with Astro. `npm run dev` to work on it, `npm run build` to ship. The
30-
build also writes `sitemap-index.xml` (every page but the 404), which
31-
`public/robots.txt` points to.
32-
33-
## Checks
34-
35-
Node 22.12 or newer, as in CI.
36-
37-
```bash
38-
npm ci
39-
npm run check # astro check: TypeScript and templates
40-
npm run build
41-
npm run test:static # the built site: metadata, links, fragments, sitemap, robots
42-
npx playwright install chromium firefox webkit # once per machine
43-
npm run test:e2e # browser regression tests against dist/: three engines + cached Chromium
44-
npm test # all of the above in order (after the browser install)
45-
```
46-
47-
- `test:static` (`scripts/check-dist.mjs`) reads every page the build
48-
produced. Each needs a title naming Nathan Lemma, one h1, one
49-
`<main id="main">`, a canonical and `og:url`/`twitter:url` equal to its own
50-
published URL, matching share titles and descriptions, and a share image
51-
that exists. Ids must be unique and ARIA id references must resolve. Every
52-
on-site `href`/`src` has to resolve to a built file the way GitHub Pages
53-
serves it, every `#fragment` to an id on its page, and any linked PDF has to
54-
be a PDF. The 404 page's links must be absolute or root-relative, since it
55-
is served at whatever address was missed. The sitemap must list exactly the
56-
published pages, and not the 404 page. Off-site links are counted, never
57-
fetched, and so are links into the other repositories' Pages sites on this
58-
origin (`/CHT_Radix/`, `/YASH/`, the `OTHER_DEPLOYS` list); anything else on
59-
the origin must be in the build. Failures name the page and the link.
60-
- `test:e2e` (`tests/e2e`, Playwright) serves `dist/` on port 4329 (set
61-
`E2E_PORT` to change it) with `tests/serve-dist.mjs`, which behaves like
62-
GitHub Pages (`/x` redirects to `/x/`, unknown paths get `404.html`). It
63-
always starts its own server, never reusing whatever is on the port. Nothing
64-
leaves 127.0.0.1. Build first. It covers:
65-
- scrolling inside `.tube`;
66-
- no sideways overflow at 320 and 390px in both designs: every published
67-
page at 100% text, and at 150% text the Experience page and every project
68-
page (the dates and periods that used to run off-screen);
69-
- print output;
70-
- the current-section marking and the no-JavaScript phone navigation;
71-
- the phone menu: Tab/Shift+Tab loop, Escape, inert background, the quick
72-
close-and-reopen race, and resizing past 720px;
73-
- per-engine default designs, the design and effects controls, persistence,
74-
storage that throws, reduced motion, and the power-button hand-off at 721px;
75-
- keyboard scrolling from a fresh page, the skip link, and scroll memory
76-
across `#hash` and cross-page back/forward.
77-
The two timing races (menu reopen, Back inside the scroll-save pause) record
78-
their timing in the browser and fail if a run was too slow to hit the race.
79-
- Projects: `chromium`, `firefox` and `webkit` run everything except
80-
`bfcache.spec.ts`. Playwright starts Chromium with the back/forward cache
81-
off, so there these cover the reload path. `chromium-bfcache` runs only
82-
`bfcache.spec.ts`, in full Chromium (`channel: 'chromium'`) with the cache
83-
on, and asserts every return came from the cache (`pageshow.persisted`) with
84-
its place and the latest display choice.
85-
- Pick projects with `--project`, e.g.
86-
`npx playwright test --project=webkit --project=chromium-bfcache`. CI runs
87-
all four on Ubuntu. If a browser won't launch locally, reinstall it with
88-
`npx playwright install <browser>` and use `--project` to run the others
89-
meanwhile; CI remains the full run.
90-
- A failed CI run uploads the HTML report and traces as `playwright-report`.
91-
Open one locally with `npx playwright show-trace <trace.zip>`.
92-
93-
The `Validate` workflow (`.github/workflows/validate.yml`) runs all of this
94-
on every push and pull request, read-only. Deployment is only
95-
`deploy.yml`, on `main`.
96-
97-
## Display settings
98-
99-
The power button (on the chin at ≥721px, in the header on phones) switches the
100-
design. The footer's *Design* and *Effects* rows set each choice directly.
101-
Everything lives in `BaseLayout.astro`: the head script decides the state
102-
before first paint, and the end-of-body script wires up the controls.
103-
104-
| `localStorage` key | Values | Nothing stored |
105-
| --- | --- | --- |
106-
| `display-design` | `crt`, `tablet` | `crt` on Chromium, `tablet` elsewhere (unchanged from before) |
107-
| `display-effects` | `on`, `off` | `off` under `prefers-reduced-motion: reduce`, else `on`; follows the OS setting live until chosen |
108-
109-
- The old key `crt-warp` (`1` CRT, `0` tablet) is moved to `display-design`
110-
once and then removed.
111-
- If storage is unavailable, a choice still applies to the current page and is
112-
forgotten on the next one.
113-
- A page restored from the back/forward cache re-reads the stored choices, so
114-
it matches whatever was chosen on the pages visited since.
115-
- Classes on `<html>`: `flat` (tablet), `calm` (CRT with effects off), `warp`
116-
(warp filter active: CRT, effects on, Chromium; the CSS adds ≥900px), `js`
117-
(the script ran). With no JavaScript the page is the CRT with effects, as
118-
before, and the phone header shows plain links instead of the menu button.
119-
- Reduced motion also stops the sweep and flicker whatever is chosen; turning
120-
effects on there brings back only the static parts (scanlines, warp). The
121-
Effects group's screen-reader description is rewritten to list only what
122-
actually runs in the current browser, width and motion setting.
123-
124-
## Keyboard and scrolling
125-
126-
- The skip link is the first Tab stop and lands on `<main>` (`tabindex="-1"`).
127-
- The page scrolls inside `.tube`, not the document. With nothing focused,
128-
PageUp/PageDown, Space/Shift+Space, the arrow keys, Home and End are
129-
forwarded to the tube, so they work on a fresh load without clicking first.
130-
- The tube's scroll offset is kept per history entry (a key in `history.state`,
131-
the offset in `sessionStorage` under `tube-y:<key>`) and restored on
132-
back/forward and reload. New visits and `#hash` links scroll as normal; a
133-
back/forward cache hit keeps the live page.
134-
- Phone menu: Tab and Shift+Tab stay inside the open drawer; Escape, the close
135-
button, the backdrop or a link close it and return focus to the menu button.
136-
Everything else, the skip link and display controls included, is inert while
137-
it is open. Resizing past 720px closes it and moves focus to the matching tab.
5+
[Visit the website](https://code-tomato.github.io)

0 commit comments

Comments
 (0)