@import "https://assets.elements.dev/assets/app/shared/styles/page.2f76a12410ad3807.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; }
.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; }
.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 nearly twice as long, and at 7xl it
     ran to four lines and pushed the feed off the first screen. The
     4xl→6xl range keeps it to two lines on a laptop while still
     reading as the largest thing on the page. */
  font-size: clamp(var(--text-4xl), 5.5vw, var(--text-6xl));
  letter-spacing: var(--tracking-tight);
  line-height: 1.04;
  margin-bottom: var(--space-6);
}
/* Keep "The full stack" on one line — never break between "The" and
   the glimmered wordmark. Paired with the mobile font-size below, which
   sizes the headline so the locked phrase fits the phone content width
   (it doesn't at the desktop-derived size). */
.hero-lockup {
  white-space: nowrap;
}
.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. */
.hero-glimmer {
  display: inline-block;
  font-weight: var(--weight-black);
  /* background-clip:text shrink-wraps the paint box to the text advance;
     the tight tracking pulls the final glyph's ink past that edge and
     the clip cuts the "s". A hair of right padding widens the paint box
     to include it, with a matching negative margin so layout is
     unchanged. */
  padding-right: 0.08em;
  margin-right: -0.08em;
  background: linear-gradient(
    90deg,
    var(--accent) 0%,
    var(--accent) 38%,
    var(--accent-deep) 50%,
    var(--accent) 62%,
    var(--accent) 100%
  );
  background-size: 260% 100%;
  background-position: 100% 50%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation:
    hero-wave    1900ms ease-in-out   50ms forwards,
    hero-glimmer 6s     ease-in-out 1950ms infinite;
}

@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%; }
}

/* ---- feed ---- */

/* No top rule between hero and feed and no FEED label — the feed
   reads as a continuation of the page, not a separate band. The
   hero's bottom margin + the feed's first row carry the visual
   transition on their own. */
.feed-wrap {
  width: 100%;
}

/* Same column + gutter as .shell-marketing (the hero above) so the feed
   header and rows share the hero's exact left edge — and match the
   /feed page, which uses the same gutter. */
.home-feed-shell {
  width: 100%;
  max-width: var(--container-marketing);
  margin: 0 auto;
  padding: 0 var(--space-8);
}


.feed-section {
  /* Modest air between the header and the first row. The deep bottom
     air the feed used to carry is gone: the dark closing band sits
     right below now, and 10rem of white ahead of it read as the page
     having ended early. */
  padding: var(--space-4) 0 var(--space-20);
}

/* Feed header. A very subtle full-bleed hairline separates the CTA
   block above from the feed below — --rule is the theme-aware divider
   token (light neutral-200 / dark neutral-800), the same one the footer
   uses, so it reads as a faint line in both modes. The band is
   full-width, so the border spans the whole viewport edge to edge. */
.feed-head-band {
  border-top: 1px solid var(--rule);
  padding: var(--space-10) 0 0;
}
.feed-head {
  margin: 0;
}
.feed-head-title {
  font-family: var(--font-sans);
  /* Section scale — a landmark heading with weight under the hero, but
     always smaller than it. Responsive: ~40px on desktop down to ~28px
     on phones, so it tracks the hero's own mobile shrink and never
     overtakes it (the hero clamps to ~36–52px on narrow screens). Held
     below the 64px --page-title token at every width. */
  font-size: clamp(1.75rem, 4.2vw, 2.5rem);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-none);
  color: var(--ink);
  margin: 0 0 var(--space-3);
}
.feed-head-sub {
  font-family: var(--font-sans);
  font-size: var(--text-md);
  color: var(--ink-soft);
  line-height: var(--leading-snug);
  margin: 0;
}

.section-foot {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  margin-top: 2.5rem;
}

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

@media (max-width: 700px) {
  /* Top padding matches the canonical 48px above-h1 air on the
     other pages: <PageChrome>.page-chrome-main contributes 24px of
     chrome padding on mobile and the canonical h1 adds 24px of
     margin-top. Home doesn't use PageChrome, so we recreate the
     combined 48px in the hero element directly. */
  .hero { padding: var(--space-12) 0 0; }
  .hero-title {
    max-width: none;
    /* Small gap to the subtitle on mobile. */
    margin-bottom: var(--space-3);
  }
  /* Two constraints on phones: the "The full stack" lockup must fit the
     content width on one line (down to ~320px), and the whole sentence
     has to leave the feed visible above the fold. The old 3.25rem cap
     satisfied the first and, at this sentence length, broke the second
     — 52 characters ran to four lines. Capping at 2.5rem holds the
     headline to about three lines; the lockup still fits, since it only
     needs the size at or below ~3.25rem. */
  .hero-title.is-sentence {
    font-size: clamp(1.875rem, 10vw, 2.5rem);
  }
  /* Match .shell-marketing's mobile gutter (1.5rem) so the feed stays
     on the hero's left edge at phone widths too. */
  .home-feed-shell { padding: 0 1.5rem; }
  .feed-section { padding: var(--space-5) 0 2rem; }
  .section-foot { margin-top: 3rem; }
}

/* ---- 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-6) 0 0; }
  .hero-title { max-width: none; margin-bottom: var(--space-2); }
  .feed-section { padding: var(--space-4) 0 var(--space-8); }
}

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

@media (prefers-reduced-motion: reduce) {
  .hero-glimmer {
    animation: none !important;
    background: var(--accent);
    -webkit-background-clip: initial;
    background-clip: initial;
    color: var(--accent);
    -webkit-text-fill-color: currentColor;
  }
}

/* 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 CTAs so they don'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 + 24px = 56px. */
  padding-top: var(--space-6);
  margin-bottom: var(--space-14);
}
.cta-band-inner {
  /* Two equal-width buttons, sized to whichever label is wider — no
     hardcoded width, so changing either label keeps the pair matched.
     inline-grid shrinks the row to content (left-aligned); the two 1fr
     tracks resolve to the widest item's width and apply it to both. */
  display: inline-grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  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);
  box-shadow: 0 12px 30px -10px color-mix(in srgb, var(--accent) 55%, transparent);
  transition: box-shadow 140ms ease, transform 140ms ease;
  white-space: nowrap;
}
.cta-band-btn:hover {
  box-shadow: 0 18px 44px -12px color-mix(in srgb, var(--accent) 72%, transparent);
  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. */
.cta-band-watch {
  font-size: var(--text-lg);
  padding: 0.9rem 1.9rem;
  border-radius: var(--radius-xl);
  white-space: nowrap;
}
.cta-band-play {
  /* Nudge the play triangle to sit optically centered against the label. */
  position: relative;
  top: 0.5px;
}
@media (max-width: 700px) {
  .cta-band { margin-bottom: var(--space-10); }
  .cta-band-inner {
    /* Stack full-width on mobile — single column, buttons fill it. */
    display: grid;
    grid-auto-flow: row;
    grid-auto-columns: auto;
    width: 100%;
    gap: var(--space-3);
  }
  .cta-band-btn,
  .cta-band-watch { width: 100%; text-align: center; }
}

/* ─── 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. */

.tool-section {
  padding: var(--space-20) 0;
}

/* 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 { display: block; }
.split-copy { margin: 0 0 var(--space-10); }
.split-demo { width: 100%; }
.split-demo .hero-terminal { margin-bottom: 0; }

.tool-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-deep);
  font-weight: var(--weight-bold);
  margin-bottom: var(--space-3);
}

/* Child headline: clearly smaller than the category title above it,
   and semibold rather than bold. */
.split-title {
  font-family: var(--font-sans);
  font-weight: var(--weight-semibold);
  font-size: clamp(var(--text-3xl), 4vw, var(--text-5xl));
  letter-spacing: var(--tracking-tight);
  line-height: 1.05;
  margin: 0 0 var(--space-5);
}

.split-lead {
  font-family: var(--font-sans);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
  color: var(--ink-soft);
  max-width: 40rem;
  margin: 0;
}

@media (max-width: 820px) {
  .tool-section { padding: var(--space-16) 0; }
  .split-lead { max-width: none; }
}

/* 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. */
.contrast {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
  align-items: start;
}
@media (max-width: 820px) {
  .contrast { grid-template-columns: 1fr; }
}

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

.term-body .line.ind { padding-left: 1.6ch; }
.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-body .i1 { padding-left: 2ch; }
.code-body .i2 { padding-left: 4ch; }
.code-body .i3 { padding-left: 6ch; }
.code-body .k  { color: #c3a6ff; }
.code-body .s  { color: #9ece6a; }
.code-body .fn { color: #7aa2ff; }
.code-body .cm { color: #5c6b7a; font-style: italic; }
.code-body .tg { color: #7dcfff; }
.code-body .at { color: #bb9af7; }
.code-body .nm { color: #ff9e64; }
.code-body .pn { color: #8b98a5; }
.code-body .ty { color: #7dcfff; }

/* 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. */
.group-head {
  padding: var(--space-16) 0;
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--accent) 12%, var(--bg)),
    var(--bg)
  );
  border-top: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
}
/* A light hairline on a near-black ground reads far fainter than a dark
   one on white, so raise the alpha in dark mode. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .group-head {
    border-top-color: color-mix(in srgb, var(--ink) 32%, transparent);
    border-bottom-color: color-mix(in srgb, var(--ink) 32%, transparent);
  }
}
:root[data-theme="dark"] .group-head {
  border-top-color: color-mix(in srgb, var(--ink) 32%, transparent);
  border-bottom-color: color-mix(in srgb, var(--ink) 32%, transparent);
}
.group-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent-deep);
  font-weight: var(--weight-bold);
  margin-bottom: var(--space-3);
}
.group-title {
  font-family: var(--font-sans);
  font-weight: var(--weight-bold);
  /* Bigger than the feature headlines below it so it reads as a major
     divider, not just another section. */
  font-size: clamp(var(--text-4xl), 7vw, var(--text-6xl));
  letter-spacing: var(--tracking-tighter);
  line-height: 1.0;
  margin: 0 0 var(--space-5);
}
.group-sub {
  font-family: var(--font-sans);
  font-size: var(--text-lg);
  color: var(--ink-soft);
  max-width: 46rem;
  margin: 0;
  line-height: var(--leading-relaxed);
}
@media (max-width: 700px) {
  .group-head { padding: var(--space-12) 0; }
}

/* 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 { counter-increment: 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);
}

/* ---- speed stat band ---- */

/* Three escalating units that tell the speed story at a glance. Big ink
   type, not more blue. */
.stat-band {
  padding: var(--space-20) 0;
  border-top: 1px solid var(--rule);
}
.stat-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-10);
  text-align: center;
}
/* The labels name a moment rather than a category, so they run longer than
   two words and wrapped mid-phrase at the default column width. */
.stat-label { max-width: 18rem; margin-left: auto; margin-right: auto; }
.stat-num {
  font-family: var(--font-sans);
  font-weight: var(--weight-bold);
  /* Sized so the long unit words fit inside a third of the row. */
  font-size: clamp(var(--text-2xl), 3.2vw, var(--text-3xl));
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-none);
  color: var(--ink);
}
.stat-label {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--ink-soft);
  letter-spacing: 0.02em;
  margin-top: var(--space-3);
}
@media (max-width: 700px) {
  .stat-band { padding: var(--space-14) 0; }
  .stat-row { grid-template-columns: 1fr; gap: var(--space-8); }
}

/* ---- 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,
    .stat-band .stat-row,
    .tool-section .split-copy {
      animation: reveal-up linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 55%;
    }
    .tool-section .split-demo {
      animation: reveal-up linear both;
      animation-timeline: view();
      animation-range: entry 8% entry 64%;
    }
  }
}
@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. */
.close-cta {
  background: #0d1b28;
  padding: var(--space-32) 0;
  text-align: center;
  color: #fff;
}
.close-title {
  font-family: var(--font-sans);
  font-weight: var(--weight-bold);
  font-size: clamp(var(--text-4xl), 7vw, var(--text-6xl));
  letter-spacing: var(--tracking-tighter);
  line-height: var(--leading-none);
  color: #fff;
  margin: 0 0 var(--space-5);
}
.close-sub {
  font-family: var(--font-sans);
  font-size: clamp(var(--text-lg), 2vw, var(--text-xl));
  color: rgba(255, 255, 255, 0.62);
  line-height: var(--leading-snug);
  /* Holds the closing band's one-line inventory sentence on a single line
     at desktop. At 34rem it broke after "and one". */
  max-width: 46rem;
  margin: 0 auto var(--space-9);
}
.close-btn {
  font-size: var(--text-lg);
  padding: 0.95rem 2rem;
  border-radius: var(--radius-xl);
  box-shadow: 0 16px 40px -12px color-mix(in srgb, var(--accent) 60%, transparent);
  transition: box-shadow 140ms ease, transform 140ms ease;
}
.close-btn:hover {
  box-shadow: 0 22px 52px -12px color-mix(in srgb, var(--accent) 78%, transparent);
  transform: translateY(-1px);
}
@media (max-width: 700px) {
  .close-cta { padding: var(--space-20) 0; }
  .close-btn { width: 100%; }
}

/* 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. */
.split-lead + .split-lead { margin-top: var(--space-4); }

/* 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);
}

/* 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. */
.split-lead code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  padding: 0.1em 0.3em;
  border-radius: var(--radius-xs);
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}

/* 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. */
.start-note {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-soft);
  line-height: var(--leading-snug);
  margin: 0 0 var(--space-3);
  max-width: 44rem;
}

