diff --git a/DECISIONS.md b/DECISIONS.md index a194766..4df0581 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -87,4 +87,5 @@ - 2026-02-28 m+git@andri.dk — `X-Ublproxy-Stats` response header on modified HTML responses. Reports `hidden=N; stripped=N` — the number of CSS element-hiding selectors injected and HTML elements (script/iframe/object/embed) stripped. Present only when the proxy modified the response. Zero performance overhead: counts are byproducts of work already being done. Useful for debugging filtering issues across browsers. - 2026-02-28 m+git@andri.dk — Warn-level logging when HTML filtering is skipped due to unsupported `Content-Encoding`, decompression init failure, or decompression read failure. Previously these were silent `return nil, false` paths — filtering was silently bypassed with no diagnostic output. - 2026-02-28 m+git@andri.dk — Pre-filter element hiding selectors against HTML content before CSS injection. With full EasyList subscriptions, `ElementHidingForDomain` returns ~64K global selectors for every domain. Chrome truncates CSS rules that exceed its internal selector limit, silently breaking element hiding. Fix: extract all class names and IDs from the decompressed HTML body (fast tokenizer pass, no DOM construction), then only inject selectors whose primary class/ID token appears in the document. Simple selectors (`.class`, `#id`, `.a.b` compounds, `tag.class`) are matched against the token set; complex selectors (combinators, attribute selectors, pseudo-classes) are always included since they can't be pre-evaluated without a full CSS engine. Reduces injected CSS from ~64K selectors to typically <200 per page. -- 2026-03-01 m+git@andri.dk — Added landing page in `web/` deployed via GitHub Pages (artifact-based workflow). Single self-contained `index.html` with all CSS inlined, no build step, no external JS dependencies. Google Fonts for typography. Dark industrial-utilitarian aesthetic with amber accent. Deployed to `andrioid.github.io/ublproxy` via `actions/deploy-pages@v4` on pushes to `main` that touch `web/**`. +- 2026-03-01 m+git@andri.dk — Added landing page in `web/` deployed via GitHub Pages (artifact-based workflow). Single self-contained `index.html` with all CSS inlined, no build step, no external JS dependencies. JetBrains Mono font, CRT/terminal aesthetic with neon green/cyan/magenta/yellow accents on dark `#08080c` background. Deployed to `andrioid.github.io/ublproxy` via `actions/deploy-pages@v4` on pushes to `main` that touch `web/**`. +- 2026-03-01 m+git@andri.dk — Added portal UI screenshots to landing page. 4 PNGs (setup wizard, dashboard, activity feed, subscriptions) captured via Playwright with mocked API responses. Displayed in 2x2 grid "See it in action" section between Features and Architecture. Screenshots are served as static assets from `web/`. diff --git a/web/index.html b/web/index.html index 2111edb..6998911 100644 --- a/web/index.html +++ b/web/index.html @@ -479,6 +479,80 @@ section { line-height: 1.65; } +/* --- Screenshots section --- */ +.screenshots-section { + border-top: 1px solid var(--border); +} + +.screenshots-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1.5rem; + max-width: 960px; + margin: 0 auto; +} + +.screenshot-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius); + overflow: hidden; + transition: border-color 0.3s, box-shadow 0.3s; +} + +.screenshot-card:hover { + border-color: rgba(0, 229, 255, 0.4); + box-shadow: 0 0 30px rgba(0, 229, 255, 0.08), 0 0 60px rgba(0, 255, 65, 0.04); +} + +.screenshot-card a { + display: block; +} + +.screenshot-card img { + width: 100%; + height: auto; + display: block; + filter: brightness(0.92) contrast(1.05); + transition: filter 0.3s; +} + +.screenshot-card:hover img { + filter: brightness(1) contrast(1.05); +} + +.screenshot-caption { + padding: 0.85rem 1rem; + border-top: 1px solid var(--border); + display: flex; + align-items: center; + gap: 0.6rem; +} + +.screenshot-caption .caption-icon { + font-size: 0.9rem; + flex-shrink: 0; +} + +.screenshot-caption .caption-text { + font-family: var(--font-mono); + font-size: 0.78rem; + font-weight: 500; + color: var(--text-muted); +} + +.screenshot-caption .caption-label { + color: var(--cyan); + font-weight: 600; +} + +@media (max-width: 768px) { + .screenshots-grid { + grid-template-columns: 1fr; + gap: 1rem; + } +} + /* --- Architecture section --- */ .arch-section { border-top: 1px solid var(--border); @@ -791,6 +865,7 @@ td:first-child {