gitshark

Clone repository

git clone https://gitshark.de/git/workaround/Gitshark.git
git clone git@gitshark.de:workaround/Gitshark.git

← Commits

✨ feat: animated glowing ASCII backdrop on landing page

75c991f3521138ca71445a46aaa109bb15bd1b12 · Michael Hainz · 2026-06-19T09:17:26Z

Changes

3 files changed, +136 -20

MODIFY src/main/resources/META-INF/resources/shark.css +95 -3
diff --git a/src/main/resources/META-INF/resources/shark.css b/src/main/resources/META-INF/resources/shark.css
index 7b6b550..a515d1a 100644
--- a/src/main/resources/META-INF/resources/shark.css
+++ b/src/main/resources/META-INF/resources/shark.css
@@ -154,13 +154,105 @@
154 154 color: var(--shark-fin);
155 155 }
156 156
157 -/* value list (landing page) */
157 +/* landing page */
158 +
159 +/* animated glowing symbol backdrop — light theme, sits behind all content */
160 +.ascii-bg {
161 + position: fixed;
162 + inset: 0;
163 + z-index: 0;
164 + overflow: hidden;
165 + pointer-events: none;
166 + display: flex;
167 + flex-direction: column;
168 + justify-content: space-around;
169 + font-family: var(--font-mono);
170 + color: var(--shark-fin);
171 + -webkit-user-select: none;
172 + user-select: none;
173 +}
174 +
175 +.ascii-bg .ascii-row {
176 + margin: 0;
177 + border: none;
178 + padding: 0;
179 + background: none;
180 + white-space: nowrap;
181 + font-size: clamp(1.1rem, 2.6vw, 1.9rem);
182 + letter-spacing: 0.15em;
183 + opacity: 0.16;
184 + animation: ascii-glow 7s ease-in-out infinite, ascii-drift 48s linear infinite alternate;
185 + will-change: transform, opacity, text-shadow;
186 +}
187 +
188 +.ascii-bg .ascii-row:nth-child(2) { animation-delay: -1.4s, -6s; font-size: clamp(1rem, 2.2vw, 1.6rem); }
189 +.ascii-bg .ascii-row:nth-child(3) { animation-delay: -2.8s, -12s; }
190 +.ascii-bg .ascii-row:nth-child(4) { animation-delay: -4.2s, -18s; font-size: clamp(1rem, 2.2vw, 1.6rem); }
191 +.ascii-bg .ascii-row:nth-child(5) { animation-delay: -5.6s, -24s; }
192 +.ascii-bg .ascii-row:nth-child(6) { animation-delay: -7s, -30s; font-size: clamp(1rem, 2.2vw, 1.6rem); }
193 +
194 +@keyframes ascii-glow {
195 + 0%, 100% { opacity: 0.08; text-shadow: 0 0 4px var(--shark-fin); }
196 + 50% { opacity: 0.30; text-shadow: 0 0 10px var(--shark-blue), 0 0 22px var(--shark-fin); }
197 +}
198 +
199 +@keyframes ascii-drift {
200 + from { transform: translateX(0); }
201 + to { transform: translateX(-14%); }
202 +}
203 +
204 +@media (prefers-reduced-motion: reduce) {
205 + .ascii-bg .ascii-row { animation: none; opacity: 0.12; }
206 +}
207 +
208 +/* keep header and content above the backdrop */
209 +header.site, main { position: relative; z-index: 1; }
210 +
211 +/* centered hero distinct from the in-app repo hero */
212 +.landing {
213 + text-align: center;
214 + max-width: 44rem;
215 + margin: var(--space-5) auto 0;
216 +}
217 +
218 +.landing .landing-logo {
219 + width: 120px;
220 + height: 120px;
221 + border-radius: 50%;
222 + border: 2px solid var(--shark-fin);
223 + box-shadow: 0 0 0 6px rgba(79, 159, 224, 0.12), 0 0 24px rgba(21, 101, 192, 0.25);
224 +}
225 +
226 +.landing h1 {
227 + font-family: var(--font-mono);
228 + font-size: 2.2rem;
229 + margin: var(--space-3) 0 var(--space-1);
230 +}
231 +
232 +.landing .tagline {
233 + font-family: var(--font-mono);
234 + color: var(--ink-muted);
235 + margin: 0 0 var(--space-5);
236 +}
237 +
238 +.landing .tagline::before {
239 + content: "$ ";
240 + color: var(--shark-fin);
241 +}
242 +
243 +.landing-cta {
244 + display: flex;
245 + gap: var(--space-3);
246 + justify-content: center;
247 + flex-wrap: wrap;
248 +}
158 249
159 250 ul.values {
160 251 list-style: none;
161 252 padding: 0;
162 - margin: 0 0 var(--space-5);
163 - max-width: 44rem;
253 + margin: 0 auto var(--space-5);
254 + max-width: 40rem;
255 + text-align: left;
164 256 }
165 257
166 258 ul.values li {
MODIFY src/main/resources/templates/HomeResource/landing.html +23 -17
diff --git a/src/main/resources/templates/HomeResource/landing.html b/src/main/resources/templates/HomeResource/landing.html
index 98b2a89..5cb765f 100644
--- a/src/main/resources/templates/HomeResource/landing.html
+++ b/src/main/resources/templates/HomeResource/landing.html
@@ -4,22 +4,28 @@
4 4 <a href="/explore">Browse public repositories</a>
5 5 <a class="btn btn-primary" href="/login">Log in</a>
6 6 {/nav}
7 -<section class="hero">
8 - <img src="/img/shark-logo.png" alt="git-shark logo">
9 - <div>
10 - <h1>git-shark</h1>
11 - <p class="tagline">self-hosted git hosting for people who still write the code</p>
12 - </div>
7 +<div class="ascii-bg" aria-hidden="true">
8 +<pre class="ascii-row">&lt;/&gt; git commit -m "ship it" ~ &lt;shark&gt; { main } /push fetch\ &gt;&gt;= 0xC0DE ;; &lt;/&gt; merge --no-ff ~~~ &gt;_</pre>
9 +<pre class="ascii-row">~ &gt;_ HEAD~1 ::= clone &lt;origin&gt; { } /\/\ rebase -i ~ 0101 &lt;shark/&gt; pull --ff-only ;; &gt;&gt;= &lt;/&gt;</pre>
10 +<pre class="ascii-row">{ } &lt;branch&gt; /\ tag -s v1.0 ~ &gt;_ stash@{0} 0xFEED &lt;/&gt; cherry-pick ;; ~~~ push --tags &gt;&gt;=</pre>
11 +<pre class="ascii-row">&gt;&gt;= /push &lt;shark&gt; ~ blame -L { HEAD } 0x5HARK reflog ;; &lt;/&gt; bisect ~~~ &gt;_ fsck --full /\</pre>
12 +<pre class="ascii-row">~ &lt;/&gt; reset --hard ;; { } /\/\ 1100 &gt;_ remote -v &lt;origin/&gt; ~ diff --stat 0xBEEF push &gt;&gt;=</pre>
13 +<pre class="ascii-row">{ main } ~ &gt;_ log --oneline /\ &lt;shark&gt; ;; switch -c ~~~ 0x1337 &lt;/&gt; worktree add &gt;&gt;= /push</pre>
14 +</div>
15 +<section class="landing">
16 + <img class="landing-logo" src="/img/shark-logo.png" alt="git-shark logo">
17 + <h1>git-shark</h1>
18 + <p class="tagline">self-hosted git hosting for people who still write the code</p>
19 +
20 + <ul class="values">
21 + <li><strong>Use AI as a tool, not as a feature.</strong> It assists when you ask; it never takes the wheel.</li>
22 + <li><strong>Focus on co-working, not lazy feeds.</strong> Built for collaborating on code, not doomscrolling activity streams.</li>
23 + <li><strong>Easy and painless to self-host.</strong> One natively-compiled binary plus Postgres &mdash; fast startup, tiny footprint.</li>
24 + </ul>
25 +
26 + <p class="landing-cta">
27 + <a class="btn btn-primary" href="/login">Log in</a>
28 + <a class="btn btn-secondary" href="https://github.com/workaround/git-shark">Self-host it</a>
29 + </p>
13 30 </section>
14 -
15 -<ul class="values">
16 - <li><strong>Use AI as a tool, not as a feature.</strong> It assists when you ask; it never takes the wheel.</li>
17 - <li><strong>Focus on co-working, not lazy feeds.</strong> Built for collaborating on code, not doomscrolling activity streams.</li>
18 - <li><strong>Easy and painless to self-host.</strong> One natively-compiled binary plus Postgres &mdash; fast startup, tiny footprint.</li>
19 -</ul>
20 -
21 -<p>
22 - <a class="btn btn-primary" href="/login">Log in</a>
23 - <a class="btn btn-secondary" href="https://github.com/workaround/git-shark">Self-host it</a>
24 -</p>
25 31 {/include}
MODIFY src/test/java/de/workaround/web/WebUiTest.java +18 -0
diff --git a/src/test/java/de/workaround/web/WebUiTest.java b/src/test/java/de/workaround/web/WebUiTest.java
index 145cf96..0b16e17 100644
--- a/src/test/java/de/workaround/web/WebUiTest.java
+++ b/src/test/java/de/workaround/web/WebUiTest.java
@@ -57,6 +57,24 @@
57 57 }
58 58
59 59 @Test
60 + void landingPageHasAnimatedAsciiBackground() throws Exception
61 + {
62 + // background symbol layer is present in the markup...
63 + given()
64 + .when().get("/")
65 + .then()
66 + .statusCode(200)
67 + .body(containsString("class=\"ascii-bg\""));
68 +
69 + // ...and the animation is defined in the shared stylesheet (no inline <style> on /)
70 + given()
71 + .when().get("/shark.css")
72 + .then()
73 + .statusCode(200)
74 + .body(containsString("@keyframes ascii-glow"));
75 + }
76 +
77 + @Test
60 78 @TestSecurity(user = "ui-alice")
61 79 void ownerSeesOwnPrivateRepositoryOnHome() throws Exception
62 80 {

Keyboard shortcuts

?Show this help
g hGo home
EscClose dialog