Add Hop logo and an explanatory public landing page

Hop-State: A_06FN4GBGQFKPXH5B5MK4P0R
Hop-Proposal: R_06FN4GAZCEER9W65XJTCVJG
Hop-Task: T_06FN4FT3436TX5AV35QM4RR
Hop-Attempt: AT_06FN4FT3401X9BHCJVKT52G
This commit is contained in:
Hop
2026-07-11 10:37:28 -07:00
parent 8115847b32
commit ae2ffae36d
7 changed files with 122 additions and 10 deletions
+10 -1
View File
@@ -10,13 +10,22 @@ fi
docker compose --env-file "$env_file" up -d gitea docker compose --env-file "$env_file" up -d gitea
docker compose --env-file "$env_file" exec -T -u root gitea \ docker compose --env-file "$env_file" exec -T -u root gitea \
mkdir -p /data/gitea/templates/custom /data/gitea/public/assets/js mkdir -p /data/gitea/templates/custom /data/gitea/public/assets/js /data/gitea/public/assets/css /data/gitea/public/assets/img
docker compose --env-file "$env_file" cp \
deploy/gitea/templates/home.tmpl \
gitea:/data/gitea/templates/home.tmpl
docker compose --env-file "$env_file" cp \ docker compose --env-file "$env_file" cp \
deploy/gitea/templates/custom/footer.tmpl \ deploy/gitea/templates/custom/footer.tmpl \
gitea:/data/gitea/templates/custom/footer.tmpl gitea:/data/gitea/templates/custom/footer.tmpl
docker compose --env-file "$env_file" cp \ docker compose --env-file "$env_file" cp \
deploy/gitea/public/assets/js/hop-native.js \ deploy/gitea/public/assets/js/hop-native.js \
gitea:/data/gitea/public/assets/js/hop-native.js gitea:/data/gitea/public/assets/js/hop-native.js
docker compose --env-file "$env_file" cp \
deploy/gitea/public/assets/css/hop-home.css \
gitea:/data/gitea/public/assets/css/hop-home.css
docker compose --env-file "$env_file" cp \
deploy/gitea/public/assets/img/hop.svg \
gitea:/data/gitea/public/assets/img/hop.svg
docker compose --env-file "$env_file" exec -T -u root gitea \ docker compose --env-file "$env_file" exec -T -u root gitea \
chown -R git:git /data/gitea/templates /data/gitea/public chown -R git:git /data/gitea/templates /data/gitea/public
docker compose --env-file "$env_file" exec -T -u git \ docker compose --env-file "$env_file" exec -T -u git \
@@ -0,0 +1,32 @@
.hop-home { max-width: 1120px; margin: 0 auto; padding: 5.5rem 2rem 4rem; }
.hop-home h1, .hop-home h2, .hop-home h3 { color: var(--color-text); letter-spacing: -0.035em; }
.hop-home p { color: var(--color-text-light-2); line-height: 1.65; }
.hop-eyebrow { color: var(--color-primary) !important; font-size: .78rem; font-weight: 700; letter-spacing: .13em; margin: 0 0 1rem; text-transform: uppercase; }
.hop-hero { align-items: center; display: grid; gap: 5rem; grid-template-columns: 1.25fr .75fr; min-height: 390px; }
.hop-hero h1 { font-size: clamp(2.75rem, 6vw, 4.8rem); line-height: 1.02; margin: 0; max-width: 750px; }
.hop-lede { font-size: 1.18rem; margin: 1.5rem 0 2rem; max-width: 650px; }
.hop-actions { display: flex; flex-wrap: wrap; gap: .75rem; }
.hop-actions .button, .hop-closing .button { margin: 0; }
.hop-hero-mark { display: grid; justify-items: center; position: relative; }
.hop-hero-mark img { filter: drop-shadow(0 18px 24px color-mix(in srgb, var(--color-primary) 22%, transparent)); width: min(100%, 220px); }
.hop-state-card { align-items: center; background: var(--color-box-body); border: 1px solid var(--color-secondary); border-radius: 8px; box-shadow: 0 12px 28px rgba(0,0,0,.12); color: var(--color-text); display: flex; font-size: .85rem; gap: .55rem; margin-top: -1rem; padding: .72rem .9rem; position: relative; }
.hop-state-dot { background: #2da44e; border-radius: 50%; height: .55rem; width: .55rem; }
.hop-intro { border-top: 1px solid var(--color-secondary); margin-top: 4.5rem; max-width: 780px; padding-top: 4.5rem; }
.hop-intro h2, .hop-flow h2, .hop-closing h2 { font-size: clamp(2rem, 3.5vw, 3rem); line-height: 1.12; margin: 0 0 1.1rem; }
.hop-intro p { font-size: 1.12rem; }
.hop-benefits { display: grid; gap: 1px; grid-template-columns: repeat(3, 1fr); margin: 5rem 0; background: var(--color-secondary); border: 1px solid var(--color-secondary); }
.hop-benefits article { background: var(--color-box-body); padding: 2rem; }
.hop-number { color: var(--color-primary); font-size: .82rem; font-weight: 700; letter-spacing: .1em; }
.hop-benefits h2 { font-size: 1.35rem; margin: 3.5rem 0 .8rem; }
.hop-benefits p { font-size: .97rem; margin: 0; }
.hop-flow { display: grid; gap: 4rem; grid-template-columns: .8fr 1.2fr; padding: 2rem 0 5rem; }
.hop-flow h2 { font-size: 2.3rem; }
.hop-flow ol { border-left: 1px solid var(--color-secondary); list-style: none; margin: 0; padding: 0 0 0 2rem; }
.hop-flow li { display: grid; gap: 1rem; grid-template-columns: 2rem 1fr; margin: 0 0 2rem; position: relative; }
.hop-flow li:last-child { margin-bottom: 0; }
.hop-flow li > span { align-items: center; background: var(--color-box-body); border: 1px solid var(--color-primary); border-radius: 50%; color: var(--color-primary); display: flex; font-size: .8rem; font-weight: 700; height: 2rem; justify-content: center; margin-left: -3.05rem; }
.hop-flow h3 { font-size: 1.12rem; margin: .25rem 0 .3rem; }
.hop-flow li p { margin: 0; }
.hop-closing { align-items: center; background: color-mix(in srgb, var(--color-primary) 9%, var(--color-box-body)); border: 1px solid color-mix(in srgb, var(--color-primary) 32%, var(--color-secondary)); display: flex; justify-content: space-between; gap: 2rem; padding: 2.5rem; }
.hop-closing h2 { font-size: 2rem; margin-bottom: 0; max-width: 540px; }
@media (max-width: 760px) { .hop-home { padding: 3.5rem 1.25rem; } .hop-hero, .hop-flow { gap: 2.5rem; grid-template-columns: 1fr; } .hop-hero-mark { justify-items: start; } .hop-hero-mark img { width: 145px; } .hop-benefits { grid-template-columns: 1fr; } .hop-benefits h2 { margin-top: 1.5rem; } .hop-closing { align-items: flex-start; flex-direction: column; } }
+4
View File
@@ -0,0 +1,4 @@
+Exit code: 0
Wall time: 0 seconds
Output:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 180" fill="none" shape-rendering="auto" aria-hidden="true" width="512" height="512"><!-- Generated by DiceBear (https://dicebear.com) --><metadata xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/"><rdf:RDF><rdf:Description><dc:title>Bottts</dc:title><dc:creator>Pablo Stanley</dc:creator><dc:source xsi:type="dcterms:URI">https://bottts.com/</dc:source><dcterms:license xsi:type="dcterms:URI">https://bottts.com/</dcterms:license><dc:rights>Remix of “Bottts” (https://bottts.com/) by “Pablo Stanley”, licensed under “Free for personal and commercial use” (https://bottts.com/)</dc:rights></rdf:Description></rdf:RDF></metadata><defs><g id="sides-antenna01-b3dae8fb"><mask id="sidesAntenna01-a" style="mask-type:luminance"><rect y="31" width="36" height="14" rx="4" fill="white"/><rect x="12" y="14" width="36" height="48" rx="4" fill="white"/><rect x="120" y="28" width="36" height="24" rx="4" fill="white"/><rect x="5" y="11" width="2" height="20" fill="white"/></mask><g mask="url(#sidesAntenna01-a)"><path d="M-6 0h180v76H-6z" fill="#9975ea"/><rect x="-6" width="180" height="76" fill="white" fill-opacity=".3"/><rect x="-6" y="38" width="180" height="38" fill="black" fill-opacity=".1"/></g><rect x="5" y="11" width="2" height="20" fill="white" fill-opacity=".4"/><circle cx="6" cy="8" r="4" fill="#FFEA8F"/><circle cx="7" cy="7" r="2" fill="white"/></g><g id="top-antennaCrooked-b3dae8fb"><mask id="topAntennaCrooked-a" style="mask-type:luminance"><path d="M47.54 34.98 43 45.59h-3.74l4.92-10.43-6.05-10.43 3.22-11.84 2.9.8-2.9 10.6z" fill="white"/><rect x="30" y="39.59" width="24" height="13" fill="white"/></mask><g mask="url(#topAntennaCrooked-a)"><path d="M-8 .6H92v52H-8z" fill="#9975ea"/><path d="M-8 6.6H92v52H-8z" fill="white" fill-opacity=".3"/><rect x="30" y="39.59" width="24" height="13" fill="white" fill-opacity=".2"/></g><circle cx="42" cy="8.59" r="8" fill="#FFE65C"/><circle cx="45" cy="5.59" r="3" fill="white"/></g><g id="texture-circuits-b3dae8fb"><path d="M66 36h49.42a5 5 0 1 1 0 4H62V6h4zm-8-12h-4V6h4z" fill="black" fill-opacity=".1"/><path d="M163 31a5 5 0 0 1 2 9.58V66h19v4h-23V40.58a5 5 0 0 1 2-9.58" fill="white" fill-opacity=".2"/><path d="M157 74h27v4h-31V52h4zm-85 26a5 5 0 0 0-2 9.58V135H51v4h23v-29.42a5 5 0 0 0-2-9.58" fill="black" fill-opacity=".2"/></g><g id="head-round02-b3dae8fb"><mask id="headRound02-a" style="mask-type:luminance"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 31v-1c.18-.48.4-1.5 1-3 .83-3.06 2.78-6.56 6-10C16.7 6.6 35.17 0 65 0s48.3 6.6 58 17c3.22 3.44 5.17 6.94 6 10 .6 1.5.82 2.52 1 3v40c0-.1-.03.5 0 1a54 54 0 0 1-1 6c-1.19 6-3.4 11.91-7 17-9.72 16.34-27.74 26-57 26s-47.28-9.66-57-26c-3.6-5.1-5.8-11-7-17a54 54 0 0 1-1-6c.03-.45 0-1.32 0-1z" fill="white"/></mask><g mask="url(#headRound02-a)"><path d="M-4-2h138v124H-4z" fill="#9975ea"/><use transform="translate(-44 -7)" href="#texture-circuits-b3dae8fb"/></g></g><g id="mouth-smile01-b3dae8fb"><path d="M23.05 4.44a2 2 0 1 1 3.9-.88C27.72 6.96 30.4 9 34 9s6.28-2.04 7.05-5.44a2 2 0 1 1 3.9.88C43.75 9.7 39.43 13 34 13s-9.76-3.3-10.95-8.56" fill="black" fill-opacity=".6"/></g><g id="eyes-frame1-b3dae8fb"><rect y="4" width="104" height="42" rx="4" fill="black" fill-opacity=".8"/><rect x="28" y="25" width="10" height="11" rx="2" fill="#8BDDFF"/><rect x="66" y="25" width="10" height="11" rx="2" fill="#8BDDFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M21 4h8L12 46H4z" fill="white" fill-opacity=".4"/></g><clipPath id="clip-b3dae8fb"><rect width="180" height="180" rx="0" ry="0"/></clipPath></defs><g clip-path="url(#clip-b3dae8fb)"><use transform="translate(6 66)" href="#sides-antenna01-b3dae8fb"/><use transform="translate(49 -.6)" href="#top-antennaCrooked-b3dae8fb"/><use transform="translate(25 44)" href="#head-round02-b3dae8fb"/><use transform="translate(56 128)" href="#mouth-smile01-b3dae8fb"/><use transform="translate(38 76)" href="#eyes-frame1-b3dae8fb"/></g></svg>
@@ -141,6 +141,8 @@
} }
function applyHopSemantics() { function applyHopSemantics() {
const brandLogo = document.querySelector('#navbar-logo img');
if (brandLogo) brandLogo.src = brandLogo.src.replace('/img/logo.svg', '/assets/img/hop.svg');
for (const root of document.querySelectorAll(semanticRoots)) replaceExactText(root); for (const root of document.querySelectorAll(semanticRoots)) replaceExactText(root);
replaceAccessibleLabels(document); replaceAccessibleLabels(document);
addWorkflowSummary(); addWorkflowSummary();
+2 -2
View File
@@ -1,2 +1,2 @@
<script src="{{AssetUrlPrefix}}/js/hop-native.js?v=1"></script> <link rel="stylesheet" href="{{AssetUrlPrefix}}/assets/css/hop-home.css?v=1">
<script src="{{AssetUrlPrefix}}/assets/js/hop-native.js?v=2"></script>
+66
View File
@@ -0,0 +1,66 @@
{{template "base/head" .}}
<main role="main" aria-label="Hop — prompt-native software development" class="page-content hop-home">
<section class="hop-hero">
<div class="hop-hero-copy">
<p class="hop-eyebrow">The prompt-native forge</p>
<h1>Turn a clear outcome into accepted, verified work.</h1>
<p class="hop-lede">Hop gives people and AI agents one shared workflow for building software: state the goal, run isolated attempts, review the evidence, and accept the result.</p>
<div class="hop-actions">
{{if .IsSigned}}
<a class="ui primary button" href="{{AppSubUrl}}/repo/create">Create a repository</a>
<a class="ui basic button" href="{{AppSubUrl}}/explore/repos">Explore work</a>
{{else}}
<a class="ui primary button" href="{{AppSubUrl}}/user/sign_up">Get started</a>
<a class="ui basic button" href="#how-it-works">See how it works</a>
{{end}}
</div>
</div>
<div class="hop-hero-mark" aria-hidden="true">
<img src="{{AssetUrlPrefix}}/assets/img/hop.svg" width="180" height="180" alt="">
<div class="hop-state-card"><span class="hop-state-dot"></span><span>Outcome ready for review</span></div>
</div>
</section>
<section class="hop-intro" aria-labelledby="hop-intro-title">
<p class="hop-eyebrow">A better unit of collaboration</p>
<h2 id="hop-intro-title">Software work begins with intent, not a branch.</h2>
<p>Git remains the durable home for your files. Hop makes the work around those files legible: what was asked for, who attempted it, what was checked, and which outcome became shared truth.</p>
</section>
<section class="hop-benefits" aria-label="Why use Hop">
<article>
<div class="hop-number">01</div>
<h2>Keep the why attached</h2>
<p>Each task starts with the requested outcome and retains its causal context, so nobody has to reconstruct intent from a terminal history.</p>
</article>
<article>
<div class="hop-number">02</div>
<h2>Try work without collisions</h2>
<p>Human and agent attempts run in isolated workspaces. Compare different approaches without putting your main line at risk.</p>
</article>
<article>
<div class="hop-number">03</div>
<h2>Review proof, not promises</h2>
<p>Checks are bound to immutable checkpoints, making it clear exactly what was verified before a proposal is accepted.</p>
</article>
</section>
<section class="hop-flow" id="how-it-works" aria-labelledby="how-it-works-title">
<div class="hop-flow-heading">
<p class="hop-eyebrow">How Hop works</p>
<h2 id="how-it-works-title">A calm, visible path from request to shared truth.</h2>
</div>
<ol>
<li><span>1</span><div><h3>Open a task</h3><p>Describe the outcome you need in plain language.</p></div></li>
<li><span>2</span><div><h3>Launch an attempt</h3><p>Work yourself, direct an agent, or run both approaches side by side.</p></div></li>
<li><span>3</span><div><h3>Inspect the evidence</h3><p>Review diffs, checkpoints, and the checks attached to them.</p></div></li>
<li><span>4</span><div><h3>Accept the outcome</h3><p>Choose the verified proposal that should become the shared state.</p></div></li>
</ol>
</section>
<section class="hop-closing">
<div><p class="hop-eyebrow">Ready when you are</p><h2>Build with agents without losing the thread.</h2></div>
{{if .IsSigned}}<a class="ui primary button" href="{{AppSubUrl}}/repo/create">Start a repository</a>{{else}}<a class="ui primary button" href="{{AppSubUrl}}/user/sign_up">Create your account</a>{{end}}
</section>
</main>
{{template "base/footer" .}}
+6 -7
View File
@@ -1,8 +1,7 @@
# Hop-native Gitea semantics # Hop-native Gitea semantics
HopWeb keeps Gitea's existing interface design and changes the meaning of its HopWeb keeps Gitea's existing forge interface and adds a Hop-specific public
collaboration elements. No custom stylesheet, theme, component library, or home page, brand mark, and semantic vocabulary for collaboration elements.
layout override is installed.
## Install ## Install
@@ -18,9 +17,10 @@ Set `ENV_FILE` when the Compose environment is stored elsewhere:
ENV_FILE=/path/to/environment ./deploy/gitea/install-hop-native.sh ENV_FILE=/path/to/environment ./deploy/gitea/install-hop-native.sh
``` ```
The installer copies the adapter into Gitea's persistent custom directory, The installer copies the home page, brand mark, styles, and adapter into
sets the application name to `Hop`, restarts Gitea, and waits for a healthy Gitea's persistent custom directory, sets the application name to `Hop`,
response. Re-run it after editing the adapter or replacing the Gitea volume. restarts Gitea, and waits for a healthy response. Re-run it after editing an
asset or replacing the Gitea volume.
## Semantic mapping ## Semantic mapping
@@ -52,4 +52,3 @@ After changing the pinned Gitea version:
4. confirm proposal creation and acceptance labels; 4. confirm proposal creation and acceptance labels;
5. inspect browser console errors; and 5. inspect browser console errors; and
6. test a narrow viewport and keyboard navigation. 6. test a narrow viewport and keyboard navigation.