1. Project Overview & Quickstart (EleutherAI/terretaqa.yaml)
terretaqa.yaml
Open-source repository EleutherAI/terretaqa.yaml
Repository Details
- Repository: EleutherAI/terretaqa.yaml
- Primary Language: Code
Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.
2. Official Technical Reference & Guides (EleutherAI/website)
File: README.md
EleutherAI Website
This repository contains the Hugo source for the EleutherAI website and blog.
- Main site: www.eleuther.ai
- Blog: blog.eleuther.ai
- Publication source of truth: EleutherAI papers Google Sheet
The main site and blog share templates, styles, data, and assets, but Hugo builds them as separate sites for separate Netlify deployments.
Deployment: Any changes made to main will be automatically deployed via Netlify. This can take a few minutes at times, but changes should be reflected in the live website pretty fast
Build and view the website
The build requires Python 3.12 or newer, Make, and Hugo Extended 0.158.0. The supported versions are recorded in .python-version and .hugo-version.
For a new local checkout, install the development dependencies in a virtual environment:
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -r requirements-dev.txt
playwright install chromium
make check-toolsPlaywright is used only for refreshing the Hugging Face download metric. Offline builds and tests do not launch a browser.
From the repository root, build the main site with current online data:
make buildThe static output is written to public/. To preview the complete website locally, start the main site and blog together:
make serve-all-offline
open http://127.0.0.1:8067/The main site runs on port 8067 and the blog runs on port 8068. Navigation automatically moves between the two local previews instead of opening the production websites.
For normal editing with Hugo's live-reloading server:
make serve-allThis refreshes the online data before starting both servers.
Build both the main site and blog:
make build-allThe individual preview commands remain available when only one deployment is needed:
make serve-offline PORT=8067
make serve-blog-offline PORT=8068When internet access is unavailable, use the checked-in data snapshots:
make build-offline
make build-all-offlineOffline builds do not check the publication Sheet, refresh online metrics, or query YouTube. They validate and use the checked-in snapshots instead.
Where to add content
Most text should be added to Markdown under content/ or structured YAML under data/. The files under layouts/ determine how that content is arranged. CSS and public assets live under site-page.css, static/, and assets/.
Files directly under data/ and data/projects/ are maintained by people. Everything under data/generated/ is written by the build scripts and must not be edited directly. Change the relevant Google Sheet, Markdown, YAML, external source, or generator and rebuild.
Page-by-page guide
| Content | Edit here | Notes |
|---|---|---|
| Homepage hero and section structure | layouts/index.html |
The homepage's main prose and arrangement currently live in the template. |
| Homepage metrics, Current Research links, manual news | data/home.yaml |
Generated metric values replace entries that have a source key. Recent outputs are generated from the papers Sheet and blog front matter. |
| About page | content/about.md |
Donor logos and links are stored separately in data/donors.yaml. |
| Community page | data/community.yaml |
content/community.md contains only the page front matter. |
| Community reading-group cards | data/reading_groups.yaml |
One entry per reading-group series with its YouTube playlist ID (from the channel's playlists page). The build refreshes data/generated/community_reading_groups.json with each series' newest recording; use the repository's refresh-community-videos skill when maintaining or troubleshooting it. |
| Staff page | data/staff.yaml |
teams mirrors the org chart; give each person a team key. Store portraits locally under static/assets/staff/. |
| Research page and research areas | data/research/areas.yaml |
Area prose, key projects, current directions, and the Major Projects list. Each area also needs a stub under content/research/. The intro paragraphs are in content/research/_index.md. Paper lists per area are generated from the Sheet's Area column via research_area_filters.csv. |
| Research Library | Google Sheet | content/papers.md only defines the route and layout. Do not hand-edit the rendered paper list. |
| SOAR page | data/soar.yaml |
The page title and description are in content/soar.md. |
| News post | content/news/ |
Dated news posts can enter the homepage Latest feed. |
| Manual homepage news item | data/home.yaml under manual_news |
Give the item a title, URL, and date if it should participate in chronological sorting. |
| Blog post | content-blog/ |
Add Markdown front matter with at least title and date. Write math as plain TeX inside $โฆ$ or $$โฆ$$; MathJax loads automatically on pages that contain it. |
| General standalone page | content/ |
Most ordinary Markdown pages use a template under layouts/_default/. |
| Header and navigation | layouts/partials/header.html |
Shared by the main site and blog. |
| Footer | layouts/partials/footer.html |
Shared by the main site and blog. |
| Shared styling | site-page.css |
Page-specific styles are under static/, such as research-library.css. |
| Logos and source images | assets/ |
Hugo mounts selected assets into the built sites. |
| Directly served assets | static/ |
Files retain their paths in the generated site. |
Directories that are not content sources
public/andpublic-blog/are generated build outputs. Do not edit them./blog/andblog.htmlremain under review as possible deployment artifacts. Do not change or remove them until that deployment is confirmed.generate_blog_pages.pybelongs to the older standalone blog export and is not called by the current Makefile.
What the build process does
The Makefile coordinates data refreshes and Hugo. The normal main-site build is:
make build
-> python3 generate_hugo_data.py
-> python3 scripts/refresh_youtube_reading_groups.py
-> hugo --cleanDestinationDirEach stage has a different purpose.
YouTube reading-group refresh
scripts/refresh_youtube_reading_groups.py reads data/reading_groups.yaml, which lists each reading-group series and its YouTube playlist ID. For every series it fetches the playlist feed (or, with YOUTUBE_API_KEY set, the full playlist through the Data API), takes the newest recording, and writes the series name, a link into the playlist at that recording, the session title, date, and a one-sentence overview from the official description to data/generated/community_reading_groups.json. A series with no playlist_id yet can set title_pattern to pick the newest matching channel upload instead; the freshness report flags this as live_limited until the playlist ID is added.
The checked-in JSON file is the deterministic offline fallback. A live build warns and uses that snapshot if YouTube is temporarily unavailable; it fails only when neither online discovery nor a valid three-video snapshot is available. make build-offline never queries YouTube and validates the snapshot before Hugo runs. make verify-live requires YOUTUBE_API_KEY so it can prove that the selection came from the complete uploads history.
Data generation: `generate_hugo_data.py`
The normal build runs this script online. It fetches external data, normalizes publication records, derives display fields, and writes JSON for Hugo.
1. Refresh the publication Sheet
The script downloads a cache-busted CSV export of the papers tab and writes it to:
eleutherai_papers.csvThe script verifies the full expected header set before replacing the local snapshot. If the Sheet cannot be downloaded, or its schema changes unexpectedly, a live build stops instead of silently claiming that stale publication data is current.
The principal Sheet columns currently used are:
| Sheet column | How the website uses it |
|---|---|
Title |
Display title and record identity |
Date |
Determines whether a paper enters the public library; supplies its displayed year and chronological sort |
Highest Impact |
Selects papers for the generated homepage Recent outputs candidate set; checked rows export as TRUE |
Display Authors |
Author line shown in the Research Library |
All Authors |
Complete semicolon-separated author list used for author search and metadata generation |
Area |
Semicolon-separated research-area metadata used by generated collections and filters |
Paper Link |
Makes the paper entry clickable |
Conference or Journal |
Primary archival venue; blank values fall back to a workshop or arXiv |
Workshop |
Workshop appearance; may coexist with an archival venue |
Superlative |
Oral, spotlight, best-paper, and runner-up text and symbols |
A row must have both a normalized title and a parseable Date to appear in the main Research Library and publication count.
2. Normalize links, dates, and venues
The script cleans OpenReview tracking parameters and uses a small URL override table for known papers whose links were missing or incorrect in earlier data.
Venue logic is derived from Conference or Journal and Workshop:
- Papers use the conference or journal, then a workshop if no archival venue exists, then arXiv as a fallback.
- Papers with both an archival venue and a distinct workshop can produce separate appearances in grouped publication data.
The generator maps the simplified Sheet schema into its internal publication model:
Datecontrols inclusion and the one-record-per-paper library chronology.- The same date is used for conference and workshop appearance sorting because the Sheet intentionally maintains one date per paper.
- arXiv groups are normalized to January 1 so they are treated as the earliest chronological point in their year and appear after later conference and workshop groups in the newest-first display.
- Workshop sort dates receive a seven-day offset so a corresponding main conference is presented above its workshops.
That final ordering rule is editorial rather than historical: it keeps main conferences visually prominent even when their workshops occurred later.
3. Derive publication distinctions
The script cleans the Superlative field and associates an award with the appropriate conference or workshop appearance. Commas inside a single award description are preserved. For the Research Library it chooses one marker using this precedence:
- runner-up or finalist
- best paper
- spotlight
- oral
The generated marker value is rendered by layouts/partials/paper-marker.html, which keeps symbols and accessible labels consistent across the site.
4. Build publication representations
The website needs two related but different publication representations.
Publication appearances
all_papers() can create more than one record for a paper when it appeared at both a workshop and an archival venue. Each appearance contains:
- title and URL
- publication year
- venue and venue year
- venue kind: conference, workshop, or arXiv
- normalized conference family
- group sort date
- appearance-specific distinctions
These records feed the chronological venue-grouped publication components.
Research Library records
library_papers() creates exactly one record per dated paper. In addition to title, URL, year, and venue, each record contains:
- authors, displayed as last names and shortened after four names
- status
- primary and additional areas
- lead organization
- EleutherAI contact
- artifact type, currently
Paper - distinction marker and text
The current public Research Library does not display every stored metadata field, but the fields remain available to its filters and templates.
5. Generate venue groups
grouped_papers() groups publication appearances first by conference family and year, then by track or workshop. Examples include a main ICML conference group, a named workshop under ICML, and an arXiv preprint group.
Within a year, the generated order favors:
- main conferences
- workshops
- arXiv
Papers inside each venue are sorted in reverse chronological order.
6. Generate research-area paper sets
The script creates data/generated/research/area_papers.json in two ways:
- Training Dynamics uses the hand-curated titles, summaries, and optional venue labels in
research_area_papers.csv. - Other areas use the broad-area, include-term, and exclude-term rules in
research_area_filters.csv.
The keyword filters search the paper title, superlative, conference or journal, workshop, and semicolon-separated Area values. These generated sets are useful data, but individual research-area pages are intentionally not exposed in the current public release.
The datasets key in this file is a filtered set of papers about datasets. It is not a catalog of released dataset artifacts, and the build does not currently query Hugging Face for a dataset inventory.
7. Refresh homepage metrics
The generator writes data/generated/home_generated_metrics.json from three sources.
Publications
It counts unique titled Sheet rows with a valid Date, rounds the result down to the nearest 25, and appends +. The resulting object uses the key publication_count.
Citations
It fetches EleutherAI's Google Scholar profile, extracts the total citation count, rounds down to the nearest thousand, and appends + when the homepage renders it. The successful response is cached in data/generated/home_scholar_metrics.json.
If Scholar cannot be refreshed, the script uses the cached value. If no cache exists, it omits the metric rather than failing the full build.
Model downloads
It obtains the Hugging Face model-download value in this order:
HF_MODEL_DOWNLOADSenvironment variable, when set- the rendered EleutherAI publisher analytics page through Playwright
- the checked-in cache in
data/generated/hf_model_downloads_cache.json
If neither a live value nor a cache is available, the metric is omitted. This is a model-download metric only; it does not count dataset downloads.
The homepage reads data/home.yaml. Metric entries with a source such as publication_count, scholar_citations, or model_downloads are filled from data/generated/home_generated_metrics.json during Hugo rendering.
8. Build the blog index used by the homepage
The generator scans content-blog/ recursively. It skips the section index and posts marked draft: true, then reads each post's title and date. It writes a sorted list to data/generated/blog_posts.json with production blog-subdomain URLs.
The homepage combines these blog entries with content/news/ and dated manual_news entries from data/home.yaml. layouts/index.html sorts the combined feed and displays the four newest items.
9. Write generated research files
The first pass writes:
| Generated file | Contents |
|---|---|
data/generated/research/papers.json |
All publication appearances, including separate workshop and conference appearances |
data/generated/research/homepage_papers.json |
The first 10 publication appearances |
data/generated/research/paper_groups.json |
All appearances grouped by venue family, year, and track |
data/generated/research/homepage_paper_groups.json |
Grouped data from the first 30 appearances |
data/generated/research/area_papers.json |
Curated and keyword-filtered research-area paper sets |
data/generated/research/library_papers.json |
One searchable record per dated paper |
data/generated/research/paper_collections.json |
Named publication collections such as SOAR |
data/generated/home_generated_metrics.json |
Publication, citation, and model-download homepage values |
data/generated/home_scholar_metrics.json |
Last successful Scholar response used as a fallback |
data/generated/hf_model_downloads_cache.json |
Last supplied or successfully fetched download value |
data/generated/blog_posts.json |
Dated blog entries used by the homepage Latest feed |
data/generated/home_recent_outputs.json |
Four newest items from highest-impact papers and published blog posts |
data/generated/community_reading_groups.json |
One card per configured reading-group series, newest recording first |
Do not edit these files directly. Edit their source data and rebuild.
Author search
The Sheet's semicolon-separated all authors column is the sole source for complete publication authorship. generate_hugo_data.py puts every full name into the hidden Research Library search index while continuing to display the shorter Display Authors line. A live or offline build stops with a list of affected titles if any paper has a blank all authors cell; fix the Sheet rather than adding a local author override.
Hugo rendering
After data generation, hugo --cleanDestinationDir renders the main site with hugo.toml and writes public/.
Important data connections include:
layouts/index.htmlreadsdata/home.yamland generated homepage data underdata/generated/.layouts/_default/research-library.htmlreadsdata/generated/research/library_papers.json.layouts/_default/research.htmlandlayouts/partials/publication-groups.htmlread the grouped publication data.layouts/_default/community.htmlreadsdata/community.yaml.layouts/_default/staff.htmlreadsdata/staff.yaml.layouts/_default/soar.htmlreadsdata/soar.yamland the SOAR paper collection.
make build-all performs the complete main-site process above and then builds the blog with hugo-blog.toml into public-blog/. A standalone make build-blog does not refresh publication data first; it uses the generated data already present in the checkout.
Before committing a content change
For ordinary content that does not depend on external data:
make verifyFor publications, homepage metrics, news aggregation, or other externally sourced data:
make verify-livemake verify runs the tests, regenerates checked-in snapshots offline, builds both deployments with Hugo warnings treated as errors, checks local links and assets, and fails if generated snapshots differ from HEAD or the diff contains whitespace errors. GitHub Actions runs the same command.
make verify-live additionally requires every external source to be current. Set YOUTUBE_API_KEY for complete YouTube uploads discovery and either install Playwright or provide HF_MODEL_DOWNLOADS. Run make freshness after any build to see which sources were fetched live and which used snapshots.
Review the affected main-site and blog pages locally before committing generated changes.
File: AGENTS.md
EleutherAI Website Agent Instructions
These instructions apply to AI agents working in this repository. Treat them as project requirements, not optional style suggestions.
Project purpose
Build a serious, legible, research-first website for EleutherAI. The site should demonstrate EleutherAI's work through concrete papers, models, datasets, tools, people, metrics, and outcomes. It should not read like a generic AI-company landing page or a stylized fake terminal.
The repository produces two related Hugo sites:
- Main site:
https://www.eleuther.ai/ - Blog:
https://blog.eleuther.ai/
The sites share layouts, styling, data, and assets but are built and deployed separately.
Before changing anything
- Read the relevant content, data, template, and CSS files before proposing a change.
- Check
git status, the current branch, and active worktrees. Do not assume the checkout is clean or that another agent is not working nearby. - Keep exploratory design work on an isolated feature branch or worktree until Stella approves it.
- Coordinate preview ports and shared-file ownership with concurrent agents.
- Never merge, push, or modify
mainunless Stella explicitly authorizes it. - Preserve unrelated user and agent changes. Do not clean up or revert work outside the assigned scope.
Do not stage or commit this AGENTS.md file unless Stella explicitly asks.
Design workflow
For layout, information architecture, homepage, navigation, research, community, staff, or visual-polish work, use a design-first process even when Stella does not explicitly request one.
- Decide what belongs on the page, what belongs on a subpage, and what should be omitted.
- Sketch the page structure using realistic public content. Do not put editorial notes or implementation labels in the rendered mockup.
- Critique the proposed structure before implementation. Identify what could feel bloated, gimmicky, generic, thin, or difficult to maintain.
- Present two or three genuinely distinct directions when the visual choice is unclear.
- Implement only after the direction is clear unless Stella explicitly requests immediate editing.
- Build and inspect the result at desktop and mobile sizes.
- Critique the rendered result for hierarchy, spacing, density, readability, wrapping, overflow, and visual continuity.
- Iterate before reporting completion. A successful Hugo build is not visual QA.
After every substantive visual change, provide the exact preview URL. When reporting a website change, also provide the build and open commands.
Source organization
Keep editable content separate from templates and styling.
content/: main-site Markdown and news postscontent-blog/: blog posts and blog front matterdata/: editable structured content; machine-produced Hugo data is isolated underdata/generated/layouts/: Hugo templates and shared partialssite-page.css: shared site-wide visual systemstatic/: page-specific CSS, JavaScript, icons, and public assetsassets/: source images and shared brand assets mounted by Hugogenerate_hugo_data.py: publication, research, homepage-metric, and blog-index generation
Prefer Markdown or YAML for copy changes. Change a template only when page structure or behavior must change. Do not embed maintainable content directly in HTML when it belongs in content/ or data/.
Data sources and generated files
Publications
The EleutherAI papers Google Sheet is the source of truth:
https://docs.google.com/spreadsheets/d/1LcB7_1lHZgO8_EmOkrvfV2BTaOngX95J5v8PJeuN4rM/edit?usp=sharing
A normal live build downloads the Sheet, regenerates the publication library and homepage publication data, and then builds Hugo.
A paper requires a title, Sort Date, and complete semicolon-separated all authors value. Display Authors supplies the public author line, all authors supplies the author-search index, semicolon-separated Area values supply research metadata, and Superlative supplies distinctions. A link makes the rendered entry clickable.
Do not manually edit these generated files:
eleutherai_papers.csv- everything under
data/generated/, including publication representations, homepage feeds and metrics, external-data caches, and Community reading-group recordings
Edit the Sheet or the appropriate editable YAML and regenerate the outputs.
The current datasets research grouping is a filtered set of publication records, not an inventory of released dataset artifacts. The build does not currently import a Hugging Face dataset catalog or dataset-download metric. Do not describe it as doing so.
Homepage and news
Homepage metrics, research priorities, links, and manual news live in data/home.yaml.
The homepage Latest feed combines:
- posts from
content-blog/ - news from
content/news/ - dated manual items from
data/home.yaml
It sorts the combined feed chronologically and displays the four newest items. Do not create a second hand-ordered copy in a template.
Community videos
The three Community reading-group recordings come from the official EleutherAI YouTube channel. A normal build refreshes data/generated/community_reading_groups.json; an offline build validates and uses that checked-in snapshot. With YOUTUBE_API_KEY, the refresh paginates through the complete uploads playlist. Without it, ordinary builds use the limited recent Atom feed and record live_limited in the freshness report.
Use the repository skill under .agents/skills/refresh-community-videos/ when maintaining the selection or summaries. Do not hand-edit the generated JSON. make verify-live must fail unless complete uploads discovery and every other external source are live or explicitly provided.
Staff and assets
Staff data lives in data/staff.yaml. Store portraits under static/assets/staff/. Do not hotlink staff portraits or core site assets from the old website or third-party CDNs.
Build and preview
Use the Makefile rather than inventing parallel build commands.
For a new checkout, install requirements-dev.txt, install Playwright Chromium, and run make check-tools. The supported Python and Hugo versions are recorded in .python-version and .hugo-version.
Main site with live data
make build
make serve-offline PORT=8060
open http://127.0.0.1:8060/For live-reloading development with a fresh data pull:
make serve PORT=8060Main site and blog
make build-allPreview in separate terminals:
make serve-offline PORT=8060
make serve-blog-offline PORT=8061Then open:
open http://127.0.0.1:8060/
open http://127.0.0.1:8061/Offline verification
make build-offline
make build-all-offlineOffline targets use checked-in snapshots and do not check the Google Sheet for new publications. Do not use an offline build to claim live data is current.
If a preview port is occupied on macOS, stop the existing process before starting another server:
PID=$(lsof -ti tcp:8060); if [ -n "$PID" ]; then kill "$PID"; fiThe production main-site Netlify configuration runs make build and publishes public/. The blog configuration under netlify/blog/ runs make build-blog and publishes public-blog/.
Visual system
Overall character
- Keep the site dark, minimal, precise, and institutional.
- Prefer authentic research artifacts and project imagery over decoration.
- Do not use fake-terminal styling, generic technology illustrations, decorative gradients, glowing blobs, or invented scientific diagrams when genuine work is available.
- Do not make the site look like a SaaS dashboard or a stack of promotional cards.
Color
The shared palette is defined in site-page.css: green, blue, gold, violet, and coral, with related surface colors.
- Use the palette consistently across the site.
- When a list or sequence gives each item its own highlight color, assign colors in this order: blue, green, violet, gold, coral. For sequences longer than five items, cycle back to blue and repeat the same order.
- Use color for hierarchy, publication distinctions, links, and selected featured material.
- Do not permanently assign one color to each research area. Research areas overlap and the taxonomy will grow.
- Do not make every section a differently colored panel.
- Preserve sufficient contrast in all states.
Typography and width
- Use the shared page-title scale and established heading levels. Do not invent a new headline system for each page.
- Do not end headings with periods.
- Put explanatory copy below its heading by default. Do not place paragraphs beside section headings unless the composition has a specific content-driven reason.
- The global
.wrapdefines the intended page frame. Do not make text extend to the viewport edges. - Within that frame, do not add arbitrary
max-widthconstraints that make headings or body text wrap earlier than the available layout requires. - Do not use viewport-scaled font sizes.
- Make text fit at mobile and desktop sizes without overlapping adjacent content.
Labels, rules, and containers
- Do not add decorative eyebrow labels or small labels that repeat a nearby heading.
- Use horizontal rules sparingly. Prefer spacing, alignment, typography, and background changes for grouping. Retain a rule only when it communicates real structure.
- Use cards for repeated objects such as people, projects, or a deliberately comparable set of items.
- Do not put cards inside cards.
- Do not turn every section into a bordered box or floating panel.
- Avoid highly uniform grids when the content has different importance or evidence. Use imagery, varied scale, and editorial composition when appropriate.
- Keep fixed-format controls dimensionally stable so interaction and dynamic content do not shift the layout.
Content and evidence
- Prefer proof over explanation: show papers, models, datasets, code, people, metrics, and outcomes.
- Do not add generic filler, temporary marketing copy, or explanations of the site's taxonomy and maintenance logic.
- Do not add visible process narration, mockup ribbons, audience labels, page-logic notes, or instructions for using the page.
- A mockup must contain only material suitable for publication. When copy is genuinely undecided, use
Lorem ipsumrather than inventing claims. - Never invent people, organizations, sponsorships, numbers, awards, publications, or links.
Images
- Use images that show the real project, research result, tool, dataset, model, person, or community.
- Do not use dark atmospheric stock imagery when the visitor needs to inspect the subject.
- Preserve source aspect ratios unless a deliberate crop has been approved.
- Verify that every image loads and remains correctly framed at desktop and mobile widths.
Publication distinctions
Render publication distinctions through layouts/partials/paper-marker.html everywhere they appear:
oral: microphone symbol, bluespotlight: flashlight symbol, greenrunnerup: silver-medal symbol, award colorbestpaper: trophy symbol, award color
Do not create page-specific symbols for the same distinction. Every symbol needs an accessible label. A qualifying recent paper should retain its distinction on the homepage as well as in the Research Library.
Information architecture
The initial public research architecture is intentionally limited to:
- one Research landing page
- the searchable Research Library
- selected mature project pages such as Pythia
Individual research-area pages are deferred. Do not expose unfinished area routes through navigation, homepage cards, sitemaps, or calls to action. Homepage research themes should link to mature public artifacts or the main Research page.
Research Areas are the normal public vocabulary. Broad categories such as Capabilities, Interpretability, and Safety are separate, overlapping metadata rather than parents in a strict hierarchy. Do not infer a category from an area or force areas into exclusive program ownership.
Keep research communication pages distinct from research artifacts:
- Communication pages explain a project, agenda, or research direction.
- The Research Library provides searchable access to papers.
- Project links should lead to real papers, repositories, models, datasets, and documentation.
Navigation and accessibility
- Preserve the responsive desktop and mobile navigation.
- Preserve
aria-currentso the current page or parent section is programmatically identifiable. - Use semantic headings, links, buttons, lists, and navigation elements.
- Keep keyboard focus states visible.
- Use familiar icons for controls and provide tooltips or labels when meaning is not obvious.
- External links opened in a new tab must use
rel="noopener noreferrer". - Do not hide essential navigation at mobile breakpoints.
Required verification
Before reporting a code or design change as complete:
- Build the affected site or both sites when shared code changed.
- Run
git diff --check. - Inspect affected pages in a real browser at desktop and mobile widths.
- Check horizontal overflow, wrapping, images, navigation, keyboard focus, and console errors.
- Confirm internal links and local assets resolve.
- Confirm generated data changed through its source rather than by hand.
- Compare the result with the surrounding site, not only with the edited component.
- Keep unapproved experiments isolated from
main.
Baseline verification:
make build-all-offline
git diff --checkFor changes affecting publications, news, blog indexing, citations, or homepage metrics, also run a live build:
make verify-liveFor all other changes, run make verify. This runs tests, regenerates offline snapshots, treats Hugo warnings as errors, checks local page and asset references, and fails if generated snapshots differ from HEAD. Run make freshness to report whether each external source was live, provided, limited, cached, offline, or missing.
When changing shared layouts, navigation, CSS, logos, favicons, or social metadata, test both the main site and a representative long technical blog post.
Reporting
When handing work back to Stella:
- State the branch and commit hash.
- List the files changed and the behavior changed.
- Report the exact build and browser QA performed.
- Give the preview URL.
- Include commands to rebuild and open the site.
- State whether the work is committed, pushed, merged, or still isolated.
- Call out unresolved factual, content, or design decisions without guessing.
File: DESIGN_HANDOFF.md
EleutherAI Website Design Handoff
Updated: 2026-08-04
Current state
main is at 4a4f52a. All five recommended design tasks below are complete and committed. The two pending feature branches (codex/blog-subdomain, codex/headcount-netlify) are also integrated into main.
Desktop navigation uses muted inactive links and a white underlined current section. Mobile navigation uses a left-hand marker. Nested pages identify their parent section, and Support Us remains green.
The current homepage research panels are approved. Individual research-area pages, including Training Dynamics, are intentionally excluded from main and are not a release blocker.
Use the Hugo source as authoritative. Do not edit the old root HTML files or the material under mockups/ and clone/ as though they were the production site.
Design system โ completed
1. Headline system โ
--title-size: 4rem, --title-lh: 1.04, and --title-mobile: 2.45rem are defined in the :root block of site-page.css and used by all non-homepage hero h1s. Community Impact, SOAR, and Research Library were updated; each also has an explicit mobile override at 680px (the page-specific class selectors would otherwise win over the generic h1 rule in the media query). The homepage hero (clamp(3.2rem, 6.2vw, 5.1rem)) remains the only deliberate exception.
2. Color palette โ
Eight accent tokens are in :root: --green, --blue, --gold, --violet, --coral (bright accents) and --blue-surface, --gold-surface, --green-surface, --violet-surface (dark filled-surface colors for the priority cards). The WCAG AA failure on priority-card link hover โ color: #081018 on all four panel backgrounds โ is fixed: hover now increases text-decoration-thickness from 1px to 2px instead of changing color. The SOAR coral (--soar-safety) and the Research Library's --lib-green have been aliased to the palette tokens.
3. Publication distinctions โ
layouts/partials/paper-marker.html is the single source for the ๐๏ธ ๐ฆ ๐ฅ ๐ markers with accessible role="img" and aria-label. Both layouts/_default/research-library.html and layouts/partials/publication-groups.html use the partial.
4. Interaction and symbol grammar โ
All -> link arrows are standardized to โ. .link and .back-link now have text-decoration: underline on :hover/:focus-visible. .button and .button.primary have hover and focus-visible states (border highlight and brightness, respectively). Every interactive element โ nav links, cards, publication items, staff icons, donor logos, footer links โ has a corresponding :focus-visible rule.
5. Final visual consistency pass โ
No oversized h1s remain outside the homepage hero. No -> arrows remain in templates. No obvious mobile overflow issues. The remaining hardcoded hex values in site-page.css are intentional: #fff for white text on colored panels, #f2d77b for a lighter gold used as badge text (the token --gold is too dark for that use), and near-black surface variants (#0c1118, #10161d, #111820) for specific element backgrounds. Do not redesign the main Research page โ Stella plans to rewrite it separately.
Open items
The Support Us page still needs a real contribution or contact destination. Stella is deciding what that should be, so do not invent one.
Local main is ahead of origin/main; confirm the final commit set before pushing.
Branch boundaries
- Keep all individual research-area work on
codex/research-area-pages. Do not merge that branch wholesale intomain. - Research Library and the general Research page belong on
main. - Staff portraits, personal-site links, Scholar links, GitHub links, metadata, favicons, social previews, and the custom 404 are already integrated into
main. AGENTS.mdis local project guidance and should not be staged unless Stella explicitly asks.
Build and preview
For a production-data build:
cd /Users/stellabiderman/Documents/research/Codex/eleutherai_homepage_draft
make buildFor a reproducible offline check and local preview:
cd /Users/stellabiderman/Documents/research/Codex/eleutherai_homepage_draft
make build-offline
make serve-offline PORT=8068Then open:
open http://127.0.0.1:8068/File: requirements-dev.txt
-r requirements-test.txt
playwright==1.62.0
File: requirements-test.txt
pytest==9.0.2
PyYAML==6.0.2