/* Generated by tools/dc_import.py from design/rendered/. Do not edit:
   edit the snapshot, re-render, re-import, reconcile. */

@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/geist-latin-ext.58a6b173d5ca.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;
}
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/geist-latin-ext.58a6b173d5ca.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;
}
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/geist-latin-ext.58a6b173d5ca.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;
}
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/geist-latin.9b6f5ff45b27.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/geist-latin.9b6f5ff45b27.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/geist-latin.9b6f5ff45b27.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/fonts/geistmono-latin-ext.745994b5cd95.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;
}
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/geistmono-latin-ext.745994b5cd95.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;
}
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/geistmono-latin-ext.745994b5cd95.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;
}
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/fonts/geistmono-latin.5f3d6ad60f29.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/geistmono-latin.5f3d6ad60f29.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/geistmono-latin.5f3d6ad60f29.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

html,body {margin:0;padding:0;background:#F1EADC;color:#242424}
body {--sans:'Geist',Arial,sans-serif;--mono:'PP Supply Mono','Geist Mono',Menlo,Consolas,monospace;font-family:var(--sans);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
a {color:inherit}
a:hover {color:#B91819}
button {font-family:var(--sans)}
@keyframes atcDash {to{stroke-dashoffset:-24}}
@keyframes atcPulse {0%,100%{opacity:1}50%{opacity:.3}}
@keyframes atcRise {from{transform:translateY(105%)}to{transform:translateY(0)}}
@keyframes atcFade {from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion: reduce) {*,*::before,*::after{animation:none !important;transition:none !important}}
button,input {font-family:var(--sans)}
input::placeholder {color:#A2A299}

/* Deliberate departures from the snapshot. Each is load-bearing. */

/* The hero image is `width: 120%; margin-left: -10%`, a bleed that reaches past
   both edges of its column. Nothing clipped the right-hand side, so the page
   scrolled horizontally at every width and showed a strip of page background
   beside the content: 54px of it at 1024, 40px at 768, 20px at 390. Clipping at
   the page edge keeps the bleed the design asked for and drops the scrollbar.
   Clipping the image's own container instead would remove the bleed entirely. */
html,
body {
  overflow-x: hidden;
}

/* runtime-generated hover and focus rules */
.h55e14e8208e8:hover { color: rgb(206, 203, 191) !important; }
.h04fa79fdcb2a:hover { background: rgb(0, 0, 0) !important; }
.hbec1fb97283c:focus { outline: rgb(255, 255, 255) solid 2px !important; outline-offset: -2px !important; }
.h909c38ec9e3b:hover { background: rgb(65, 23, 30) !important; color: rgb(255, 255, 255) !important; }
.he7a2a2bb66ca:focus { outline: rgb(255, 255, 255) solid 2px !important; }
.h64dd0f1f89db:hover { color: rgb(255, 255, 255) !important; }
.hdd183235d9ac:hover { background: rgb(255, 255, 255) !important; color: rgb(185, 24, 25) !important; }
.h63de607ddddd:hover { opacity: 0.85 !important; }
.h6dce7f73a1f5:hover { color: rgb(185, 24, 25) !important; }
.h5127dc91198f:focus { outline: none !important; color: rgb(185, 24, 25) !important; }
.h5421a3fe1807:hover { background: rgb(241, 234, 220) !important; }
.h27d0c229c683:focus { border-color: rgb(36, 36, 36) !important; }
.h5d1bc583f57e:hover { background: rgb(65, 23, 30) !important; }


/* A collapsed tab draws the rule across its own bottom, so the line running along
   the strip carries straight through it and a row of collapsed tabs reads as one
   unbroken bar. An open tab draws nothing there: its own background covers the
   strip's rule, so it reads as continuous with the section it opens.

   Painted, NOT moved. Offsetting the tab by 1px did produce the same picture, but
   the tab visibly jumped on every click, which is a worse bug than the one it
   fixed. Nothing here changes geometry.

   The rule waits out the collapse. The body animates grid-template-rows over
   0.5s, so an undelayed line arrived while the section was still visibly closing,
   before the thing it is meant to close off had finished. Duration stays 0s
   because a 1px rule should land, not fade. Opening is NOT delayed: the tab has
   to stop drawing the line the instant it starts opening. Interpolating from a
   transparent shadow rather than `none` keeps that a well-defined colour change. */
[data-collapse]{box-shadow:inset 0 -1px 0 transparent;transition:box-shadow 0s}
[data-collapse][aria-expanded="false"]{box-shadow:inset 0 -1px 0 rgb(36,36,36);transition:box-shadow 0s 0.5s}

/* Read by assistive tech, never painted. The install line's host is Braille
   glyphs carrying no meaning, so they are aria-hidden and this stands in for
   them; without it a screen reader announces "$ curl -fsSL | sh", a broken
   command that gives no hint anything was withheld. Not `display:none` or
   `visibility:hidden`, which remove the text from the accessibility tree too. */
.atc-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* Chopped bottom-right corner, at 45 degrees. Meant to be reused, so the cut is
   parameterised by ONE length: the polygon steps the same distance left along the
   bottom as it steps up the right side, which is what keeps the angle at 45 no
   matter the element's aspect ratio. A percentage would not — percentages in
   clip-path resolve per axis, so `calc(100% - 25%)` is 25% of the width on x and
   25% of the height on y, two different pixel amounts on anything but a square.

   The default scales with the viewport so the cut stays about a quarter of the
   way up a half-width landscape image: ~65px at 1024, ~95px at 1440 and above.
   Override --atc-chop on any element that wants a bigger or smaller bite. */
.atc-chop{--atc-chop:clamp(60px,6.6vw,96px);clip-path:polygon(0 0,100% 0,100% calc(100% - var(--atc-chop)),calc(100% - var(--atc-chop)) 100%,0 100%)}
/* Mirrored: the bite comes out of the bottom-LEFT instead. Overrides the
   clip-path above, so `class="atc-chop atc-chop-left"` reads as the effect
   plus which corner. */
.atc-chop-left{clip-path:polygon(0 0,100% 0,100% 100%,var(--atc-chop) 100%,0 calc(100% - var(--atc-chop)))}

/* Photo left, copy right, at a deliberate 0.45 : 1 split. The page's other
   two-column areas use repeat(auto-fit, minmax(...)) and land on equal columns;
   equal columns here would starve the item grid beside the photo and push it from
   two rows to three, which is what makes this section balloon. Explicit fractions
   need an explicit breakpoint, hence the media query: one column below 900px,
   where the photo goes back above the copy. */
.atc-split{display:grid;gap:clamp(32px,4vw,64px);align-items:start;grid-template-columns:1fr}
/* The item grid is stated, not inferred. auto-fit picks a column count from the
   available width, and the column beside the photo lands in exactly the range
   where that flips: measured 1x4 between 960 and 1152 and 2x2 from 1280 up, so
   the section swung ~170px taller across ordinary laptop widths. Two columns is
   the design, so two columns is written down. */
.atc-split-body > div{grid-template-columns:1fr}
@media (min-width:600px){.atc-split-body > div{grid-template-columns:repeat(2,minmax(0,1fr))}}

@media (min-width:900px){
  /* The heading sits alone in the right column's first row; the photo and the
     item grid share the second. That is what lets the photo centre against the
     heading-plus-table block instead of lining up with one edge of it. Doing it
     with a margin would mean guessing the heading's height, and the heading
     rewraps with the viewport. Below 900px the placements drop away and the
     three stack in source order: heading, photo, items.

     1.15fr : 1fr gives the photo the wider column. It was 0.45 : 1 when the
     table still held six items in three columns; four items in two need less
     room, and the photo took the difference. */
  .atc-split{grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);row-gap:0}
  .atc-split-head{grid-column:2;grid-row:1}
  .atc-split-body{grid-column:2;grid-row:2}
  /* The photo spans both rows and centres itself against them, so it sits
     against the middle of the heading-plus-table block rather than lining up
     with one edge of it. */
  .atc-split-media{grid-column:1;grid-row:1 / span 2;align-self:center}
}

/* The atc-race video and the STATS panel that overlaps it.

   The ratio here is the clip's own, so the box never needs to crop to fill and
   object-fit has nothing to do. It has to be kept in step with the file, which
   has now changed twice: 1120x480, then 1120x612, now 2464x1350. A box still
   declaring an old ratio would squash the frame rather than letterbox it, because
   the default object-fit is `fill`, and 1.830 against 1.825 is close enough to
   look almost right.

   There is deliberately no min-height. A 280px floor used to sit here, and below
   a 653px content box it forced the box taller than its ratio while
   `object-fit: cover` ate the width to fill it: 45% of the frame cut off the
   sides on a 390px phone, on a video whose entire subject is two terminals side
   by side. Without a floor the frame is always whole. It gets short on a phone,
   but short-and-complete beats tall-and-half-gone for this shot.

   The panel's overlap is a percentage, and percentage margins resolve against
   the containing block's WIDTH even on the vertical axis. The video's height is
   that same width x 9/21, so a width-relative margin holds a constant fraction
   of the video no matter the viewport. -7% is the -96px the design had at a
   1360px content box, and it stays that same 16% of the video's height all the
   way down instead of growing into a third of a phone-sized frame. */
/* 1000px is the cap on the whole composition, not just the clip. The panel and
   caption row is capped to the same right edge (its own offset subtracted, since
   it starts inset from the container's left), so the caption stays flush with the
   clip's right edge instead of floating out to the container's.

   The panel's grid column drops 640 -> 560 to pay for it. At a 1000px clip the row
   is 936px wide, and a 640px panel would leave the caption 253px, about 32
   characters of 13px mono: four lines in a column nothing else on the page is
   that narrow. The panel's own max-width is still 640, so it is the column that
   binds here, and only above 1080px where the two share a row. */
.atc-race-video{display:block;width:100%;max-width:1000px;height:auto;aspect-ratio:2464/1350}
/* The panel and the caption travel together, so the overlap lives on the wrapper
   rather than on the panel: one negative margin to reason about instead of two
   that have to agree.

   DOM order is caption-then-panel, which is the mobile order read straight down:
   video, caption, panel. That is what keeps the caption BETWEEN the two on a
   phone instead of tucked under the panel, and it means the phone layout needs
   no placement rules at all. Above 900px the grid puts the panel back on the
   left and the caption in the second column, so source order and visual order
   diverge only where there are two columns to diverge into.

   No overlap below 1080px. The pull-up is what makes the panel read as sitting
   ON the clip, and it cannot do that while the caption is between them; -7%
   there would just drag the caption over the video instead.

   1080 rather than the 900 the rest of this file uses, because this breakpoint
   is about fitting TWO things. At 900 the panel takes 640 of an 828px container
   and leaves the caption 161px, which is six lines of 13px mono in a column
   nothing else is that narrow. The stacked layout is the better answer for
   everything below. */
.atc-race-after{display:grid;gap:20px;margin:12px 0 0;max-width:1000px}
.atc-race-note{margin:0;font-family:var(--mono);font-size:13px;line-height:1.5;letter-spacing:.02em;color:rgb(70,70,70);max-width:56ch}
@media (min-width:1080px){
  /* -96px is the design's own overlap, back as a pixel value now that only this
     breakpoint uses it. It was a percentage while one rule had to serve every
     width, because a share of the container tracks the clip's height; below
     1080px there is no overlap at all any more, so the reason is gone and the
     fixed value is both what was drawn and what makes the caption's offset
     exact. */
  .atc-race-after{grid-template-columns:minmax(0,560px) minmax(0,1fr);column-gap:clamp(24px,3vw,48px);margin:-96px 0 0 clamp(0px,4vw,64px);max-width:calc(1000px - clamp(0px,4vw,64px))}
  .atc-race-panel{grid-column:1;grid-row:1}
  /* Pinned under the clip, not to the bottom of the row. The row starts 96px ABOVE
     the clip's bottom edge (that is the overlap), so aligning to the row's start
     would lay the caption over the footage and aligning to its end would drop the
     caption to the bottom of the panel, a long way below the clip it describes.
     Adding the overlap back puts the caption's top exactly on the clip's bottom
     edge; the remaining 12px is the gap, matching the stacked layout above. */
  .atc-race-note{grid-column:2;grid-row:1;align-self:start;margin-top:calc(96px + 12px);text-align:right;justify-self:end;max-width:none}
}

/* The "in beta today with" logo row.

   Wide, it is a hairline grid: a grey field showing through 1px gaps draws the
   rules between cells, and each cell paints its own cream back over it. That
   needs all three cells on one line to read as a grid at all.

   They stop fitting at about 461px of viewport. Three 140px cells plus gaps and
   borders need 424px, and the row's container is 0.92vw once the page padding is
   proportional, so below that the third cell wraps and the second line is one
   140px cell against a stretch of bare grey field. The chrome is what breaks:
   the logos themselves stack fine.

   So below 560px there is no chrome. No field, no borders, no cells, no gaps
   pretending to be rules, just the three logos down the left edge. The 560px cut
   leaves ~100px of margin over the real 461px failure point, which is worth
   having because the threshold moves with the user's font size.

   The inset padding is here rather than inline for the same reason the video's
   geometry is: an inline style wins, and stacked it would indent two of the three
   logos against the first. */
.atc-beta-logos{display:flex;flex-wrap:wrap;gap:1px;background:rgb(206,203,191);border:1px solid rgb(206,203,191)}
.atc-beta-logo{background:rgb(241,234,220);height:56px;min-width:140px;display:flex;align-items:center;justify-content:center}
.atc-beta-logo-inset{padding:0 20px}
@media (max-width:559px){
  .atc-beta-logos{flex-direction:column;flex-wrap:nowrap;align-items:flex-start;gap:22px;background:none;border:0}
  .atc-beta-logo,.atc-beta-logo-inset{background:none;min-width:0;height:auto;justify-content:flex-start;padding:0}
}

/* Horizontal drags on the carousel belong to the page, vertical ones to the
   browser. Without this the browser treats the whole gesture as a possible pan,
   takes the pointer stream two moves in and cancels it, so `pointerup` never
   arrives and the swipe in site.js can never commit. `pan-y` keeps the page
   scrolling normally through the carousel while handing the other axis over. */
[data-carousel]{touch-action:pan-y}

/* Prose that a photo floats into.

   The company story and the launch post both lay their text out as a flex
   column, and a float has no effect on a flex item: the image would become a
   column entry of its own and the paragraphs would sit above and below it
   rather than around it. So the paragraphs that share space with a photo are
   moved inside one `.atc-prose` block, which is a single flex item from the
   outside and ordinary flow on the inside, where `float` means what it says.

   The margins the paragraphs lose by leaving the flex column are given back
   here, so the rhythm is identical whether a paragraph is a direct child of the
   column or lives in the block.

   `flow-root` is what makes the block's own height contain the floats. Without
   it a photo taller than the text beside it hangs out of the bottom and lands
   on whatever the flex column puts next. */
.atc-prose{display:flow-root}
.atc-prose > p{margin:0 0 28px}
.atc-prose > p:last-child{margin-bottom:0}
.atc-float{float:right;width:min(46%,340px);margin:6px 0 20px 28px}
/* The launch post's three partner photos share one prose block and alternate
   sides, so a right float and a left float can occupy the same band and the
   paragraph between them gets whatever is left. That is the constraint that
   sets this width, not the photos themselves.

   At 230px the middle column fell to ~28 characters and the Tempo paragraph,
   the shortest of the three, was the one wearing it. 175px puts the tightest
   column at 42 characters wide and never below 31 across 720-1440. Measured by
   taking each paragraph's widest line box, since its narrowest is just the last
   line and says nothing.

   Giving each photo its own block was the other candidate and is worse: the
   figures are ~150px tall against two-line paragraphs, so every one of them
   left a band of empty column beside the text. */
.atc-float-sm{width:min(24%,175px);margin-bottom:16px}
.atc-float-left{float:left;margin:6px 28px 20px 0}
.atc-float img{display:block;width:100%;height:auto}
.atc-float figcaption{margin:8px 0 0;font-family:var(--mono);font-size:11px;line-height:1.5;letter-spacing:.06em;color:rgb(162,162,153)}

/* Narrow, a 340px float leaves a ~30-character measure beside it, which is
   below the point where a line of prose still reads as prose. The photo goes
   full width and the text goes back to running underneath it. */
@media (max-width:719px){
  .atc-float,.atc-float-left{float:none;width:100%;margin:0 0 24px}
}

/* The blog index cards.

   They used to be `auto-fit` tracks over a grey field, so a single post
   stretched to the full 1360px and read as a banner rather than a card. Fixed
   4:3 tiles instead: `auto-fill` keeps the track width honest as posts are
   added, and the grey hairline field is gone because empty `auto-fill` tracks
   would paint it as stray rules next to the one real card. Each card draws its
   own edge now.

   `box-sizing` is the whole reason the ratio holds. Nothing in this stylesheet
   sets it globally, so the card was `content-box` and `aspect-ratio` shaped the
   *content* box: the 32px padding was added on afterwards and the card came out
   440x346, which is 1.27 and reads as "nearly 4:3" rather than wrong. Measured
   at eighteen widths rather than eyeballed, because 1.27 looks fine.

   There is no narrow-viewport escape hatch, and that is measured too. The card
   only ever forms one track: `auto-fill` counts repetitions using the track's
   max sizing function when that is definite, so it divides by 440 and not by
   320. The excerpt needs 234px at its tallest and the 4:3 box is never tighter
   than 276px, so it fits at every width from 320 to 1440. A media query that
   dropped the ratio below 400px was removed rather than kept as insurance: it
   fired where the ratio already fit and made the card *shorter* than 4:3. */
.atc-post-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,440px));gap:24px}
.atc-post-card{box-sizing:border-box;aspect-ratio:4/3}

/* The launch video.

   YouTube's player has no intrinsic size, so the 16:9 has to be declared or the
   iframe collapses to the CSS default 150px tall. */
.atc-embed{position:relative;width:100%;aspect-ratio:16/9;background:rgb(36,36,36)}
.atc-embed iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
