Skip to content

580 update roadmap - #581

Merged
jameseastwood merged 31 commits into
v2from
580-update-roadmap
Jul 20, 2026
Merged

580 update roadmap#581
jameseastwood merged 31 commits into
v2from
580-update-roadmap

Conversation

@jameseastwood

Copy link
Copy Markdown
Contributor

Adapted the 2026 Roadmap Proposal https://github.com/openforcefield/openff-roadmap-proposal-2026 site into a permanent page on our main website. Removed some extraneous features, brought into line with the Hugo site, removed projects that were explicitly voted down by the advisory board, and added new projects reflecting new proposals in development. New projects were drafted with the help of Claude to summarize existing Letters of Intent for these proposals. Most modifications to page layout were done by Claude.

jameseastwood and others added 21 commits July 9, 2026 14:41
Removes the old single-page roadmap (_index.md, 2025_roadmap.png) in
favor of the new interactive roadmap site, and adds its remaining
supporting files (404 page, build script, JS modules, proposal PDF).

Also fixes index.html referencing removed #sort-key/#sort-dir controls,
which threw on load and left the "All Projects" grid empty.
Drops the timeline/milestone display from project detail pages
(project.html, project.js, project.css) and removes the underlying
timeline field from project frontmatter, build.py, and the generated
data/projects.js.
Replaces the standalone index.html with content/about/roadmap/_index.md,
using the same front matter conventions as sibling About pages
(organization, team, branding). The intro text is now proper markdown;
the dynamic project grid is preserved as embedded HTML/JS since
goldmark unsafe rendering is already enabled site-wide.
Swaps the Google Fonts Inter/JetBrains Mono import for local
Montserrat @font-face rules pointing at the same font files the Hugo
theme already serves, so the roadmap pages match the rest of the
site's typography instead of loading a separate external font family.
project.html was still a standalone HTML document that Hugo copied
verbatim, so clicking into a project dropped visitors out of the
site's nav/header entirely. Give it the same treatment _index.md
already got: strip it down to a content fragment with front matter
so it renders inside the shared Hugo layout, now at the clean URL
/about/roadmap/project/ instead of project.html. Updates the
URL-building helpers, two hardcoded links, and one in-body project
link accordingly, and hides the theme's generic page title in favor
of the dynamic project hero.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Drop "A peptide force field", "Adopt Presto", and "Refactor OpenFF
Toolkit" from the proposal. Also clears the now-dangling dependency
on peptide-forcefield from protein-forcefield.md, regenerates
data/projects.js, and updates the project count in README.md
(23 -> 21).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Category infrastructure, marked as alternative. Content (summary,
goals, benefits, FTE, metrics, go/no-go gates) is left as TODO
placeholders for staff to fill in.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adapts the full proposal text into the summary, goals, and benefits
fields, condensed and reoriented for an internal staff audience
rather than a funding pitch. Also infers infra_updates and
benchmarking as pipeline stages from the described work.

FTE and go/no-go gate date are left blank — the source text gives a
90% success target but no FTE estimate or a dated gate, and I didn't
want to invent either.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ield

Marks "A folded protein force field" as a dependency, and mirrors it
as an "enables" entry on protein-forcefield.md to keep the
dependency graph consistent in both directions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
6 months science (new code), 6 months science (experiments),
12 months infrastructure.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Category infrastructure, marked as alternative. Content (summary,
goals, benefits, FTE, metrics, go/no-go gates) is left as TODO
placeholders for staff to fill in.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sync generated data with the manual edits to
mlip-setup-inference.md (commit 81e0db1).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Category infrastructure, marked as alternative. Content (summary,
goals, benefits, FTE, metrics, go/no-go gates) is left as TODO
placeholders for staff to fill in.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adapts the proposal text into summary, goals, benefits, and metrics,
focused on the OpenFF-side work (active-learning-capable fitting
pipeline, QCArchive/OpenFF interoperability). The QCArchive-side
agent-friendliness work (chemical search, permissions) is scoped as
an external-goal metric rather than an OpenFF goal, and FTE is set
to 24 infrastructure / 12 science (new code) / 12 science
(experiments) months.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Category usability, marked as alternative. Content (summary, goals,
benefits, FTE, metrics, go/no-go gates) is left as TODO placeholders
for staff to fill in.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds summary, goals, benefits, FTE, stages, and metrics based on the
proposal for making OpenFF and Open Free Energy AI-native: MCP
interfaces, a hardened agentic workflow built on Genentech's OpenFE
agent, guardrails against invalid calculation setups, and Alchemiscale
execution-state improvements. Goals that involve OpenFE, Genentech, or
Alchemiscale rather than OpenFF's own codebase are marked as external.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
_projects/*.md and README.md were being picked up as regular content
pages (Hugo has no special handling for a leading-underscore directory
name), so every project appeared twice on the roadmap page: once as a
JS-rendered card and once via the theme's list.html looping over
Paginator.Pages. Excludes both via ignoreFiles in config.toml.

project.html (the project detail template) is also excluded from page
listings via _build.list: never, since it's meant to be navigated to
directly with a ?id= query param, not listed as its own article.

Verified via a full before/after site build diff that no other page
outside content/about/roadmap/ is affected.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jameseastwood jameseastwood linked an issue Jul 14, 2026 that may be closed by this pull request

@jameseastwood jameseastwood left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit (edit: 40f2d36) modified config.toml, so I consider it this only high-risk Claude commit (meaning high risk of breaking the website). I had Claude check the entire site diffs for anything that could have broken, and the only thing that turned up was a sort order of some entries that (Claude claimed) were an artifact of obscure Hugo tie-breaking rules for ranking unordered lists. My manual spot-checks couldn't find anything else affected by the changes either, but please check any other way you can think of.

@jameseastwood

Copy link
Copy Markdown
Contributor Author
Screenshot from 2026-07-13 21-11-07

@Yoshanuikabundi Yoshanuikabundi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I've done a quick once over after noticing that dark mode looks pretty bad. I think Claude can probably take care of these items itself pretty handily, probably with a lot of "oh great point" "good catch" etc. Happy to do another round later on the actual aesthetics!

Comment thread content/about/roadmap/css/main.css Outdated
Comment on lines +93 to +119
/* ---- Theme toggle button --------------------------------- */
.theme-toggle {
display: flex;
align-items: center;
gap: 0.4rem;
padding: 0.3rem 0.65rem;
background: var(--color-surface-2);
border: 1px solid var(--color-border);
border-radius: 999px;
color: var(--color-text-muted);
font-size: 0.75rem;
font-weight: 500;
font-family: var(--font-sans);
cursor: pointer;
transition: border-color 0.15s, color 0.15s, background 0.15s;
white-space: nowrap;
margin-left: auto;
flex-shrink: 0;
}

.theme-toggle:hover {
border-color: var(--color-border-light);
color: var(--color-text);
}

.theme-toggle .toggle-icon { font-size: 0.9rem; line-height: 1; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This button is never used! I think this CSS can safely be deleted, and should be especially if the dark theme above is removed:

Suggested change
/* ---- Theme toggle button --------------------------------- */
.theme-toggle {
display: flex;
align-items: center;
gap: 0.4rem;
padding: 0.3rem 0.65rem;
background: var(--color-surface-2);
border: 1px solid var(--color-border);
border-radius: 999px;
color: var(--color-text-muted);
font-size: 0.75rem;
font-weight: 500;
font-family: var(--font-sans);
cursor: pointer;
transition: border-color 0.15s, color 0.15s, background 0.15s;
white-space: nowrap;
margin-left: auto;
flex-shrink: 0;
}
.theme-toggle:hover {
border-color: var(--color-border-light);
color: var(--color-text);
}
.theme-toggle .toggle-icon { font-size: 0.9rem; line-height: 1; }

Comment thread content/about/roadmap/css/main.css Outdated
Comment on lines +27 to +92
/* ---- Custom Properties — Dark (default) ------------------ */
:root {
--color-bg: #0f1117;
--color-surface: #1a1d27;
--color-surface-2: #222636;
--color-border: #2d3148;
--color-border-light: #3d4260;
--color-text: #e2e8f0;
--color-text-muted: #8892a4;
--color-text-faint: #4a5568;
--color-accent: #6366f1;
--color-accent-hover: #818cf8;

/* Category colors — must match projects.js */
--cat-infrastructure: #6366f1;
--cat-domain: #10b981;
--cat-accuracy: #f59e0b;
--cat-benchmarking: #3b82f6;
--cat-usability: #ec4899;

/* Maturity colors */
--mat-early: #f97316;
--mat-mid: #eab308;
--mat-late: #22c55e;
--mat-end: #94a3b8;
--mat-full: #a78bfa;

--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;

--shadow-sm: 0 1px 3px rgba(0,0,0,0.4);
--shadow-md: 0 4px 16px rgba(0,0,0,0.5);
--shadow-lg: 0 8px 32px rgba(0,0,0,0.6);

--font-sans: "Montserrat", system-ui, -apple-system, sans-serif;
--font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

--max-width: 1400px;
--nav-height: 60px;

/* Graph node text (SVG fill fallback via CSS variable) */
--graph-node-text: #e2e8f0;
}

/* ---- Light mode ------------------------------------------ */
[data-theme="light"] {
--color-bg: #f8f9fc;
--color-surface: #ffffff;
--color-surface-2: #f1f3f8;
--color-border: #dde1ee;
--color-border-light: #c8cee0;
--color-text: #1a1d2e;
--color-text-muted: #5a6378;
--color-text-faint: #9ba3b8;
--color-accent: #5254cc;
--color-accent-hover: #4547b0;

--shadow-sm: 0 1px 3px rgba(0,0,0,0.08);
--shadow-md: 0 4px 16px rgba(0,0,0,0.1);
--shadow-lg: 0 8px 32px rgba(0,0,0,0.12);

--graph-node-text: #1a1d2e;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dark mode looks really bad, as only the roadmap has this feature:

Image

I'd suggest just removing the [data-theme] selector and making light mode the only mode:

Suggested change
/* ---- Custom Properties — Dark (default) ------------------ */
:root {
--color-bg: #0f1117;
--color-surface: #1a1d27;
--color-surface-2: #222636;
--color-border: #2d3148;
--color-border-light: #3d4260;
--color-text: #e2e8f0;
--color-text-muted: #8892a4;
--color-text-faint: #4a5568;
--color-accent: #6366f1;
--color-accent-hover: #818cf8;
/* Category colors — must match projects.js */
--cat-infrastructure: #6366f1;
--cat-domain: #10b981;
--cat-accuracy: #f59e0b;
--cat-benchmarking: #3b82f6;
--cat-usability: #ec4899;
/* Maturity colors */
--mat-early: #f97316;
--mat-mid: #eab308;
--mat-late: #22c55e;
--mat-end: #94a3b8;
--mat-full: #a78bfa;
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--shadow-sm: 0 1px 3px rgba(0,0,0,0.4);
--shadow-md: 0 4px 16px rgba(0,0,0,0.5);
--shadow-lg: 0 8px 32px rgba(0,0,0,0.6);
--font-sans: "Montserrat", system-ui, -apple-system, sans-serif;
--font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
--max-width: 1400px;
--nav-height: 60px;
/* Graph node text (SVG fill fallback via CSS variable) */
--graph-node-text: #e2e8f0;
}
/* ---- Light mode ------------------------------------------ */
[data-theme="light"] {
--color-bg: #f8f9fc;
--color-surface: #ffffff;
--color-surface-2: #f1f3f8;
--color-border: #dde1ee;
--color-border-light: #c8cee0;
--color-text: #1a1d2e;
--color-text-muted: #5a6378;
--color-text-faint: #9ba3b8;
--color-accent: #5254cc;
--color-accent-hover: #4547b0;
--shadow-sm: 0 1px 3px rgba(0,0,0,0.08);
--shadow-md: 0 4px 16px rgba(0,0,0,0.1);
--shadow-lg: 0 8px 32px rgba(0,0,0,0.12);
--graph-node-text: #1a1d2e;
}
/* ---- Custom Properties ------------------ */
:root {
/* Category colors — must match projects.js */
--cat-infrastructure: #6366f1;
--cat-domain: #10b981;
--cat-accuracy: #f59e0b;
--cat-benchmarking: #3b82f6;
--cat-usability: #ec4899;
/* Maturity colors */
--mat-early: #f97316;
--mat-mid: #eab308;
--mat-late: #22c55e;
--mat-end: #94a3b8;
--mat-full: #a78bfa;
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--font-sans: "Montserrat", system-ui, -apple-system, sans-serif;
--font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
--max-width: 1400px;
--nav-height: 60px;
--color-bg: #f8f9fc;
--color-surface: #ffffff;
--color-surface-2: #f1f3f8;
--color-border: #dde1ee;
--color-border-light: #c8cee0;
--color-text: #1a1d2e;
--color-text-muted: #5a6378;
--color-text-faint: #9ba3b8;
--color-accent: #5254cc;
--color-accent-hover: #4547b0;
--shadow-sm: 0 1px 3px rgba(0,0,0,0.08);
--shadow-md: 0 4px 16px rgba(0,0,0,0.1);
--shadow-lg: 0 8px 32px rgba(0,0,0,0.12);
/* Graph node text (SVG fill fallback via CSS variable) */
--graph-node-text: #1a1d2e;
}

Comment thread content/about/roadmap/css/main.css Outdated
--color-accent: #6366f1;
--color-accent-hover: #818cf8;

/* Category colors — must match projects.js */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is incorrect. These colors do appear in projects.js, but where they have to match is build.py which generates projects.js. They also appear in utils.js. In both cases, the JS files should be corrected to use the variable defined here to preserve a single source of truth and prevent things drifting out of alignment.

Comment thread content/about/roadmap/js/utils.js Outdated
Comment on lines +3 to +17
export const CATEGORIES = {
infrastructure: { label: "Infrastructure / Fitting Pipeline", color: "#6366f1" },
domain: { label: "Domain Expansion", color: "#10b981" },
accuracy: { label: "Accuracy Improvements", color: "#f59e0b" },
benchmarking: { label: "Benchmarking", color: "#3b82f6" },
usability: { label: "Usability / Community", color: "#ec4899" },
};

export const MATURITY_COLORS = {
early: "#f97316",
mid: "#eab308",
late: "#22c55e",
end: "#94a3b8",
full: "#a78bfa",
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should use the color CSS variables - just replacing the color strings with things like var(--cat-infrastructure) might work? Using the variable names defined in content/about/roadmap/css/main.css

Comment thread content/about/roadmap/build.py Outdated
Comment on lines +137 to +161
export const CATEGORIES = {{
infrastructure: {{ label: "Infrastructure / Fitting Pipeline", color: "#6366f1" }},
domain: {{ label: "Domain Expansion", color: "#10b981" }},
accuracy: {{ label: "Accuracy Improvements", color: "#f59e0b" }},
usability: {{ label: "Usability / Community", color: "#ec4899" }},
}};

export const STAGE_LABELS = {{
infra_updates: "Upfront Infrastructure",
data_generation: "Data Generation",
fitting: "Fitting",
benchmarking: "Benchmarking",
release: "Release",
community_maintenance: "Community & Maintenance",
}};

export const ALL_STAGES = ["infra_updates", "data_generation", "fitting", "benchmarking", "release", "community_maintenance"];

export const MATURITY_COLORS = {{
early: "#f97316",
mid: "#eab308",
late: "#22c55e",
end: "#94a3b8",
full: "#a78bfa",
}};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These colors appear to be duplicates of those found in content/about/roadmap/css/main.css, they should be replaced with references to those CSS variables. This might be as simple as var(--cat-infrastructure), depending on what the JS does with them.

Comment thread content/about/roadmap/data/projects.js Outdated
Comment on lines +1 to +2
// AUTO-GENERATED by build.py — do not edit manually.
// Edit _projects/*.md files instead, then re-run: python build.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems really fragile, would be good to find a way for this (or an equivalent) to be run automatically by Hugo during the build process.

Comment thread content/about/roadmap/404.html Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't appear to be wired up anywhere, and putting a nonsense URL like http://localhost:1313/about/roadmap/asdf into the Hugo web server doesn't bring it up. It would be great if something like this could be wired up to the entire site, as we currently just have the GH Pages 404 page. I don't think there's any need for the roadmap to have its own 404 page.

Comment thread content/about/roadmap/build.py Outdated
import frontmatter
import markdown
except ImportError:
print("ERROR: Missing dependencies. Run: pip install -r requirements.txt")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asking most of the people who would plausibly run this script to install things to the system Python is probably a bit of a nonstarter - we should use a simple pixi setup, or a conda environment.yaml, or (best option) reimplement this script in Ruby or JS or whatever Hugo uses to write extensions.

Comment thread content/about/roadmap/build.py Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I asked Claude about using hugo-native features to replace this (Claude is at least pretty good at cleaning up its mistakes and shortsightedness when you identify them!) and it said the following:

Hugo can do this natively — it's basically the core of what Hugo is. The pieces you want:

Content sections + list templates are the main mechanism. Put the markdown files under content/<section>/. Everything in the frontmatter surfaces in templates as .Params (plus the built-ins like .Title, .Date, .Weight), and the body is available as .Content (rendered HTML), .RawContent, .Plain, or .Summary. Then the section's template does the collation that build.py was doing, and emits your custom HTML directly:

{{/* layouts/notes/section.html  (Hugo ≥ 0.146; layouts/notes/list.html on older versions) */}}
{{ define "main" }}
  <ul class="notes">
    {{ range .Pages.ByDate.Reverse }}
      <li>
        <h2>{{ .Title }}</h2>
        <p class="meta">{{ .Params.category }}</p>
        {{ .Content }}
      </li>
    {{ end }}
  </ul>
{{ end }}

where, sort, group, first, complement etc. cover essentially any filtering/ordering/grouping you'd do in Python, and taxonomies give you tag-style groupings with their own generated pages for free. This replaces both halves at once: collation happens at build time in the template, and the "JS rendering" becomes plain server-generated HTML.

Suppressing per-item pages. If these files are data-like and shouldn't each get their own URL, cascade build options from the section's _index.md:

cascade:
  build:
    render: never
    list: local

The pages still appear in .Pages for the section template but produce no standalone output.

Module mounts if the markdown can't live under content/ for some reason:

[[module.mounts]]
source = "some/subdir"
target = "content/notes"

Hugo then treats that directory as if it were content, no file moves required.

Custom output formats, in case anything still genuinely needs JSON (a search index, say). JSON is a built-in output format; enable it per page kind and add a template for it:

[outputs]
section = ["html", "json"]
{{/* layouts/notes/section.json */}}
{{- $items := slice -}}
{{- range .Pages -}}
  {{- $items = $items | append (dict "title" .Title "url" .RelPermalink "body" .Plain) -}}
{{- end -}}
{{- $items | jsonify -}}

This is the standard way people build client-side search indexes without a second build system — but given you're dropping the JS renderer, you probably only need the HTML output.

Two smaller things worth knowing. First, templates can fail the build: {{ errorf "notes/%s missing required 'category'" .File.Path }} when a required frontmatter field is absent. Hugo has no built-in frontmatter schema validation, but errorf guards in the list template (plus cascade for defaults) get you build-time enforcement rather than silently-wrong output, which fits your error-before-runtime lean. Second, if "custom HTML" partly means customizing how the markdown itself renders (links, images, headings, code fences), that's render hooks — layouts/_markup/render-image.html and friends — rather than anything in the list template.

One caveat on paths: Hugo v0.146 (April 2025) flattened the template layout — layouts/_default/list.html became layouts/section.html, single.html became page.html, partials moved to layouts/_partials/. The old names still resolve for compatibility, so match whatever the project already uses, but new templates are better written against the new names.

Comment thread config.toml Outdated
Comment on lines +8 to +12
# content/about/roadmap/_projects/*.md are data sources for build.py
# (compiled into data/projects.js), not standalone Hugo pages.
# content/about/roadmap/README.md is repo documentation, not a page.
ignoreFiles = ["/_projects/", "README\\.md$"]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would bite us in the future if we ever add another _projects directory or README.md file expecting it to build normally. The readme is probably safe but _projects could definitely come back to haunt us. Fortunately we can probably remove _projects if we port build.py to a Hugo-native format, or else put more of the path in that element or change it to something like "/_manually_built_data/" or something else less overloaded.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestions. I thought this was ugly but didn't have a great idea of how else to approach it.

@jaclark5 jaclark5 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read the agentic*.md and descent/smee files and didn't notice anything to change.

I have made a couple stylistic suggestions.

Comment thread content/about/roadmap/css/main.css Outdated

/* ---- Custom Properties — Dark (default) ------------------ */
:root {
--color-bg: #0f1117;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
--color-bg: #0f1117;
--color-bg: ##ffffff;

Change background from gray to white to create a continuous background color and avoid this:

Image

Comment thread content/about/roadmap/_index.md Outdated
const fte = totalFTE(p);
return `
<a href="${projectURL(p.id)}" class="card card-link" style="
border-left: 3px ${p.recommended ? 'solid' : 'dotted'} ${cat.color};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
border-left: 3px ${p.recommended ? 'solid' : 'dotted'} ${cat.color};
border-left: ${p.recommended ? '5px solid' : '2px dotted'} ${cat.color};

Make the priority cards more prominent

from:

Image

to:

Image

jameseastwood and others added 3 commits July 14, 2026 23:02
…ting hex

Category and maturity colors were hardcoded separately in build.py's
generated output, data/projects.js, and js/utils.js, several of which
were unused duplicates that had drifted out of sync with css/main.css.
JS now reads the colors from :root via a cssVar() helper instead.

Also fixes css/main.css itself: the last two commits removed the
:root/[data-theme="light"] selectors around the --cat-*/--mat-*
declarations but left the declarations behind, so they'd been sitting
outside any rule (and thus ignored by the browser) since then.

Regenerating data/projects.js via build.py also picked up the
already-committed FTE correction for agentic-qc-data-ecosystem that
the stale generated file hadn't reflected yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
content/about/roadmap/404.html was a static file with roadmap-relative
links that nothing ever served or linked to. layouts/404.html is a
proper Hugo template extending the theme's baseof, so it renders with
the site's real header/nav/footer. Hugo builds this into public/404.html
automatically, which GitHub Pages serves for any unmatched path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
_projects/*.md were compiled by a Python script (build.py) into
data/projects.js, which project.js/graph.js/the _index.md grid then
read client-side to render everything via innerHTML. Nothing in CI
ran build.py, so data/projects.js had to be regenerated and committed
by hand -- exactly how it went stale and produced wrong FTE numbers
earlier on this branch.

Projects now live under content/about/roadmap/projects/ as real Hugo
pages, rendered server-side by layouts/_default/roadmap-project.html
(selected via a cascaded `layout: roadmap-project`) and the
roadmap-grid shortcode on the overview page. Category/stage labels
move to data/roadmap/*.yaml (Hugo site data) as the single source of
truth. Bad category/stage values or dangling dependencies/enables
references now fail the Hugo build with errorf instead of silently
falling back to a default.

Dropped along with this: the D3 dependency graph (graph.js/graph.css),
which was already unwired from every page, and the grid's client-side
sort-by-key code, which had no UI ever wired up to trigger it. Deleted
build.py, requirements.txt, project.html, and the four now-unused JS
files; removed the CSS left dangling by their removal.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jameseastwood

Copy link
Copy Markdown
Contributor Author
image image

I think these changes address Ashley's comments from the previous review: remove dark mode, use the 404 page across the whole site, strip out the nested build system and convert the entire roadmap structure to native Hugo pages. Couldn't have done it myself, but I think the result is much lighter-weight and more useable.

@Yoshanuikabundi Yoshanuikabundi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is much better! The code is simpler to build, easier to understand, I think there's less of it, and it doesn't need to carry around a JSON-formatted copy of everything in _projects/!

My comments are mostly regarding the legibility of color choices, but there's a bit of layout and DRYness. There are no blockers, but I think most of my suggestions are straightforward improvements.

I do have one possibly controversial comprehensibility suggestion in roadmap/_index.md that suggests making the difference between alt and recommended projects clearer by breaking them into separate grids, and also using markdown instead of html to format their headings. But I could just be misreading the whole point.

Also, at the moment Hugo orders pages (roughly?) alphabetically, but I think it would be slightly more slick to order projects them by their pipeline stage, both in the grid and the next/prev buttons on each project page. I've pushed this as a PR to this PR's branch: #582

This is really neat and I'm looking forward to how easy its going to make updating the roadmap!

- **Infrastructure** — Improving the software tools we use for fitting, to enable faster fitting experiments involving larger datasets and advanced fitting targets or methods.
- **Usability / Community** — Putting our software and models into the hands of real users and enabling them to advance their scientific programs.

The projects listed here are proposals developed by staff that represent our vision of steps we could take that move us toward our roadmap objectives. Projects that we believe to offer the most direct path toward value to the Open Force Field Consortium are listed first. Projects listed as "ALT" (dashed border) may be of interest to alternative funding sources.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Projects listed as "ALT" (dashed border) may be of interest to alternative funding sources.

Does this mean we're not actually planning to do them unless someone gives us more money? If so I think we should make them stand out more - make the ALT label pillbox like bright red with a tooltip that says, like, "Pending additional funding", or break the grid up to put them in an altogether separate category with its own explanation, something like

# Recommended projects
{{< roadmap-grid-rec >}}
# Alternative projects
These are projects we'd like to do, but presently require additional funding sources.
{{< roadmap-grid-alt >}}

And maybe a more idiomatic terminology like "stretch goal" would be clearer than "alternative"?

Comment thread content/about/roadmap/css/main.css
Comment thread layouts/404.html

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works! Amazing!

Comment on lines +21 to +28
<section style="margin-top:3rem;">
<div style="display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-bottom:1.25rem; flex-wrap:wrap;">
<h2 style="font-size:1rem; font-weight:600; color:var(--color-text-muted); text-transform:uppercase; letter-spacing:0.08em; margin:0;">
All Projects
</h2>
</div>
{{< roadmap-grid >}}
</section>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(non-blocking) I'd be tempted to just do:

Suggested change
<section style="margin-top:3rem;">
<div style="display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-bottom:1.25rem; flex-wrap:wrap;">
<h2 style="font-size:1rem; font-weight:600; color:var(--color-text-muted); text-transform:uppercase; letter-spacing:0.08em; margin:0;">
All Projects
</h2>
</div>
{{< roadmap-grid >}}
</section>
### All Projects
{{< roadmap-grid >}}

Looks approximately the same but more in line with the overall theme, and much easier to read in the source.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scrolling this page all the way down leaves no margin between the bottom of the grid and the footer:

image

I'd just ask Claude where the best place to fix this is coz I'm not sure, it depends on the interplay between Claude's CSS and the overall website theme's, neither of which I really understand.

--max-width: 1400px;
--nav-height: 60px;

--color-bg: #f8f9fc;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
--color-bg: #f8f9fc;
--color-bg: #ffffff00;

I agree with Jen, this should be either white to match the site background, transparent, or just removed everywhere so that the background falls back to the containing element.

Comment thread layouts/shortcodes/roadmap-grid.html Outdated
Comment on lines +1 to +12
{{/* Renders the "All Projects" card grid: recommended projects first, then alternatives. */}}
{{ $projSection := .Page.Site.GetPage "/about/roadmap/projects" }}
{{ $cats := .Page.Site.Data.roadmap.categories }}

<div id="project-grid" style="display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:1rem;">
{{ range (where $projSection.Pages "Params.recommended" true) }}
{{ partial "roadmap-grid-card" (dict "page" . "cats" $cats) }}
{{ end }}
{{ range (where $projSection.Pages "Params.recommended" false) }}
{{ partial "roadmap-grid-card" (dict "page" . "cats" $cats) }}
{{ end }}
</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Splitting the recommended and alternatives into different grids could be done like this:

Suggested change
{{/* Renders the "All Projects" card grid: recommended projects first, then alternatives. */}}
{{ $projSection := .Page.Site.GetPage "/about/roadmap/projects" }}
{{ $cats := .Page.Site.Data.roadmap.categories }}
<div id="project-grid" style="display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:1rem;">
{{ range (where $projSection.Pages "Params.recommended" true) }}
{{ partial "roadmap-grid-card" (dict "page" . "cats" $cats) }}
{{ end }}
{{ range (where $projSection.Pages "Params.recommended" false) }}
{{ partial "roadmap-grid-card" (dict "page" . "cats" $cats) }}
{{ end }}
</div>
{{/* Renders the "All Projects" card grid: recommended projects or alternatives based on recommended argument. */}}
{{ $projSection := .Page.Site.GetPage "/about/roadmap/projects" }}
{{ $cats := .Page.Site.Data.roadmap.categories }}
{{ $recommended := .Get "recommended" | default true }}
<div id="project-grid-{{cond $recommended "recommended" "alternate"}}" style="display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:1rem;">
{{ range (where $projSection.Pages "Params.recommended" $recommended) }}
{{ partial "roadmap-grid-card" (dict "page" . "cats" $cats) }}
{{ end }}
</div>

Then {{< roadmap-grid recommended=true >}} displays the recommended grid and {{< roadmap-grid recommended=false >}} displays the alternates. So the bottom of _index.html could look something like:

<link rel="stylesheet" href="css/main.css">

### Recommended Projects

{{< roadmap-grid recommended=true >}}

### Alternative Projects

These projects may be achievable with additional funding.

{{< roadmap-grid recommended=false >}}

Comment thread layouts/shortcodes/roadmap-grid.html Outdated
Comment on lines +6 to +8
{{ range (where $projSection.Pages "Params.recommended" true) }}
{{ partial "roadmap-grid-card" (dict "page" . "cats" $cats) }}
{{ end }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorting this by pipeline stage rather than alphabetically by page source name would be swish!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #582!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much better than the Python script with runtime JS!

Comment on lines +219 to +236
<div class="project-nav">
{{ if $prev }}
<a href="{{ $prev.RelPermalink }}" class="project-nav-link prev">
&larr; <span>
<span class="nav-link-label">Previous</span>
<span class="nav-link-title">{{ $prev.Title }}</span>
</span>
</a>
{{ else }}<span></span>{{ end }}
{{ if $next }}
<a href="{{ $next.RelPermalink }}" class="project-nav-link next">
<span>
<span class="nav-link-label">Next</span>
<span class="nav-link-title">{{ $next.Title }}</span>
</span> &rarr;
</a>
{{ end }}
</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is neat for going through the projects one at a time, but we should try and order them by pipeline stage.

@jameseastwood

Copy link
Copy Markdown
Contributor Author

Fixed the margin:
image

Co-authored-by: Ashley Mitchell <yoshanuikabundi@gmail.com>
@jameseastwood

Copy link
Copy Markdown
Contributor Author

Upon discussion with @j-wags in standup and after checking the site render locally, I'm merging as-is so we have live links that folks have asked for. If it's broke, I'll fix it.

@jameseastwood
jameseastwood merged commit 447ddc8 into v2 Jul 20, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update "Roadmap"

3 participants