gitshark

Clone repository

git clone https://gitshark.ha1nz.de/git/workaround/Gitshark.git
git clone ssh://git@gitshark.ha1nz.de:22/workaround/Gitshark.git

Context

The web UI is server-rendered with Qute (11 templates, one base layout.html). All styling currently lives in a single inline <style> block in the layout: dark grey header, system font, default tables. There is no static resource pipeline yet — src/main/resources/META-INF/resources/ does not exist. The service compiles to a GraalVM native image, so everything must be self-contained (no CDN, no build-time CSS tooling that complicates the Maven build).

User direction: blue & white (shark colors), light theme only, "modern & nerdy" (terminal font accents) but genuinely usable with buttons & tabs, optionally hotkeys.

Goals / Non-Goals

Goals:

  • One shared stylesheet with CSS custom properties as the single source of design truth
  • Shark identity: blue/white light theme, monospace accents, branded header
  • Consistent components: buttons, tabs, tables, forms, code blocks, badges
  • Tab navigation on repository pages (Files / Commits / Branches)
  • Optional hotkeys as progressive enhancement; zero-JS baseline stays fully functional

Non-Goals:

  • Dark mode / theme switching
  • CSS frameworks, preprocessors, or a frontend build step (no Tailwind, no npm)
  • Client-side rendering or SPA behavior of any kind
  • Syntax highlighting for file contents (separate future change)
  • Redesigning page structure beyond styling + repo tabs

Decisions

D1: Hand-written vanilla CSS, no framework

A single shark.css (~300–500 lines) with custom properties on :root. Alternatives: Tailwind (needs npm build step, conflicts with the Maven-only/native-image-simple setup), classless frameworks like Pico.css (fights the custom shark identity, adds a dependency for little gain). The UI surface is 11 templates — small enough that hand-written CSS is cheaper than any framework integration.

D2: Color tokens

Shark palette (light theme), defined once as custom properties:

Token Value Use
--shark-blue #1565c0 primary actions, links, active tab
--shark-deep #0d3b66 header bar, headings
--shark-fin #4f9fe0 hover/focus accents
--shark-belly #f4f8fb page/code-block tinted background
--surface #ffffff cards, tables, main background
--ink #16242f body text (dark blue-grey, not pure black)
--ink-muted #5b7282 secondary text
--border #d3e0ea borders, dividers
--danger #c62828 destructive actions

All pairs chosen to clear WCAG AA 4.5:1 against their designated backgrounds (verify during implementation).

D3: Typography — system font stacks, no font files

Body: system-ui, -apple-system, "Segoe UI", sans-serif. Terminal accents: ui-monospace, "SF Mono", "JetBrains Mono", "Cascadia Code", Menlo, Consolas, monospace. Alternative considered: self-hosting JetBrains Mono as WOFF2 (~100 KB, needs @font-face plus resource-inclusion config for native image). System stacks give the terminal feel on every modern OS with zero payload and zero native-image config; revisit only if the rendered result disappoints. This satisfies "self-hosted, no CDN" trivially — there are no font requests at all.

Addendum (2026-07-07): the rendered result did disappoint — during implementation the UI adopted Space Grotesk + JetBrains Mono, initially via Google Fonts CDN, which violated the "no external font requests" requirement. Resolved by self-hosting both families as variable WOFF2 (latin + latin-ext, ~97 KB total) under META-INF/resources/fonts/ with @font-face in shark.css and OFL license texts alongside. System stacks remain as fallbacks in the font tokens.

D4: Tabs are links, active state from a template parameter

The repo templates already render per-section pages; each repository page passes an activeTab string into the layout/partial, and the tab markup sets the active class by comparison in Qute. No JS, no URL sniffing in CSS. Resource classes pass at most one extra template parameter — the only Java change in this change.

D5: Hotkeys — one small vanilla JS file, allowlist-based

shark-hotkeys.js (<100 lines, self-hosted, defer): a key→action map (? help overlay, Escape close, g h home as a two-key sequence with a short timeout). Guard clause ignores events when event.target is input/textarea/select or isContentEditable. The help overlay is a <dialog> element baked into layout.html (renders nothing visible without JS). Alternatives: a hotkey library (dependency for 5 shortcuts — no) or no JS at all (drops a feature the user explicitly wants as optional).

D6: Static resources via Quarkus default mechanism

Files go in src/main/resources/META-INF/resources/ (shark.css, shark-hotkeys.js), served by Quarkus automatically, included in native image automatically (classpath resources under META-INF/resources are picked up by the default resource config). No additional configuration expected.

Risks / Trade-offs

  • [Hand-written CSS drifts as templates grow] → tokens-only rule: components must reference custom properties; review new templates against the design system spec
  • [System monospace stack varies across OS — "terminal feel" weaker on some platforms] → accepted for now; D3 documents the WOFF2 upgrade path if needed
  • [Two-key sequence hotkeys (g h) can swallow keystrokes if the timeout logic is buggy] → keep sequence window short (~1s), only g starts a sequence, everything else is single-key
  • [Contrast assumptions in D2 might fail AA for small/muted text] → check pairs with a contrast tool during implementation and adjust token values, not component CSS

Migration Plan

Pure additive UI change: ship stylesheet + restyled templates in one release; no data, schema, or API impact. Rollback = revert the commit.

Open Questions

  • None blocking. Shark logo mark: keep the 🦈 emoji initially (already in use); a proper SVG mark can replace it later without spec changes.

Keyboard shortcuts

?Show this help
g hGo home
EscClose dialog