Files
GitHop/deploy/gitea/templates/home.tmpl
T
Hop fd6a666d36 Rebuild the homepage around Hop's prompt-to-accepted workflow with a responsive causal ledger and convergent state mark
Hop-State: A_06FN4TE052229S00DNHZFA8
Hop-Proposal: R_06FN4TBDM9ZV9PKZY5VCPTG
Hop-Task: T_06FN4JDW51KJ8GC0YKC8ZW0
Hop-Attempt: AT_06FN4JDW5079JSM69JHWJF0
2026-07-11 11:21:30 -07:00

1301 lines
31 KiB
Cheetah

{{template "base/head" .}}
<style>
html:has(.hop-ledger-page) {
color-scheme: dark;
}
body:has(.hop-ledger-page) {
--hop-ink: oklch(0.145 0.018 292);
--hop-ink-soft: oklch(0.19 0.024 292);
--hop-panel: oklch(0.205 0.025 292);
--hop-line: oklch(0.34 0.035 292);
--hop-line-soft: oklch(0.27 0.03 292);
--hop-paper: oklch(0.945 0.018 88);
--hop-paper-muted: oklch(0.82 0.02 88);
--hop-muted: oklch(0.71 0.028 292);
--hop-violet: oklch(0.73 0.18 292);
--hop-violet-deep: oklch(0.38 0.16 292);
--hop-amber: oklch(0.83 0.15 82);
--hop-accepted: oklch(0.84 0.125 148);
background: var(--hop-ink);
}
body:has(.hop-ledger-page),
body:has(.hop-ledger-page) #navbar,
body:has(.hop-ledger-page) .page-footer {
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
body:has(.hop-ledger-page) #navbar {
background: var(--hop-ink) !important;
border-bottom: 1px solid var(--hop-line-soft) !important;
min-height: 56px;
}
body:has(.hop-ledger-page) #navbar > .navbar-left > .item,
body:has(.hop-ledger-page) #navbar > .navbar-right > .item,
body:has(.hop-ledger-page) #navbar .navbar-mobile-right > .item {
color: var(--hop-paper-muted) !important;
font-weight: 500;
}
body:has(.hop-ledger-page) #navbar > .navbar-left > .item:hover,
body:has(.hop-ledger-page) #navbar > .navbar-left > .item:focus-visible,
body:has(.hop-ledger-page) #navbar > .navbar-right > .item:hover,
body:has(.hop-ledger-page) #navbar > .navbar-right > .item:focus-visible,
body:has(.hop-ledger-page) #navbar .navbar-mobile-right > .item:hover,
body:has(.hop-ledger-page) #navbar .navbar-mobile-right > .item:focus-visible {
background: var(--hop-panel) !important;
color: var(--hop-paper) !important;
}
body:has(.hop-ledger-page) #navbar-logo img {
height: 32px;
opacity: 0;
width: 32px;
}
body:has(.hop-ledger-page) #navbar-logo {
position: relative;
}
body:has(.hop-ledger-page) #navbar-logo::after {
background: url('{{AssetUrlPrefix}}/img/hop.svg?v=3') center / contain no-repeat;
content: '';
height: 32px;
left: 50%;
pointer-events: none;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
width: 32px;
}
body:has(.hop-ledger-page) .page-footer {
background: var(--hop-ink);
border-top: 1px solid var(--hop-line-soft);
color: var(--hop-muted);
}
body:has(.hop-ledger-page) .page-footer a {
color: var(--hop-paper-muted);
}
.hop-ledger-page {
background: var(--hop-ink);
color: var(--hop-paper);
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
margin: 0;
max-width: none;
min-width: 0 !important;
overflow: clip;
padding: 0;
width: 100%;
}
.hop-ledger-page *,
.hop-ledger-page *::before,
.hop-ledger-page *::after {
box-sizing: border-box;
}
.hop-ledger-page > :first-child {
margin-top: 0 !important;
}
.hop-ledger-page h1,
.hop-ledger-page h2,
.hop-ledger-page h3,
.hop-ledger-page p,
.hop-ledger-page figure,
.hop-ledger-page ol,
.hop-ledger-page dl,
.hop-ledger-page dd {
margin: 0;
}
.hop-ledger-page h1,
.hop-ledger-page h2,
.hop-ledger-page h3 {
color: inherit;
text-wrap: balance;
}
.hop-ledger-page p {
color: inherit;
}
.hop-ledger-page a:focus-visible,
.hop-ledger-page button:focus-visible,
.hop-ledger-page [tabindex]:focus-visible {
outline: 3px solid var(--hop-amber);
outline-offset: 4px;
}
.hop-shell {
margin: 0 auto;
max-width: 1360px;
min-width: 0;
padding-inline: clamp(1.5rem, 5vw, 5rem);
width: 100%;
}
.hop-kicker {
align-items: center;
color: var(--hop-violet);
display: flex;
font-size: 0.78rem;
font-weight: 700;
gap: 0.7rem;
letter-spacing: 0.13em;
line-height: 1.3;
text-transform: uppercase;
}
.hop-kicker > span {
background: currentColor;
display: inline-block;
height: 2px;
width: 1.6rem;
}
.hop-ledger-hero {
border-bottom: 1px solid var(--hop-line-soft);
isolation: isolate;
min-height: calc(100svh - 56px);
overflow: hidden;
position: relative;
}
.hop-ledger-hero::before {
background-image:
linear-gradient(to right, oklch(0.34 0.035 292 / 0.28) 1px, transparent 1px),
linear-gradient(to bottom, oklch(0.34 0.035 292 / 0.28) 1px, transparent 1px);
background-size: 48px 48px;
content: '';
inset: 0 0 0 48%;
mask-image: linear-gradient(to bottom, transparent, black 22%, black 78%, transparent);
opacity: 0.55;
pointer-events: none;
position: absolute;
z-index: -1;
}
.hop-ledger-hero-grid {
align-items: center;
display: grid;
gap: clamp(3.5rem, 6vw, 7rem);
grid-template-columns: minmax(0, 1.04fr) minmax(450px, 0.96fr);
min-height: calc(100svh - 56px);
padding-block: clamp(5.5rem, 10vw, 9rem);
}
.hop-ledger-hero-copy {
min-width: 0;
position: relative;
z-index: 1;
}
.hop-ledger-hero h1 {
font-size: clamp(4.25rem, 6.35vw, 6.8rem);
font-weight: 650;
letter-spacing: -0.06em;
line-height: 0.92;
margin-top: 1.4rem;
max-width: 10.5ch;
}
.hop-ledger-hero h1 span {
display: block;
white-space: nowrap;
}
.hop-ledger-hero h1 .hop-title-accent {
color: var(--hop-violet);
}
.hop-ledger-lede {
color: var(--hop-paper-muted) !important;
font-size: clamp(1.08rem, 1.4vw, 1.24rem);
line-height: 1.55;
margin-top: 2rem !important;
max-width: 61ch;
}
.hop-ledger-actions {
display: flex;
flex-wrap: wrap;
gap: 0.8rem;
margin-top: 2.2rem;
}
.hop-ledger-page .hop-button.ui.button {
align-items: center;
border: 1px solid transparent !important;
border-radius: 2px !important;
box-shadow: none !important;
display: inline-flex;
font-family: inherit;
font-size: 0.98rem;
font-weight: 700;
justify-content: center;
line-height: 1;
margin: 0;
min-height: 3.15rem;
padding: 0.95rem 1.25rem;
transition: background-color 180ms ease, border-color 180ms ease, color 180ms ease, transform 180ms cubic-bezier(0.22, 1, 0.36, 1);
}
.hop-ledger-page .hop-button.ui.button:hover {
transform: translateY(-2px);
}
.hop-ledger-page .hop-button-primary.ui.button {
background: var(--hop-paper) !important;
border-color: var(--hop-paper) !important;
color: var(--hop-ink) !important;
}
.hop-ledger-page .hop-button-primary.ui.button:hover {
background: var(--hop-amber) !important;
border-color: var(--hop-amber) !important;
}
.hop-ledger-page .hop-button-secondary.ui.button {
background: transparent !important;
border-color: var(--hop-muted) !important;
color: var(--hop-paper) !important;
}
.hop-ledger-page .hop-button-secondary.ui.button:hover {
background: var(--hop-panel) !important;
border-color: var(--hop-muted) !important;
}
.hop-git-note {
align-items: center;
color: var(--hop-muted) !important;
display: flex;
font-size: 0.88rem;
gap: 0.55rem;
line-height: 1.5;
margin-top: 1.35rem !important;
}
.hop-git-note span {
color: var(--hop-amber);
}
.hop-ledger {
background: var(--hop-panel);
border: 1px solid var(--hop-line);
box-shadow: 24px 24px 0 oklch(0.09 0.014 292 / 0.78);
min-width: 0;
position: relative;
}
.hop-ledger::after {
border: 1px solid oklch(0.73 0.18 292 / 0.45);
content: '';
inset: 9px -9px -9px 9px;
pointer-events: none;
position: absolute;
z-index: -1;
}
.hop-ledger-head {
align-items: center;
border-bottom: 1px solid var(--hop-line);
color: var(--hop-paper);
display: flex;
font-size: 0.77rem;
font-weight: 700;
justify-content: space-between;
letter-spacing: 0.055em;
padding: 1rem 1.1rem;
text-transform: uppercase;
}
.hop-ledger-head > span {
align-items: center;
display: flex;
gap: 0.55rem;
}
.hop-ledger-head i {
background: var(--hop-violet);
border-radius: 999px;
box-shadow: 0 0 0 4px oklch(0.73 0.18 292 / 0.12);
height: 0.5rem;
width: 0.5rem;
}
.hop-ledger-head small {
color: var(--hop-muted);
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.1em;
}
.hop-ledger-track {
list-style: none;
padding: 1.8rem 1.6rem 2rem;
position: relative;
}
.hop-ledger-track::before {
background: var(--hop-line);
bottom: 3.1rem;
content: '';
left: 2.79rem;
position: absolute;
top: 3rem;
width: 1px;
}
.hop-ledger-node {
align-items: stretch;
display: grid;
gap: 0.9rem;
grid-template-columns: 2.4rem minmax(0, 1fr);
margin-top: 1rem;
position: relative;
z-index: 1;
}
.hop-ledger-node:first-child {
margin-top: 0;
}
.hop-state-token {
align-items: center;
align-self: start;
background: var(--hop-ink-soft);
border: 1px solid var(--hop-line);
color: var(--hop-paper);
display: flex;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
font-size: 0.75rem;
font-weight: 700;
height: 2.4rem;
justify-content: center;
width: 2.4rem;
}
.hop-ledger-node > div {
background: var(--hop-ink-soft);
border: 1px solid var(--hop-line-soft);
min-width: 0;
padding: 0.9rem 1rem;
}
.hop-state-label {
color: var(--hop-violet);
display: block;
font-size: 0.66rem;
font-weight: 700;
letter-spacing: 0.095em;
line-height: 1.3;
text-transform: uppercase;
}
.hop-ledger-node strong {
color: var(--hop-paper);
display: block;
font-size: 0.95rem;
font-weight: 650;
line-height: 1.35;
margin-top: 0.32rem;
}
.hop-ledger-node small {
color: var(--hop-muted);
display: block;
font-size: 0.75rem;
line-height: 1.4;
margin-top: 0.25rem;
}
.hop-ledger-prompt .hop-state-token,
.hop-ledger-prompt > div {
border-color: oklch(0.73 0.18 292 / 0.7);
}
.hop-ledger-attempts {
border-top: 1px solid var(--hop-line);
display: grid;
gap: 0.7rem;
grid-template-columns: 1fr 1fr;
list-style: none;
margin: 1.2rem 0 0 3.3rem;
padding-top: 0.75rem;
position: relative;
z-index: 1;
}
.hop-ledger-attempts::before {
background: var(--hop-line);
content: '';
height: 1px;
left: -2.1rem;
position: absolute;
top: -1px;
width: 2.1rem;
}
.hop-attempt {
background: var(--hop-ink-soft);
border: 1px solid var(--hop-line-soft);
min-width: 0;
padding: 0.7rem 0.75rem;
}
.hop-attempt span,
.hop-attempt small {
display: block;
font-size: 0.66rem;
line-height: 1.3;
}
.hop-attempt span {
color: var(--hop-muted);
font-weight: 700;
letter-spacing: 0.07em;
text-transform: uppercase;
}
.hop-attempt strong {
color: var(--hop-paper);
display: block;
font-size: 0.85rem;
line-height: 1.35;
margin-top: 0.25rem;
}
.hop-attempt small {
color: var(--hop-muted);
margin-top: 0.2rem;
}
.hop-attempt-muted {
background: oklch(0.18 0.02 292);
border-color: var(--hop-line-soft);
}
.hop-attempt-muted strong {
color: var(--hop-paper-muted);
}
.hop-attempt-active {
border-color: var(--hop-violet);
}
.hop-attempt-active small {
color: var(--hop-violet);
}
.hop-ledger-checkpoint .hop-state-token {
border-color: var(--hop-amber);
color: var(--hop-amber);
}
.hop-ledger-checkpoint .hop-state-label {
color: var(--hop-amber);
}
.hop-evidence {
align-items: center;
color: var(--hop-paper-muted);
display: flex;
flex-wrap: wrap;
font-size: 0.72rem;
gap: 0.38rem;
line-height: 1.4;
margin-top: 0.55rem;
}
.hop-evidence b {
background: oklch(0.84 0.125 148 / 0.14);
border: 1px solid oklch(0.84 0.125 148 / 0.45);
color: var(--hop-accepted);
font-size: 0.65rem;
letter-spacing: 0.05em;
padding: 0.16rem 0.34rem;
text-transform: uppercase;
}
.hop-ledger-proposal .hop-state-token,
.hop-ledger-proposal > div {
border-color: var(--hop-paper-muted);
}
.hop-ledger-accepted .hop-state-token,
.hop-ledger-accepted > div {
background: var(--hop-accepted);
border-color: var(--hop-accepted);
color: var(--hop-ink);
}
.hop-ledger-accepted .hop-state-token,
.hop-ledger-accepted .hop-state-label,
.hop-ledger-accepted strong,
.hop-ledger-accepted small {
color: var(--hop-ink);
}
.hop-questions {
border-bottom: 1px solid var(--hop-line-soft);
padding-block: clamp(6.5rem, 11vw, 10.5rem);
}
.hop-questions-grid {
align-items: start;
display: grid;
gap: clamp(4rem, 9vw, 9rem);
grid-template-columns: 0.82fr 1.18fr;
}
.hop-section-heading h2,
.hop-workflow-intro h2,
.hop-guardrails h2,
.hop-ledger-closing h2 {
font-size: clamp(2.7rem, 4.6vw, 4.7rem);
font-weight: 600;
letter-spacing: -0.055em;
line-height: 0.99;
}
.hop-section-heading h2,
.hop-workflow-intro h2 {
margin-top: 1.2rem;
}
.hop-section-heading > p:last-child,
.hop-workflow-intro > p:last-child {
color: var(--hop-muted);
font-size: 1.06rem;
line-height: 1.62;
margin-top: 1.5rem;
max-width: 62ch;
}
.hop-answers {
border-top: 1px solid var(--hop-line);
}
.hop-answers > div {
border-bottom: 1px solid var(--hop-line);
display: grid;
gap: 1.5rem;
grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
padding: 1.55rem 0;
}
.hop-answers dt {
align-items: baseline;
color: var(--hop-paper);
display: flex;
font-size: 1.03rem;
font-weight: 650;
gap: 0.85rem;
line-height: 1.4;
}
.hop-answers dt span {
color: var(--hop-violet);
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
font-size: 0.7rem;
}
.hop-answers dd {
color: var(--hop-muted);
font-size: 0.98rem;
line-height: 1.55;
}
.hop-workflow {
background: var(--hop-paper);
color: var(--hop-ink);
padding-block: clamp(6.5rem, 11vw, 10rem);
}
.hop-workflow .hop-kicker {
color: var(--hop-violet-deep);
}
.hop-workflow-intro {
display: grid;
gap: 0 5rem;
grid-template-columns: minmax(0, 1fr) minmax(260px, 0.58fr);
}
.hop-workflow-intro .hop-kicker,
.hop-workflow-intro h2 {
grid-column: 1;
}
.hop-workflow-intro > p:last-child {
align-self: end;
color: oklch(0.39 0.025 292);
grid-column: 2;
grid-row: 1 / span 2;
margin: 0;
}
.hop-workflow-list {
border-bottom: 1px solid oklch(0.72 0.025 88);
list-style: none;
margin-top: clamp(4rem, 7vw, 6.5rem) !important;
padding: 0;
}
.hop-workflow-list li {
align-items: center;
border-top: 1px solid oklch(0.72 0.025 88);
display: grid;
gap: 1.75rem;
grid-template-columns: 4.4rem minmax(0, 1fr) auto;
padding: 1.9rem 0;
}
.hop-step-number {
color: var(--hop-violet-deep);
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
font-size: 0.76rem;
font-weight: 700;
}
.hop-workflow-list h3 {
color: var(--hop-ink);
font-size: clamp(1.35rem, 2vw, 1.75rem);
font-weight: 650;
letter-spacing: -0.035em;
line-height: 1.15;
}
.hop-workflow-list p {
color: oklch(0.39 0.025 292);
font-size: 0.97rem;
line-height: 1.55;
margin-top: 0.45rem !important;
max-width: 68ch;
}
.hop-workflow-list code,
.hop-step-term {
background: var(--hop-ink);
border: 1px solid var(--hop-ink);
border-radius: 2px;
color: var(--hop-paper);
display: inline-block;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
font-size: 0.75rem;
font-weight: 600;
min-width: 8.2rem;
padding: 0.55rem 0.7rem;
text-align: center;
}
.hop-step-term {
background: transparent;
color: var(--hop-ink);
}
.hop-guardrails {
background: var(--hop-violet-deep);
color: var(--hop-paper);
padding-block: clamp(6.5rem, 10vw, 9rem);
}
.hop-guardrails-grid {
align-items: start;
display: grid;
gap: clamp(4rem, 9vw, 9rem);
grid-template-columns: 0.76fr 1.24fr;
}
.hop-guardrails .hop-kicker {
color: var(--hop-amber);
}
.hop-guardrails h2 {
margin-top: 1.2rem;
}
.hop-guardrail-list {
border-top: 1px solid oklch(0.9 0.025 88 / 0.3);
}
.hop-guardrail-list article {
border-bottom: 1px solid oklch(0.9 0.025 88 / 0.3);
display: grid;
gap: 1.4rem;
grid-template-columns: 3.2rem minmax(0, 1fr);
padding: 1.8rem 0;
}
.hop-guardrail-list article > span {
align-items: center;
border: 1px solid oklch(0.9 0.025 88 / 0.5);
color: var(--hop-amber);
display: flex;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
font-size: 0.76rem;
font-weight: 700;
height: 3.2rem;
justify-content: center;
width: 3.2rem;
}
.hop-guardrail-list h3 {
color: var(--hop-paper);
font-size: clamp(1.3rem, 2vw, 1.65rem);
font-weight: 650;
letter-spacing: -0.03em;
line-height: 1.2;
}
.hop-guardrail-list p {
color: oklch(0.89 0.025 88 / 0.78);
font-size: 0.97rem;
line-height: 1.55;
margin-top: 0.45rem !important;
}
.hop-git {
background: var(--hop-ink);
border-bottom: 1px solid var(--hop-line-soft);
color: var(--hop-paper);
padding-block: clamp(6.5rem, 11vw, 10rem);
}
.hop-git-grid {
align-items: start;
display: grid;
gap: clamp(4rem, 9vw, 9rem);
grid-template-columns: 0.9fr 1.1fr;
}
.hop-mapping-wrap {
border-top: 1px solid var(--hop-line);
overflow-x: auto;
}
.hop-mapping {
border-collapse: collapse;
color: var(--hop-paper);
min-width: 500px;
width: 100%;
}
.hop-mapping caption {
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
clip: rect(0 0 0 0);
}
.hop-mapping th,
.hop-mapping td {
border-bottom: 1px solid var(--hop-line);
padding: 1.05rem 0;
text-align: left;
vertical-align: top;
}
.hop-mapping th {
color: var(--hop-violet);
font-size: 0.68rem;
font-weight: 700;
letter-spacing: 0.11em;
text-transform: uppercase;
}
.hop-mapping th:first-child,
.hop-mapping td:first-child {
color: var(--hop-muted);
padding-right: 2rem;
width: 41%;
}
.hop-mapping td {
font-size: 0.94rem;
line-height: 1.45;
}
.hop-mapping td strong,
.hop-mapping td span {
display: block;
}
.hop-mapping td strong {
color: var(--hop-paper);
font-size: 1rem;
font-weight: 650;
}
.hop-mapping td span {
color: var(--hop-muted);
font-size: 0.82rem;
margin-top: 0.18rem;
}
.hop-ledger-closing {
background: var(--hop-accepted);
color: var(--hop-ink);
padding-block: clamp(5.5rem, 9vw, 8rem);
}
.hop-ledger-closing-grid {
align-items: end;
display: grid;
gap: 4rem;
grid-template-columns: minmax(0, 1.15fr) minmax(260px, 0.55fr);
}
.hop-ledger-closing .hop-kicker {
color: oklch(0.29 0.08 148);
}
.hop-ledger-closing h2 {
margin-top: 1.15rem;
max-width: 12ch;
}
.hop-ledger-closing-action {
justify-self: end;
max-width: 23rem;
}
.hop-ledger-closing-action p {
color: oklch(0.27 0.035 148);
font-size: 1.05rem;
line-height: 1.55;
margin-bottom: 1.35rem !important;
}
.hop-ledger-page .hop-button-dark.ui.button {
background: var(--hop-ink) !important;
border-color: var(--hop-ink) !important;
color: var(--hop-paper) !important;
}
.hop-ledger-page .hop-button-dark.ui.button:hover {
background: var(--hop-violet-deep) !important;
border-color: var(--hop-violet-deep) !important;
}
@media (prefers-reduced-motion: no-preference) {
.hop-ledger-hero-copy {
animation: hop-rise 700ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
.hop-ledger {
animation: hop-rise 800ms 120ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
}
@keyframes hop-rise {
from {
opacity: 0;
transform: translateY(18px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@media (max-width: 1100px) {
.hop-ledger-hero,
.hop-ledger-hero-grid {
min-height: auto;
}
.hop-ledger-hero::before {
inset: 40% 0 0;
}
.hop-ledger-hero-grid {
grid-template-columns: 1fr;
}
.hop-ledger-hero-copy {
max-width: 800px;
}
.hop-ledger-hero h1 {
font-size: clamp(4.2rem, 9vw, 6.5rem);
}
.hop-ledger {
max-width: 720px;
}
.hop-questions-grid,
.hop-guardrails-grid,
.hop-git-grid {
gap: clamp(3.5rem, 7vw, 6rem);
}
}
@media (max-width: 820px) {
.hop-shell {
padding-inline: clamp(1.35rem, 5vw, 2.5rem);
}
.hop-questions-grid,
.hop-guardrails-grid,
.hop-git-grid,
.hop-ledger-closing-grid {
grid-template-columns: 1fr;
}
.hop-workflow-intro {
display: block;
}
.hop-workflow-intro > p:last-child {
margin-top: 1.4rem !important;
max-width: 62ch;
}
.hop-ledger-closing-action {
justify-self: start;
}
}
@media (max-width: 620px) {
.hop-ledger-hero-grid {
gap: 4.5rem;
padding-block: 4.5rem 5.5rem;
}
.hop-ledger-hero h1 {
font-size: clamp(2.15rem, 10.5vw, 3.2rem);
letter-spacing: -0.055em;
line-height: 0.95;
}
.hop-ledger-hero h1 span {
white-space: normal;
}
.hop-ledger-lede {
font-size: 1rem;
line-height: 1.58;
}
.hop-ledger-actions {
align-items: stretch;
flex-direction: column;
}
.hop-ledger-page .hop-button.ui.button {
width: 100%;
}
.hop-git-note {
align-items: flex-start;
}
.hop-ledger {
box-shadow: 12px 12px 0 oklch(0.09 0.014 292 / 0.78);
width: calc(100% - 12px);
}
.hop-ledger-head {
align-items: flex-start;
flex-direction: column;
gap: 0.45rem;
}
.hop-ledger-track {
padding-inline: 1rem;
}
.hop-ledger-track::before {
left: 2.19rem;
}
.hop-ledger-node {
gap: 0.65rem;
grid-template-columns: 2.4rem minmax(0, 1fr);
}
.hop-ledger-node > div {
padding: 0.78rem 0.8rem;
}
.hop-ledger-node strong {
font-size: 0.85rem;
}
.hop-ledger-attempts {
grid-template-columns: 1fr;
margin-left: 3.05rem;
}
.hop-answers > div {
gap: 0.55rem;
grid-template-columns: 1fr;
}
.hop-section-heading h2,
.hop-workflow-intro h2,
.hop-guardrails h2,
.hop-ledger-closing h2 {
font-size: clamp(2.4rem, 11.5vw, 3.5rem);
}
.hop-workflow-list li {
align-items: start;
gap: 0.8rem 1rem;
grid-template-columns: 2.4rem minmax(0, 1fr);
padding: 1.55rem 0;
}
.hop-workflow-list code,
.hop-step-term {
grid-column: 2;
justify-self: start;
margin-top: 0.35rem;
}
.hop-guardrail-list article {
gap: 1rem;
grid-template-columns: 2.65rem minmax(0, 1fr);
}
.hop-guardrail-list article > span {
height: 2.65rem;
width: 2.65rem;
}
.hop-mapping {
min-width: 430px;
}
.hop-ledger-closing-grid {
gap: 2.5rem;
}
}
@media (prefers-reduced-motion: reduce) {
.hop-ledger-page *,
.hop-ledger-page *::before,
.hop-ledger-page *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
scroll-behavior: auto !important;
transition-duration: 0.01ms !important;
}
}
</style>
<main id="hop-main" tabindex="-1" role="main" aria-label="Hop, the control layer for coding agents" class="page-content hop-ledger-page">
<section class="hop-ledger-hero" aria-labelledby="hop-ledger-hero-title">
<div class="hop-shell hop-ledger-hero-grid">
<div class="hop-ledger-hero-copy">
<p class="hop-kicker"><span aria-hidden="true"></span>The control layer for coding agents</p>
<h1 id="hop-ledger-hero-title"><span>Keep the prompt.</span><span>Prove the work.</span><span class="hop-title-accent">Land the patch.</span></h1>
<p class="hop-ledger-lede">Hop captures your request before work begins, gives every coding-agent attempt an isolated workspace, and attaches checks to the exact code they evaluated. Review a frozen proposal, then land only the result you trust.</p>
<div class="hop-ledger-actions">
{{if .IsSigned}}
<a class="ui button hop-button hop-button-primary" href="{{AppSubUrl}}/repo/create">Create a repository</a>
<a class="ui button hop-button hop-button-secondary" href="{{AppSubUrl}}/explore/repos">Explore repositories</a>
{{else}}
<a class="ui button hop-button hop-button-primary" href="{{AppSubUrl}}/user/sign_up">Create a Hop account</a>
<a class="ui button hop-button hop-button-secondary" href="#hop-workflow">Trace the workflow</a>
{{end}}
</div>
<p class="hop-git-note"><span aria-hidden="true">↳</span> Git stays underneath. Your repositories and tools keep working.</p>
</div>
<figure class="hop-ledger" aria-labelledby="hop-ledger-title">
<figcaption class="hop-ledger-head" id="hop-ledger-title">
<span><i aria-hidden="true"></i>Example task / Homepage rewrite</span>
<small>Illustrative record</small>
</figcaption>
<ol class="hop-ledger-track">
<li class="hop-ledger-node hop-ledger-prompt">
<span class="hop-state-token" aria-hidden="true">P</span>
<div>
<span class="hop-state-label">Requested outcome · captured first</span>
<strong>Explain Hop clearly on the homepage.</strong>
<small>Illustrative prompt state, stored before project effects</small>
</div>
</li>
<li class="hop-ledger-attempts" aria-label="Two isolated attempts">
<div class="hop-attempt hop-attempt-muted">
<span>Attempt 01</span>
<strong>Human</strong>
<small>Paused</small>
</div>
<div class="hop-attempt hop-attempt-active">
<span>Attempt 02</span>
<strong>Codex</strong>
<small>Selected path</small>
</div>
</li>
<li class="hop-ledger-node hop-ledger-checkpoint">
<span class="hop-state-token" aria-hidden="true">C</span>
<div>
<span class="hop-state-label">Checkpoint · exact tree</span>
<strong>Homepage candidate</strong>
<span class="hop-evidence"><b>Passed</b> render · mobile · tests</span>
</div>
</li>
<li class="hop-ledger-node hop-ledger-proposal">
<span class="hop-state-token" aria-hidden="true">R</span>
<div>
<span class="hop-state-label">Proposal · frozen</span>
<strong>Ready for review</strong>
<small>The candidate cannot drift</small>
</div>
</li>
<li class="hop-ledger-node hop-ledger-accepted">
<span class="hop-state-token" aria-hidden="true">A</span>
<div>
<span class="hop-state-label">Accepted · shared state</span>
<strong>Chosen result landed</strong>
<small>Visible project root synchronized</small>
</div>
</li>
</ol>
</figure>
</div>
</section>
<section class="hop-questions" aria-labelledby="hop-questions-title">
<div class="hop-shell hop-questions-grid">
<div class="hop-section-heading">
<p class="hop-kicker"><span aria-hidden="true"></span>The missing context</p>
<h2 id="hop-questions-title">Git tells you what changed. Hop keeps the decisions around the change.</h2>
<p>Stop reconstructing an agent run from terminal scrollback, branches, and trust-me summaries.</p>
</div>
<dl class="hop-answers">
<div>
<dt><span>01</span>What was requested?</dt>
<dd>The prompt, captured before any project file changes.</dd>
</div>
<div>
<dt><span>02</span>Who or what tried?</dt>
<dd>Every human and agent attempt, isolated and attributable.</dd>
</div>
<div>
<dt><span>03</span>What exactly passed?</dt>
<dd>Check evidence attached to the immutable tree it evaluated.</dd>
</div>
<div>
<dt><span>04</span>Which result became truth?</dt>
<dd>The frozen proposal deliberately accepted into shared state.</dd>
</div>
</dl>
</div>
</section>
<section class="hop-workflow" id="hop-workflow" aria-labelledby="hop-workflow-title">
<div class="hop-shell">
<div class="hop-workflow-intro">
<p class="hop-kicker"><span aria-hidden="true"></span>One task, end to end</p>
<h2 id="hop-workflow-title">A chain of custody for agent-written code.</h2>
<p>Each Hop command advances the work without separating intent from implementation or proof.</p>
</div>
<ol class="hop-workflow-list">
<li>
<span class="hop-step-number">01</span>
<div><h3>Capture intent before effects</h3><p>The request becomes a durable prompt state before an agent reads or edits the project.</p></div>
<code>hop begin</code>
</li>
<li>
<span class="hop-step-number">02</span>
<div><h3>Work in isolation</h3><p>Every attempt gets its own workspace, so agents can explore without colliding with your accepted tree.</p></div>
<span class="hop-step-term">Attempt</span>
</li>
<li>
<span class="hop-step-number">03</span>
<div><h3>Verify the exact result</h3><p>Checks run against an immutable checkpoint. Later edits cannot change what the evidence means.</p></div>
<code>hop check</code>
</li>
<li>
<span class="hop-step-number">04</span>
<div><h3>Freeze the candidate</h3><p>A proposal is a fixed outcome for review, complete with its diff, evidence, and causal history.</p></div>
<code>hop propose</code>
</li>
<li>
<span class="hop-step-number">05</span>
<div><h3>Land deliberately</h3><p>Only the chosen result advances the accepted state. Unrelated workspace changes stay out.</p></div>
<code>hop land</code>
</li>
</ol>
</div>
</section>
<section class="hop-guardrails" aria-labelledby="hop-guardrails-title">
<div class="hop-shell hop-guardrails-grid">
<div>
<p class="hop-kicker"><span aria-hidden="true"></span>Evidence is attached, not implied</p>
<h2 id="hop-guardrails-title">Nothing important is allowed to drift.</h2>
</div>
<div class="hop-guardrail-list">
<article>
<span aria-hidden="true">C</span>
<div><h3>Checks name the tree they tested.</h3><p>A green result always points back to one exact checkpoint.</p></div>
</article>
<article>
<span aria-hidden="true">R</span>
<div><h3>Frozen means frozen.</h3><p>The proposal you review cannot quietly become a different proposal.</p></div>
</article>
<article>
<span aria-hidden="true">A</span>
<div><h3>Acceptance is an explicit event.</h3><p>The actor, policy, evidence, and result stay connected in the record.</p></div>
</article>
</div>
</div>
</section>
<section class="hop-git" aria-labelledby="hop-git-title">
<div class="hop-shell hop-git-grid">
<div class="hop-section-heading">
<p class="hop-kicker"><span aria-hidden="true"></span>Git compatible by design</p>
<h2 id="hop-git-title">Hop adds a native history for agent work. It does not replace Git.</h2>
<p>Repositories, commits, diffs, and standard Git clients remain available. Hop changes the primary story from file history to requested outcomes and verified results.</p>
</div>
<div class="hop-mapping-wrap">
<table class="hop-mapping">
<caption>How familiar Git collaboration concepts map to Hop</caption>
<thead><tr><th scope="col">Git view</th><th scope="col">Hop view</th></tr></thead>
<tbody>
<tr><td>Branch or worktree</td><td><strong>Attempt</strong><span>One isolated approach</span></td></tr>
<tr><td>Commit or tree</td><td><strong>Checkpoint</strong><span>The exact evaluated state</span></td></tr>
<tr><td>CI status</td><td><strong>Evidence</strong><span>Proof bound to that state</span></td></tr>
<tr><td>Pull request</td><td><strong>Proposal</strong><span>A frozen candidate outcome</span></td></tr>
<tr><td>Merge</td><td><strong>Accept</strong><span>Advance shared truth</span></td></tr>
</tbody>
</table>
</div>
</div>
</section>
<section class="hop-ledger-closing" aria-labelledby="hop-ledger-closing-title">
<div class="hop-shell hop-ledger-closing-grid">
<div>
<p class="hop-kicker"><span aria-hidden="true"></span>One agent or many</p>
<h2 id="hop-ledger-closing-title">Start with intent. End with an accepted result.</h2>
</div>
<div class="hop-ledger-closing-action">
<p>Give every agent run a reviewable chain of custody.</p>
{{if .IsSigned}}
<a class="ui button hop-button hop-button-dark" href="{{AppSubUrl}}/repo/create">Create a repository</a>
{{else}}
<a class="ui button hop-button hop-button-dark" href="{{AppSubUrl}}/user/sign_up">Create a Hop account</a>
{{end}}
</div>
</div>
</section>
</main>
{{template "base/footer" .}}