Imported from adriankarlen/textfox (
AGENTS.md). Install upstream withnpx skills add adriankarlen/textfox. Copyright stays with the author.
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this is
textfox is a Firefox userChrome CSS theme for TUI enthusiasts. No JavaScript framework, no bundler — just CSS files, SVG icons, shell scripts, and a Nix flake.
Commands
Nix formatting (CI enforced):
nix run nixpkgs#nixfmt-tree # format all Nix files
nix run nixpkgs#nixfmt-tree -- --check # check only (what CI runs)
Install/uninstall (manual testing):
sh tf-install.sh # interactive install to a Firefox profile
sh tf-uninstall.sh # interactive uninstall
No test suite exists. Changes are validated by loading Firefox with the theme applied.
Architecture
CSS layer
chrome/userChrome.css is the entry point — it @imports every other CSS file and applies global font/body rules. Load order matters: defaults.css must come before config.css (user overrides).
All theming flows through CSS custom properties prefixed --tf-*, defined in chrome/defaults.css. Users customize by creating chrome/config.css which overrides those variables. Never hard-code colors; always reference --tf-* vars or Firefox's own theme vars (e.g. var(--lwt-accent-color)).
CSS file responsibilities:
defaults.css— canonical--tf-*variable definitions and their defaultsoverwrites.css— Firefox internal style resetsnavbar.css,urlbar.css,sidebar.css,tabs.css,findbar.css,menus.css,browser.css— per-component stylesicons.css— icon overrides (references SVGs inchrome/icons/)content/newtab.css,content/about.css→ loaded intouserContent.css
Nix layer
The flake exposes two delivery mechanisms:
home-manager module (nix/modules/home-manager.nix):
- Copies
chrome/directory into the Firefox profile viahome.file - Writes a generated
config.css(fromtextfox.configCss) intochrome/config.css - Injects
user.jsprefs viaprograms.firefox.profiles.<name>.extraConfig
NixOS module (nix/modules/nixos.nix):
- Uses
wrapTextfox(nix/pkgs/wrapTextfox.nix) to wrap the Firefox binary wrapTextfoxgenerates a single concatenateduserChrome.cssanduserContent.cssat build time (no@import, all CSS inlined), then installs them via an autoconfig script that runs on Firefox startup and copies files from the Nix store to the profile'schrome/dir- Hash-file mechanism detects when the Nix store path changes and restarts Firefox to apply updates
All Nix option definitions live in nix/modules/options.nix and are shared by both modules. The textfox.configCss (read-only) attribute assembles the final CSS string from all structured options.
Key design constraints
- No hard-coded colors anywhere in CSS — theme colors come from Firefox's LWT variables or user's
config.css config.cssis user-owned and excluded from wrapTextfox's@importchain (it's appended at the end)- Icon logic (
shyfox.*prefs) is inherited from ShyFox; the sameabout:configkeys apply
Keeping CSS and Nix in sync
Adding or renaming a --tf-* variable requires changes in three places:
chrome/defaults.css— add the variable with its default valuenix/modules/options.nix— add a correspondingmkOptionunderoptions.textfox.confignix/modules/options.nixconfigCssstring — wire the new option into the generated:root { }block
The configCss read-only option is what home-manager writes as config.css and what wrapTextfox appends last. If a variable exists in defaults.css but not in configCss, Nix users can't configure it and the default will always win over their textfox.config.* settings.