detached c6e3d36

homepage: add creative SVG favicon (inline data URL) — stylized D with speed bolt on dark rounded card; link rel=icon in head

commit
c6e3d36c95579b0af3ddb063940b81848b73bf9c
author
bamen · · 2025-09-09 16:21 UTC
committer
bamen · · 2025-09-09 21:51 UTC
parent
d3c3c1d
signature
unsigned
1 file · +38 -0
M frontend/src/utils/html-builder.ts +38 -0
@@ -1,5 +1,6 @@
11 export class HTMLBuilder {
22 static createBaseHTML(): string {
3+ const faviconData = this.getFaviconDataURL();
34 return `
45 <!DOCTYPE html>
56 <html lang="en">
@@ -7,6 +8,7 @@ export class HTMLBuilder {
78 <meta charset="UTF-8">
89 <meta name="viewport" content="width=device-width, initial-scale=1.0">
910 <title>Dumber Browser</title>
11+ <link rel="icon" type="image/svg+xml" href="${faviconData}">
1012 <style>
1113 ${this.getStyles()}
1214 </style>
@@ -32,6 +34,42 @@ export class HTMLBuilder {
3234 </html>`;
3335 }
3436
37+ private static getFaviconDataURL(): string {
38+ const svg = this.getFaviconSVG();
39+ // Minimal encoding for safe inline usage
40+ const encoded = encodeURIComponent(svg)
41+ .replace(/'/g, '%27')
42+ .replace(/\(/g, '%28')
43+ .replace(/\)/g, '%29');
44+ return `data:image/svg+xml;utf8,${encoded}`;
45+ }
46+
47+ private static getFaviconSVG(): string {
48+ // Stylized D with speed bolt on a subtle dark rounded card
49+ return `<?xml version="1.0" encoding="UTF-8"?>
50+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
51+ <defs>
52+ <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
53+ <stop offset="0%" stop-color="#101214"/>
54+ <stop offset="100%" stop-color="#1b1e22"/>
55+ </linearGradient>
56+ <filter id="inset" x="-20%" y="-20%" width="140%" height="140%">
57+ <feOffset dx="0" dy="1"/>
58+ <feGaussianBlur stdDeviation="0.6" result="blur"/>
59+ <feComposite in2="SourceAlpha" operator="out"/>
60+ <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
61+ <feBlend in="SourceGraphic" mode="normal"/>
62+ </filter>
63+ </defs>
64+ <rect x="4" y="4" width="56" height="56" rx="14" ry="14" fill="url(#bg)" filter="url(#inset)"/>
65+ <rect x="4.5" y="4.5" width="55" height="55" rx="13.5" ry="13.5" fill="none" stroke="#252a2f" stroke-width="1"/>
66+ <!-- D glyph -->
67+ <path d="M20 16 L20 48 M20 16 H34 q12 0 12 16 t-12 16 H20" fill="none" stroke="#e9eef3" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round"/>
68+ <!-- Speed bolt accent -->
69+ <path d="M36 22 L32 34 h6 l-8 16 4-12 h-6 z" fill="#ff9800" opacity="0.95"/>
70+</svg>`;
71+ }
72+
3573 private static getStyles(): string {
3674 return `
3775 * {
@@ -1,5 +1,6 @@
1 export class HTMLBuilder {1 export class HTMLBuilder {
2 static createBaseHTML(): string {2 static createBaseHTML(): string {
3+ const faviconData = this.getFaviconDataURL();
3 return `4 return `
4 <!DOCTYPE html>5 <!DOCTYPE html>
5 <html lang="en">6 <html lang="en">
@@ -7,6 +8,7 @@ export class HTMLBuilder {
7 <meta charset="UTF-8">8 <meta charset="UTF-8">
8 <meta name="viewport" content="width=device-width, initial-scale=1.0">9 <meta name="viewport" content="width=device-width, initial-scale=1.0">
9 <title>Dumber Browser</title>10 <title>Dumber Browser</title>
11+ <link rel="icon" type="image/svg+xml" href="${faviconData}">
10 <style>12 <style>
11 ${this.getStyles()}13 ${this.getStyles()}
12 </style>14 </style>
@@ -32,6 +34,42 @@ export class HTMLBuilder {
32 </html>`;34 </html>`;
33 }35 }
34 36
37+ private static getFaviconDataURL(): string {
38+ const svg = this.getFaviconSVG();
39+ // Minimal encoding for safe inline usage
40+ const encoded = encodeURIComponent(svg)
41+ .replace(/'/g, '%27')
42+ .replace(/\(/g, '%28')
43+ .replace(/\)/g, '%29');
44+ return `data:image/svg+xml;utf8,${encoded}`;
45+ }
46+
47+ private static getFaviconSVG(): string {
48+ // Stylized D with speed bolt on a subtle dark rounded card
49+ return `<?xml version="1.0" encoding="UTF-8"?>
50+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
51+ <defs>
52+ <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
53+ <stop offset="0%" stop-color="#101214"/>
54+ <stop offset="100%" stop-color="#1b1e22"/>
55+ </linearGradient>
56+ <filter id="inset" x="-20%" y="-20%" width="140%" height="140%">
57+ <feOffset dx="0" dy="1"/>
58+ <feGaussianBlur stdDeviation="0.6" result="blur"/>
59+ <feComposite in2="SourceAlpha" operator="out"/>
60+ <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
61+ <feBlend in="SourceGraphic" mode="normal"/>
62+ </filter>
63+ </defs>
64+ <rect x="4" y="4" width="56" height="56" rx="14" ry="14" fill="url(#bg)" filter="url(#inset)"/>
65+ <rect x="4.5" y="4.5" width="55" height="55" rx="13.5" ry="13.5" fill="none" stroke="#252a2f" stroke-width="1"/>
66+ <!-- D glyph -->
67+ <path d="M20 16 L20 48 M20 16 H34 q12 0 12 16 t-12 16 H20" fill="none" stroke="#e9eef3" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round"/>
68+ <!-- Speed bolt accent -->
69+ <path d="M36 22 L32 34 h6 l-8 16 4-12 h-6 z" fill="#ff9800" opacity="0.95"/>
70+</svg>`;
71+ }
72+
35 private static getStyles(): string {73 private static getStyles(): string {
36 return `74 return `
37 * {75 * {

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close