@import "https://assets.elements.dev/assets/app/shared/styles/page.5197036215c2c241.css";

.home-page { color: var(--ink); }

.home-wrap {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  position: relative;
}

.home-main { flex: 1; }

/* ---- hero ---- */

.hero {
  /* Top air recreates Feed's: 4rem from <PageChrome>.page-chrome-main
     (var(--space-16)) + 2rem from the canonical h1 margin-top = 6rem
     total. /home doesn't use PageChrome, so we put the combined
     value (var(--space-24)) on .hero directly. The result is that the
     top line of the hero headline sits at the same Y as the page title
     on /feed, /learn, /install, so clicking between them doesn't jump. */
  padding: var(--space-24) 0 0;
}

.hero-title {
  /* Logo mark + wordmark as one lockup row. gap + align in em so both
     track the clamped title size. */
  display: flex;
  align-items: center;
  gap: 0.14em;
  font-family: var(--font-sans);
  /* The tagline is the heaviest heading on the page: base sits at bold
     and the glimmer phrase lifts to black, so it out-weighs the section
     headers below it. */
  font-weight: var(--weight-bold);
  /* Display scale straight off the type system: --text-6xl (72px)
     floor on phones up to the --text-8xl (128px) cap on wide screens,
     10vw riding between. */
  font-size: clamp(var(--text-6xl), 10vw, var(--text-8xl));
  letter-spacing: var(--tracking-tighter);
  line-height: var(--leading-none);
  /* The intro paragraph carries the breathing room down to the CTAs,
     but at desktop display sizes the title needs real clearance above
     the paragraph or the pair reads crammed. */
  margin: 0 0 var(--space-6);
}

/* Terminal card in the hero: shows the getting-started command flow.
   Deep ink card so it reads as a real terminal on the white page and
   holds up in dark mode. */
.hero-terminal {
  /* Full width of the content column so the right edge aligns with the
     headline's right edge. */
  width: 100%;
  margin: 0 0 var(--space-8);
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: #0d1b28;
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 24px 48px -24px rgba(16, 44, 66, 0.5);
}
.term-bar {
  display: flex;
  gap: 6px;
  padding: 10px 14px;
  background: rgba(255, 255, 255, 0.04);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.term-dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.16);
}
.term-body {
  margin: 0;
  padding: 16px 18px;
  font-family: var(--font-mono);
  font-size: 14px;
  line-height: 1.75;
  color: #c6d3de;
  overflow-x: auto;
  /* Render like a real TUI: no ligatures, so => stays => and !== stays !==. */
  font-variant-ligatures: none;
  font-feature-settings: "liga" 0, "calt" 0;
}
.term-body .line { white-space: pre; }
/* The global ::selection sets color: var(--ink), which is dark ink. On this
   card the surface is fixed dark in both themes, so a selected command lost
   its text entirely. The .terminal component in @elements/style solves this
   for itself; the hero card is hand-rolled and never inherited that. Keep
   the glyph color and tint the wash instead. */
.hero-terminal ::selection {
  background: rgba(73, 169, 231, 0.42);
  /* Not `inherit` — see the note on the band's ::selection below. */
  color: #f2f7fb;
}
.term-body .line.gap { height: 0.9em; }

.term-body .p { color: #6d7d8b; }
.term-body .c { color: #f2f7fb; font-weight: var(--weight-medium); }
.term-body .ok { color: #5fd0a0; font-weight: var(--weight-bold); }
.term-body .lbl { color: #e6edf3; font-weight: var(--weight-bold); display: inline-block; width: 9ch; }
/* Package rows in the install demo. The compiler folds runs of spaces in a
   text node, so the columns cannot be padded with literal spaces the way the
   real terminal output is. Same fix as .lbl above: give the cell a width. */
.term-body .pkg  { display: inline-block; width: 18ch; padding-left: 2ch; }
.term-body .pkgv { display: inline-block; width: 10ch; }
.term-body .dim { color: #8b98a5; }
.term-body .link { color: var(--accent); }
.term-body .arrow { color: var(--accent); }

/* Startup animation. Command lines type out one character at a time
   (a steps() sweep over an overflow-hidden inline-block), then the
   fast-boot output snaps in as a block to sell the 22µs startup. */
.term-body.animate .cmd { opacity: 0; }
.term-body.animate .cmd .c {
  display: inline-block;
  overflow: hidden;
  white-space: nowrap;
  vertical-align: bottom;
  width: 0;
}
/* Three commands type in sequence, each starting 100ms after the one
   above finishes. Durations are per-command because steps() must match
   the exact character count:
     c1 "elements create app" 19ch — 150ms  →  630ms
     c2 "cd app"               6ch — 730ms  →  910ms
     c3 "elements start"      14ch — 1010ms → 1390ms
   Changing a command's text means changing its char count in BOTH the
   steps() and the matching @keyframes width. */
.term-body.animate .c1 { animation: term-reveal 1ms linear 150ms forwards; }
.term-body.animate .c1 .c { animation: type-37 900ms steps(37) 150ms forwards; }
@keyframes term-reveal { to { opacity: 1; } }
/* +1ch buffer past the exact character count so the final glyph never
   clips when the mono font's metrics round narrow (seen on mobile).
   The extra width is trailing blank on the dark card, so it's invisible. */
@keyframes type-37 { to { width: 38ch; } }

/* The agent's steps land one at a time after the prompt finishes typing
   (150 + 900 = 1050ms), each a quick fade. The gap before the failing build
   and again before the green one is deliberate: the pause is where a reader
   registers that it broke and then fixed itself. */
.term-body.animate .s1,
.term-body.animate .s2,
.term-body.animate .s3,
.term-body.animate .s4,
.term-body.animate .s5,
.term-body.animate .s6 {
  opacity: 0;
  transform: translateY(3px);
}
.term-body.animate .s1 { animation: term-line 150ms ease-out 1150ms forwards; }
.term-body.animate .s2 { animation: term-line 150ms ease-out 1400ms forwards; }
.term-body.animate .s3 { animation: term-line 150ms ease-out 1650ms forwards; }
.term-body.animate .s4 { animation: term-line 150ms ease-out 2000ms forwards; }
.term-body.animate .s5 { animation: term-line 150ms ease-out 2500ms forwards; }
.term-body.animate .s6 { animation: term-line 150ms ease-out 2800ms forwards; }
@keyframes term-line {
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .term-body.animate .cmd,
  .term-body.animate .line:not(.cmd) {
    opacity: 1;
    transform: none;
    animation: none;
  }
  .term-body.animate .cmd .c { width: auto; }
}

/* Sentence headline variant: block layout, smaller than the wordmark
   scale, with the lead words in ink and only "elements" accented. */
.hero-title.is-sentence {
  display: block;
  /* Sized down from the 5xl→7xl range the short "for web apps."
     headline used. This sentence is longer, and at 7xl it ran to four
     lines and pushed the feed off the first screen. */
  /* 4rem, not 4.25: at 68px the sentence broke to three lines in the 756px
     column and stranded "apps with AI." on its own. 64px is the largest size
     that holds it to two at every desktop width. */
  font-size: clamp(var(--text-4xl), 5.5vw, 4rem);
  letter-spacing: var(--tracking-tight);
  /* The sentence ends on "with AI", two characters and a period, which the
     greedy algorithm drops on a line of its own at most desktop widths.
     balance evens the lines out instead, so the break lands at a phrase
     rather than stranding the last word. It only applies to short blocks,
     which a headline is. */
  text-wrap: balance;
  /* Leading is set by .home-page .hero-title.is-sentence further down, which
     wins on specificity. Changing this one has no effect on /. */
  line-height: 1.1;
  margin-bottom: var(--space-6);
}

/* The scope claim inside the headline, lifted into accent and italic so the
   phrase that says how much Elements covers reads before the sentence around
   it. Italic on its own is too quiet at this weight; the color carries it. */
.hero-title .hero-accent {
  color: var(--accent);
  font-style: italic;
}
.hero-para {
  font-size: var(--text-md);
  line-height: var(--leading-relaxed);
  color: var(--ink-soft);
  /* Fills the content column so its edges align with the headline and
     terminal above/below. A single short intro paragraph reads fine at
     the column width; the ~66ch readability cap is for long-form body
     copy, not a three-sentence hero blurb. */
  max-width: none;
  margin: 0 0 var(--space-8);
}

/* The glimmering blue "elements" in the hero tagline. On load it does
   a one-time bright sweep (wave), then settles into a slow, subtle
   infinite glimmer — same treatment as the generator boilerplate's
   home page. The gradient runs accent → deep → accent so the sweep
   reads as a highlight travelling across the word. */

@keyframes hero-wave {
  from { background-position: 100% 50%; }
  to   { background-position:   0% 50%; }
}

@keyframes hero-glimmer {
  0%   { background-position:  0% 50%; }
  50%  { background-position: 30% 50%; }
  100% { background-position:  0% 50%; }
}

/* ---- mobile ---- */

@media (max-width: 700px) {
  /* Half the canonical 48px above-h1 air the other pages carry. Home
     gives that air up on phones to buy the terminal room: at 48px the
     paste block's last two commands sat below the fold on a 844px
     iPhone viewport, and the point of the block is that a visitor can
     read it without scrolling. */
  .hero { padding: var(--space-10) 0 0; }
  .hero-title {
    max-width: none;
    /* Small gap to the subtitle on mobile. */
    margin-bottom: var(--space-3);
  }
  /* The 2.5rem cap was here to keep the home feed preview above the fold.
     That preview is gone, so the headline no longer has to make room for
     anything and the extra line it costs is free. */
  .hero-title.is-sentence {
    font-size: clamp(2.25rem, 12vw, 3.25rem);
  }
}

/* ---- landscape phones ---- */

/* Phones in landscape exceed the 700px max-width above (iPhone 14
   Pro = 844px wide rotated) but the viewport height collapses to
   ~390px. The desktop hero padding of 8rem 0 6rem leaves only a
   thin strip of content visible above the fold. Compress to phone-
   like padding when the viewport is short and wide. */
@media (orientation: landscape) and (max-height: 500px) {
  .hero { padding: var(--space-10) 0 0; }
  .hero-title { max-width: none; margin-bottom: var(--space-2); }
}

/* ---- reduced motion ---- */

/* CTA framed as a full-width band — a distinct action strip spanning the
   viewport so the CTAs aren't lost. Buttons sit in the content column,
   left-aligned, Introducing then Install so the eye lands on Install. */
/* Buttons stand alone under the terminal — no band framing. They sit in
   the hero flow, left-aligned like the copy and terminal above; the blue
   Install carries the emphasis on its own. The terminal's space-8 bottom
   margin sets the gap above; margin-bottom sets the gap down to the feed. */
.cta-band {
  /* Extra air above the button so it doesn't crowd the terminal box.
     Uses padding, not margin: a margin here just collapses into the
     terminal's space-8 bottom margin (larger wins) and does nothing,
     so padding is what actually adds to the gap. 32px + 32px = 64px. */
  padding-top: var(--space-8);
  /* Air under the button before the band closes. The button is the last
     thing on the page now, so this is the bottom of the hero, not a gap to
     whatever came next. */
  margin-bottom: var(--space-8);
}
.cta-band-inner {
  /* flex + fit-content keeps the button shrink-wrapped and left-aligned
     rather than stretching to the container. */
  display: flex;
  width: fit-content;
  align-items: center;
  gap: var(--space-3);
}
.cta-band-btn {
  font-size: var(--text-lg);
  padding: 0.9rem 1.9rem;
  border-radius: var(--radius-xl);
  /* No drop shadow. Stacked on mobile it fell straight onto the outline
     button below and ate its top border, and the lift reads fine without
     it. */
  transition: transform 140ms ease;
  white-space: nowrap;
}
.cta-band-btn:hover {
  transform: translateY(-1px);
}
/* Secondary "Watch the intro" — same size/shape as the primary but the
   base outlined button chrome (transparent fill, rule border), so it
   reads as the quieter of the two actions. */
.start-head .start-label { margin-bottom: 0; }
/* Watch link on the terminal's title bar, opposite COPY. Mono and dim
   so it reads as terminal chrome, not as a second CTA competing with
   Install below. */
@media (max-width: 700px) {
  .cta-band { margin-bottom: var(--space-10); }
  .cta-band-inner {
    /* Stack. Side by side, the two nowrap buttons are wider than a phone
       and pushed the whole page into horizontal scroll. */
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    gap: var(--space-3);
  }
  .cta-band-btn,
  .cta-band-watch {
    width: 100%;
    justify-content: center;
    text-align: center;
  }
  /* Keep the label on one line. Wrapping put "(1 min)" on a row of its
     own, orphaned to the right, which read as broken. Smaller type and
     tighter side padding buy the width instead. */
  }

/* ─── Marketing sections (below the hero) ───────────────────────────
   The page makes one argument in three numbered acts, and each act is
   a category masthead followed by feature children. A child is copy
   stacked over a dark terminal or code card: the claim, then the thing
   itself. Lifted from the pre-v1 mockup at app/pages/mockups/home,
   which is where these were designed. */

/* Stacked, not side by side: the pitch reads first, then the demo card
   gets the full content width below it. Section cards are static (no
   typing) so they don't compete with the hero's animation. */
.split-demo .hero-terminal { margin-bottom: 0; }

/* Child headline: clearly smaller than the category title above it,
   and semibold rather than bold. */

/* Two cards side by side for the before/after: what an agent writes
   with nothing under it, and what it writes on Elements. Stacks on
   narrow screens, where the left card reads first and still lands as
   the setup. */

/* ---- terminal extras used by the section cards ---- */

.term-body .line.ind { padding-left: 1.6ch; }

/* One diagnostic: the error number in its own column, the whole body in
   the next. Matches the errors list in the build's TUI, where the number
   is column one and everything about the error (path, message, code
   frame, call stack, tags) goes in column two, so the body reads as a
   block hanging off its number instead of running back under it. */
.term-body .ediag {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 1ch;
  padding-left: 1.6ch;
}
.term-body .ediag .enum { text-align: right; }
.term-body .ediag .ebody { min-width: 0; }

/* The code frame inside a body: a right-aligned line-number gutter and
   the source beside it, the same two-column shape one level down. */
.term-body .snip {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 1ch;
}
.term-body .snip .ln { text-align: right; color: #525964; }
/* The line the error sits on gets a red number, as it does in the TUI. */
.term-body .snip .ln.e { color: #f7768e; }
.term-body .snip .sl { white-space: pre; }
.term-body .err { color: #f7768e; font-weight: var(--weight-bold); }
.term-body .warn { color: #e0af68; }
.term-body .jk { color: #7dcfff; }

/* Test-tree rows: label left, right-aligned [pass] tag, matching the
   elements test TUI. Flex keeps the tag aligned instead of padding it
   out with spaces. */
.term-body .tline {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1.5rem;
}
.term-body .tline.ind { padding-left: 1.6ch; }
.term-body .tpath { color: #c6d3de; }
.term-body .tree { color: #c6d3de; }
.term-body .pass { color: #5fd0a0; font-weight: var(--weight-bold); }

/* File rows in the project-shape cards: name in a fixed column, the
   note about it in muted text beside it. */
.term-body .frow {
  display: grid;
  grid-template-columns: 15ch auto;
  column-gap: 1.25rem;
  align-items: baseline;
}
.term-body .fname { color: #c6d3de; }

/* ---- code cards (framework syntax boxes) ---- */

.term-bar .term-name {
  margin-left: 8px;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: #6d7d8b;
}

/* Code cards show a filename in the bar, no window dots. */
.code-card .term-dot { display: none; }
.code-card .term-bar .term-name { margin-left: 0; }

/* ---- category masthead ---- */

/* A brand-tinted band behind each act's masthead, mixed from --accent
   and --bg so it adapts to light and dark on its own. */
/* A light hairline on a near-black ground reads far fainter than a dark
   one on white, so raise the alpha in dark mode. */

/* A big pale ordinal above each masthead (01 / 02 / 03) makes the three
   acts read as a set, clearly apart from the children beneath them. */
.home-main { counter-reset: category; }
.group-head .shell-marketing::before {
  content: counter(category, decimal-leading-zero);
  display: inline-block;
  border-top: 3px solid var(--accent);
  padding-top: var(--space-3);
  font-family: var(--font-mono);
  font-weight: var(--weight-bold);
  font-size: clamp(var(--text-2xl), 3vw, var(--text-4xl));
  color: var(--ink-faint);
  letter-spacing: 0.02em;
  line-height: 1;
  margin-bottom: var(--space-5);
}

/* ---- scroll-triggered reveals ---- */

/* Sections fade and rise as they enter the viewport, driven by the CSS
   view() timeline. No JS. Guarded by @supports so unsupported browsers
   just show the content. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .group-head .shell-marketing,
    .tool-section .split-copy {
      animation: reveal-up linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 55%;
    }
      }
}
@keyframes reveal-up {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}

/* ---- closing cta ---- */

/* Full-bleed dark band as the final beat: one contrast moment against
   all the white, echoing the hero, and the loudest place for the #1
   action. */

/* A section can carry a second paragraph. .split-lead has no bottom margin
   so the copy block ends flush with the demo card, which leaves two leads
   running together without this. */

/* Wider name column for rows whose left side is a phrase rather than a
   filename. */
.term-body .frow.is-wide { grid-template-columns: 24ch auto; }

/* ---- get started box ---- */

/* The copy button sits in the title bar rather than floating over the code,
   because the box is four commands tall and an overlay would cover one of
   them at some width. */
.start-box .term-bar { align-items: center; }
.start-box .term-name { flex: 1; }

/* Same chip as the one on /install, to the pixel.

   The source of truth is `.terminal > .copy` in app/shared/styles/site.css,
   which is itself an override of the package default (that one is tighter:
   4px vertical, a hard 6.5rem). This terminal is not a `.terminal`, so it
   cannot inherit the rule and the values are repeated here. Change one and
   change the other: two copy buttons that are almost the same size read as a
   bug in whichever one you see second.

   min-width rather than width is what stops the chip resizing when the label
   flips to "copied". */
.start-copy {
  height: auto;
  min-height: 0;
  min-width: 6.5rem;
  width: auto;
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  text-align: center;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-xs);
  color: rgba(255, 255, 255, 0.72);
  cursor: pointer;
  box-shadow: none;
  flex-shrink: 0;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.start-copy:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.16);
}

/* Agent picker, left of the copy chip: a native select dressed as a dark chip,
   the same type, height and radius as .start-copy so the title bar is one
   family. A select rather than pills because the list grows over time and a
   row of pills stops fitting a phone-width bar at four. color-scheme: dark
   asks the browser for a dark popup so the open list matches the card. */
.term-agent {
  /* The copy chip is border + padding + one line at its font size, and it
     sets line-height 1. A select's line-height is `normal` regardless, which
     came out 3px taller and read as a mismatch. State the same sum here. */
  height: calc(var(--text-2xs) + 2 * var(--space-2) + 2px);
  min-height: 0;
  width: auto;
  padding: 0 var(--space-6) 0 var(--space-3);
  margin-right: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
  color-scheme: dark;
  background-color: rgba(255, 255, 255, 0.06);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='rgba(255,255,255,0.72)' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-2-5) center;
  background-size: 10px 6px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-xs);
  box-shadow: none;
  cursor: pointer;
  flex-shrink: 0;
  transition: color 120ms, border-color 120ms, background-color 120ms;
}
.term-agent:hover {
  color: #fff;
  background-color: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.16);
}
.term-agent:focus-visible {
  outline: none;
  border-color: rgba(255, 255, 255, 0.4);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.18);
}
.term-agent option {
  text-transform: none;
  background: #0d1b28;
  color: #f2f7fb;
}

/* Under 24rem the name, the picker and the copy chip no longer share a row with
   the three dots: the chip slid past the card edge. The dots are decoration and
   the chip's reserved width is for the "copied" flip, so both give way here. */
@media (max-width: 24rem) {
  .start-box .term-dot { display: none; }
  .start-box .start-copy { min-width: 0; }
}

/* Both labels are always in the DOM and swapped with display, so the button
   never changes width between states and never moves under the cursor that
   just clicked it. */
.start-copy .start-copy-done    { display: none; }
.start-copy.is-copied .start-copy-default { display: none; }
.start-copy.is-copied .start-copy-done    { display: inline; }
.start-copy.is-copied,
.start-copy.is-copied:hover {
  color: #5fd0a0;
  border-color: rgba(95, 208, 160, 0.5);
}

/* One command per line, scrolled rather than wrapped. Wrapping the install
   line broke a single command across two rows, which read as two commands
   and made the block look longer and messier than it is. */
.start-box .term-body { overflow-x: auto; }
.start-box .term-body .line { white-space: pre; }
.start-box .term-body .line.gap { height: 0.75em; }

/* A section can show two cards, when the point is that they are two views of
   one thing. The first has no bottom margin so a single card ends flush with
   the copy, so the gap goes on the second. */
.split-demo .hero-terminal + .hero-terminal { margin-top: var(--space-5); }

/* Inline code in a section lead. The prose names real commands, and a command
   set in the body face reads as a phrase rather than a thing you type. */

/* Label above the get-started box. Small and quiet: it is an instruction, not
   a heading, and the box below it is the thing being looked at. */
.start-label {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--ink);
  /* Enough air that the label reads as introducing the terminal below
     rather than clinging to it. */
  margin: 0 0 var(--space-3);
  max-width: none;
}

/* The label names the block; this says what running it does. Prose, so it
   takes the body face at normal weight rather than continuing the mono label
   and reading as more heading. */

/* t 20665 */

/* t2 6789 */

/* ---- hero sheet ---- */

/* The hero was ruled paper: a 24px grid across the band. It is off as of
   2026-09-15 to see the hero with nothing behind the type. The layer stays,
   carrying only the two hairlines, since home drops the topbar's own bottom
   border and takes the opening rule from here. The ruling and its
   --sheet-rule tokens are in the history of this file if it comes back. */

/* Home drops the topbar's own bottom edge. The sheet below it opens on a
   ruled line of its own, and two hairlines a hair apart is the misalignment
   this is avoiding. The band carries the separator instead, at exactly the
   grid's first rule. */
.home-page .topbar.topbar-v2 { border-bottom: 0; }

.hero-wrap {
  position: relative;
  isolation: isolate;
  background: var(--bg);
  padding-bottom: var(--space-12);
}
.hero-wrap::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: -1;
  pointer-events: none;
  height: 100%;
  /* The opening rule under the nav, and nothing closing the band: the hero
     runs into the page below it. A layer rather than a border on .hero-wrap,
     since a border sits outside the padding box and painted a pixel off from
     anything drawn inside it. Home drops the topbar's own bottom border and
     takes this line instead, so this is the only thing separating the two. */
  background-image: linear-gradient(var(--chrome-rule), var(--chrome-rule));
  background-size: 100% 1px;
  background-position: 0 0;
  background-repeat: no-repeat;
}

/* Install follows the paste block: the reader gets the claim, then the four
   commands, then the button for anyone who would rather not paste. It lives
   inside the hero so the band carries it too, and so the gap above it is
   tuned here rather than by a separate section's padding. */
.hero-actions {
  margin-top: var(--space-6);
}

/* Phones: the paste block and the button both have to clear a 844px fold, so
   the terminal gives up the type size it does not need. At 14px/1.75 the
   button landed ~90px under the fold on an iPhone viewport. */
/* Phones: the bar keeps all three controls by giving up padding and a
   little type, rather than folding. */
@media (max-width: 480px) {
  .card-head { padding: 8px; gap: 6px; }
  .seg-btn { padding: 6px 10px; }
  .card-head .bar-select { padding: var(--space-2) 8px; }
  .card-head .start-copy { min-width: 5rem; padding: var(--space-2) 8px; }
}

@media (max-width: 700px) {
  .term-body {
    font-size: 11.5px;
    line-height: 1.5;
    padding: 12px 14px;
  }
  .term-body .line.gap { height: 0.55em; }
  .hero-actions { margin-top: var(--space-3); }
  /* Every gap in the hero gives up a few pixels for the same reason: on a
     844px viewport the four blocks only fit if none of them keeps the air it
     would have on a desktop. */
  .hero-title.is-sentence { font-size: clamp(2.1rem, 10vw, 2.75rem); }
  .hero-para {
    margin-bottom: var(--space-5);
    /* Relaxed leading is for long-form reading. Nine lines of hero copy at
       1.75 spend 30px on air the fold cannot afford. */
    line-height: 1.6;
  }
  .start-label { margin-top: 0.9rem; }
}

/* A slow sheen across the accent phrase. The band is narrow and the light
   stop is one step off --accent (#1F6BA8 → #3f8cc9), not a pale blue: the
   earlier version ran to #9fd4ff and read as a rendering fault rather than as
   a highlight. It never leaves the blue, so any frame of it looks deliberate.
   Text stays --accent for anyone who has asked for less motion. */
.hero-accent {
  background-image:
    linear-gradient(102deg,
      var(--accent) 0%,
      var(--accent) 38%,
      #3f8cc9 47%,
      var(--accent) 56%,
      var(--accent) 100%);
  background-size: 300% 100%;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  /* background-clip: text paints inside the inline box, which is the sum of
     the glyphs' advance widths. Italic ink leans past that on the last
     character, so the final letter loses its top right corner and reads as a
     rendering fault. The padding widens the paintable box; the negative
     margin gives the space back, so nothing moves. */
  padding-right: 0.1em;
  margin-right: -0.1em;
  animation: hero-glimmer-slow 7s ease-in-out infinite;
}

@keyframes hero-glimmer-slow {
  0%   { background-position: 115% 50%; }
  55%  { background-position: -15% 50%; }
  100% { background-position: -15% 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-accent {
    animation: none;
    background-image: none;
    -webkit-text-fill-color: var(--accent);
  }
}

/* Air under the last block of the hero, down to the rule that closes the band.
   Lives after the .hero-wrap block above, not in the mobile media query
   earlier in the file, which loses to it on source order. */
.hero-wrap { padding-bottom: 54px; }

@media (max-width: 700px) {
  .hero-wrap { padding-bottom: 68px; }
}

/* ---- the one box ---- */

/* Two layers, kept apart on purpose. `.start-controls` is ours: it selects
   which picture to show. Below it is the picture, and a picture of a terminal
   has to look like a terminal, an agent composer like an agent composer. The
   moment our switches sit inside their chrome, neither is believable. */

/* The demo band. Full bleed, so what marks the section is the page changing
   colour rather than another rectangle drawn around the content. The windows
   inside keep their own frames; this only says where the demo starts and
   ends. */
/* Paper, in both themes. These were literals and stayed light when the rest
   of the page went dark, which left light text on a white band. */
.home-page {
  --paper:       #faf9f7;
  --paper-panel: #faf9f7;
  --paper-high:  #fffefc;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .home-page {
    --paper:       #0e141a;
    --paper-panel: #161e27;
    --paper-high:  #1f2935;
  }
}
:root[data-theme="dark"] .home-page {
  --paper:       #0e141a;
  --paper-panel: #161e27;
  --paper-high:  #1f2935;
}

.start-band {
  position: relative;
  isolation: isolate;
  width: 100%;
  /* Closer to the hero paragraph than it was. The gap above read as a
     missing section rather than as a breath, because nothing separates this
     band from the hero but air. */
  padding: var(--space-4) 0 var(--space-12);
  /* Paper: the exact ground the agent window sits on, so the band and the
     box are one surface. A different grey left a seam between them. */
  background: var(--paper);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}



.start { margin: 0; }

/* The line that hands the reader over to the box. Same weight and face as it
   had above the old paste block, so the hero still ends on an invitation. */
/* The line that hands the reader to the box. A step up in size and real air
   under it: it opens the section, so it should not sit on the controls. */
.start .start-label {
  font-family: var(--font-mono);
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  color: var(--ink);
  margin: 0 0 var(--space-6);
}

/* Wraps. At 320 the segment and the tools together are wider than the column,
   and nowrap pushed the copy chip 31px off the right edge with no scrollbar to
   find it by. The row stays on one line at every width where it fits. */

.start-controls {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}

/* Agent or Terminal. Two words, nothing else.
 *
 * Specificity matters here: the style package's own button rules set a white
 * ground and zero the border, so a bare `.seg-btn` lost both the transparent
 * background and the underline (computed: rgb(255,255,255) and 0px none).
 * Scoping to .start-controls wins, and the underline is an inset shadow so no
 * border shorthand anywhere can flatten it again. */
/* The style package draws a bordered white chip on this span from inside a
   @layer, which is why it kept reappearing: it does not show up in a plain
   scan of document.styleSheets. Neutralised explicitly. */
.start-controls .seg {
  display: inline-flex;
  align-items: center;
  gap: var(--space-5);
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  padding: 0;
}

.start-controls .seg .seg-btn {
  appearance: none;
  font: inherit;
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  height: auto;
  min-height: 0;
  width: auto;
  padding: 0 0 6px;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--ink-dim);
  cursor: pointer;
  transition: color 120ms, box-shadow 120ms;
}
.start-controls .seg .seg-btn:hover {
  color: var(--ink-soft);
  background: transparent;
}
.start-controls .seg .seg-btn.is-on {
  color: var(--ink);
  background: transparent;
  box-shadow: inset 0 -2px 0 var(--accent);
}

.start-tools {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

/* The chip in the options row. Quiet: the sentence under the box is the
   instruction, this is the shortcut for somebody already reaching. */
.start-controls .start-copy {
  height: auto;
  min-height: 0;
  min-width: 5.5rem;
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  text-align: center;
  border: 1px solid var(--rule);
  border-radius: var(--radius-xs);
  background: var(--bg);
  color: var(--ink-soft);
  cursor: pointer;
  box-shadow: none;
}
.start-controls .start-copy:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 4%, var(--bg)); }
.start-controls .start-copy.is-copied {
  color: #14724d;
  border-color: rgba(31, 157, 107, 0.5);
  background: rgba(31, 157, 107, 0.1);
}

/* Centred, and sized to its own label plus room for the caret. Left aligned
   in a box wider than the text, it read as a half-filled input. */
.start-select {
  text-align: center;
  text-align-last: center;
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  height: auto;
  min-height: 0;
  width: auto;
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--rule);
  border-radius: var(--radius-xs);
  background: var(--bg);
  color: var(--ink-soft);
  cursor: pointer;
}

/* The instruction, with the click inside it. The copy word carries the weight
   the button used to: accent, bold, underlined, and it turns green when the
   clipboard has the text. The page's one filled button is Install, below. */
.do {
  margin: var(--space-5) 0 0;
  font-size: var(--text-base);
  color: var(--ink-soft);
}
.do a { color: var(--accent); }
.do a + a::before { content: ", "; color: var(--ink-dim); }

.do-copy {
  appearance: none;
  font: inherit;
  font-weight: var(--weight-bold);
  height: auto;
  min-height: 0;
  width: auto;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: var(--accent);
  text-decoration: underline;
  /* Continuous, and clear of the descenders in "Copy this prompt": ink-skip
     chopped the rule into pieces around the p and the y. */
  text-decoration-thickness: 1px;
  text-decoration-skip-ink: none;
  text-underline-offset: 4px;
  cursor: pointer;
}
.do-copy:hover { color: color-mix(in srgb, var(--accent) 80%, #000); background: none; }
.do-copy.is-copied { color: #14724d; text-decoration: none; }

/* ---- the terminal, as a terminal ---- */

.term-window {
  width: 100%;
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: #0d1b28;
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 24px 48px -24px rgba(16, 44, 66, 0.5);
}

.term-window .term-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 14px;
  background: rgba(255, 255, 255, 0.04);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.term-window .term-name {
  margin-left: 6px;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: #8b98a5;
}

/* ---- the agent composer, as an agent composer ---- */

/* A window, like the terminal is a window. On the wash both modes then read
   as the same kind of object: chrome of their own, holding the thing you
   paste into. */
.agent-window {
  border: 1px solid var(--rule);
  border-radius: var(--radius-xl);
  overflow: hidden;
  padding: 16px;
  /* Warm, not white: the agent apps all sit on a paper-ish ground, and a flat
     white panel on a grey band reads as a dialog instead. */
  background: var(--paper-panel);
  box-shadow: 0 24px 48px -32px rgba(16, 44, 66, 0.35);
}

.composer-body {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin: 0 0 12px;
  padding: 22px 20px 22px 24px;
  background: var(--paper-high);
  border: 1px solid var(--rule);
  border-radius: 28px;
  font-size: var(--text-sm);
  line-height: 1.6;
  /* Set back, matched to the install panel's pictures. Literal fallback for
     the same reason: --ink-dim exists only inside .start-band. */
  color: var(--ink-dim);
}

.composer-text {
  flex: 1;
  min-width: 0;
  overflow-x: auto;
  white-space: pre;
}

/* No return glyph. It looks like a button in a box that cannot be typed
   into, and a control that does nothing is worse than no control. */

.composer-chrome {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 8px 4px;
  font-size: var(--text-2xs);
  white-space: nowrap;
  color: var(--ink-dim);
}

.chrome-icon,
.chrome-caret { width: 15px; height: 15px; color: var(--ink-dim); }
.chrome-caret { width: 12px; height: 12px; margin-left: -4px; }
.chrome-mode { margin-left: 2px; }

/* Getting an agent, for somebody who has none. Below the box and quiet. */
/* The last thing in the band, with real air above it so it reads as a
   footnote to the demo rather than part of the instruction. */
.pick {
  margin: var(--space-10) 0 0;
  font-size: var(--text-sm);
  color: var(--ink-dim);
}
.pick a { color: var(--accent); text-decoration: none; }
.pick a:hover {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-skip-ink: none;
  text-underline-offset: 4px;
}

/* The comma sits inside the next anchor, so a hover underline ran through it
   too. inline-block keeps the parent's line off it. */
/* inline-block keeps the hover underline off the comma, but it also collapses
   a trailing space, so the space is a non-breaking one in the content above. */
.pick a + a::before { display: inline-block; }
.pick a + a::before { content: ",\00a0"; color: var(--ink-dim); }

.pick-pills { display: flex; gap: 6px; flex-wrap: wrap; }

.pill {
  padding: 4px 12px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--bg);
  color: var(--ink);
  text-decoration: none;
  font-size: var(--text-sm);
}
.pill:hover { border-color: var(--accent); color: var(--accent); }


/* ---- the install row, under the demo ---- */

.install-row {
  /* No margin: the band's padding is the only thing setting this row's air,
     so the space above and below stays identical. */
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-6);
}

.install-note { font-size: var(--text-sm); color: var(--ink-dim); }

/* The mode select is the phone's version of the Agent/Terminal words: at
   phone width the two words plus the scaffold picker and copy cannot share a
   row, and the words are what a dropdown says better anyway. */
.mode-select { display: none; }

@media (max-width: 620px) {
  /* The phone keeps the words. It used to swap them for a select, because the
     two words plus the scaffold picker plus copy could not share a row — and
     the scaffold picker is gone, so the row fits again.

     Worth losing: a select with two options makes a binary choice cost a trip
     through the OS picker, which iOS docks to the bottom of the screen and
     Android opens as a centred modal. Both land nowhere near the control, so
     the switch read as broken. Two buttons are one tap and stay put. */
  .mode-select { display: none; }

  .start-controls .seg .seg-btn {
    padding: 6px 8px;
    font-size: var(--text-2xs);
  }

  /* Phones give the band more of their width: at 1.5rem each side the pill
     inside two nested boxes had barely 60% of the screen for the prompt. */
  .start-band .shell-marketing { padding: 0 1rem; }
  .agent-window { padding: 10px; }
  .composer-body { padding: 18px 14px; }
  .home-page .start-band .agent-window { padding: 10px; }
  .home-page .start-band .composer-body { padding: 16px 14px; }
  .start-band { padding: var(--space-4) 0 var(--space-10); }
  .start .start-label { margin-bottom: var(--space-5); }
}

/* The demo sits closer to the hero now: the hero's own bottom air plus the
   band's top air was a screen and a half of nothing between the paragraph and
   the thing to try. */
.home-page .hero-wrap { padding-bottom: var(--space-3); }

/* ---- install, its own section ---- */

/* One row: the line on the left, the button on the right, separated from the
   demo by a rule and air. No box, no fine print. */
/* Equal air above and below the row. The measured gaps were 64 and 49: the
   paddings differed, and the button's own height sits inside the row box. */
.install-band {
  width: 100%;
  padding: var(--space-12) 0;
  border-bottom: 1px solid var(--rule);
}

/* One row at every width. It never wraps: the type gives way instead, and the
   button keeps its size because it is the thing being clicked. */
.install-row {
  /* No margin: the band's padding is the only thing setting this row's air,
     so the space above and below stays identical. */
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: nowrap;
}

.install-row .button { flex: 0 0 auto; }

.install-title {
  margin: 0;
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight);
}

@media (max-width: 620px) {
  .install-band { padding: var(--space-10) 0; }
  .install-title { font-size: var(--text-lg); }
  .install-row .button { padding-left: var(--space-5); padding-right: var(--space-5); }
}

@media (max-width: 400px) {
  .install-title { font-size: var(--text-base); }
}

/* ---- copy button treatments, ?cta= ---- */

/* ink: outlined, the page's ink. Reads as the action of this section without
   claiming the page's one blue. */
.do-copy.is-ink {
  border: 1px solid var(--ink);
  background: var(--bg);
  color: var(--ink);
}
.do-copy.is-ink:hover { background: var(--ink); color: var(--bg); }

/* dark: solid ink. Loudest of the neutral options, and it echoes the
   terminal. */
.do-copy.is-dark {
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--bg);
}
.do-copy.is-dark:hover { background: color-mix(in srgb, var(--ink) 85%, #fff); }

/* blue: the same accent as Install. Two blues in a column, for comparison. */
.do-copy.is-blue {
  border: 1px solid var(--accent);
  background: var(--accent);
  color: #fff;
}
.do-copy.is-blue:hover { background: color-mix(in srgb, var(--accent) 88%, #000); }

/* ghost: hairline and ink text. Quietest; the sentence carries the weight. */
.do-copy.is-ghost {
  border: 1px solid var(--rule);
  background: var(--bg);
  color: var(--ink-soft);
}
.do-copy.is-ghost:hover { border-color: var(--ink-dim); color: var(--ink); }


/* ─── The demo band, as a machine ─────────────────────────────────────
   2026-09-16. The band used to be paper: near-white in light mode, a dark
   grey in dark mode, following the page. The campaign landing pages gave
   the same composer a band that is dark in BOTH themes, and it reads
   better for a reason worth keeping: the band is the part of the page that
   runs, and a terminal is dark whether or not the visitor's OS is. Paper
   made it a section of the page. This makes it the machine on the page.

   Implemented as a local theme on .start-band rather than as edits spread
   through the rules above it. Every rule inside the band already reads
   --ink / --rule / --accent, so overriding the tokens here flips all of
   them at once and the band stays one place to tune.

   The band used to name two of these --ink-2 / --ink-3, which are not
   tokens @elements/style ships and were defined nowhere else, so every use
   outside the band silently computed to `inherit`. They are --ink-soft and
   --ink-dim now, which the design system does define; the values here are
   the band's own overrides of them. */
.home-page .start-band {
  /* Paper, not a lighter shade of the slab. Lifting the panels through the
     blue-grey between them landed on the desaturated navy-slate every
     enterprise design system uses, and stacking three steps of it is what
     read as dense in the first place. Warm paper is one move away from the
     ground instead of three steps along it: the panels separate because
     they are a different material, not because they are 8% lighter.

     The ground went light and the panels went dark, which is the inverse of
     where this started and the version that holds together. Every warm stock
     tried here (cream, ochre, sand) was the only warm thing on a site that
     is blue, white and near-black, and a pale panel on a white band had less
     presence than the terminal it was the primary alternative to.

     Dark panels on a white band fix both. The page is calm and the two
     pictures are the only figures on it, they carry equal weight so the tab
     switch is not a lurch, and neither of them is a colour the brand has to
     explain. An agent composer in dark mode is also what most people running
     one actually see. */
  --stage-paper: #070C13;
  --stage-shell: #070C13;
  /* The same values the terminal uses. The composer was on #DEE7F0 while
     the terminal ran #f2f7fb for commands and #8b98a5 for comments, so the
     two modes showed the same payload in two slightly different whites: a
     near-miss, not a distinction. The terminal keeps its dim level because
     those lines really are comments; the composer is all payload, so it
     takes the payload colour. */
  --stage-paper-ink: #f2f7fb;
  --stage-paper-mid: #8b98a5;
  --stage-paper-rule: rgba(255, 255, 255, 0.16);

  position: relative;
  isolation: isolate;
  /* No ground of its own. Every colour this band ever had for itself was
     wrong in one theme or the other: navy read as dense, and white became a
     lit slab sitting in the middle of a near-black page. The panels are the
     figure, so the band is simply the page, and --ink / --rule / --accent
     come from the site the way they do in every other section. */
  background: transparent;
  /* No edges, and no tint. The band is the same white as the hero above it
     and the button below, and it does not need to announce itself: a black
     panel arriving is a stronger section marker than a hairline, and a rule
     drawn next to one is a line nobody reads. Tinting the ground would put
     back the slab that competed with the panels in the first place. */
  border-top: 0;
  border-bottom: 0;
  color: var(--ink);
}

/* In dark mode the panels lift instead of dropping. At #070C13 they were
   BELOW the page, so each one read as a hole cut in the background with two
   outlines drawn round it rather than as an object sitting on it. Nothing
   can be blacker than a near-black page and still be a panel, so on a dark
   OS the surface goes above the ground and the light-mode black is simply
   the wrong direction to push. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .home-page .start-band {
    --stage-paper: #161F2A;
    --stage-shell: #161F2A;
    --stage-paper-rule: rgba(255, 255, 255, 0.13);
  }
  :root:not([data-theme="light"]) .home-page .start-band .term-window,
  :root:not([data-theme="light"]) .home-page .start-band .term-body {
    background: #161F2A;
  }
  :root:not([data-theme="light"]) .home-page .start-band .term-window {
    border-color: rgba(255, 255, 255, 0.13);
  }
}

:root[data-theme="dark"] .home-page .start-band {
  --stage-paper: #161F2A;
  --stage-shell: #161F2A;
  --stage-paper-rule: rgba(255, 255, 255, 0.13);
}
:root[data-theme="dark"] .home-page .start-band .term-window,
:root[data-theme="dark"] .home-page .start-band .term-body {
  background: #161F2A;
}
:root[data-theme="dark"] .home-page .start-band .term-window {
  border-color: rgba(255, 255, 255, 0.13);
}

/* No accent rule on the top edge. A half-width gradient reads as a broken
   border, and a solid one competes with the colour change for the same job.
   The slab is the separation. */

/* Two shapes, told apart by shape. The old pairing was a 14px box holding a
   22px field: close enough that the eye read the gap between them as a third
   surface instead of as a frame, which is most of what felt dense. Collapsing
   to one shape fixed the density and lost the window.

   So they stay nested, and the radii go to opposite ends instead of sitting
   one step apart. The shell is a hard rectangle and the field inside it is
   properly round, which is also what a composer looks like: an app window
   with a rounded input in it. */
.home-page .start-band .agent-window {
  padding: 14px;
  border-radius: 0;
  background: var(--stage-shell);
  border-color: var(--stage-paper-rule);
  box-shadow: none;
}

.home-page .start-band .composer-body {
  margin: 0 0 4px;
  padding: 20px 22px;
  border-radius: 16px;
  border-color: var(--stage-paper-rule);
  background: var(--stage-paper);
  font-size: 0.8125rem;
  line-height: 1.75;
  font-family: var(--font-mono);
  /* The prompt is the thing being read. Dim ink on a dark field made it the
     third quiet layer in a row; on paper it is simply text. */
  color: var(--stage-paper-ink);
}

.home-page .start-band .composer-chrome { padding: 6px 8px 0; }
.home-page .start-band .composer-chrome,
.home-page .start-band .chrome-icon,
.home-page .start-band .chrome-caret { color: var(--stage-paper-mid); }

/* Terminals are not beige, and that goes for the frame as well as the screen.
   The paper belongs to the composer, which is depicting a document you type
   into. This is depicting a screen, so it is black to its edges: title bar,
   frame and all.

   It went light once so both modes would be the same material. What that
   actually did was show a reader a terminal that looks nothing like the one
   they are about to get, in the panel whose entire job is "this is what you
   will see".

   Being darker than the slab is what separates it. A window at the old
   #0d1b28 sat four points off the band behind it and dissolved; this one is
   below the band, not above it, so the screen recesses into the slab instead
   of floating on it, and a white-alpha edge draws the frame. */
.home-page .start-band .term-window {
  background: #070C13;
  border-color: rgba(255, 255, 255, 0.13);
  /* The same hard rectangle as the composer's shell. */
  border-radius: 0;
  box-shadow: none;
  padding: 0;
}

/* No tonal strip. The dots are in colour and the word "terminal" is right
   there, so a lighter band was a third thing saying "this is a window" and
   the one surface of the three that nobody could quite see. A hairline is
   enough to divide chrome from screen. */
.home-page .start-band .term-window .term-bar {
  margin: 0;
  background: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}

/* Traffic lights, in their own colours. Grey dots are a drawing of a window;
   these three are the one thing on the band a reader recognises without
   reading it, and they cost nothing to get right. Apple's values. */
.home-page .start-band .term-window .term-dot:nth-child(1) { background: #FF5F57; }
.home-page .start-band .term-window .term-dot:nth-child(2) { background: #FEBC2E; }
.home-page .start-band .term-window .term-dot:nth-child(3) { background: #28C840; }

.home-page .start-band .term-window .term-name { color: #8b98a5; }

/* The install command is longer than any column we could give it, and always
   will be: it carries a host, an os and a tid. Wrapping a shell command makes
   it look broken, so it scrolls, and the fade says it scrolls rather than
   letting it stop mid-token at a hard edge.

   A mask rather than a gradient overlay, so the same rule works over paper
   and over the black screen without naming either colour. Content that fits
   fades over its own empty space, which is nothing to see. */
.home-page .start-band .composer-text,
.home-page .start-band .term-body {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 56px), transparent);
          mask-image: linear-gradient(to right, #000 calc(100% - 56px), transparent);
}

/* Click anywhere to copy. The COPY chip stays: it is the affordance a reader
   looks for and the only one that reports back. This is the larger target for
   somebody who has already decided, so it needs to look live without becoming
   a second button — a cursor and a lit edge, nothing that competes with the
   chip. Text inside stays selectable; the handler bails on a real selection. */
.home-page .start-band .is-copyable { cursor: pointer; }

/* Selectable, and readable while selected. The global ::selection sets
   color: var(--ink), which is the page's dark ink: on these black panels a
   dragged selection painted dark glyphs on a light wash and the text
   disappeared. Keep the glyph colour and tint the wash instead.

   The wash is the brand blue, not white. A white scrim on a black panel is
   only a few points off the panel itself, so a selection read as a smudge
   and the dim comment lines under it stayed hard to make out. Blue separates
   from black at the same opacity and keeps both text levels legible.

   Selection has to work at all, too. The panels copy on click, and the
   handler bails when the click ends a real selection, so dragging out one
   line is still how you take one line. */
.home-page .start-band .agent-window ::selection,
.home-page .start-band .term-window ::selection {
  background: rgba(73, 169, 231, 0.42);
  /* An explicit colour, not `inherit`. On ::selection, `inherit` takes the
     PARENT's selection colour, not the element's own text colour — so it
     resolved to the global rule's var(--ink), which is the page's dark ink,
     and selected glyphs went dark on the wash. That is the bug it was
     written to avoid. Selection flattens the dim/bright levels; on a black
     panel that is the right trade. */
  color: #f2f7fb;
}

/* One gesture in both modes: the panel lifts off the page. It changed colour
   before, which was wrong twice over — subtle enough to miss, and once it
   was strong enough to see, the thing you are reading changed shade under
   the cursor. A shadow says "pick me up" without touching the depiction. */
.home-page .start-band .is-copyable:hover {
  box-shadow: 0 12px 28px -12px rgba(7, 12, 19, 0.55);
  border-color: rgba(255, 255, 255, 0.26);
}

/* A cast shadow barely registers on a dark page, so the edge does more of
   the work there. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .home-page .start-band .is-copyable:hover {
    box-shadow: 0 12px 28px -12px rgba(0, 0, 0, 0.7);
    border-color: rgba(255, 255, 255, 0.30);
  }
}
:root[data-theme="dark"] .home-page .start-band .is-copyable:hover {
  box-shadow: 0 12px 28px -12px rgba(0, 0, 0, 0.7);
  border-color: rgba(255, 255, 255, 0.30);
}

@media (prefers-reduced-motion: no-preference) {
  .home-page .start-band .is-copyable {
    transition: box-shadow 140ms ease-out, border-color 140ms ease-out;
  }
}

/* The scaffold and mode pickers are native selects, so the popup is drawn by
   the OS and follows the page, not the band. Only the closed control is ours
   to colour. */
/* background-color, not the shorthand: the mode select carries a caret as a
   background-image and `background: var(--bg)` here would erase it. */
.home-page .start-band .start-select,
.home-page .start-band .mode-select {
  color: var(--ink-soft);
  background-color: var(--bg);
}

.home-page .start-band .start-select option,
.home-page .start-band .mode-select option {
  color: var(--ink);
  background: var(--stage);
}

/* The copied state on the inline sentence button: the light-mode green is
   unreadable on the slab. */
.home-page .start-band .do-copy.is-copied { color: #14724d; }
.home-page .start-band .do-copy:hover { color: var(--ink); }

/* ─── The headline, at the demo's scale ───────────────────────────────
   2026-09-16. The 4rem cap was set when the band below it was paper and
   the headline was the loudest thing on the page. The band is a dark
   machine now and it out-weighed the sentence introducing it, which is
   backwards: the claim should land before the demonstration of it.

   Same figures as the /c/* headlines, so the front door and the landing
   pages read as one family rather than as two scales of the same brand.
   The old note about 4rem being "the largest size that holds it to two
   lines" was measured in a 756px column; this page runs to the marketing
   column's full width and 5rem still breaks to two. */
.home-page .hero-title.is-sentence {
  font-size: clamp(2.75rem, 6.4vw, 5rem);
  letter-spacing: -0.035em;
  /* 1.06, not 0.97. At 0.97 the line box was SMALLER than the type size
     (41.6px of leading under 42.9px type at phone width), and the accent
     phrase is italic: this face's italic f carries a descender deep enough
     to land in the ascenders below it, so "full" sat inside "building".
     1.06 clears it and still reads as display leading rather than prose. */
  line-height: 1.06;
  /* No balance. It splits a two-line headline into equal halves, which on
     this sentence broke it early and left the line short of the column. */
  text-wrap: wrap;
}

@media (max-width: 700px) {
  .home-page .hero-title.is-sentence { font-size: clamp(2.25rem, 11vw, 3.25rem); }
}

/* ─── The install band, saying what is behind it ──────────────────────
   "It's time to build." was a slogan beside a button: it gave no reason to
   click and named nothing you would get. Devs do come looking for the
   install command, so the band stays, but it now says that is what it is,
   which platforms it covers, and that the trial costs nothing. The trial
   was not stated anywhere on this page before. */
.home-page .install-row {
  align-items: center;
  gap: var(--space-8);
}

/* The band holds one button. Left aligned with everything else on the page
   rather than centred, and not stretched: a full-width bar here would
   out-shout the paste above it, which is still the action this page wants. */
.home-page .install-row { justify-content: flex-start; }

/* Phones stack it. Two columns at phone width put a heading and a button in
   a squeezed row where the button ends up narrower than the text beside it,
   which reads as the smaller of two things to do. Stacked, the button is the
   full width of the column and is unmistakably the action. */
@media (max-width: 620px) {
  .home-page .install-row {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-5);
    flex-wrap: nowrap;
  }

  .home-page .install-row .button {
    width: 100%;
    justify-content: center;
  }
}


/* ─── The controls row is one height ──────────────────────────────────
   The copy chip and the scaffold select sit side by side and have to be
   the same box. They were not, twice:

     29px vs 32.3px   a button inherits line-height 1 from the base button
                      styles; a native select computes `normal`
     32px vs 32.3px   matching the line-height keyword got them within a
                      third of a pixel, which at 2x lands their borders on
                      different device pixels and still reads as crooked

   So neither control derives its height from font metrics any more. Both
   are pinned to the same value with the vertical padding removed, which is
   the only way two elements this different (a button and a native select)
   come out identical. The button already computes display grid with
   align-items center, and a select centres its text natively, so the label
   stays centred in both without further help. */
.start-controls .start-copy,
.start-controls .start-select {
  height: 2rem;
  min-height: 2rem;
  padding-top: 0;
  padding-bottom: 0;
}

/* ─── The session: three exhibits ────────────────────────────────────
   One window per command, each labelled by the command in its title bar
   and introduced by the claim it settles. An earlier draft ran all three
   frames as one continuous session and it read as a wall: forty lines of
   monospace with no entry point and no boundaries the reader could see.

   One column, the same one the rest of the page uses. An earlier draft ran
   the windows wider than the text on the theory that a hundred columns of
   monospace needed the room and that the overhang would read as a
   deliberate bleed. It did not; it read as nothing lining up. The terminal
   was recaptured at 96 columns instead, which fits the page's own measure,
   and every edge in the section now starts where the hero paragraph
   starts. */
/* Its own ground, so the argument is not mistaken for more of the demo.

   The page above this is white from the headline down through the paste
   panel, and with nothing between them the section read as a continuation
   of the invitation rather than as the case being made for it. A soft band
   and a hairline give it a floor and a ceiling. The demo band deliberately
   has no ground of its own, which is what makes one here work: two tinted
   bands in a row would be stripes, one is a room. */
.session {
  padding: var(--space-14) 0;
  background: var(--bg-soft);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}

.session-shell {
  max-width: var(--container-marketing);
  margin: 0 auto;
  padding: 0 var(--space-8);
}

.session-head { margin-bottom: var(--space-12); }

.session-title {
  margin: 0 0 var(--space-4);
  font-size: clamp(1.875rem, 3.6vw, 2.75rem);
  font-weight: var(--weight-bold);
  letter-spacing: -0.032em;
  line-height: 1.1;
}

.session-lede {
  max-width: 60ch;
  margin: 0;
  font-size: var(--text-md);
  line-height: var(--leading-relaxed);
  color: var(--ink-soft);
}

/* The gap between exhibits is larger than any gap inside one, so the three
   read as three rather than as a stack. */
.exhibit { margin-bottom: var(--space-14); }

/* Two windows in one exhibit sit closer to each other than to anything
   else, so they read as one answer in two forms rather than as two
   separate claims. */
.exhibit .session-window + .session-window { margin-top: var(--space-4); }

/* Inline code, set like documentation rather than like a product page.

   These were grey pills with a radius, which is the chip every marketing
   site puts around a command to make it look like a feature. A command
   named in a sentence is just a command: the mono face already says it is
   one, and a tinted capsule around it says the sentence is selling. */
.session-lede code,
.exhibit-say code {
  font-family: var(--font-mono);
  font-size: 0.92em;
  padding: 0;
  border-radius: 0;
  background: none;
  color: var(--ink);
}
.exhibit:last-child { margin-bottom: 0; }

.exhibit-title {
  /* auto, not 0, on the inline axis: .session-prose centres these in the
     1080 shell so their left edge lands on the page column, and a flat
     `margin: 0 0 x` here would win on source order and undo it. */
  margin: 0 0 var(--space-3);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  letter-spacing: -0.024em;
  line-height: 1.2;
}

.exhibit-say {
  max-width: 60ch;
  margin: 0 0 var(--space-5);
  font-size: var(--text-md);
  line-height: var(--leading-relaxed);
  color: var(--ink-soft);
}

/* A ring, not a shadow. The page is flat white everywhere else and a drop
   shadow under one element is the tell of a component kit rather than a
   decision. */
.session-window {
  border-radius: 12px;
  overflow: hidden;
  background: #070C13;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07);
}

.session-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 13px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}

.session-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.16);
}

/* The command, in the bar. It is the window's label, which means the body
   below it is captured output end to end with nothing of ours typed into
   it. The demo band's terminal carries no name for the opposite reason:
   that window depicts somebody else's software. */
.session-cmd {
  margin-left: 6px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: #8b98a5;
}

/* 1.45, not the 1.75 the demo terminal uses. That panel is five lines of
   invitation and wants air; this is a real screen and reads as one only at
   the density a screen has. */
.session-body {
  padding: 18px 20px 20px;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  color: #ABB2BF;
  overflow-x: auto;
  font-variant-ligatures: none;
  font-feature-settings: "liga" 0, "calt" 0;
}

.session-line {
  white-space: pre;
  min-height: 1.5em;
}

.session-body .is-bold { font-weight: 600; }

.session-foot {
  padding: 11px 20px 13px;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  font-family: var(--font-mono);
  font-size: 12px;
  white-space: pre;
  color: #6d7d8b;
  overflow-x: auto;
}

/* The close sits on the same measure as the rest of the prose and is set
   a step larger than the exhibit captions, so it reads as the section
   summing up rather than as a fourth caption with no window under it. The
   rule above it is the only one inside the band: it is the single place
   the section changes what it is doing. */
.session-close {
  max-width: 60ch;
  margin-top: var(--space-12);
  padding-top: var(--space-8);
  border-top: 1px solid var(--rule);
}

.session-close p {
  margin: 0 0 var(--space-4);
  font-size: var(--text-md);
  line-height: var(--leading-relaxed);
  color: var(--ink-soft);
}

.session-close p:first-child {
  color: var(--ink);
  font-weight: var(--weight-medium);
}

.session-close p:last-child { margin-bottom: 0; }

/* The second band goes back to the page white. Two tinted bands in a row
   would be stripes; alternating gives each section a floor without the
   page turning into a pattern. */
.session.is-alt {
  background: var(--bg);
  border-top: 0;
}

@media (max-width: 900px) {
  .session { padding: var(--space-10) 0 var(--space-12); }
  .session-shell { padding: 0 var(--space-5); }
  .session-head { margin-bottom: var(--space-9); }
  .exhibit { margin-bottom: var(--space-10); }
  .session-body { font-size: 11.5px; padding: 14px 14px 16px; }
}

/* ─── The finale ─────────────────────────────────────────────────────
   The one inverted band on the page. Every section above it is a claim
   with a dark panel of evidence under it on a light ground; this one has
   no evidence to show because it is the summary, so it takes the dark
   ground itself and says the thing the hero opened with. */
/* Black, and the type does the work.

   Five grounds were tried here: the panels' blue-black read as an
   institutional slab, a deep brand blue read as nineteen seventies
   corporate, a warm off black read as brown, a light neutral read as grey,
   and a dark navy was closer but still a coloured slab.

   The ground was never the problem. This is the last thing on the page and
   the only place it asks for anything, so it is where the boldness gets
   spent, and spending it on a background colour is spending it on the
   quietest surface available. Black, and the sentence is set at display
   size: the words are the figure, the band is the ground, and the accent
   appears once, on the button.

   A rule on the top edge, because in dark mode the page ground and this
   band are both near-black and the boundary between the letter and the
   ask was invisible on a phone. The rule is the separation there; the
   colour change is the separation in light mode. */
.finale {
  padding: var(--space-14) 0;
  background: #08090B;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  color: #F2F7FB;
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  /* Centred, and the only centred thing on the page. It is a statement
     rather than a piece of the argument, so it does not sit on the column
     the argument was made in. Title and paragraph share one measure so the
     two blocks have the same edges. */
  text-align: center;
}

/* Display scale. This is the sentence the hero opened with and the four
   sections earned, so it is set like a statement rather than like another
   section head. */
.finale-title {
  max-width: 16ch;
  margin: 0 auto var(--space-6);
  font-size: clamp(2.5rem, 7vw, 5.25rem);
  font-weight: var(--weight-bold);
  letter-spacing: -0.042em;
  line-height: 0.98;
  color: #F2F7FB;
}

.finale-say {
  max-width: 700px;
  margin: 0 auto var(--space-8);
  font-size: var(--text-md);
  line-height: var(--leading-relaxed);
  color: #A8B6C6;
}

/* The accent, used once on the page and used here, on the only thing the
   section asks anybody to do. */
/* Wider, not taller. The height matches the buttons everywhere else on
   the site; the extra width is what gives the page's one ask its weight. */
.finale-cta {
  display: inline-block;
  padding: var(--space-4) var(--space-16);
  border-radius: 8px;
  /* The accent, used once on the page and used here, on the only thing
     the section asks anybody to do. */
  background: #49A9E7;
  color: #06111C;
  font-weight: var(--weight-bold);
  font-size: var(--text-md);
  text-decoration: none;
}

.finale-cta:hover { background: #6BBBED; }
.finale-cta:focus-visible { outline: 2px solid #F2F7FB; outline-offset: 3px; }

@media (max-width: 900px) {
  .finale { padding: var(--space-11) 0; }
}

/* The exhibit title sat one weight away from the caption under it and read
   as a bold first line rather than as a heading. A size step and tighter
   tracking separate them; the caption goes a shade lighter so the pair has
   a clear order. Tried the h2s in mono at the same time and reverted it:
   at heading size the mono reads as a code comment rather than a title. */

/* Left aligned, like the argument above it and the letter below it.

   It was centred for a while to match the finale, which worked when the
   two were adjacent. They are not any more: the letter sits between them
   now, left aligned on the page column, and a centred block in the middle
   of that run read as a stray. Centring is the finale's alone. */
.consequence {
  padding: var(--space-12) 0;
  background: var(--bg-soft);
  border-top: 1px solid var(--rule);
}

/* Sized as a section heading, because that is what it is: the one claim
   the four sections above it were evidence for. At text-xl it read as an
   emphasised paragraph and the band looked like an afterthought.

   The heading and the paragraph under it share one max-width, in px rather
   than ch. A ch is relative to the element's own font size, so 22ch on a
   40px heading and 62ch on a 16px paragraph produced two different column
   widths stacked on each other, which read as a broken layout. */
.consequence-lead {
  max-width: 700px;
  margin: 0 0 var(--space-6);
  font-size: clamp(1.75rem, 3.4vw, 2.5rem);
  font-weight: var(--weight-bold);
  line-height: 1.12;
  letter-spacing: -0.03em;
  color: var(--ink);
}

.consequence-body {
  max-width: 700px;
  margin: 0;
  font-size: var(--text-md);
  line-height: var(--leading-relaxed);
  color: var(--ink-soft);
}

@media (max-width: 900px) {
  .consequence { padding: var(--space-10) 0; }
}

/* ─── The framework surface ──────────────────────────────────────────
   Two columns of term and definition. Not cards: a definition list is what
   this is, and boxing eleven of them would turn the one place the page
   shows its size into a feature grid.

   The term is set in the mono face because every one of them is something
   you type. That is the only place outside the terminal panels where the
   mono appears in running content, and it earns it here. */
.surface {
  margin: var(--space-8) 0 var(--space-10);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6) var(--space-8);
}

.surface > div {
  padding-top: var(--space-4);
  border-top: 1px solid var(--rule);
}

.surface dt {
  margin-bottom: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--ink);
}

/* The design system's base gives every dd a padding-inline-start, which is
   right for a definition list in prose and wrong in a two column grid: the
   description sat a space to the right of its own term and the columns
   looked misaligned. */
.surface dd {
  margin: 0;
  padding-inline-start: 0;
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  color: var(--ink-soft);
}

@media (max-width: 760px) {
  .surface { grid-template-columns: 1fr; gap: var(--space-5); }
}

/* The letter sits on the page ground, not on the finale's.

   It was dark, directly above the dark finale, and the two read as one
   long black area with a hairline drawn through it for no reason. Worse,
   a personal note on the same surface as the call to action made the note
   look like part of the pitch.

   White here, so the page alternates: the consequence on the soft tint,
   the letter on the page, the finale on near-black. Dark is the colour of
   the ask now, and it is used once. */
.note-band {
  padding: var(--space-14) 0;
  background: var(--bg);
  border-top: 1px solid var(--rule);
}

/* 700px, the same measure as the consequence and the finale. At 560 it
   was the only column on the page at its own width and read as cramped. */




/* Placeholder for the drawn mark. An <img> of the same height drops in
   here without touching anything else. */
/* The signature. Keyed off a white page into an alpha channel and filled
   white, so the ink is the shape and the colour is ours: the same file
   works on this dark band and on any light ground later.

   Sized by height, since the source's aspect ratio should not decide how
   tall the block is. */


/* The founder letter's block. Left on the column with everything else: a
   700px box centred inside the 756px column put it 28px right of every
   other left edge on the page. */
.note {
  max-width: 700px;
  margin: 0;
}

/* ─── Dark mode ──────────────────────────────────────────────────────
   Two things go wrong when the page is inverted.

   The tinted bands resolve --bg-soft to a navy slab over a near-black
   page, which is the heaviness this was meant to avoid. On a dark ground
   a band does not need a fill to be a band: the hairline is enough.

   The near-black bands have nowhere to go. You cannot be darker than a
   near-black page, so they lift instead, to the same #161F2A the demo
   band's panels already use. Same convention, one colour, and it is a
   soft blue-grey rather than a slab. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .home-page .session,
  :root:not([data-theme="light"]) .home-page .consequence {
    background: transparent;
    border-top: 1px solid var(--rule);
    border-bottom: 0;
  }

  /* The letter's rule is heavier than the others. Every other band in
     dark mode is separated by the theme rule, but the letter is prose on
     the page ground directly under prose on the page ground, so at that
     weight the two ran together on a phone. */
  :root:not([data-theme="light"]) .home-page .note-band {
    background: transparent;
    border-top: 1px solid rgba(255, 255, 255, 0.20);
  }

  :root:not([data-theme="light"]) .home-page .finale {
    background: #08090B;
    border-top: 1px solid rgba(255, 255, 255, 0.14);
  }

  :root:not([data-theme="light"]) .home-page .session-window {
    background: #161F2A;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.10);
  }
}

:root[data-theme="dark"] .home-page .session,
:root[data-theme="dark"] .home-page .consequence {
  background: transparent;
  border-top: 1px solid var(--rule);
  border-bottom: 0;
}

:root[data-theme="dark"] .home-page .note-band {
  background: transparent;
  border-top: 1px solid rgba(255, 255, 255, 0.20);
}

:root[data-theme="dark"] .home-page .finale {
  background: #08090B;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}

:root[data-theme="dark"] .home-page .session-window {
  background: #161F2A;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.10);
}

/* Headings wrap at a measure, not at a hard break. A <br> is a decision
   made at one viewport and wrong at every other: at phone width it turned
   the two line section heads into four short ones. A max-width in ch does
   the same job at every size and follows the text when the copy changes. */
.session-title { max-width: 22ch; }
.hero-title.is-sentence { max-width: 13ch; }
