Branding: the Oxygen mark as logo and favicon; palette tuned to its cyan and blue 5c6eb1feaa71
The RetroPlay theme stays as the rough shape (fonts, band, tabs, panels); the colours now come from the mark shared with the VS Code extension.
- Author
- Andy McCall @andymccall <[email protected]>
- When
- · 2026-09-27 17:41 UTC
- Signature
- ✔ signed by Andy McCall
- Hash
5c6eb1feaa71c26bcdc584fd171453dca0ebf265440864084d1b3ccd00078039- Depends on
- 93be9ce4653e d23464c0ac60
- Depended on by
- 03bfb945f5c1 f6346d875ee5 6ad368c5958e 756fe44a0f4d 42a0ba4bac4e c40c2d3edb51 19bb31ff1f5c abb98fa9964e
- In bookmarks
- api-unknown-fields cancel-landed-runs clear-waiting close-proposal-140 diffusion-pin-bookmark draft-ready image-check job-waits main oh-comment-body-file proposal-list-fast run-one-job wiki-says-so
- In tags
- v0.1.0 v0.2.0 v0.3.0 v0.3.1 v0.4.0 v0.4.1 v0.4.2 v0.5.0 v0.5.1 v0.5.2 v0.6.0 v0.6.1 v0.7.0 v0.8.0 v0.9.0 v0.9.1 v0.9.11 v0.9.15 v0.9.16 v0.9.19 v0.9.2 v0.9.20 v0.9.21 v0.9.22 v0.9.23 v0.9.24 v0.9.3 v0.9.4 v0.9.5 v0.9.6 v0.9.7 v0.9.8 v0.9.9
- Edits
- 18 atoms, 1 tree operation, 5 files
Browse the tree at this change
added assets/icons/mark.svg +14 −0
| 1 | + | <svg xmlns="http://www.w3.org/2000/svg" viewBox="-24 -12 48 24" width="48" height="24" aria-hidden="true"> |
|
| 2 | + | <defs> |
|
| 3 | + | <linearGradient id="oxyGrad" x1="0%" y1="0%" x2="100%" y2="100%"> |
|
| 4 | + | <stop offset="0%" stop-color="#00F0FF"/> |
|
| 5 | + | <stop offset="100%" stop-color="#0072FF"/> |
|
| 6 | + | </linearGradient> |
|
| 7 | + | </defs> |
|
| 8 | + | <path d="M -11 -6 L 11 -6" stroke="url(#oxyGrad)" stroke-width="3" stroke-linecap="round"/> |
|
| 9 | + | <path d="M -11 6 L 11 6" stroke="url(#oxyGrad)" stroke-width="3" stroke-linecap="round"/> |
|
| 10 | + | <circle cx="-11" cy="0" r="10" fill="none" stroke="url(#oxyGrad)" stroke-width="3"/> |
|
| 11 | + | <circle cx="-11" cy="0" r="3.5" fill="#00F0FF"/> |
|
| 12 | + | <circle cx="11" cy="0" r="10" fill="none" stroke="url(#oxyGrad)" stroke-width="3"/> |
|
| 13 | + | <circle cx="11" cy="0" r="3.5" fill="#FFFFFF"/> |
|
| 14 | + | </svg> |
modified assets/icons/oxygenhub.svg +20 −1
| 1 | - | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" shape-rendering="crispEdges"><rect width="16" height="16" fill="#141430"/><path fill="#ffc83c" d="M5 3h6v1H5zM4 4h1v1H4zM11 4h1v1h-1zM3 5h1v6H3zM12 5h1v6h-1zM4 11h1v1H4zM11 11h1v1h-1zM5 12h6v1H5z"/><path fill="#ffdd00" d="M7 7h2v2H7z"/></svg> |
|
| 1 | + | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="100%" height="100%"> |
|
| 2 | + | <defs> |
|
| 3 | + | <linearGradient id="oxyGrad" x1="0%" y1="0%" x2="100%" y2="100%"> |
|
| 4 | + | <stop offset="0%" stop-color="#00F0FF" /> |
|
| 5 | + | <stop offset="100%" stop-color="#0072FF" /> |
|
| 6 | + | </linearGradient> |
|
| 7 | + | ||
| 8 | + | <g id="oxy-mark-mini"> |
|
| 9 | + | <path d="M -11 -6 L 11 -6" stroke="url(#oxyGrad)" stroke-width="3" stroke-linecap="round" /> |
|
| 10 | + | <path d="M -11 6 L 11 6" stroke="url(#oxyGrad)" stroke-width="3" stroke-linecap="round" /> |
|
| 11 | + | <circle cx="-11" cy="0" r="10" fill="none" stroke="url(#oxyGrad)" stroke-width="3" /> |
|
| 12 | + | <circle cx="-11" cy="0" r="3.5" fill="#00F0FF" /> |
|
| 13 | + | <circle cx="11" cy="0" r="10" fill="none" stroke="url(#oxyGrad)" stroke-width="3" /> |
|
| 14 | + | <circle cx="11" cy="0" r="3.5" fill="#FFFFFF" /> |
|
| 15 | + | </g> |
|
| 16 | + | </defs> |
|
| 17 | + | ||
| 18 | + | <rect width="64" height="64" rx="14" fill="#070c18" /> |
|
| 19 | + | <use href="#oxy-mark-mini" x="32" y="32" /> |
|
| 20 | + | </svg> |
modified docs/spec.md +2 −2
| … | 196 unchanged lines |
||
| 197 | 197 | ||
| 198 | 198 | ### 6.1 Theme |
|
| 199 | 199 | ||
| 200 | - | The visual language is the RetroPlay Network's: dark by default, the Commander X16 palette, `Barlow` for text and `Press Start 2P` for the wordmark, ranks and first columns, square corners, thin `--line` rules, a `--panel` header and footer, and a full-width `--band` navigation bar with the active tab underlined in `--acc`. The stylesheet starts from `retroplay-manager/templates/style.css` lines 1–171 (tokens, shell, band, tabs, main, tables, forms, footer) and adds forge components; the store, showcase and game components are not carried over. |
|
| 200 | + | The visual language follows the RetroPlay Network's shape (dark by default, `Barlow` for text and `Press Start 2P` for the wordmark and first columns, square corners, thin `--line` rules, a `--panel` header and footer, a full-width `--band` navigation bar with the active tab underlined in `--acc`) with the palette taken from the Oxygen mark shared with the VS Code extension: the mark's cyan `#00F0FF` to blue `#0072FF` gradient on `#070c18`, so `--acc` is cyan, `--acc-2` blue, and the band a deep blue. The mark itself is the logo in the header, the footer and the favicon; the wordmark beside it reads OXYGEN**HUB**. The stylesheet starts from `retroplay-manager/templates/style.css` lines 1–171 (tokens, shell, band, tabs, main, tables, forms, footer) and adds forge components; the store, showcase and game components are not carried over. |
|
| 201 | 201 | ||
| 202 | 202 | Tokens (dark default, light under `:root[data-theme="light"]`): |
|
| 203 | 203 | ||
| … | 7 unchanged lines |
||
| 211 | 211 | ||
| 212 | 212 | Theme selection: cookie `theme=light|dark|auto`; `auto` follows `prefers-color-scheme`. The `<head>` sets `data-theme` before paint exactly as retroplay-manager does. Fonts are vendored under `/static/fonts/` rather than loaded from Google, so a hub on a private network paints without internet access. |
|
| 213 | 213 | ||
| 214 | - | The wordmark is `OXY<span>◆</span>GEN` in the pixel font with the diamond in `--acc`. Favicon: a 16×16 pixel-art "O" in amber on `--panel`, matching `retroplay.svg`'s style. |
|
| 214 | + | The logo is `assets/icons/oxygenhub.svg`, a copy of the extension's `oxygen.svg` (two linked rings, the molecule), inlined in the header at 22px beside the wordmark. |
|
| 215 | 215 | ||
| 216 | 216 | ### 6.2 Page shell |
|
| 217 | 217 | ||
| … | 325 unchanged lines |
modified templates/base.html +2 −2
| … | 9 unchanged lines |
||
| 10 | 10 | </head> |
|
| 11 | 11 | <body{% block bodyattrs %}{% endblock %}> |
|
| 12 | 12 | <header> |
|
| 13 | - | <a class="brand px" href="/">OXY<span>◆</span>GEN</a> |
|
| 13 | + | <a class="brand" href="/"><svg xmlns="http://www.w3.org/2000/svg" viewBox="-24 -12 48 24" width="48" height="24" aria-hidden="true"><defs><linearGradient id="oxyGradH" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#00F0FF"/><stop offset="100%" stop-color="#0072FF"/></linearGradient></defs><path d="M -11 -6 L 11 -6" stroke="url(#oxyGradH)" stroke-width="3" stroke-linecap="round"/><path d="M -11 6 L 11 6" stroke="url(#oxyGradH)" stroke-width="3" stroke-linecap="round"/><circle cx="-11" cy="0" r="10" fill="none" stroke="url(#oxyGradH)" stroke-width="3"/><circle cx="-11" cy="0" r="3.5" fill="#00F0FF"/><circle cx="11" cy="0" r="10" fill="none" stroke="url(#oxyGradH)" stroke-width="3"/><circle cx="11" cy="0" r="3.5" fill="#FFFFFF"/></svg><span class="px">OXYGEN<em>HUB</em></span></a> |
|
| 14 | 14 | <form class="find" action="/search" method="get" role="search"><input type="search" name="q" placeholder="Search…" aria-label="Search" autocomplete="off"></form> |
|
| 15 | 15 | <nav> |
|
| 16 | 16 | <a class="go" href="/explore">EXPLORE</a> |
|
| … | 12 unchanged lines |
||
| 29 | 29 | <footer> |
|
| 30 | 30 | <div class="foot"> |
|
| 31 | 31 | <div> |
|
| 32 | - | <a class="brand px" href="/">OXY<span>◆</span>GEN</a> |
|
| 32 | + | <a class="brand" href="/"><svg xmlns="http://www.w3.org/2000/svg" viewBox="-24 -12 48 24" width="48" height="24" aria-hidden="true"><defs><linearGradient id="oxyGradF" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#00F0FF"/><stop offset="100%" stop-color="#0072FF"/></linearGradient></defs><path d="M -11 -6 L 11 -6" stroke="url(#oxyGradF)" stroke-width="3" stroke-linecap="round"/><path d="M -11 6 L 11 6" stroke="url(#oxyGradF)" stroke-width="3" stroke-linecap="round"/><circle cx="-11" cy="0" r="10" fill="none" stroke="url(#oxyGradF)" stroke-width="3"/><circle cx="-11" cy="0" r="3.5" fill="#00F0FF"/><circle cx="11" cy="0" r="10" fill="none" stroke="url(#oxyGradF)" stroke-width="3"/><circle cx="11" cy="0" r="3.5" fill="#FFFFFF"/></svg><span class="px">OXYGEN<em>HUB</em></span></a> |
|
| 33 | 33 | <p class="small">{{ shell.site }} · a forge for Oxygen repositories. Nothing here is inferred: what a page says, the object store says.</p> |
|
| 34 | 34 | </div> |
|
| 35 | 35 | <div class="cols"> |
|
| … | 12 unchanged lines |
modified templates/style.css +21 −18
| … | 9 unchanged lines |
||
| 10 | 10 | @font-face { font-family: "Press Start 2P"; font-weight: 400; font-display: swap; src: url(/static/fonts/PressStart2P-400.woff2) format("woff2"); } |
|
| 11 | 11 | ||
| 12 | 12 | :root { |
|
| 13 | - | --bg:#0b0b16; --panel:#141430; --soft:#1c1c3c; --ink:#e8e8f0; --mute:#8a8aa0; --line:#2c2c5a; --dim:#4a4a68; |
|
| 14 | - | --acc:#ffc83c; --band:#3a5fd0; --band-ink:#ffffff; --band-line:rgba(11,11,22,.45); --now:#ffc83c; --now-ink:#0b0b16; |
|
| 15 | - | --ok:#7dd87d; --bad:#ff5a5a; --warn:#ffb347; |
|
| 16 | - | --add:#123a22; --del:#3f1520; --add-ink:#9fe8a8; --del-ink:#ffa5a5; |
|
| 17 | - | --m1:#ffdd00; --m2:#d6d6e0; --m3:#d29a55; --m4:#c07a5a; --m5:#9a9ab8; |
|
| 13 | + | /* Oxygen's mark: cyan #00F0FF to blue #0072FF on #070c18. */ |
|
| 14 | + | --bg:#070c18; --panel:#0e1526; --soft:#141d33; --ink:#e6ecf7; --mute:#8592ad; --line:#1f2b47; --dim:#43506d; |
|
| 15 | + | --acc:#00e0f0; --acc-2:#0072ff; --band:#0b3f9e; --band-ink:#ffffff; --band-line:rgba(7,12,24,.5); --now:#00f0ff; --now-ink:#070c18; |
|
| 16 | + | --ok:#5fe3a1; --bad:#ff5e7a; --warn:#ffb347; |
|
| 17 | + | --add:#0d3a3a; --del:#3f1a2e; --add-ink:#8ff0d8; --del-ink:#ffa5b8; |
|
| 18 | + | --m1:#00f0ff; --m2:#d6dcea; --m3:#5aa8ff; --m4:#0072ff; --m5:#8592ad; |
|
| 18 | 19 | /* syntax */ |
|
| 19 | - | --sy-kw:#ff9de6; --sy-str:#a8e39b; --sy-num:#ffd479; --sy-cmt:#6e6e8c; --sy-fn:#8ad8ff; --sy-ty:#ffc83c; --sy-var:#e8e8f0; --sy-const:#ffb347; |
|
| 20 | + | --sy-kw:#7fb4ff; --sy-str:#8ff0d8; --sy-num:#ffd479; --sy-cmt:#5b6785; --sy-fn:#00e0f0; --sy-ty:#c6a0ff; --sy-var:#e6ecf7; --sy-const:#ffb347; |
|
| 20 | 21 | color-scheme: dark; |
|
| 21 | 22 | } |
|
| 22 | 23 | :root[data-theme="light"] { |
|
| 23 | - | --bg:#f5f7f2; --panel:#ffffff; --soft:#eef2ea; --ink:#2b2f2a; --mute:#7a807a; --line:#d9ddd6; --dim:#b9bfb5; |
|
| 24 | - | --acc:#5b9c1c; --band:#6aa91f; --band-ink:#ffffff; --band-line:rgba(255,255,255,.25); --now:#3e5f8f; --now-ink:#ffffff; |
|
| 25 | - | --ok:#2e8b3a; --bad:#c8322b; --warn:#b8651b; |
|
| 26 | - | --add:#e3f5e1; --del:#fbe3e1; --add-ink:#1f6b2a; --del-ink:#a12b25; |
|
| 27 | - | --m1:#c9931a; --m2:#7a8290; --m3:#b0693a; --m4:#a25c46; --m5:#8a8f9c; |
|
| 28 | - | --sy-kw:#a626a4; --sy-str:#50a14f; --sy-num:#986801; --sy-cmt:#9a9a9a; --sy-fn:#4078f2; --sy-ty:#c18401; --sy-var:#2b2f2a; --sy-const:#b8651b; |
|
| 24 | + | --bg:#f4f7fc; --panel:#ffffff; --soft:#e9eef8; --ink:#1b2333; --mute:#66718a; --line:#d6dded; --dim:#b3bccf; |
|
| 25 | + | --acc:#0072ff; --acc-2:#00b8d4; --band:#0b3f9e; --band-ink:#ffffff; --band-line:rgba(255,255,255,.25); --now:#0072ff; --now-ink:#ffffff; |
|
| 26 | + | --ok:#1f8f5f; --bad:#c62d47; --warn:#b8651b; |
|
| 27 | + | --add:#e1f5ee; --del:#fbe3e8; --add-ink:#176b48; --del-ink:#a1243c; |
|
| 28 | + | --m1:#0090a8; --m2:#7a8290; --m3:#2f6fcf; --m4:#0055c0; --m5:#8a8f9c; |
|
| 29 | + | --sy-kw:#0b4fc9; --sy-str:#1f8f5f; --sy-num:#986801; --sy-cmt:#8a94a8; --sy-fn:#0083a8; --sy-ty:#7a3fd1; --sy-var:#1b2333; --sy-const:#b8651b; |
|
| 29 | 30 | color-scheme: light; |
|
| 30 | 31 | } |
|
| 31 | 32 | ||
| … | 20 unchanged lines |
||
| 52 | 53 | ||
| 53 | 54 | /* shell */ |
|
| 54 | 55 | header { background: var(--panel); border-bottom: 1px solid var(--line); padding: 14px 22px; display: flex; align-items: center; gap: 16px; } |
|
| 55 | - | header .brand span, footer .brand span { color: var(--acc); } |
|
| 56 | - | header .brand, footer .brand { color: var(--ink); } |
|
| 56 | + | .brand { display: inline-flex; align-items: center; gap: 10px; color: var(--ink); } |
|
| 57 | + | .brand svg { height: 22px; width: auto; } |
|
| 58 | + | .brand em { font-style: normal; color: var(--acc); } |
|
| 59 | + | .brand:hover { text-decoration: none; } |
|
| 57 | 60 | header nav { margin-left: auto; display: flex; gap: 8px; } |
|
| 58 | 61 | form.find { margin: 0; flex: 0 1 320px; } |
|
| 59 | 62 | form.find input { width: 100%; background: var(--bg); border: 1px solid var(--line); color: var(--ink); padding: 6px 10px; font: inherit; } |
|
| … | 1 unchanged lines |
||
| 61 | 64 | .band { background: var(--band); display: flex; align-items: stretch; padding: 0 22px; } |
|
| 62 | 65 | .band a { color: var(--band-ink); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; padding: 9px 14px; border-right: 1px solid var(--band-line); } |
|
| 63 | 66 | .band a:first-child { border-left: 1px solid var(--band-line); } |
|
| 64 | - | .band a.on { box-shadow: inset 0 -3px 0 var(--acc); } |
|
| 67 | + | .band a.on { box-shadow: inset 0 -3px 0 var(--acc); background: rgba(0,0,0,.18); } |
|
| 65 | 68 | .band a:hover { text-decoration: none; background: rgba(0,0,0,.12); } |
|
| 66 | 69 | .band .grow { flex: 1; } |
|
| 67 | 70 | .band a.dim { opacity: .6; border: 0; } |
|
| … | 9 unchanged lines |
||
| 77 | 80 | .foot { max-width: 1180px; margin: 0 auto; padding: 22px; display: grid; grid-template-columns: 1fr auto; gap: 22px; } |
|
| 78 | 81 | .foot .cols { display: flex; gap: 32px; } |
|
| 79 | 82 | .foot .cols a { display: block; font-size: 13px; } |
|
| 80 | - | .head { border-bottom: 2px solid var(--band); margin: 6px 0 16px; padding-bottom: 6px; } |
|
| 83 | + | .head { border-bottom: 2px solid var(--band); border-image: linear-gradient(90deg, var(--acc), var(--acc-2)) 1; margin: 6px 0 16px; padding-bottom: 6px; } |
|
| 81 | 84 | .head h1 { font-size: 30px; font-weight: 300; color: var(--mute); } |
|
| 82 | 85 | .head h1 small { display: block; font-size: 13px; color: var(--acc); font-weight: 400; } |
|
| 83 | 86 | .strip { padding: 8px 12px; margin: 0 0 12px; border: 1px solid; font-size: 13px; } |
|
| … | 5 unchanged lines |
||
| 89 | 92 | ||
| 90 | 93 | /* buttons, tags, chips */ |
|
| 91 | 94 | button, a.go, button.go { font: inherit; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; background: var(--panel); color: var(--acc); border: 1px solid var(--acc); padding: 5px 10px; cursor: pointer; } |
|
| 92 | - | button:hover, a.go:hover { background: var(--acc); color: var(--bg); text-decoration: none; } |
|
| 95 | + | button:hover, a.go:hover { background: var(--acc); color: var(--now-ink); text-decoration: none; } |
|
| 93 | 96 | button.small, a.go.small { padding: 2px 8px; font-size: 11px; } |
|
| 94 | 97 | .tag { display: inline-block; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--acc); background: var(--soft); padding: 1px 6px; vertical-align: middle; } |
|
| 95 | 98 | .tag.bad { color: var(--bad); } |
|
| … | 90 unchanged lines |
||
| 186 | 189 | .lane { stroke: var(--band); stroke-width: 2; fill: none; } |
|
| 187 | 190 | .lane.none { stroke: none; } |
|
| 188 | 191 | .lane.dashed { stroke-dasharray: 3 3; stroke: var(--dim); } |
|
| 189 | - | .node { fill: var(--acc); } |
|
| 192 | + | .node { fill: var(--acc-2); stroke: var(--acc); stroke-width: 1.5; } |
|
| 190 | 193 | .node.head { fill: var(--now); stroke: var(--ink); stroke-width: 1.5; } |
|
| 191 | 194 | .node.res { fill: var(--ok); } |
|
| 192 | 195 | .chg { display: flex; justify-content: space-between; align-items: center; gap: 14px; padding: 8px 12px; flex: 1; min-width: 0; } |
|
| … | 33 unchanged lines |