From 5ce87ef70401319d8d7cc3edfc9aa5cc813edc8d Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Mon, 19 Oct 2026 20:31:37 -0700 Subject: [PATCH] Expand byre.run's feature tiles with mockups and animated detail --- site/index.html | 1109 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1096 insertions(+), 13 deletions(-) diff --git a/site/index.html b/site/index.html index 0257ae2..87b42f9 100644 --- a/site/index.html +++ b/site/index.html @@ -32,6 +32,7 @@ --green: #34d058; --purple: #b05cff; --cyan: #00d5f0; + --on-color: #15171a; --tint: 7%; } @media (prefers-color-scheme: dark) { @@ -118,7 +119,7 @@ h2 { padding: 0; list-style: none; } -.features li { +.features > li { --c: var(--blue); padding: 20px; border: 1px solid var(--border); @@ -152,15 +153,763 @@ h2 { .features .hero h3 { font-size: 22px; } -.features p { +.features summary p { margin: 0; color: var(--muted); font-size: 14px; } -.features .hero p { +.features .hero summary p { max-width: 52em; font-size: 16px; } +.features summary { + position: relative; + display: block; + padding-right: 32px; + cursor: pointer; + list-style: none; +} +.features summary::-webkit-details-marker { + display: none; +} +.more { + position: absolute; + top: 4px; + right: 4px; + width: 10px; + height: 10px; + border-right: 2px solid var(--muted); + border-bottom: 2px solid var(--muted); + transform: rotate(45deg); + transition: transform 250ms cubic-bezier(0.65, 0, 0.35, 1), border-color 150ms; +} +.features summary:hover .more { + border-color: var(--c); +} +details[open] .more { + transform: translateY(5px) rotate(225deg); +} +.features > li:has(details[open]) { + grid-column: 1 / -1; +} +::view-transition-group(*) { + overflow: hidden; + border-radius: 10px; + animation-duration: 300ms; + animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); +} +::view-transition-old(*), +::view-transition-new(*) { + height: 100%; + object-fit: none; + object-position: left top; +} +.detail { + margin-top: 24px; + padding-top: 24px; + border-top: 1px solid color-mix(in srgb, var(--c) 30%, var(--border)); +} +.points { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20px; + margin: 28px 0 0; + padding: 0; + list-style: none; + color: var(--muted); + font-size: 14px; + text-wrap: pretty; +} +.points strong { + display: block; + margin-bottom: 4px; + color: var(--text); +} +.fig { + font-size: 13px; + line-height: 1.5; +} +.fig ul { + margin: 0; + padding: 0; + list-style: none; +} +.fig i { + display: inline-block; + flex: none; + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--c); +} +.fig .live { + animation: pulse 1.6s ease-in-out infinite; +} +.fig b { + font-weight: 700; +} +.muted { + color: var(--muted); +} +.split { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; + align-items: start; +} +.stack { + display: grid; + gap: 12px; +} +.win { + overflow: hidden; + border: 1px solid var(--border); + border-radius: 10px; + background: var(--bg); +} +.bar { + display: flex; + align-items: center; + gap: 5px; + padding: 6px 10px; + border-bottom: 1px solid var(--border); + background: var(--surface); + color: var(--muted); + font-size: 12px; +} +.fig .bar i { + width: 7px; + height: 7px; + background: var(--border); +} +.bar i:last-of-type { + margin-right: 6px; +} +.body { + padding: 12px; +} +.row { + display: flex; + align-items: center; + gap: 10px; + padding: 6px 0; + border-top: 1px solid var(--border); +} +.row:first-child { + border-top: 0; +} +.row .end { + margin-left: auto; + color: var(--muted); +} +.chip { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 1px 8px; + border: 1px solid var(--border); + border-radius: 999px; + background: var(--bg); + font-size: 12px; + white-space: nowrap; +} +.chip.on { + border-color: var(--c); + background: color-mix(in srgb, var(--c) 14%, var(--bg)); +} +.btn { + display: inline-block; + padding: 4px 12px; + border-radius: 6px; + background: var(--c); + color: var(--on-color); + font-size: 12px; + font-weight: 700; + white-space: nowrap; +} +.btn.ghost { + border: 1px solid var(--border); + background: var(--bg); + color: var(--text); +} +.msg { + max-width: 88%; + margin-top: 8px; + padding: 8px 10px; + border-radius: 8px; + background: var(--surface); +} +.msg:first-child { + margin-top: 0; +} +.msg.you { + margin-left: auto; + background: color-mix(in srgb, var(--c) 16%, var(--bg)); +} +.msg .row { + padding: 3px 0; + border: 0; +} +.caption { + margin-top: 8px; + color: var(--muted); + font-size: 12px; + text-align: center; +} +.wires { + width: 100%; + height: 100%; + overflow: visible; +} +.wires path { + fill: none; + stroke: var(--c); + stroke-width: 2; + stroke-dasharray: 6 6; + vector-effect: non-scaling-stroke; + animation: flow 1s linear infinite; +} +.wires .off { + stroke: var(--border); + animation: none; +} +.diagram { + display: grid; + grid-template-columns: minmax(0, 5fr) minmax(48px, 2fr) minmax(0, 5fr); +} +.server { + align-self: center; + padding: 16px; + box-shadow: 0 0 0 4px color-mix(in srgb, var(--c) 18%, transparent); +} +.server .label { + display: flex; + justify-content: space-between; + margin-bottom: 6px; + font-weight: 700; +} +.server .label span { + color: var(--muted); + font-weight: 400; +} +.server .row:first-child { + border-top: 1px solid var(--border); +} +.server .red .end { + color: var(--text); + font-weight: 700; +} +.clients { + display: grid; + grid-template-rows: repeat(3, 1fr); + gap: 12px; +} +.client .rows { + display: flex; + align-items: center; + gap: 8px; + padding: 10px; + color: var(--muted); + font-size: 12px; +} +.rows span { + flex: 1; + height: 8px; + border-radius: 4px; + background: var(--c); +} +.client.asleep { + opacity: 0.45; +} +.servers .row.on { + margin: 0 -12px; + padding: 6px 12px; + background: color-mix(in srgb, var(--c) 12%, var(--bg)); +} +.projects { + padding: 4px 0 6px 18px; + color: var(--muted); +} +.projects li::before { + content: "└ "; + color: var(--border); +} +.synced .body { + display: flex; + flex-wrap: wrap; + gap: 6px; +} +.task .body { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 6px; +} +.task .name { + flex-basis: 100%; + font-weight: 700; +} +.option { + display: flex; + align-items: center; + gap: 10px; + margin-top: 8px; + padding: 8px 10px; + border: 1px solid var(--border); + border-radius: 8px; +} +.option::before { + content: ""; + flex: none; + width: 12px; + height: 12px; + border: 2px solid var(--border); + border-radius: 50%; +} +.option.on { + border-color: var(--c); + background: color-mix(in srgb, var(--c) 10%, var(--bg)); +} +.option.on::before { + border-color: var(--c); + background: radial-gradient(var(--c) 40%, transparent 45%); +} +.option > span { + margin-left: auto; +} +.notif { + display: flex; + gap: 12px; + padding: 14px; + border: 1px solid var(--border); + border-radius: 14px; + background: color-mix(in srgb, var(--surface) 80%, var(--bg)); + box-shadow: 0 6px 24px color-mix(in srgb, var(--text) 10%, transparent); +} +.notif .app { + flex: none; + width: 32px; + height: 32px; + border-radius: 8px; + background: linear-gradient(135deg, var(--red), var(--orange), var(--purple)); +} +.flow { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 8px; + margin-bottom: 16px; +} +.flow .arrow { + color: var(--muted); +} +.finding { + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + gap: 6px 10px; + padding: 10px 0; + border-top: 1px solid var(--border); +} +.finding:first-child { + border-top: 0; +} +.finding .reply { + grid-column: 2 / -1; + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 8px; + color: var(--muted); +} +.squash { + align-items: center; +} +.ready .body { + display: grid; + justify-items: start; + gap: 8px; +} +.graph svg { + display: block; + width: 100%; +} +.graph path { + fill: none; + stroke-width: 2; +} +.graph .line { + stroke: var(--border); +} +.graph .branch { + stroke: var(--c); + stroke-dasharray: 5 5; + animation: flow 1s linear infinite; +} +.graph .old { + fill: var(--border); +} +.graph .turn { + fill: var(--bg); + stroke: var(--muted); + stroke-width: 1.5; +} +.graph .new { + fill: var(--c); + stroke: color-mix(in srgb, var(--c) 30%, transparent); + stroke-width: 8; +} +.legend { + display: flex; + justify-content: space-between; + gap: 12px; + margin-top: 6px; + color: var(--muted); + font-size: 12px; +} +.legend b { + color: var(--text); +} +.timeline { + position: relative; + display: flex; + justify-content: space-between; + padding: 0 4%; +} +.timeline::before { + content: ""; + position: absolute; + top: 50%; + left: 4%; + right: 4%; + border-top: 2px solid var(--border); +} +.node { + position: relative; + display: grid; + place-items: center; + width: 36px; + height: 36px; + border: 2px solid var(--border); + border-radius: 50%; + background: var(--bg); + font-size: 12px; +} +.node.on { + border-color: var(--c); + background: color-mix(in srgb, var(--c) 18%, var(--bg)); + font-weight: 700; +} +.fork { + display: flex; + flex-direction: column; + align-items: center; +} +.fork::before { + content: ""; + height: 28px; + border-left: 2px dashed var(--c); +} +.fork .win { + width: min(100%, 380px); +} +.snaps .split { + align-items: center; +} +.diff .row { + font-variant-numeric: tabular-nums; +} +.plus { + color: var(--green); +} +.minus { + color: var(--red); +} +.pipeline { + display: grid; + grid-template-columns: minmax(0, 3fr) minmax(32px, 1fr) minmax(0, 3fr) minmax(32px, 1fr) minmax(0, 3fr); + align-items: stretch; +} +.pipeline .stack { + grid-template-rows: repeat(3, 1fr); +} +.stage { + align-self: center; + padding: 10px 12px; + border: 1px solid var(--border); + border-radius: 10px; + background: var(--bg); +} +.pipeline .stack .stage { + align-self: stretch; +} +.stage .muted { + display: block; + font-size: 12px; +} +.screen { + position: relative; +} +.screen .body { + display: grid; + gap: 10px; +} +.screen .title { + line-height: 20px; +} +.field { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + height: 34px; + padding: 0 10px; + border: 1px solid var(--border); + border-radius: 6px; +} +.typed { + overflow: hidden; + white-space: nowrap; +} +.email { + width: 15ch; + animation: type-email 8s infinite; +} +.password { + width: 8ch; + animation: type-password 8s infinite; +} +.screen .btn { + justify-self: end; + height: 28px; + line-height: 20px; + animation: press 8s infinite; +} +.toast { + position: absolute; + left: 12px; + bottom: 12px; + display: flex; + align-items: center; + gap: 8px; + padding: 4px 10px; + border: 1px solid var(--c); + border-radius: 6px; + background: color-mix(in srgb, var(--c) 16%, var(--bg)); + font-size: 12px; + animation: toast 8s infinite; +} +.cursor { + position: absolute; + top: 170px; + left: calc(100% - 56px); + display: flex; + align-items: flex-start; + pointer-events: none; + animation: steer 8s infinite; +} +.cursor svg { + width: 18px; + height: 18px; + fill: var(--c); + stroke: var(--bg); + stroke-width: 1; +} +.cursor .tag { + margin: 14px 0 0 -2px; + padding: 0 6px; + border-radius: 4px; + background: var(--c); + color: var(--on-color); + font-size: 11px; + font-weight: 700; +} +.log .row:nth-child(1) { + animation: log-1 8s infinite; +} +.log .row:nth-child(2) { + animation: log-2 8s infinite; +} +.log .row:nth-child(3) { + animation: log-3 8s infinite; +} +.log .row:nth-child(4) { + animation: log-4 8s infinite; +} +@keyframes steer { + 0%, + 4% { + top: 200px; + left: 25%; + opacity: 0; + } + 12%, + 32% { + top: 84px; + left: 55%; + opacity: 1; + } + 40%, + 52% { + top: 128px; + left: 55%; + } + 60%, + 64% { + top: 170px; + left: calc(100% - 56px); + transform: none; + } + 62% { + transform: scale(0.85); + } + 92% { + opacity: 1; + } + 100% { + top: 170px; + left: calc(100% - 56px); + opacity: 0; + } +} +@keyframes type-email { + 0%, + 12% { + width: 0; + animation-timing-function: steps(15); + } + 30%, + 92% { + width: 15ch; + opacity: 1; + } + 100% { + opacity: 0; + } +} +@keyframes type-password { + 0%, + 40% { + width: 0; + animation-timing-function: steps(8); + } + 50%, + 92% { + width: 8ch; + opacity: 1; + } + 100% { + opacity: 0; + } +} +@keyframes press { + 0%, + 61%, + 64%, + 100% { + transform: none; + } + 62% { + transform: scale(0.92); + } +} +@keyframes toast { + 0%, + 64% { + opacity: 0; + transform: translateY(6px); + } + 68%, + 92% { + opacity: 1; + transform: none; + } + 100% { + opacity: 0; + } +} +@keyframes log-1 { + 0%, + 6% { + opacity: 0; + } + 8%, + 92% { + opacity: 1; + } + 100% { + opacity: 0; + } +} +@keyframes log-2 { + 0%, + 30% { + opacity: 0; + } + 32%, + 92% { + opacity: 1; + } + 100% { + opacity: 0; + } +} +@keyframes log-3 { + 0%, + 50% { + opacity: 0; + } + 52%, + 92% { + opacity: 1; + } + 100% { + opacity: 0; + } +} +@keyframes log-4 { + 0%, + 66% { + opacity: 0; + } + 68%, + 92% { + opacity: 1; + } + 100% { + opacity: 0; + } +} +@keyframes pulse { + 50% { + opacity: 0.3; + } +} +@keyframes flow { + to { + stroke-dashoffset: -12; + } +} +@media (prefers-reduced-motion: reduce) { + .fig .live, + .wires path, + .graph .branch, + .typed, + .screen .btn, + .toast, + .cursor, + .log .row { + animation: none; + } + .more { + transition: none; + } + ::view-transition-group(*), + ::view-transition-old(*), + ::view-transition-new(*) { + animation: none; + } +} .features .red { --c: var(--red); } @@ -176,6 +925,9 @@ h2 { .features .purple { --c: var(--purple); } +.features .blue { + --c: var(--blue); +} @media (max-width: 900px) { .features { grid-template-columns: repeat(2, 1fr); @@ -194,6 +946,30 @@ h2 { .features .wide { grid-column: auto; } + .split, + .diagram, + .pipeline { + grid-template-columns: 1fr; + gap: 16px; + } + .wires { + display: none; + } + .clients { + grid-template-rows: none; + grid-template-columns: repeat(3, 1fr); + gap: 8px; + } + .client .bar i { + display: none; + } + .pipeline .stack { + grid-template-rows: none; + } + .points { + grid-template-columns: 1fr; + gap: 14px; + } } ol { margin: 0; @@ -227,16 +1003,309 @@ footer {

What it does

Getting started

@@ -249,5 +1318,19 @@ footer { byre is Apache 2.0 licensed. Source · Releases +