Tilo themes and native UI refinements for Forgejo.
  • CSS 55.6%
  • JavaScript 20.6%
  • TypeScript 17.3%
  • Go Template 6.4%
  • Makefile 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-25 08:04:22 +00:00
assets Rebalance dark paper and repository hierarchy 2026-10-24 23:08:58 -07:00
legacy@fb23c66063 Reference the preserved legacy theme from its own repository 2026-10-25 00:10:44 -07:00
licenses Add a tilo homepage and a quieter Forgejo application theme 2026-10-24 12:41:19 -07:00
public/assets/css Use OS graphite and brand yellow; retain named legacy themes 2026-10-25 00:03:46 -07:00
src Use OS graphite and brand yellow; retain named legacy themes 2026-10-25 00:03:46 -07:00
templates Name themes in the native picker without overriding locales 2026-10-25 01:03:38 -07:00
.gitattributes Add a tilo homepage and a quieter Forgejo application theme 2026-10-24 12:41:19 -07:00
.gitignore Add a tilo homepage and a quieter Forgejo application theme 2026-10-24 12:41:19 -07:00
.gitmodules Reference the preserved legacy theme from its own repository 2026-10-25 00:10:44 -07:00
build.mjs Reference the preserved legacy theme from its own repository 2026-10-25 00:10:44 -07:00
bun.lock Add a tilo homepage and a quieter Forgejo application theme 2026-10-24 12:41:19 -07:00
deployment-patch.yaml Name themes in the native picker without overriding locales 2026-10-25 01:03:38 -07:00
Makefile Add a tilo homepage and a quieter Forgejo application theme 2026-10-24 12:41:19 -07:00
package.json Name themes in the native picker without overriding locales 2026-10-25 01:03:38 -07:00
podman-compose.yaml Name themes in the native picker without overriding locales 2026-10-25 01:03:38 -07:00
PROD_PLAN.md Share the native masthead and responsive frame across the forge 2026-10-24 15:25:06 -07:00
README.md Name themes in the native picker without overriding locales 2026-10-25 01:03:38 -07:00
review-controls.mjs Use OS graphite and brand yellow; retain named legacy themes 2026-10-25 00:03:46 -07:00
review-navigation.mjs Rebalance dark paper and repository hierarchy 2026-10-24 23:08:58 -07:00
review-repository.mjs Name themes in the native picker without overriding locales 2026-10-25 01:03:38 -07:00
review-themes.mjs Name themes in the native picker without overriding locales 2026-10-25 01:03:38 -07:00
review.mjs Name themes in the native picker without overriding locales 2026-10-25 01:03:38 -07:00
seed-projects.mjs Add a tilo homepage and a quieter Forgejo application theme 2026-10-24 12:41:19 -07:00
seed.mjs Keep long diff paths within narrow viewports 2026-10-24 19:10:00 -07:00
VISUAL-REVIEW.md Name themes in the native picker without overriding locales 2026-10-25 01:03:38 -07:00

tilo — Forgejo

One visual system, with poster density on the homepage and working density throughout the application:

  • The public homepage is a ruled, cream-and-ink print using the same native masthead and desktop frame as every other route, with the original full-colour tilo logos and tilo.so's Bayer-dithered Bauhaus composition. The artwork is exploratory: no instruction panel or visible control buttons. Keyboard users can focus it and use Enter to change shapes, Space to pause/resume, and Escape to stop. Reduced motion and page visibility are respected.
  • The application carries the print language into the components themselves: tilo.so's exact cream paper (#f0e9d8) and risograph grain across every route (warm charcoal in dark mode), square controls, ink rules, monospaced navigation/metadata and bold proportional headings. Blue links and yellow active tabs connect the workbench to the masthead; semantic statuses and diffs retain their own colours. Repository titles, toolbars and file lists share an ordinary centered content column, capped at 1280px. The outer sheet, border and masthead remain near the viewport edges; content gains no extra enclosing card or frame. Counts form an inline metadata row; language proportions span the content width, with native disclosure for names and percentages. Repository actions have one outline per action/count pair. Topic names deterministically select blue, red or yellow across repository and directory pages. File actions are one unboxed utility row, and history is a heading, search and table rather than nested panels. Mobile is edge-to-edge, with no outer print border. Repository controls stay compact. Repositories, Users and Organizations share a directory heading and small, idle-free pixel print; search, filters and result lists remain native. Personal collections are grouped under Your work, preserving the native routes and visibility gates.

Repository composition

Dark paper uses the OS's graphite base #16171b, with warm off-white text, quieter rules and reduced grain. Light paper remains exactly #f0e9d8. Outer sheet/masthead rules are 2px; application boundaries are 1px, with no extra active-tab edge. Native semantic status and diff colours remain independent of topic colours.

src/theme.ts adds topic-colour attributes and names the native language disclosure for assistive technology. It does not replace links, forms, dropdowns or disclosure handlers. bun test src/theme.test.ts checks stable topic hashing.

Theme choices

The default tilo-auto follows the system appearance using the new design. In the native theme picker, tilo-light is Tilo, tilo-dark is Tilo Dark, and tilo-auto is Tilo (system). Both modes use the brand yellow #f2b51c.

The stable podesta-light, podesta-dark and podesta-auto preference IDs now serve their original rounded stylesheets, labelled Tilo Legacy, Tilo Legacy Dark and Tilo Legacy (system). Legacy uses native homepage/directory layouts, without the new theme's navigation or topic enhancements. A pinned native appearance template supplies only the theme display names; built-in translations are not overridden and saved theme IDs remain valid.

Local preview

Requires rootless Podman, podman-compose, Bun and Playwright's browser dependencies.

git submodule update --init --recursive
bun install
bunx playwright install chromium firefox
make preview

Open http://localhost:19100. Sign in as reviewer, password tilo-preview-only.

The public homepage is visible while signed out. Signing in opens Forgejo's normal dashboard. The preview includes tilo/tilo, a syntax-highlighted Rust file, a pull request with additions/deletions and merge controls, a labelled issue, project boards with a real issue card, an organization, and public/private repositories. All are synthetic local fixtures.

The preview uses the exact production Forgejo 16.0.3 image digest, including its existing backend patches, but a separate disposable SQLite database and rootless volume. Only 127.0.0.1:19100 is published. It uses no production data or credentials, SSO setup, mail delivery, registered runners or host container socket. SSH is not published, and no Kubernetes credentials are mounted. Local password sign-in does not simulate production SSO; production authentication settings are not changed by this theme.

make reload             # regenerate assets and restart template caches
bun run review          # Chromium + Firefox, functional and visual checks
make down               # delete only this disposable preview and its data

make preview is repeatable. Asset generation needs Bun but not a native compiler or image build. Review evidence stays in ignored review-artifacts/.

Sources and generated files

Source Output / purpose
src/forgejo-16.0.3-{light,dark}.css Complete native theme foundation extracted from the pinned image; retains current tokens and control states. Upstream licence in licenses/Forgejo-LICENSE.
legacy/theme-podesta-{light,dark}.css (pinned tilo/forgejo-theme-old submodule) Historical baseline and source of established literal signal colours only. Its warm neutral ramp, floating-card selectors and typography are not compiled into the new theme. Compound-control and attached-stack regressions are covered explicitly in src/app.css and browser tests.
src/app.css, build.mjs Standalone public/assets/css/theme-tilo-{light,dark,auto}.css.
src/home.tmpl Generated templates/home.tmpl; uses the same upstream navbar as all other pages, with native footer and application-relative links.
templates/custom/extra_links.tmpl Shared discovery links and a personal-collections disclosure through the supported navbar hook.
src/explore-navbar.tmpl, src/directory.ts Generated directory heading and assets/directory.js; replaces the duplicate Explore tabs, not the native search/results.
src/bauhaus.ts, src/dither.ts, src/home.ts Generated assets/home.js; artwork adapted from tilo.so source revision 70bc75c.
assets/home.css Scoped homepage layout. Never loaded on application routes.
assets/ Unmodified official SVG/PNG logos, self-hosted fonts and OFL licences.
templates/base/head_style.tmpl Generated two-line upstream template with an additional content stamp for theme updates.
templates/custom/header.tmpl Generated favicon and font definitions, including for native-theme fallback.
templates/custom/extra_links_footer.tmpl Keeps Forgejo documentation accessible in the footer instead of the top bar.
deployment-patch.yaml Read-only mounts, theme allowlist, default, compatibility aliases and reload annotations.

Run bun run build after editing sources. Commit generated outputs too: production does not build this repository. A deterministic content stamp updates CSS, font and homepage asset URLs without requiring a Forgejo image upgrade. Do not hand-edit generated templates or stylesheets.

Forgejo constraints worth preserving

  1. A custom theme is loaded instead of, not merged with, a default theme. Shipping only a palette loses syntax highlighting and semantic tokens. Each generated theme includes the complete current native foundation plus Chroma rules. Older token lists alone also lose newer controls: an undefined secondary-border token makes unchecked checkboxes disappear.
  2. Attached panels need continuous square seams. Both internal and outer ends are square in this design; Fomantic's hard-coded compound-control corners must not reintroduce rounding or gaps.
  3. Split controls must retain their width on hover. Forgejo 16 uses logical border edges; overriding only physical borders revives the one-pixel resize.
  4. Thin coloured text and solid button fills need different colours. --color-thin-* and the diff-summary overrides keep red/green counts readable in dark mode without breaking button contrast.
  5. The upstream navbar, mobile toggle, account controls, forms, Markdown, syntax, diff signs and merge actions remain native. Supported template hooks provide the shared discovery links and personal-collections disclosure; no client-side DOM replacement is used. Conditional code search stays in the directory heading under the upstream indexer gate, rather than changing the primary masthead between routes.
  6. Go templates are cached and ConfigMap subPath updates do not propagate. Restart after updates. Do not replace the whole assets or custom-template directory in production: mount just these files/directories alongside Forgejo's embedded assets and any existing customizations.
  7. Keep native theme choices as an escape hatch. Production compatibility CSS aliases preserve existing users' explicit light/dark/automatic preferences rather than silently resetting them. Their old internal identifiers remain in the Appearance list until a separately approved preference migration removes them.
  8. Refresh the captured native foundation CSS and re-check the six small custom templates against the embedded upstream files before a Forgejo version change. In particular, keep the navigation visibility and indexer conditions aligned with the upstream navbar and Explore templates. Keep AssetVersion, ThemeName, PathEscape, AssetUrlPrefix and AppSubUrl; hard-coded root-relative application links break subpath installs.

See VISUAL-REVIEW.md for review coverage and PROD_PLAN.md for deployment and rollback. Publishing a theme revision does not deploy it: production changes only when the infra repository updates its pinned revision and Argo CD syncs it.