@import "https://assets.elements.dev/assets/app/shared/styles/page.c7d2c7963e3f0ee.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(255, 255, 255, 0.22);
  color: inherit;
}
.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. The 4.25rem cap is
     the largest size at which "application environment." still fits the
     content column on one line, so the headline breaks as
     "The integrated / application environment." rather than orphaning
     a word. Raise it and the last line breaks again. */
  font-size: clamp(var(--text-4xl), 5.5vw, 4.25rem);
  letter-spacing: var(--tracking-tight);
  /* The headline is two lines again, so this is back to the tighter
     leading it was set at before. 1.1 was for the three-line version,
     where descenders sat on the caps of the line below. */
  line-height: 1.04;
  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%; }
}

/* ---- 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 {
  /* Equal air top and bottom, measured from what is visible: the band's
     closing rule down to the first row's title, and the More link down to the
     footer's rule. The top used to hold a FEED heading and kept its space
     after the heading went. The two paddings are not the same number because
     the top carries 16px the bottom does not — 8px of margin on .feed and 8px
     inside the row — so it is set 16px shorter to come out even. */
  padding: var(--space-8) 0 var(--space-12);
}

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

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

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

/* ---- 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);
  /* Enough to separate the button from the feed, not enough to read as
     the page having ended. The feed is the next thing to look at, not a
     new section, so it starts close. */
  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 is ruled paper. One 24px rule at a weight that reads as a surface
   and never as lines across a headline (the 120px major rule that drafting
   paper also has was exactly what cut through the type), running the full
   height of the band between the topbar's hairline and the one that closes
   it. The rule lives on a pseudo-element so its mask is
   independent of the band's own colour.

   The sheet is var(--bg), never a literal. It shipped as #fcfdfe, which is
   the page colour in light mode and a white slab under light text in dark
   mode: the headline and the paragraph disappeared into it. The ruling is a
   token too, since a blue-on-white hairline is invisible on near-black. */
.home-page {
  --sheet-rule: rgba(37, 99, 152, 0.055);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .home-page {
    --sheet-rule: rgba(150, 194, 232, 0.12);
  }
}
:root[data-theme="dark"] .home-page {
  --sheet-rule: rgba(150, 194, 232, 0.12);
}

/* 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;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(var(--sheet-rule) 1px, transparent 1px),
    linear-gradient(90deg, var(--sheet-rule) 1px, transparent 1px),
    /* The opening and closing rules, pinned to the band's two edges. These
       are layers rather than a border on .hero-wrap: a border sits outside
       the padding box, so it painted at y=0 and the grid's own first rule at
       y=1, and two 1px lines in different colours one pixel apart read as a
       doubled border under the nav. As layers they land on exactly the same
       pixel as the ruling and there is one line. */
    linear-gradient(var(--chrome-rule), var(--chrome-rule)),
    linear-gradient(var(--chrome-rule), var(--chrome-rule));
  /* Both axes repeat at a true 24px. Dividing the band into a whole number of
     rows instead (100%/33) put every rule at a fractional offset, and on a 3x
     phone a 1px line at a fractional y lands on a device pixel for some rows
     and straddles two for others: the ruling rendered at visibly different
     weights row to row. Integer steps are the only way these stay even. The
     band's padding is what makes the last row come out whole. */
  background-size: 24px 24px, 24px 24px, 100% 1px, 100% 1px;
  /* Aligned to the band's top edge, not offset. The grid's first horizontal
     rule and the hairline under the topbar are the same line here: offset by
     half a cell they were two lines 12px apart, which reads as a grid that
     missed its mark. */
  /* The vertical rules are offset half a cell so neither edge of the viewport
     carries one. A rule sitting exactly on the left edge read as a border on
     the band; off-centre, the ruling plainly runs off both sides the way a
     sheet wider than the screen would. */
  background-position: 0 0, 12px 0, 0 0, 0 100%;
  background-repeat: repeat, repeat, no-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. */
@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;
  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);
  }
}

/* The band's bottom padding is tuned per breakpoint so its height comes out a
   multiple of the 24px cell and the last row is whole: 888px over 37 rows on a
   desktop, 816 over 34 on a phone. It is measured, not derived — css cannot
   read an element's own height — so a copy edit that changes how the hero
   wraps will leave a short row at the bottom until this is re-measured.
   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; }
}
