2026-10-19 16:59:59 -07:00
<!doctype html>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< title > byre</ title >
2026-10-19 19:43:47 -07:00
< meta name = "description" content = "Run many coding agents in parallel on one Mac, each on its own branch, with a lead agent that keeps track of them for you, and drive them from every Mac you use." >
2026-10-19 21:16:38 -07:00
< link rel = "icon" href = "/icon.png" type = "image/png" sizes = "180x180" >
2026-10-19 16:59:59 -07:00
< link rel = "icon" href = "/icon.svg" type = "image/svg+xml" >
2026-10-19 21:16:38 -07:00
< link rel = "apple-touch-icon" href = "/icon.png" >
2026-10-19 22:04:11 -07:00
< meta property = "og:type" content = "website" >
< meta property = "og:url" content = "https://byre.run/" >
< meta property = "og:site_name" content = "byre" >
< meta property = "og:title" content = "byre: a crew of coding agents, on all your Macs" >
< meta property = "og:description" content = "Run Claude Code, Codex and Antigravity side by side, each on its own branch, with a lead agent that tells you what needs you." >
< meta property = "og:image" content = "https://byre.run/card.png" >
< meta property = "og:image:width" content = "1200" >
< meta property = "og:image:height" content = "630" >
< meta property = "og:image:alt" content = "byre: A crew of coding agents, on all your Macs." >
< meta name = "twitter:card" content = "summary_large_image" >
2026-10-19 16:59:59 -07:00
< style >
@ font-face {
font-family : "Atkinson Hyperlegible Mono" ;
font-weight : 200 800 ;
src : url ( "/fonts/atkinson-hyperlegible-mono-latin-wght-normal.woff2" ) format ( "woff2" );
}
@ font-face {
font-family : "Atkinson Hyperlegible Mono" ;
font-weight : 200 800 ;
src : url ( "/fonts/atkinson-hyperlegible-mono-latin-ext-wght-normal.woff2" ) format ( "woff2" );
unicode-range : U + 0100-02BA , U + 02BD-02C5 , U + 02C7-02CC , U + 02CE-02D7 , U + 02DD-02FF , U + 0304 , U + 0308 , U + 0329 , U + 1D00-1DBF , U + 1E00-1E9F , U + 1EF2-1EFF , U + 2020 , U + 20A0-20AB , U + 20AD-20C0 , U + 2113 , U + 2C60-2C7F , U + A720-A7FF ;
}
: root {
--bg : #fbfbfa ;
--surface : #f2f3f5 ;
--border : #d6d9de ;
--text : #16181b ;
--muted : #4a5260 ;
2026-10-19 19:43:47 -07:00
--accent : #1f55d6 ;
2026-10-19 16:59:59 -07:00
--accent-tint : #e7edfb ;
2026-10-19 19:43:47 -07:00
--blue : #3d7dff ;
--red : #ff3b4e ;
--orange : #ff9500 ;
--green : #34d058 ;
--purple : #b05cff ;
--cyan : #00d5f0 ;
2026-10-19 20:31:37 -07:00
--on-color : #15171a ;
2026-10-19 19:43:47 -07:00
--tint : 7 % ;
2026-10-19 16:59:59 -07:00
}
@ media ( prefers-color-scheme : dark ) {
: root {
--bg : #15171a ;
--surface : #1c1f23 ;
--border : #353b43 ;
--text : #eceff3 ;
--muted : #a9b1bc ;
--accent : #8ab4ff ;
--accent-tint : #1e2a40 ;
2026-10-19 19:43:47 -07:00
--tint : 10 % ;
2026-10-19 16:59:59 -07:00
}
}
* {
box-sizing : border-box ;
}
body {
margin : 0 ;
background : var ( -- bg );
color : var ( -- text );
font : 16 px / 1.6 "Atkinson Hyperlegible Mono" , ui-monospace , monospace ;
2026-10-19 19:43:47 -07:00
border-top : 6 px solid ;
border-image : linear-gradient ( 90 deg , var ( -- red ), var ( -- orange ), var ( -- green ), var ( -- cyan ), var ( -- blue ), var ( -- purple )) 1 ;
2026-10-19 16:59:59 -07:00
}
main {
max-width : 960 px ;
margin : 0 auto ;
padding : 64 px 16 px ;
}
a {
color : var ( -- accent );
}
header {
display : flex ;
flex-direction : column ;
align-items : flex-start ;
gap : 24 px ;
padding-bottom : 56 px ;
border-bottom : 1 px solid var ( -- border );
}
header img {
width : 72 px ;
height : 72 px ;
border-radius : 16 px ;
}
h1 {
margin : 0 ;
font-size : clamp ( 32 px , 6 vw , 52 px );
line-height : 1.15 ;
font-weight : 700 ;
letter-spacing : -0.02 em ;
}
2026-10-19 19:43:47 -07:00
h1 span {
background : linear-gradient ( transparent 72 % , color-mix ( in srgb , var ( -- blue ) 30 % , transparent ) 72 % );
}
2026-10-19 16:59:59 -07:00
. lede {
margin : 0 ;
max-width : 44 em ;
color : var ( -- muted );
font-size : 18 px ;
}
. download {
display : inline-block ;
padding : 12 px 22 px ;
border-radius : 8 px ;
background : var ( -- accent );
color : var ( -- bg );
font-weight : 700 ;
text-decoration : none ;
}
. download : hover {
opacity : 0.9 ;
}
h2 {
margin : 56 px 0 24 px ;
font-size : 22 px ;
}
. features {
display : grid ;
2026-10-19 19:43:47 -07:00
grid-template-columns : repeat ( 3 , 1 fr );
2026-10-19 16:59:59 -07:00
gap : 16 px ;
margin : 0 ;
padding : 0 ;
list-style : none ;
}
2026-10-19 20:31:37 -07:00
. features > li {
2026-10-19 19:43:47 -07:00
--c : var ( -- blue );
2026-10-19 16:59:59 -07:00
padding : 20 px ;
border : 1 px solid var ( -- border );
2026-10-19 19:43:47 -07:00
border-top : 4 px solid var ( -- c );
2026-10-19 16:59:59 -07:00
border-radius : 10 px ;
2026-10-19 19:43:47 -07:00
background : color-mix ( in srgb , var ( -- c ) var ( -- tint ), var ( -- surface ));
}
. features . wide {
grid-column : span 2 ;
}
. features . hero {
grid-column : 1 / -1 ;
padding : 28 px ;
2026-10-19 16:59:59 -07:00
}
. features h3 {
2026-10-19 19:43:47 -07:00
display : flex ;
align-items : flex-start ;
gap : 10 px ;
2026-10-19 16:59:59 -07:00
margin : 0 0 8 px ;
font-size : 16 px ;
}
2026-10-19 19:43:47 -07:00
. features h3 :: before {
content : "" ;
flex : none ;
width : 10 px ;
height : 10 px ;
margin-top : calc ( 0.8 em - 5 px );
border-radius : 50 % ;
background : var ( -- c );
}
. features . hero h3 {
font-size : 22 px ;
}
2026-10-19 20:31:37 -07:00
. features summary p {
2026-10-19 16:59:59 -07:00
margin : 0 ;
color : var ( -- muted );
font-size : 14 px ;
}
2026-10-19 20:31:37 -07:00
. features . hero summary p {
2026-10-19 19:43:47 -07:00
max-width : 52 em ;
font-size : 16 px ;
}
2026-10-19 20:31:37 -07:00
. features summary {
position : relative ;
display : block ;
padding-right : 32 px ;
cursor : pointer ;
list-style : none ;
}
. features summary :: -webkit-details-marker {
display : none ;
}
. more {
position : absolute ;
top : 4 px ;
right : 4 px ;
width : 10 px ;
height : 10 px ;
border-right : 2 px solid var ( -- muted );
border-bottom : 2 px solid var ( -- muted );
transform : rotate ( 45 deg );
transition : transform 250 ms cubic-bezier ( 0.65 , 0 , 0.35 , 1 ), border-color 150 ms ;
}
. features summary : hover . more {
border-color : var ( -- c );
}
details [ open ] . more {
transform : translateY ( 5 px ) rotate ( 225 deg );
}
. features > li : has ( details [ open ]) {
grid-column : 1 / -1 ;
}
:: view-transition-group (*) {
overflow : hidden ;
border-radius : 10 px ;
animation-duration : 300 ms ;
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 : 24 px ;
padding-top : 24 px ;
border-top : 1 px solid color-mix ( in srgb , var ( -- c ) 30 % , var ( -- border ));
}
. points {
display : grid ;
grid-template-columns : repeat ( 3 , 1 fr );
gap : 20 px ;
margin : 28 px 0 0 ;
padding : 0 ;
list-style : none ;
color : var ( -- muted );
font-size : 14 px ;
text-wrap : pretty ;
}
. points strong {
display : block ;
margin-bottom : 4 px ;
color : var ( -- text );
}
. fig {
font-size : 13 px ;
line-height : 1.5 ;
}
. fig ul {
margin : 0 ;
padding : 0 ;
list-style : none ;
}
. fig i {
display : inline-block ;
flex : none ;
width : 8 px ;
height : 8 px ;
border-radius : 50 % ;
background : var ( -- c );
}
. fig . live {
animation : pulse 1.6 s ease-in-out infinite ;
}
. fig b {
font-weight : 700 ;
}
. muted {
color : var ( -- muted );
}
. split {
display : grid ;
grid-template-columns : 1 fr 1 fr ;
gap : 20 px ;
align-items : start ;
}
. stack {
display : grid ;
gap : 12 px ;
}
. win {
overflow : hidden ;
border : 1 px solid var ( -- border );
border-radius : 10 px ;
background : var ( -- bg );
}
. bar {
display : flex ;
align-items : center ;
gap : 5 px ;
padding : 6 px 10 px ;
border-bottom : 1 px solid var ( -- border );
background : var ( -- surface );
color : var ( -- muted );
font-size : 12 px ;
}
. fig . bar i {
width : 7 px ;
height : 7 px ;
background : var ( -- border );
}
. bar i : last-of-type {
margin-right : 6 px ;
}
2026-10-20 17:24:58 -07:00
. bar . chip {
margin-left : auto ;
}
2026-10-19 20:31:37 -07:00
. body {
padding : 12 px ;
}
. row {
display : flex ;
align-items : center ;
gap : 10 px ;
padding : 6 px 0 ;
border-top : 1 px 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 : 6 px ;
padding : 1 px 8 px ;
border : 1 px solid var ( -- border );
border-radius : 999 px ;
background : var ( -- bg );
font-size : 12 px ;
white-space : nowrap ;
}
. chip . on {
border-color : var ( -- c );
background : color-mix ( in srgb , var ( -- c ) 14 % , var ( -- bg ));
}
. btn {
display : inline-block ;
padding : 4 px 12 px ;
border-radius : 6 px ;
background : var ( -- c );
color : var ( -- on - color );
font-size : 12 px ;
font-weight : 700 ;
white-space : nowrap ;
}
. btn . ghost {
border : 1 px solid var ( -- border );
background : var ( -- bg );
color : var ( -- text );
}
. msg {
max-width : 88 % ;
margin-top : 8 px ;
padding : 8 px 10 px ;
border-radius : 8 px ;
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 : 3 px 0 ;
border : 0 ;
}
. caption {
margin-top : 8 px ;
color : var ( -- muted );
font-size : 12 px ;
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 1 s linear infinite ;
}
. wires . off {
stroke : var ( -- border );
animation : none ;
}
. diagram {
display : grid ;
grid-template-columns : minmax ( 0 , 5 fr ) minmax ( 48 px , 2 fr ) minmax ( 0 , 5 fr );
}
. server {
align-self : center ;
padding : 16 px ;
box-shadow : 0 0 0 4 px color-mix ( in srgb , var ( -- c ) 18 % , transparent );
}
. server . label {
display : flex ;
justify-content : space-between ;
margin-bottom : 6 px ;
font-weight : 700 ;
}
. server . label span {
color : var ( -- muted );
font-weight : 400 ;
}
. server . row : first-child {
border-top : 1 px solid var ( -- border );
}
. server . red . end {
color : var ( -- text );
font-weight : 700 ;
}
. clients {
display : grid ;
grid-template-rows : repeat ( 3 , 1 fr );
gap : 12 px ;
}
. client . rows {
display : flex ;
align-items : center ;
gap : 8 px ;
padding : 10 px ;
color : var ( -- muted );
font-size : 12 px ;
}
. rows span {
flex : 1 ;
height : 8 px ;
border-radius : 4 px ;
background : var ( -- c );
}
. client . asleep {
opacity : 0.45 ;
}
. servers . row . on {
margin : 0 -12 px ;
padding : 6 px 12 px ;
background : color-mix ( in srgb , var ( -- c ) 12 % , var ( -- bg ));
}
. projects {
padding : 4 px 0 6 px 18 px ;
color : var ( -- muted );
}
. projects li :: before {
content : "└ " ;
color : var ( -- border );
}
. synced . body {
display : flex ;
flex-wrap : wrap ;
gap : 6 px ;
}
. task . body {
display : flex ;
flex-wrap : wrap ;
align-items : center ;
gap : 6 px ;
}
. task . name {
flex-basis : 100 % ;
font-weight : 700 ;
}
. option {
display : flex ;
align-items : center ;
gap : 10 px ;
margin-top : 8 px ;
padding : 8 px 10 px ;
border : 1 px solid var ( -- border );
border-radius : 8 px ;
}
. option :: before {
content : "" ;
flex : none ;
width : 12 px ;
height : 12 px ;
border : 2 px 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 : 12 px ;
padding : 14 px ;
border : 1 px solid var ( -- border );
border-radius : 14 px ;
background : color-mix ( in srgb , var ( -- surface ) 80 % , var ( -- bg ));
box-shadow : 0 6 px 24 px color-mix ( in srgb , var ( -- text ) 10 % , transparent );
}
. notif . app {
flex : none ;
width : 32 px ;
height : 32 px ;
border-radius : 8 px ;
background : linear-gradient ( 135 deg , var ( -- red ), var ( -- orange ), var ( -- purple ));
}
. flow {
display : flex ;
flex-wrap : wrap ;
align-items : center ;
gap : 8 px ;
margin-bottom : 16 px ;
}
. flow . arrow {
color : var ( -- muted );
}
. finding {
display : grid ;
grid-template-columns : auto 1 fr auto ;
align-items : center ;
gap : 6 px 10 px ;
padding : 10 px 0 ;
border-top : 1 px solid var ( -- border );
}
. finding : first-child {
border-top : 0 ;
}
. finding . reply {
grid-column : 2 / -1 ;
display : flex ;
flex-wrap : wrap ;
align-items : center ;
gap : 8 px ;
color : var ( -- muted );
}
. squash {
align-items : center ;
}
. ready . body {
display : grid ;
justify-items : start ;
gap : 8 px ;
}
. 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 1 s 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 : 12 px ;
margin-top : 6 px ;
color : var ( -- muted );
font-size : 12 px ;
}
. 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 : 2 px solid var ( -- border );
}
. node {
position : relative ;
display : grid ;
place-items : center ;
width : 36 px ;
height : 36 px ;
border : 2 px solid var ( -- border );
border-radius : 50 % ;
background : var ( -- bg );
font-size : 12 px ;
}
. 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 : 28 px ;
border-left : 2 px dashed var ( -- c );
}
. fork . win {
width : min ( 100 % , 380 px );
}
. 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 , 3 fr ) minmax ( 32 px , 1 fr ) minmax ( 0 , 3 fr ) minmax ( 32 px , 1 fr ) minmax ( 0 , 3 fr );
align-items : stretch ;
}
. pipeline . stack {
grid-template-rows : repeat ( 3 , 1 fr );
}
. stage {
align-self : center ;
padding : 10 px 12 px ;
border : 1 px solid var ( -- border );
border-radius : 10 px ;
background : var ( -- bg );
}
. pipeline . stack . stage {
align-self : stretch ;
}
. stage . muted {
display : block ;
font-size : 12 px ;
}
. screen {
position : relative ;
}
. screen . body {
display : grid ;
gap : 10 px ;
}
. screen . title {
line-height : 20 px ;
}
. field {
display : flex ;
align-items : center ;
justify-content : space-between ;
gap : 12 px ;
height : 34 px ;
padding : 0 10 px ;
border : 1 px solid var ( -- border );
border-radius : 6 px ;
}
. typed {
overflow : hidden ;
white-space : nowrap ;
}
. email {
width : 15 ch ;
animation : type-email 8 s infinite ;
}
. password {
width : 8 ch ;
animation : type-password 8 s infinite ;
}
. screen . btn {
justify-self : end ;
height : 28 px ;
line-height : 20 px ;
animation : press 8 s infinite ;
}
. toast {
position : absolute ;
left : 12 px ;
bottom : 12 px ;
display : flex ;
align-items : center ;
gap : 8 px ;
padding : 4 px 10 px ;
border : 1 px solid var ( -- c );
border-radius : 6 px ;
background : color-mix ( in srgb , var ( -- c ) 16 % , var ( -- bg ));
font-size : 12 px ;
animation : toast 8 s infinite ;
}
. cursor {
position : absolute ;
top : 170 px ;
left : calc ( 100 % - 56 px );
display : flex ;
align-items : flex-start ;
pointer-events : none ;
animation : steer 8 s infinite ;
}
. cursor svg {
width : 18 px ;
height : 18 px ;
fill : var ( -- c );
stroke : var ( -- bg );
stroke-width : 1 ;
}
. cursor . tag {
margin : 14 px 0 0 -2 px ;
padding : 0 6 px ;
border-radius : 4 px ;
background : var ( -- c );
color : var ( -- on - color );
font-size : 11 px ;
font-weight : 700 ;
}
. log . row : nth-child ( 1 ) {
animation : log-1 8 s infinite ;
}
. log . row : nth-child ( 2 ) {
animation : log-2 8 s infinite ;
}
. log . row : nth-child ( 3 ) {
animation : log-3 8 s infinite ;
}
. log . row : nth-child ( 4 ) {
animation : log-4 8 s infinite ;
}
@ keyframes steer {
0 %,
4 % {
top : 200 px ;
left : 25 % ;
opacity : 0 ;
}
12 %,
32 % {
top : 84 px ;
left : 55 % ;
opacity : 1 ;
}
40 %,
52 % {
top : 128 px ;
left : 55 % ;
}
60 %,
64 % {
top : 170 px ;
left : calc ( 100 % - 56 px );
transform : none ;
}
62 % {
transform : scale ( 0.85 );
}
92 % {
opacity : 1 ;
}
100 % {
top : 170 px ;
left : calc ( 100 % - 56 px );
opacity : 0 ;
}
}
@ keyframes type-email {
0 %,
12 % {
width : 0 ;
animation-timing-function : steps ( 15 );
}
30 %,
92 % {
width : 15 ch ;
opacity : 1 ;
}
100 % {
opacity : 0 ;
}
}
@ keyframes type-password {
0 %,
40 % {
width : 0 ;
animation-timing-function : steps ( 8 );
}
50 %,
92 % {
width : 8 ch ;
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 ( 6 px );
}
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 ;
}
}
2026-10-19 19:43:47 -07:00
. features . red {
--c : var ( -- red );
}
. features . orange {
--c : var ( -- orange );
}
. features . green {
--c : var ( -- green );
}
. features . cyan {
--c : var ( -- cyan );
}
. features . purple {
--c : var ( -- purple );
}
2026-10-19 20:31:37 -07:00
. features . blue {
--c : var ( -- blue );
}
2026-10-19 19:43:47 -07:00
@ media ( max-width : 900px ) {
. features {
grid-template-columns : repeat ( 2 , 1 fr );
}
}
@ media ( max-width : 560px ) {
h1 {
text-wrap : balance ;
}
h1 br {
display : none ;
}
. features {
grid-template-columns : 1 fr ;
}
. features . wide {
grid-column : auto ;
}
2026-10-19 20:31:37 -07:00
. split ,
. diagram ,
. pipeline {
grid-template-columns : 1 fr ;
gap : 16 px ;
}
. wires {
display : none ;
}
. clients {
grid-template-rows : none ;
grid-template-columns : repeat ( 3 , 1 fr );
gap : 8 px ;
}
. client . bar i {
display : none ;
}
. pipeline . stack {
grid-template-rows : none ;
}
. points {
grid-template-columns : 1 fr ;
gap : 14 px ;
}
2026-10-19 19:43:47 -07:00
}
2026-10-19 16:59:59 -07:00
ol {
margin : 0 ;
padding-left : 24 px ;
max-width : 48 em ;
}
ol li + li {
margin-top : 12 px ;
}
2026-10-19 19:43:47 -07:00
ol li :: marker {
color : var ( -- accent );
font-weight : 700 ;
2026-10-19 16:59:59 -07:00
}
footer {
margin-top : 72 px ;
padding-top : 24 px ;
border-top : 1 px solid var ( -- border );
color : var ( -- muted );
font-size : 14 px ;
}
</ style >
</ head >
< body >
< main >
< header >
2026-10-20 17:24:58 -07:00
< img src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 36 36'%3E%3Crect width='36' height='36' fill='%231c1f23'/%3E%3Cg transform='translate(2 2.5)' stroke='%23a9b1bc' stroke-width='1.5'%3E%3Cline x1='16' y1='16' x2='16' y2='4'/%3E%3Cline x1='16' y1='16' x2='27.4' y2='12.3'/%3E%3Cline x1='16' y1='16' x2='23.1' y2='25.7'/%3E%3Cline x1='16' y1='16' x2='8.9' y2='25.7'/%3E%3Cline x1='16' y1='16' x2='4.6' y2='12.3'/%3E%3C/g%3E%3Cg transform='translate(2 2.5)'%3E%3Ccircle fill='%233d7dff' cx='16' cy='16' r='6'/%3E%3Ccircle fill='%23ff3b4e' cx='16' cy='4' r='3.5'/%3E%3Ccircle fill='%23ff9500' cx='27.4' cy='12.3' r='3.5'/%3E%3Ccircle fill='%2334d058' cx='23.1' cy='25.7' r='3.5'/%3E%3Ccircle fill='%23b05cff' cx='8.9' cy='25.7' r='3.5'/%3E%3Ccircle fill='%2300d5f0' cx='4.6' cy='12.3' r='3.5'/%3E%3C/g%3E%3C/svg%3E" alt = "" >
2026-10-19 19:43:47 -07:00
< h1 > A crew of coding agents, < br >< span > on all your Macs.</ span ></ h1 >
< p class = "lede" > byre runs Claude Code, Codex and Antigravity side by side on one Mac, each on its own branch and worktree, with a lead agent that watches them all and tells you what needs you. Pick up from whichever Mac you're at.</ p >
2026-10-19 16:59:59 -07:00
< a class = "download" href = "https://dl.byre.run/byre.dmg" > Download for macOS</ a >
</ header >
< h2 > What it does</ h2 >
< ul class = "features" >
2026-10-19 20:31:37 -07:00
< li class = "hero" >< details name = "feature" >
< summary >< h3 > One server, every Mac</ h3 >< p > The agents run on one Mac that stays on, such as a Mac mini in a closet. Open byre on your laptop, your desk Mac, or all of them at once: each shows the same tasks, questions and transcripts live. Close the laptop and the agents keep working.</ p >< span class = "more" ></ span ></ summary >
< div class = "detail" >
< div class = "fig diagram" aria-hidden = "true" >
< div class = "win server" >
< div class = "label" > Mac mini< span > in the closet</ span ></ div >
< ul >
< li class = "row green" >< i class = "live" ></ i > fix-login< span class = "end" > working</ span ></ li >
< li class = "row green" >< i class = "live" ></ i > website< span class = "end" > working</ span ></ li >
< li class = "row red" >< i ></ i > deploy< span class = "end" > needs you</ span ></ li >
< li class = "row cyan" >< i ></ i > search< span class = "end" > in review</ span ></ li >
</ ul >
</ div >
< svg class = "wires" viewBox = "0 0 100 300" preserveAspectRatio = "none" >
< path d = "M0 150 C50 150 50 50 100 50" />
< path d = "M0 150 L100 150" />
< path class = "off" d = "M0 150 C50 150 50 250 100 250" />
</ svg >
< div class = "clients" >
< div class = "win client" >< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > MacBook Air</ div >< div class = "rows" >< span class = "green" ></ span >< span class = "green" ></ span >< span class = "red" ></ span >< span class = "cyan" ></ span ></ div ></ div >
< div class = "win client" >< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > iMac</ div >< div class = "rows" >< span class = "green" ></ span >< span class = "green" ></ span >< span class = "red" ></ span >< span class = "cyan" ></ span ></ div ></ div >
< div class = "win client asleep" >< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > MacBook Pro</ div >< div class = "rows" > lid closed</ div ></ div >
</ div >
</ div >
< ul class = "points" >
< li >< strong > Live on every screen.</ strong > Answer a question on the laptop and it's gone from the iMac the same second.</ li >
< li >< strong > Close the lid.</ strong > The crew lives on the server, so shut the laptop and come back to finished work.</ li >
< li >< strong > From anywhere.</ strong > byre talks over Tailscale, so the closet Mac is one click from the coffee shop.</ li >
</ ul >
</ div >
</ details ></ li >
< li class = "wide purple" >< details name = "feature" >
< summary >< h3 > Every server, every project</ h3 >< p > Your servers sync through iCloud, so a new Mac finds them on first launch. Switch between servers in one window, each with as many projects as you like and its own color.</ p >< span class = "more" ></ span ></ summary >
< div class = "detail" >
< div class = "fig split" aria-hidden = "true" >
< div class = "win servers" >
< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > byre</ div >
< div class = "body" >
< ul >
< li class = "row on purple" >< i ></ i >< b > mac-mini</ b >< span class = "end" > 3 projects</ span ></ li >
</ ul >
< ul class = "projects" >
< li > byre</ li >
< li > website</ li >
< li > infra</ li >
</ ul >
< ul >
< li class = "row cyan" >< i ></ i > studio< span class = "end" > 2 projects</ span ></ li >
< li class = "row orange" >< i ></ i > build-box< span class = "end" > 5 projects</ span ></ li >
</ ul >
</ div >
</ div >
< div >
< div class = "stack" >
< div class = "win synced" >< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > MacBook Air</ div >< div class = "body" >< span class = "chip purple" >< i ></ i > mac-mini</ span >< span class = "chip cyan" >< i ></ i > studio</ span >< span class = "chip orange" >< i ></ i > build-box</ span ></ div ></ div >
< div class = "win synced" >< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > new Mac Studio</ div >< div class = "body" >< span class = "chip purple" >< i ></ i > mac-mini</ span >< span class = "chip cyan" >< i ></ i > studio</ span >< span class = "chip orange" >< i ></ i > build-box</ span ></ div ></ div >
</ div >
< div class = "caption" > first launch, synced through iCloud</ div >
</ div >
</ div >
< ul class = "points" >
< li >< strong > Already there.</ strong > Servers sync through iCloud, so a new Mac finds them all on first launch.</ li >
< li >< strong > One window.</ strong > Switch between every server and all of its projects without leaving it.</ li >
< li >< strong > Color-coded.</ strong > Each server wears its own color, so you always know which one you're on.</ li >
</ ul >
</ div >
</ details ></ li >
< li class = "green" >< details name = "feature" >
< summary >< h3 > Tasks</ h3 >< p > Every task gets its own git worktree, branch and port block. Talk to its agent in a live transcript, even mid-turn.</ p >< span class = "more" ></ span ></ summary >
< div class = "detail" >
< div class = "fig split" aria-hidden = "true" >
< div class = "stack" >
< div class = "win task" >< div class = "body" >< span class = "name" > fix-login</ span >< span class = "chip" > ⎇ byre/fix-login</ span >< span class = "chip" > own worktree</ span >< span class = "chip" > ports 41000– 41009</ span ></ div ></ div >
< div class = "win task" >< div class = "body" >< span class = "name" > website</ span >< span class = "chip" > ⎇ byre/website</ span >< span class = "chip" > own worktree</ span >< span class = "chip" > ports 41010– 41019</ span ></ div ></ div >
< div class = "win task" >< div class = "body" >< span class = "name" > search</ span >< span class = "chip" > ⎇ byre/search</ span >< span class = "chip" > own worktree</ span >< span class = "chip" > ports 41020– 41029</ span ></ div ></ div >
</ div >
< div class = "win" >
< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > fix-login</ div >
< div class = "body" >
< div class = "msg" > Moving sessions to the new table and copying the old rows across…</ div >
< div class = "msg you" > keep the old column until the migration ships</ div >
< div class = "msg" > Got it, I'll leave < b > legacy_id</ b > in place and finish the copy.</ div >
< div class = "row" >< i class = "live" ></ i >< span class = "muted" > working</ span ></ div >
</ div >
</ div >
</ div >
< ul class = "points" >
< li >< strong > Isolated.</ strong > Its own worktree, branch and ports, so parallel tasks never collide.</ li >
< li >< strong > Talk mid-turn.</ strong > Message the agent while it works and it takes the note on board.</ li >
< li >< strong > As many as you like.</ strong > Start another whenever an idea strikes; they all run at once.</ li >
</ ul >
</ div >
</ details ></ li >
< li class = "orange" >< details name = "feature" >
2026-10-20 17:24:58 -07:00
< summary >< h3 > Lead agent</ h3 >< p > One agent watches every task, points you at what needs you, and starts, merges or discards tasks when you ask.</ p >< span class = "more" ></ span ></ summary >
2026-10-19 20:31:37 -07:00
< div class = "detail" >
< div class = "fig" aria-hidden = "true" >
< div class = "win" >
< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > Lead</ div >
< div class = "body" >
< div class = "msg" > Three tasks need you:
< ul >
< li class = "row red" >< i ></ i >< b > deploy</ b >< span class = "muted" > has a question about cache lifetime</ span ></ li >
< li class = "row orange" >< i ></ i >< b > website</ b >< span class = "muted" > is ready to merge</ span ></ li >
< li class = "row cyan" >< i ></ i >< b > search</ b >< span class = "muted" > got two review findings</ span ></ li >
</ ul >
</ div >
< div class = "msg you" > merge website, and start a task to add dark mode to the docs</ div >
< div class = "msg" > Merging website now. Started < b > docs dark mode</ b > ; I'll tell you when it needs you.</ div >
</ div >
</ div >
</ div >
< ul class = "points" >
< li >< strong > Watches everything.</ strong > Every task's turns, questions and reviews pass by the lead.</ li >
< li >< strong > Knows what needs you.</ strong > It tells you which tasks are waiting on you, and why.</ li >
< li >< strong > Does the legwork.</ strong > Ask it to start, message, merge or discard tasks, and it does.</ li >
</ ul >
</ div >
</ details ></ li >
< li class = "wide red" >< details name = "feature" >
2026-10-20 17:24:58 -07:00
< summary >< h3 > Questions, not interruptions</ h3 >< p > When an agent needs a decision, it lays out the options and recommends one. A notification brings you straight to it; pick an answer and the agent carries on. Every option says what you get and what you give up, so the call takes seconds.</ p >< span class = "more" ></ span ></ summary >
2026-10-19 20:31:37 -07:00
< div class = "detail" >
< div class = "fig split" aria-hidden = "true" >
< div class = "win" >
< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > deploy · question</ div >
< div class = "body" >
< b > How long should the download page be cached?</ b >
< div class = "option" > 1 hour< span class = "muted" > fresh, more load</ span ></ div >
< div class = "option on" > 1 day< span class = "chip on" > recommended</ span ></ div >
< div class = "option" > 1 week< span class = "muted" > stale after a release</ span ></ div >
</ div >
</ div >
< div class = "notif" >
< div class = "app" ></ div >
< div >
< b > byre · deploy</ b >
< div class = "muted" > How long should the download page be cached?</ div >
</ div >
</ div >
</ div >
< ul class = "points" >
< li >< strong > Options laid out.</ strong > Every choice comes with what you get and what you give up.</ li >
< li >< strong > A recommendation.</ strong > The agent always says which option it would pick, and why.</ li >
< li >< strong > Never miss one.</ strong > A notification lands the moment a question does, a click away.</ li >
</ ul >
</ div >
</ details ></ li >
2026-10-20 17:24:58 -07:00
< li class = "wide purple" >< details name = "feature" >
< summary >< h3 > Step away, they keep going</ h3 >< p > Flip on Away and agents stop waiting on you: each one makes its best call and keeps working. Back at your desk? Answer any question they asked, and byre forks the task from that moment with your answer.</ p >< span class = "more" ></ span ></ summary >
< div class = "detail" >
< div class = "fig split" aria-hidden = "true" >
< div class = "win" >
< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > deploy< span class = "chip on" > AWAY · click when back</ span ></ div >
< div class = "body" >
< b > How long should the download page be cached?</ b >
< div class = "option on" > 1 day< span class = "chip on" > agent's pick</ span ></ div >
< div class = "option" > 1 hour</ div >
< div class = "row" >< i class = "live" ></ i >< span class = "muted" > kept working while you were away</ span ></ div >
</ div >
</ div >
< div >
< div class = "win" >
< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > deploy · you're back</ div >
< div class = "body" >
< div class = "option" > 1 day</ div >
< div class = "option on" > 1 hour< span class = "chip on" > your answer</ span ></ div >
</ div >
</ div >
< div class = "fork" >< div class = "win" >< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > new task</ div >< div class = "body" >< b > deploy: cache for 1 hour</ b >< div class = "muted" > forked with your answer</ div ></ div ></ div ></ div >
</ div >
</ div >
< ul class = "points" >
< li >< strong > Never stalled.</ strong > Questions don't wait on you: each agent makes its best call and keeps going.</ li >
< li >< strong > Your call still counts.</ strong > Answer when you're back and byre forks the task from that moment.</ li >
< li >< strong > No guessing on secrets.</ strong > Passwords, permissions and test results still wait for you.</ li >
</ ul >
</ div >
</ details ></ li >
< li class = "green" >< details name = "feature" >
< summary >< h3 > Snapshots and forks</ h3 >< p > Step through a task's snapshots, diff any of them, and fork a new task from any one, conversation included.</ p >< span class = "more" ></ span ></ summary >
< div class = "detail" >
< div class = "fig snaps" aria-hidden = "true" >
< div class = "split" >
< div >
< div class = "timeline" >< span class = "node" > #1</ span >< span class = "node" > #2</ span >< span class = "node on" > #3</ span >< span class = "node" > #4</ span >< span class = "node" > #5</ span ></ div >
< div class = "fork" >< div class = "win" >< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > new task</ div >< div class = "body" >< b > search: try SQLite FTS instead</ b >< div class = "muted" > forked from #3, conversation included</ div ></ div ></ div ></ div >
</ div >
< div class = "win diff" >
< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > diff #3 → #5</ div >
< div class = "body" >
< div class = "row" > index/build.go< span class = "end" >< span class = "plus" > +48</ span > < span class = "minus" > − 12</ span ></ span ></ div >
< div class = "row" > index/query.go< span class = "end" >< span class = "plus" > +21</ span > < span class = "minus" > − 30</ span ></ span ></ div >
< div class = "row" > docs/search.md< span class = "end" >< span class = "plus" > +9</ span > < span class = "minus" > − 2</ span ></ span ></ div >
</ div >
</ div >
</ div >
</ div >
< ul class = "points" >
< li >< strong > Every step kept.</ strong > Each turn that changes files leaves a snapshot behind it.</ li >
< li >< strong > Diff anything.</ strong > Compare any two snapshots to see exactly what each turn did.</ li >
< li >< strong > Fork the past.</ strong > Start a new task from any snapshot, conversation included.</ li >
</ ul >
</ div >
</ details ></ li >
2026-10-19 20:31:37 -07:00
< li class = "wide cyan" >< details name = "feature" >
< summary >< h3 > Cross-vendor reviews</ h3 >< p > Every turn that changes files is reviewed by the other vendor's model. The agent fixes the findings it agrees with on its own and says why it skips the rest; you can overrule any of them with a click.</ p >< span class = "more" ></ span ></ summary >
< div class = "detail" >
< div class = "fig" aria-hidden = "true" >
< div class = "flow" >< span class = "chip" > Claude Code turn</ span >< span class = "arrow" > →</ span >< span class = "chip" > snapshot 3</ span >< span class = "arrow" > →</ span >< span class = "chip on" > Codex review</ span >< span class = "arrow" > →</ span >< span class = "chip" > agent triages</ span ></ div >
< div class = "win" >
< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > search · review of snapshot 3</ div >
< div class = "body" >
< div class = "finding red" >< i ></ i >< b > Port block isn't freed when a task is discarded</ b >< span class = "chip" > medium</ span >< div class = "reply" >< span class = "chip green on" > fixing</ span > Releasing it in the discard path.</ div ></ div >
< div class = "finding orange" >< i ></ i >< b > Rename cfg to config</ b >< span class = "chip" > low</ span >< div class = "reply" >< span class = "chip" > ignoring</ span > Matches the surrounding code.< span class = "btn ghost" > Fix it anyway</ span ></ div ></ div >
</ div >
</ div >
</ div >
< ul class = "points" >
< li >< strong > A second opinion.</ strong > Each turn that changes files is read by the other vendor's model.</ li >
< li >< strong > Triaged for you.</ strong > The agent fixes what holds up and explains what it leaves.</ li >
< li >< strong > Your call.</ strong > Overrule any finding it skipped with one click and it gets fixed.</ li >
</ ul >
</ div >
</ details ></ li >
< li >< details name = "feature" >
< summary >< h3 > One-click merge</ h3 >< p > The agent merges main in and resolves conflicts, then byre squashes, pushes and closes the task.</ p >< span class = "more" ></ span ></ summary >
< div class = "detail" >
< div class = "fig split squash" aria-hidden = "true" >
< div class = "win ready" >
< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > avatars</ div >
< div class = "body" >
< span class = "chip on" > ready to merge</ span >
< b > Let people upload a profile photo</ b >
< span class = "muted" > Photos are cropped to a square and resized, and initials show until one is set.</ span >
< span class = "btn" > Merge</ span >
</ div >
</ div >
< div class = "graph" >
< svg viewBox = "0 0 300 120" >
< path class = "line" d = "M10 95 H290" />
< path class = "branch" d = "M60 95 C85 95 85 30 110 30 H210 C235 30 235 95 260 95" />
< circle class = "old" cx = "30" cy = "95" r = "6" />
< circle class = "old" cx = "60" cy = "95" r = "6" />
< circle class = "turn" cx = "115" cy = "30" r = "4" />
< circle class = "turn" cx = "138" cy = "30" r = "4" />
< circle class = "turn" cx = "161" cy = "30" r = "4" />
< circle class = "turn" cx = "184" cy = "30" r = "4" />
< circle class = "turn" cx = "207" cy = "30" r = "4" />
< circle class = "new" cx = "260" cy = "95" r = "9" />
</ svg >
< div class = "legend" >< span > 5 turns on byre/avatars</ span >< span >< b > 1 commit on main</ b ></ span ></ div >
</ div >
</ div >
< ul class = "points" >
< li >< strong > Conflicts handled.</ strong > The agent merges main in and works through any conflicts.</ li >
< li >< strong > One clean commit.</ strong > The whole task lands on main as a single squashed commit.</ li >
< li >< strong > Then it's done.</ strong > byre pushes and closes the task, so your list stays short.</ li >
</ ul >
</ div >
</ details ></ li >
< li class = "orange" >< details name = "feature" >
< summary >< h3 > Teams and workflows</ h3 >< p > Agents spawn subtasks or share a worktree as a team. Workflows chain stages with fan-out and fan-in.</ p >< span class = "more" ></ span ></ summary >
< div class = "detail" >
< div class = "fig pipeline" aria-hidden = "true" >
< div class = "stage" >< b > plan</ b >< span class = "muted" > one agent</ span ></ div >
< svg class = "wires" viewBox = "0 0 100 300" preserveAspectRatio = "none" >
< path d = "M0 150 C50 150 50 50 100 50" />
< path d = "M0 150 L100 150" />
< path d = "M0 150 C50 150 50 250 100 250" />
</ svg >
< div class = "stack" >
< div class = "stage" >< b > build api</ b >< span class = "muted" > Claude Code</ span ></ div >
< div class = "stage" >< b > build app</ b >< span class = "muted" > Codex</ span ></ div >
< div class = "stage" >< b > write docs</ b >< span class = "muted" > Antigravity</ span ></ div >
</ div >
< svg class = "wires" viewBox = "0 0 100 300" preserveAspectRatio = "none" >
< path d = "M0 50 C50 50 50 150 100 150" />
< path d = "M0 150 L100 150" />
< path d = "M0 250 C50 250 50 150 100 150" />
</ svg >
< div class = "stage" >< b > review</ b >< span class = "muted" > all three, together</ span ></ div >
</ div >
< ul class = "points" >
< li >< strong > Subtasks.</ strong > An agent hands off pieces of work to new agents on their own branches.</ li >
< li >< strong > Teams.</ strong > Several agents share one worktree and build the same change together.</ li >
< li >< strong > Workflows.</ strong > Save a pipeline once: stages fan out, fan back in, and run again.</ li >
</ ul >
</ div >
</ details ></ li >
2026-10-20 17:24:58 -07:00
< li class = "wide purple" >< details name = "feature" >
< summary >< h3 > Hands on your Macs</ h3 >< p > Agents can see and drive the Mac byre runs on, and the Macs you have the app open on, when a task needs it. They click through what they just built and check it works before telling you it's done.</ p >< span class = "more" ></ span ></ summary >
2026-10-19 20:31:37 -07:00
< div class = "detail" >
< div class = "fig hands" aria-hidden = "true" >
< div class = "split" >
< div class = "win screen" >
< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > your app · on the iMac</ div >
< div class = "body" >
< b class = "title" > Sign in</ b >
< div class = "field" >< span class = "muted" > Email</ span >< span class = "typed email" > ada@example.com</ span ></ div >
< div class = "field" >< span class = "muted" > Password</ span >< span class = "typed password" > ••••••••</ span ></ div >
< span class = "btn" > Sign in</ span >
</ div >
< div class = "toast green" >< i ></ i > Signed in as Ada</ div >
< div class = "cursor" >< svg viewBox = "0 0 16 16" >< path d = "M2 1 L2 14 L5.5 10.5 L8 15 L10 14 L7.5 9.5 L12.5 9.5 Z" /></ svg >< span class = "tag" > fix-login</ span ></ div >
</ div >
< div class = "win" >
< div class = "bar" >< i ></ i >< i ></ i >< i ></ i > fix-login</ div >
< div class = "body log" >
< div class = "row" >< i ></ i > found the Sign in window</ div >
< div class = "row" >< i ></ i > typed a test email</ div >
< div class = "row" >< i ></ i > typed the password</ div >
< div class = "row green" >< i ></ i > clicked Sign in: it works</ div >
</ div >
</ div >
</ div >
</ div >
< ul class = "points" >
< li >< strong > Sees the screen.</ strong > Agents read screenshots and every window's controls.</ li >
< li >< strong > Drives the Mac.</ strong > They click, type and browse to try what they just built.</ li >
< li >< strong > Your Macs too.</ strong > Any Mac with byre's app open can lend the agents a hand.</ li >
</ ul >
</ div >
</ details ></ li >
2026-10-19 16:59:59 -07:00
</ ul >
< h2 > Getting started</ h2 >
< ol >
2026-10-20 17:24:58 -07:00
< li >< a href = "https://dl.byre.run/byre.dmg" > Download byre</ a > , sign in to Tailscale, and click < strong > Run byre on this Mac</ strong > .</ li >
2026-10-19 19:43:47 -07:00
< li > Open it on every other Mac you own. Your crew is already there.</ li >
2026-10-19 16:59:59 -07:00
</ ol >
< footer >
byre is Apache 2.0 licensed. < a href = "https://g.fc.run/ai/byre" > Source</ a > · < a href = "https://g.fc.run/ai/byre/releases" > Releases</ a >
</ footer >
</ main >
2026-10-19 20:31:37 -07:00
< script >
for ( const [ i , el ] of [... document . querySelectorAll ( ".features > li, main > h2, main > ol, footer" )]. entries ()) {
el . style . viewTransitionName = `block- ${ i } ` ;
}
for ( const summary of document . querySelectorAll ( ".features summary" )) {
summary . addEventListener ( "click" , ( event ) => {
event . preventDefault ();
const details = summary . parentElement ;
document . startViewTransition (() => {
details . open = ! details . open ;
});
});
}
</ script >
2026-10-19 16:59:59 -07:00
</ body >
</ html >