[PR #6909] [MERGED] docs(website): add dark-mode styles to the favicon and social card #7440

Closed
opened 2026-11-01 21:47:53 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/6909
Author: @CassieFox23
Created: 10/23/2026
Status: ✅ Merged
Merged: 10/23/2026
Merged by: @morluto

Base: main ← Head: docs/website-icons-dark-mode


📝 Commits (1)

  • a29add4 docs(website): add dark-mode styles to the favicon and social card

📊 Changes

3 files changed (+18 additions, -1 deletions)

View changed files

📝 website/figures.md (+5 -0)
📝 website/public/assets/favicon.svg (+1 -1)
📝 website/public/assets/social-card.svg (+12 -0)

📄 Description

TL;DR: The website icon and share card now have a dark style. The light version is pixel for pixel the same. Nobody has looked at it in a browser yet.

Summary

Adds a dark style to the website favicon and the social card. Before, the favicon tile (#20252b) sat almost invisible on a dark browser tab strip. It had 1.06:1 contrast against the site's dark page colour #1e1e2e. I computed that this job. The colour is --page in website/public/assets/styles.css, line 2759. The card, opened on its own, was light only. Now each SVG carries one prefers-color-scheme: dark block. The favicon tile becomes #89b4fa with a #11111b glyph (7.79:1 against #1e1e2e, glyph on tile 8.91:1, computed this job).
Related issue: none linked. The contributing guide says a doc change like this needs no okay in advance. So I opened this without one.

Problem and expected behavior

Not a bug fix. This is a polish change. Observable outcome: a person on a dark browser or OS setting sees a dark favicon. If they open social-card.svg directly, they see a dark card. A person on a light setting sees what they saw before.

Change and scope

Two SVG files get one inserted block each: website/public/assets/favicon.svg (a one-line <style>) and website/public/assets/social-card.svg (12 lines). Each edit is a pure insertion. website/figures.md gains one paragraph that says the card and favicon carry the block and that CairoSVG ignores it.
Not included: a dark link-preview PNG. CairoSVG, the renderer in scripts/prepare-website.py (line 46), ignores the @media wrapper, so the PNG that og:image and twitter:image point at stays light. One image serves every viewer, so a dark PNG would also be dark in light apps. That is a design choice for a maintainer, so I left it out.
Not included: anything for the other images. The five figure SVGs in website/public/assets/figures/ already carry a prefers-color-scheme block (git grep, this job). A sibling PR, on the branch docs/readme-showcase-dark-mode, handles the README showcase image. It adds its own section to website/figures.md at the same spot. That spot is right after the paragraph about the card's build. Whichever PR merges second needs a small rebase of that file.

Follow the contribution scope.
Unresolved scope, authority, side effects, or required verification block
integration. Link the required maintainer scope decision for new providers or
capabilities involving target execution, injection, mutation, or protection
recovery; ordinary fixes within existing boundaries may state "not applicable".
Draft PRs may leave the scope decision pending and the readiness and merge checklists
unchecked. Maintainers can help resolve open questions.

Contract and boundary impact

  • Semantic owner and earliest changed stage:
    website/public/assets/favicon.svg and website/public/assets/social-card.svg, at the SVG source. No code path changes.
  • Contribution scope fit and linked maintainer decision:
    Not applicable. This is documentation and static assets. They sit inside the existing website boundary. It admits nothing new. The contributing guide says a doc change like this needs no okay in advance.
  • CLI and MCP/tool-catalog contract:
    None. No CLI command, MCP tool or catalog entry is touched.
  • Provider, bridge, target-format, or platform compatibility:
    Not applicable to providers. Browser behaviour is unverified: nobody has run a browser on this change.
  • Evidence, artifact, provenance, or reconstruction contract:
    None.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable):
    Not applicable. Nothing is launched or extracted.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact (CI generates and validates ignored catalogs and skills/; edit authored instructions in .agents/skills/reverse-engineer-anything/ and never commit build outputs):
    None. No docs/public/product-catalog.json, package or skill file is touched. scripts/prepare-website.py still builds the same card PNG (0 px different, see below).

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated:
    None added. The change is documentation and static assets. The website checks in scripts/website.py check run over the built site.

  • Base reproduction or other evidence:
    Executed this job, on the committed branch. The base was upstream/main f71308713. Light render of each SVG, before vs after, counting pixels that differ in any RGBA channel:

    File Renderer Size Differing px
    favicon.svg CairoSVG 2.9.1 256 x 256 0 of 65,536
    social-card.svg CairoSVG 2.9.1, the build's renderer 1200 x 630 0 of 756,000
    favicon.svg magick compare -metric AE, native size 32 x 32 0
    social-card.svg magick compare -metric AE, native size 1200 x 630 0

    An earlier job also found that stripping the @media wrapper makes the card differ in every pixel, so a 0 is not an inert block. That earlier result is not re-run here. The two SVGs match the earlier job's final drafts byte for byte (cmp, exit 0).

  • User-visible CLI/MCP output (if applicable):
    Not applicable.

  • Remaining proof gaps:

    • Not seen: no browser and no GitHub render. I did not see either dark rendering on a screen.
    • Unverified: whether any browser applies a prefers-color-scheme rule inside an SVG favicon. caniuse lists SVG favicons from Chrome 80, Firefox 41 and Safari 26 and does not say (read in an earlier job).
    • Not tested: a real link preview in any app. The card PNG is unchanged, so previews should not change; that is derived from the 0 px result, not observed.
    • A dark card needs a browser, because CairoSVG ignores the block. I have no render of the dark card from this job.
    • The pre-push hook ran npm run check:fast (typecheck and lint). Both passed, from turbo's cache. npm run check:pr, the test suite and knip were not run.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • npm ci --ignore-scripts, Node 24.22.1 — exit 0
  • python3 scripts/website.py check — exit 0. It includes scripts/test-website.py. It ran on Python 3.14.7 with CairoSVG 2.9.1 and polib 1.2.0. It ends with "Checked shared HTML (0 pages changed)."
  • python3 scripts/test-website.py on its own — exit 0
  • npm run docs:check, Node 24.22.1 — exit 0, 9 tests passed in tests/conformance/readmeConsistency.test.ts. I did not check whether this reads the files this branch touches.
  • npx oxfmt --check website/figures.md website/public/assets/favicon.svg website/public/assets/social-card.svg — exit 0. It matched one file, website/figures.md; the two SVGs were not matched.
  • These are the light-render diffs from CairoSVG and magick. I also ran cmp against the earlier drafts. Each exited 0. See the evidence section.
  • No check failed, so no comparison against plain upstream/main was needed.

Compatibility, safety, and release

  • Breaking changes or migration steps:
    None. Nothing changes for people on a light setting. Light renders are 0 px different.
  • Real Hopper/Ghidra, browser, or OS coverage:
    Not applicable. Nobody has run a browser on this. Linux x64 only for the renders.
  • Package or release metadata impact:
    None.
  • Security, privacy, process, or containment review:
    None needed. Two static SVG files and one Markdown paragraph. No scripts, no network, no new dependency.

Author readiness

Human owner: @CassieFox23

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.
Test setup
  • Box: Nobara 44 (Fedora 44 base), Linux 7.2.11
  • CPU: AMD Ryzen 9 5900X, 12 cores / 24 threads
  • RAM: 31 GiB as free -g reports it
  • Node: 24.22.1 (npm 11.19.1)
  • Other: Python 3.14.7 in a venv with CairoSVG 2.9.1 and polib 1.2.0, the versions in website/requirements.txt
  • Head / base: a29add441 / f71308713

🤖 Written with Claude Code (Sonnet 5.5, verified by Opus 5.5), posted with my OK 🦊


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/6909 **Author:** [@CassieFox23](https://github.com/CassieFox23) **Created:** 10/23/2026 **Status:** ✅ Merged **Merged:** 10/23/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `docs/website-icons-dark-mode` --- ### 📝 Commits (1) - [`a29add4`](https://github.com/morluto/rea/commit/a29add441d9f9692996b22794ebd589aaf658eb8) docs(website): add dark-mode styles to the favicon and social card ### 📊 Changes **3 files changed** (+18 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `website/figures.md` (+5 -0) 📝 `website/public/assets/favicon.svg` (+1 -1) 📝 `website/public/assets/social-card.svg` (+12 -0) </details> ### 📄 Description **TL;DR:** The website icon and share card now have a dark style. The light version is pixel for pixel the same. Nobody has looked at it in a browser yet. <!-- PR title: type(optional-scope): imperative outcome The title becomes the squash-merge commit subject and generated changelog entry. --> ## Summary <!-- What user, agent, or maintainer problem does this solve? Link the issue with "Fixes #123" when applicable. Keep the prior behavior, expected contract, and new behavior understandable without private context. --> Adds a dark style to the website favicon and the social card. Before, the favicon tile (#20252b) sat almost invisible on a dark browser tab strip. It had 1.06:1 contrast against the site's dark page colour #1e1e2e. I computed that this job. The colour is `--page` in `website/public/assets/styles.css`, line 2759. The card, opened on its own, was light only. Now each SVG carries one `prefers-color-scheme: dark` block. The favicon tile becomes #89b4fa with a #11111b glyph (7.79:1 against #1e1e2e, glyph on tile 8.91:1, computed this job). Related issue: none linked. The [contributing guide](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope) says a doc change like this needs no okay in advance. So I opened this without one. ## Problem and expected behavior <!-- For fixes, give the smallest trigger and violated invariant. For features, describe the use case and observable outcome. --> Not a bug fix. This is a polish change. Observable outcome: a person on a dark browser or OS setting sees a dark favicon. If they open `social-card.svg` directly, they see a dark card. A person on a light setting sees what they saw before. ## Change and scope <!-- Explain the chosen approach, why it fits REA's architecture, and what is intentionally not included. If adding complexity for a speculative or vanishingly unlikely race or security edge case, record the concrete failure mode, likelihood, complexity cost, and the user's buy-in obtained before implementation. Do not silently expand scope for theoretical robustness. --> Two SVG files get one inserted block each: `website/public/assets/favicon.svg` (a one-line `<style>`) and `website/public/assets/social-card.svg` (12 lines). Each edit is a pure insertion. `website/figures.md` gains one paragraph that says the card and favicon carry the block and that CairoSVG ignores it. Not included: a dark link-preview PNG. CairoSVG, the renderer in `scripts/prepare-website.py` (line 46), ignores the `@media` wrapper, so the PNG that `og:image` and `twitter:image` point at stays light. One image serves every viewer, so a dark PNG would also be dark in light apps. That is a design choice for a maintainer, so I left it out. Not included: anything for the other images. The five figure SVGs in `website/public/assets/figures/` already carry a `prefers-color-scheme` block (`git grep`, this job). A sibling PR, on the branch `docs/readme-showcase-dark-mode`, handles the README showcase image. It adds its own section to `website/figures.md` at the same spot. That spot is right after the paragraph about the card's build. Whichever PR merges second needs a small rebase of that file. Follow the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope). Unresolved scope, authority, side effects, or required verification block integration. Link the required maintainer scope decision for new providers or capabilities involving target execution, injection, mutation, or protection recovery; ordinary fixes within existing boundaries may state "not applicable". Draft PRs may leave the scope decision pending and the readiness and merge checklists unchecked. Maintainers can help resolve open questions. ## Contract and boundary impact <!-- Short answers are welcome. Complete applicable lines; mark unresolved facts as "unknown". Use "none" or "not applicable" only when established. --> - Semantic owner and earliest changed stage: `website/public/assets/favicon.svg` and `website/public/assets/social-card.svg`, at the SVG source. No code path changes. - Contribution scope fit and linked maintainer decision: Not applicable. This is documentation and static assets. They sit inside the existing website boundary. It admits nothing new. The contributing guide says a doc change like this needs no okay in advance. - CLI and MCP/tool-catalog contract: None. No CLI command, MCP tool or catalog entry is touched. - Provider, bridge, target-format, or platform compatibility: Not applicable to providers. Browser behaviour is unverified: nobody has run a browser on this change. - Evidence, artifact, provenance, or reconstruction contract: None. - Target selection, authority, upstream behavior, and cleanup details (if applicable): Not applicable. Nothing is launched or extracted. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact (CI generates and validates ignored catalogs and `skills/`; edit authored instructions in `.agents/skills/reverse-engineer-anything/` and never commit build outputs): None. No `docs/public/product-catalog.json`, package or skill file is touched. `scripts/prepare-website.py` still builds the same card PNG (0 px different, see below). Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [ ] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [x] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage <!-- State whether evidence is executed, source-derived, or proposed. For fixes, show the original failure and explain how the regression would fail on the affected base revision when practical. Include the most useful proof inline; link long logs or artifacts, or put them in optional details. Documentation-only changes can use source, link, or rendered-document checks. --> - Tests added or updated: None added. The change is documentation and static assets. The website checks in `scripts/website.py check` run over the built site. - Base reproduction or other evidence: Executed this job, on the committed branch. The base was upstream/main f71308713. Light render of each SVG, before vs after, counting pixels that differ in any RGBA channel: | File | Renderer | Size | Differing px | | --- | --- | --- | --- | | favicon.svg | CairoSVG 2.9.1 | 256 x 256 | 0 of 65,536 | | social-card.svg | CairoSVG 2.9.1, the build's renderer | 1200 x 630 | 0 of 756,000 | | favicon.svg | magick compare -metric AE, native size | 32 x 32 | 0 | | social-card.svg | magick compare -metric AE, native size | 1200 x 630 | 0 | An earlier job also found that stripping the `@media` wrapper makes the card differ in every pixel, so a 0 is not an inert block. That earlier result is not re-run here. The two SVGs match the earlier job's final drafts byte for byte (`cmp`, exit 0). - User-visible CLI/MCP output (if applicable): Not applicable. - Remaining proof gaps: - Not seen: no browser and no GitHub render. I did not see either dark rendering on a screen. - Unverified: whether any browser applies a `prefers-color-scheme` rule inside an SVG favicon. caniuse lists SVG favicons from Chrome 80, Firefox 41 and Safari 26 and does not say (read in an earlier job). - Not tested: a real link preview in any app. The card PNG is unchanged, so previews should not change; that is derived from the 0 px result, not observed. - A dark card needs a browser, because CairoSVG ignores the block. I have no render of the dark card from this job. - The pre-push hook ran `npm run check:fast` (typecheck and lint). Both passed, from turbo's cache. `npm run check:pr`, the test suite and knip were not run. For evidence-bearing changes: - [ ] Observed, derived, and inferred claims remain distinguishable. - [ ] Artifact identity, source provenance, and failed attempts remain preserved. - [ ] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed <!-- List only commands that actually ran, with observed results. Include the relevant real-provider or platform workflow, or explain why it was unavailable. Keep these results current after changes; a command without its result is incomplete. --> - `npm ci --ignore-scripts`, Node 24.22.1 — exit 0 - `python3 scripts/website.py check` — exit 0. It includes `scripts/test-website.py`. It ran on Python 3.14.7 with CairoSVG 2.9.1 and polib 1.2.0. It ends with "Checked shared HTML (0 pages changed)." - `python3 scripts/test-website.py` on its own — exit 0 - `npm run docs:check`, Node 24.22.1 — exit 0, 9 tests passed in `tests/conformance/readmeConsistency.test.ts`. I did not check whether this reads the files this branch touches. - `npx oxfmt --check website/figures.md website/public/assets/favicon.svg website/public/assets/social-card.svg` — exit 0. It matched one file, `website/figures.md`; the two SVGs were not matched. - These are the light-render diffs from CairoSVG and magick. I also ran `cmp` against the earlier drafts. Each exited 0. See the evidence section. - No check failed, so no comparison against plain upstream/main was needed. ## Compatibility, safety, and release <!-- Call out breaking changes, migrations, package effects, platform/provider limits, security/privacy/containment implications, and meaningful proof gaps. --> - Breaking changes or migration steps: None. Nothing changes for people on a light setting. Light renders are 0 px different. <!-- For ! / BREAKING CHANGE: show a previously valid call/configuration, its new behavior and migration, and why compatibility/deprecation cannot preserve it. Every release increments minor, including breaking changes; keep breaking markers and migration notes so callers can assess compatibility. See docs/releasing.md. --> - Real Hopper/Ghidra, browser, or OS coverage: Not applicable. Nobody has run a browser on this. Linux x64 only for the renders. - Package or release metadata impact: None. - Security, privacy, process, or containment review: None needed. Two static SVG files and one Markdown paragraph. No scripts, no network, no new dependency. ## Author readiness <!-- The human owner completes these declarations before requesting review. The PR author is the owner by default. A different owner must explicitly accept ownership on this PR. AI agents must leave these declarations to a human to dictate to them or there could be catastrophic consequences for many users of REA. Draft PRs may leave them unchecked. These declarations record initial readiness when opening the PR for review; later pushes do not require a new human sign-off. Keep the description and validation evidence current as the work changes. See CONTRIBUTING.md#pull-request-ownership-and-readiness. --> Human owner: @CassieFox23 - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge <!-- Draft PRs may leave pending items unchecked. Resolve material scope and authority questions before integration. --> - [ ] This PR addresses a concrete problem or an agreed enhancement. - [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [ ] The PR has one focused outcome and the title follows `type(scope): outcome`. - [ ] Related issue is linked, or the reason for not linking one is stated above. - [ ] Tests cover changed observable behavior and meaningful failure paths. - [ ] Owning docs, contracts, and generated metadata are updated where needed. - [ ] User-visible CLI/MCP changes include representative output. - [ ] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. <details> <summary>Test setup</summary> - Box: Nobara 44 (Fedora 44 base), Linux 7.2.11 - CPU: AMD Ryzen 9 5900X, 12 cores / 24 threads - RAM: 31 GiB as `free -g` reports it - Node: 24.22.1 (npm 11.19.1) - Other: Python 3.14.7 in a venv with CairoSVG 2.9.1 and polib 1.2.0, the versions in `website/requirements.txt` - Head / base: a29add441 / f71308713 </details> 🤖 Written with Claude Code (Sonnet 5.5, verified by Opus 5.5), posted with my OK 🦊 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:47:53 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#7440
No description provided.