/* ═══ landing ═════════════════════════════════════════════════════════════
   The marketing page, built from the app's own tokens so the product and the
   page describing it cannot drift apart.                                    */

body.landing {
  display: block;
  height: auto;
  min-height: 100dvh;
  padding-bottom: 0 !important;
  background: var(--bg);
  color: var(--fg);
  font: 14px/1.55 var(--font-ui);
  overflow: auto;
}
.landing .btn { text-decoration: none; display: inline-flex; align-items: center }
.landing h1, .landing h2, .landing h3 { text-transform: none; letter-spacing: -.02em }

/* ── header ── */
.lp-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  height: 56px;
  padding: 0 1.75rem;
  background: var(--panel);
  border-bottom: 1px solid var(--edge);
}
.lp-top .brand { text-decoration: none; font-family: var(--font-code); font-size: .94rem }
.lp-top nav { display: flex; gap: .5rem }
.lp-top .btn { height: 32px; padding: 0 .9rem }

/* ── hero ── */
.lp-hero {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3.5rem;
  align-items: center;
  padding: 5.5rem 4rem 5rem;
  border-bottom: 1px solid var(--edge);
}
.lp-pitch h1 {
  margin: 0 0 1.25rem;
  font-size: 3.25rem;
  line-height: 1.08;
  font-weight: 700;
  letter-spacing: -.025em;
  text-wrap: pretty;
}
.lp-pitch p {
  margin: 0 0 .9rem;
  max-width: 44ch;
  font-size: 1.06rem;
  line-height: 1.6;
  color: var(--muted);
  text-wrap: pretty;
}
.lp-cta { display: flex; gap: .75rem; margin: 2rem 0 1rem }
.lp-cta .btn { height: 44px; padding: 0 1.4rem; font-size: .94rem }
.lp-facts {
  display: flex;
  flex-wrap: wrap;
  gap: .1rem .6rem;
  margin: 0 0 .6rem !important;
  font-family: var(--font-code);
  font-size: .84rem !important;
  color: var(--muted);
}
.lp-facts b { color: var(--fg); font-weight: 400 }
.lp-facts .sep { color: var(--edge) }
.lp-note { font-size: .82rem !important; margin: 0 !important }

/* The crab walks the line under the pitch: the scuttle scene's own drawing,
   with its walk cycle expressed as CSS rather than a React timeline. It is the
   one moving thing on the site and it stops for prefers-reduced-motion.
   ponytail: the scene's drop-in, sand puffs and claw snap are not ported —
   they are a hero video, not a page ornament. */
/* The crab runs the timeline from the scuttle scene — drop, run, snap, exit —
   in crab.js. The stylesheet only places it and paints it. */
.lp-walk {
  position: relative;
  height: 64px;
  margin-top: 1.5rem;
  overflow: hidden;
}
.crab-walk { position: absolute; left: 0; bottom: 0; width: 44px; height: 44px }
.crab-art {
  /* the mark keeps its own palette in both themes, like the wordmark's crab */
  --crab-body: #e2683a;
  --crab-shell: #f6c3a5;
  --crab-ink: #2a1a12;
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  transform-origin: 50% 76%;
}
.leg, .claw, .pincer, .eyes { transform-box: view-box }   /* origins are in viewBox units */
.crab-dust { position: absolute; inset: 0; pointer-events: none }
.crab-dust i { position: absolute; border-radius: 50%; background: rgb(120 104 86 / .30) }

/* Without motion it simply stands at the start of the line. */
@media (prefers-reduced-motion: reduce) {
  .crab-walk { left: 0; bottom: 0 }
}

/* ── the workspace, shown rather than described ── */
.lp-shot {
  border: 1px solid var(--edge);
  border-radius: var(--r);
  background: var(--inset);
  overflow: hidden;
}
.shot-task {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .7rem 1rem;
  background: var(--bg);
  border-bottom: 1px solid var(--edge);
}
.shot-task .badge {
  font-family: var(--font-code);
  font-size: 1.15rem;
  line-height: 1;
  color: var(--rust);
  padding-right: .75rem;
  border-right: 1px solid var(--edge-soft);
}
.shot-task .crumb { font-size: .82rem; color: var(--muted) }
.shot-task .crumb .sep { color: var(--edge-soft); margin: 0 .25rem; font-weight: 700 }
.shot-task .crumb b { font-family: var(--font-code); color: var(--fg) }
.shot-aid { margin-left: auto; display: flex; gap: .4rem }
.shot-aid .btn { padding: .25rem .6rem; font-size: .8rem }

.shot-body { display: grid; grid-template-columns: minmax(0, 1fr) }
.shot-code {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  font: 400 .84rem/1.7 var(--font-code);
  background: var(--inset);
  height: 15rem;                      /* a window on the file, not the whole file */
}
.shot-code pre { margin: 0; white-space: pre; overflow: hidden }
/* the app's trick: a painted layer under a transparent textarea */
.shot-code .stack { position: relative; overflow: hidden }
.shot-code .stack > * {
  margin: 0;
  padding: .8rem 1rem;
  font: inherit;
  line-height: 1.7;
  tab-size: 4;
  border: 0;
}
.shot-code textarea {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  resize: none;
  background: transparent;
  color: transparent;
  caret-color: var(--rust);
  white-space: pre;
  overflow: auto;
  outline: none;
}
.shot-code textarea::selection { background: color-mix(in srgb, var(--rust) 24%, transparent) }
.shot-tabs button {
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  color: inherit;
  font: inherit;
  padding: .45rem .6rem;
  cursor: pointer;
}
.shot-tabs button:hover { color: var(--fg) }
.shot-tabs .on { color: var(--rust); border-bottom-color: var(--rust) }
.shot-out .raw { margin: 0; padding: .7rem .9rem; font: .8rem/1.6 var(--font-code);
  color: var(--muted); white-space: pre }
/* edited code means the diagnostic below it is about the old code */
#demo.stale .shot-out .problem, #demo.stale .shot-out .raw { opacity: .45 }
/* hints and the solution share one shape: a titled strip above the output */
.demo-aid { border-bottom: 1px solid var(--edge-soft); background: var(--panel) }
.aid-head {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .4rem .9rem;
  border-bottom: 1px solid var(--edge-soft);
}
.aid-title { font: 600 .74rem var(--font-code); color: var(--gold) }
.demo-sol .aid-title { color: var(--muted) }
.aid-nav { margin-left: auto; display: flex; gap: .1rem }
.aid-nav button {
  background: none;
  border: 0;
  color: var(--muted);
  font: 500 .76rem var(--font-ui);
  padding: .15rem .45rem;
  border-radius: var(--r);
  cursor: pointer;
}
.aid-nav button:hover:not(:disabled) { background: var(--panel-hi); color: var(--fg) }
.aid-nav button:disabled { opacity: .35; cursor: default }
.aid-body { margin: 0; padding: .6rem .9rem; font-size: .84rem; line-height: 1.55;
  color: var(--fg); white-space: pre-wrap }
.aid-code {
  margin: 0;
  padding: .6rem .9rem;
  overflow: auto;
  font: .8rem/1.6 var(--font-code);
  color: var(--fg);
  white-space: pre;
}
/* code spans inside prose, the app's own treatment */
.demo-aid code, .lp-shot .problem code {
  font-family: var(--font-code);
  font-size: .92em;
  background: var(--panel-hi);
  border-radius: 4px;
  padding: .05rem .3rem;
}
.shot-code .gut { overflow: hidden;
  color: var(--edge);
  text-align: right;
  padding: .8rem .6rem .8rem .9rem;
  border-right: 1px solid var(--edge-soft);
  font-variant-numeric: tabular-nums;
}
.shot-code .src { color: var(--fg); overflow: hidden }
.shot-code .c { color: var(--muted); font-style: italic }
.shot-code .k { color: var(--rust) }
.shot-code .t { color: var(--info) }
.shot-code .f { color: var(--ember) }
.shot-code mark {
  background: color-mix(in srgb, var(--red) 16%, transparent);
  box-shadow: 0 1px 0 var(--red);
  color: inherit;
}
.shot-run {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .45rem .9rem;
  background: var(--panel);
  border-top: 1px solid var(--edge-soft);
}
.shot-run .say { margin-left: auto; font-size: .78rem; color: var(--muted) }
.shot-run .say.pass { color: var(--green, #3fb950) }
.shot-out { background: var(--inset); display: flex; flex-direction: column }
/* The card must not change height when you switch tabs or open a hint: the hero
   is centred, so a taller panel would shove the headline down the page. */
#d-panel { height: 8.5rem; overflow: auto }
.shot-tabs {
  display: flex;
  align-items: stretch;
  padding: 0 .4rem;
  background: var(--panel);
  border-bottom: 1px solid var(--edge);
  font-size: .78rem;
  color: var(--muted);
}
.shot-tabs span { padding: .45rem .6rem }
.shot-tabs .right { display: flex; margin-left: auto; padding: 0 }
.shot-tabs .on { color: var(--rust); border-bottom: 2px solid var(--rust) }
.shot-tabs .right { margin-left: auto; display: flex; padding: 0 }
.lp-shot .problem { display: block; padding: .7rem .9rem; font-family: var(--font-code); font-size: .84rem }
.lp-shot .problem .head { display: flex; align-items: baseline; gap: .55rem; flex-wrap: wrap }
.lp-shot .problem .what { font-weight: 700; color: var(--fg) }
.lp-shot .problem .code {
  border: 1px solid var(--red);
  background: color-mix(in srgb, var(--red) 15%, transparent);
  color: var(--red);
  font-weight: 700;
  font-size: .72rem;
  padding: .05rem .35rem;
}
.lp-shot .problem .where { color: var(--muted); font-size: .72rem }
.lp-shot .problem .label { display: block; margin-top: .25rem; color: var(--ember) }
.lp-shot .problem .help { display: block; margin-top: .3rem; color: var(--info) }

/* ── the bands below the fold ── */
.lp-band { padding: 4.5rem 4rem; border-bottom: 1px solid var(--edge) }
.lp-kicker {
  margin: 0 0 1.75rem;
  font-size: .84rem;
  font-weight: 600;
  letter-spacing: .01em;
  color: var(--muted);
  text-transform: none;
}
.lp-kicker-row { display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem }
.lp-kicker-row .lp-kicker { margin-bottom: 1.75rem }
.lp-aside { font-size: .82rem; color: var(--muted) }

.lp-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--edge);
}
.lp-steps li { padding: 1.75rem; border-right: 1px solid var(--edge-soft) }
.lp-steps li:first-child { padding-left: 0 }
.lp-steps li:last-child { padding-right: 0; border-right: 0 }
.lp-steps .n { font-size: .82rem; font-weight: 600; color: var(--muted); font-family: var(--font-code) }
.lp-steps h3 { margin: .75rem 0 .5rem; font-size: 1.2rem; font-weight: 600 }
.lp-steps p { margin: 0; color: var(--muted); font-size: .92rem; line-height: 1.6; text-wrap: pretty }

.lp-lead {
  margin: 0 0 2.5rem;
  max-width: 24ch;
  font-size: 1.85rem;
  line-height: 1.4;
  font-weight: 600;
  letter-spacing: -.015em;
  color: var(--muted);
  text-wrap: pretty;
}
.lp-lead b { color: var(--fg); font-weight: 600 }

.lp-chapters { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: 1rem }
.lp-chapters span {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 34px;
  padding: 0 .6rem;
  font-family: var(--font-code);
  font-size: .82rem;
  border: 1px solid var(--edge-soft);
  color: var(--edge);
}
.lp-chapters .done { border-color: var(--edge); color: var(--muted) }
.lp-chapters .here {
  border-color: var(--rust);
  background: color-mix(in srgb, var(--rust) 10%, transparent);
  color: var(--rust);
}
.lp-legend { display: flex; align-items: center; gap: .5rem; margin: 0 0 2.5rem;
  font-size: .82rem; color: var(--muted) }
.lp-legend i { width: 10px; height: 10px; background: var(--rust); display: block }
.lp-legend code { font-family: var(--font-code); color: var(--fg) }

.lp-two { display: grid; grid-template-columns: repeat(2, minmax(0, 36ch)); gap: 3.5rem }
.lp-two p { margin: 0; color: var(--muted); font-size: .96rem; line-height: 1.6; text-wrap: pretty }

.lp-topics {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0 2rem;
  border-top: 1px solid var(--edge);
}
.lp-topics div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .75rem;
  padding: .6rem 0;
  border-bottom: 1px solid var(--edge-soft);
  font-size: .88rem;
}
.lp-topics .n { font-family: var(--font-code); font-size: .78rem; color: var(--muted) }

/* ── what people say about rustlings ───────────────────────────────────────
   Quotes from public pages, each card showing that page's own screenshot and
   linking to it. The strip loops because the cards are in the DOM twice; the
   second copy is aria-hidden so nothing is read out twice. It stops on hover,
   on focus, and under prefers-reduced-motion, where it scrolls by hand. */
.lp-marquee {
  border-top: 1px solid var(--edge);
  padding-top: 1.5rem;
  overflow: hidden;
  /* the strip is far wider than the page; without this its width would be the
     section's width, and every band on the page would stretch to match */
  contain: inline-size;
  /* the ends fade out rather than cutting a card in half */
  mask-image: linear-gradient(to right, transparent, #000 4rem, #000 calc(100% - 4rem), transparent);
}
.lp-track {
  display: flex;
  width: max-content;
  animation: lp-drift 120s linear infinite;
}
.lp-marquee:hover .lp-track,
.lp-marquee:focus-within .lp-track { animation-play-state: paused }
.lp-run { display: flex; gap: 1rem; padding-right: 1rem }
@keyframes lp-drift {
  from { transform: translateX(-50%) }
  to { transform: translateX(0) }
}
.lp-say {
  display: block;
  flex: 0 0 260px;
  border: 1px solid var(--edge);
  border-radius: var(--r);
  background: var(--panel);
  color: inherit;
  text-decoration: none;
  overflow: hidden;
}
.lp-say:hover { background: var(--panel-hi) }
.lp-say img {
  display: block;
  width: 100%;
  height: 120px;
  object-fit: cover;
  object-position: top left;
  border-bottom: 1px solid var(--edge);
}
.lp-say .q { margin: .8rem .9rem .5rem; font-size: .88rem; line-height: 1.5; color: var(--fg) }
.lp-say .by {
  margin: 0 .9rem .9rem;
  font-family: var(--font-code);
  font-size: .72rem;
  color: var(--muted);
}
.lp-say .by b { color: var(--fg); font-weight: 600 }

/* The strip stands still and is scrolled by hand. The duplicate copy of the
   cards exists only to close the loop, so it goes with the loop. This block
   sits after the rules it overrides, which is the only reason it wins. */
@media (prefers-reduced-motion: reduce) {
  .lp-marquee { overflow-x: auto; mask-image: none }
  .lp-track { animation: none }
  .lp-track > [aria-hidden="true"] { display: none }
}

.lp-for { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem; align-items: start }
.lp-for p { margin: 0; font-size: 1.06rem; line-height: 1.55; color: var(--muted); text-wrap: pretty }
.lp-for b { color: var(--fg); font-weight: 600 }

.lp-faq { max-width: 760px; border-top: 1px solid var(--edge) }
.lp-faq details { border-bottom: 1px solid var(--edge-soft); padding: 1rem 0 }
.lp-faq summary { cursor: pointer; font-size: 1rem; font-weight: 600; list-style: none }
.lp-faq summary::-webkit-details-marker { display: none }
.lp-faq summary::after { content: " +"; color: var(--muted); font-family: var(--font-code) }
.lp-faq details[open] summary::after { content: " −" }
.lp-faq p { margin: .6rem 0 0; color: var(--muted); font-size: .92rem; line-height: 1.6 }

.lp-last {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding: 3.5rem 4rem;
  border-bottom: 1px solid var(--edge);
}
.lp-last .big { margin: 0 0 .35rem; font-size: 1.6rem; font-weight: 700; letter-spacing: -.02em }
.lp-last .small { margin: 0; color: var(--muted); font-size: .94rem }
.lp-last .btn { height: 46px; padding: 0 1.5rem; font-size: .94rem; flex: none }

.lp-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.5rem 4rem;
  background: var(--panel);
  color: var(--muted);
  font-size: .78rem;
}
.lp-foot .mark { display: inline-flex; align-items: center; gap: .5rem; font-family: var(--font-code) }
.lp-foot .crab { width: 16px; height: 16px; opacity: .8 }
.lp-foot nav { display: flex; gap: 1.25rem }
.lp-foot a { color: var(--muted); text-decoration: none; border-bottom: 1px solid transparent }
.lp-foot a:hover { color: var(--fg); border-bottom-color: var(--edge) }

.landing .brand .crab { width: 22px; height: 22px }

/* ── narrower: the shot goes under the pitch, the grids collapse ── */
@media (max-width: 1099px) {
  .lp-hero { grid-template-columns: 1fr; gap: 2.5rem; padding: 3.5rem 2.5rem }
  .lp-pitch h1 { font-size: 2.6rem }
  .lp-band, .lp-last { padding: 3.5rem 2.5rem }
  .lp-foot { padding: 1.5rem 2.5rem }
  .lp-topics { grid-template-columns: repeat(2, 1fr) }
  .lp-for { grid-template-columns: 1fr; gap: 1.4rem }
  .lp-for p { font-size: 1.15rem }
}

@media (max-width: 767px) {
  .lp-top { padding: 0 1.1rem }
  .lp-top .btn { height: 34px; padding: 0 .7rem; font-size: .8rem }
  .lp-hero { padding: 2.5rem 1.25rem; gap: 2rem }
  .lp-pitch h1 { font-size: 2.05rem }
  .lp-pitch p { font-size: 1rem }
  .lp-cta { flex-direction: column; align-items: stretch }
  .lp-cta .btn { justify-content: center; height: 48px }
  .lp-band, .lp-last { padding: 2.5rem 1.25rem }
  .lp-steps { grid-template-columns: 1fr }
  .lp-topics { grid-template-columns: repeat(2, 1fr); gap: 0 1.25rem }
  /* A phone hero that starts on a sentence cut mid-word is a bad first line. */
  .shot-code { font-size: .76rem }
  .lp-topics div { font-size: .82rem }
  .lp-kicker-row { flex-direction: column; gap: .2rem }
  /* a narrow screen cannot spare 4rem of fade at each end */
  .lp-marquee { mask-image: linear-gradient(to right, transparent, #000 1.5rem, #000 calc(100% - 1.5rem), transparent) }
  .lp-say { flex-basis: 240px }
  .lp-kicker-row .lp-kicker { margin-bottom: .3rem }
  .lp-steps li { padding: 1.4rem 0; border-right: 0; border-bottom: 1px solid var(--edge-soft) }
  .lp-steps li:last-child { border-bottom: 0 }
  .lp-lead { font-size: 1.4rem; max-width: none }
  .lp-two { grid-template-columns: 1fr; gap: 1.2rem }
  .lp-for p { font-size: 1.05rem }
  .lp-last { flex-direction: column; align-items: stretch; text-align: left }
  .lp-last .btn { justify-content: center }
  .lp-foot { flex-direction: column; align-items: flex-start; gap: 1rem; padding: 1.5rem 1.25rem }
  /* the code sample scrolls rather than squeezing the page sideways */
  .shot-code .src { overflow-x: auto }
}

/* ── the written pages: terms, privacy, credits ────────────────────────────
   One column, and headings that are the questions people actually ask, each
   answered in a paragraph. A legal page nobody finishes is worse than a short
   one, so there is no contents list, no numbering and no callout furniture:
   the question is the navigation.

   The measure is wider than prose typography would pick. These are documents
   people scan for one answer, not essays read start to finish, and the extra
   width keeps most answers to two or three lines. */
.doc {
  width: 100%;
  max-width: 108ch;
  margin: 0 auto;
  padding: 4rem 2rem 4.5rem;
  box-sizing: border-box;
}
.doc-head { padding-bottom: .9rem; border-bottom: 1px solid var(--edge) }
.doc-head h1 { margin: 0 0 .4rem; font-size: 1.5rem; font-weight: 700; letter-spacing: -.02em }
.doc-date { margin: 0; font-size: .82rem; color: var(--muted) }

.doc h2 { margin: 1.75rem 0 .5rem; font-size: 1rem; font-weight: 600 }
.doc h2:first-of-type { margin-top: 2rem }
.doc p { margin: 0; color: var(--muted); font-size: .95rem; line-height: 1.65; text-wrap: pretty }
.doc p + p { margin-top: .7rem }
.doc ul { margin: .7rem 0 0; padding-left: 1.1rem }
.doc li { margin: 0 0 .35rem; color: var(--muted); font-size: .95rem; line-height: 1.65 }
.doc b { color: var(--fg); font-weight: 600 }
.doc a { color: var(--fg); text-decoration: none; border-bottom: 1px solid var(--edge) }
.doc a:hover { color: var(--rust); border-bottom-color: var(--rust) }
.doc code {
  font-family: var(--font-code);
  font-size: .92em;
  background: var(--panel-hi);
  border-radius: 4px;
  padding: .05rem .3rem;
}

/* The one thing that cannot be paraphrased: a licence reproduced verbatim.
   Folded away so it does not become the page. */
.doc-licence { margin: .8rem 0 0 }
.doc-licence summary {
  cursor: pointer;
  list-style: none;
  font-family: var(--font-code);
  font-size: .78rem;
  color: var(--muted);
}
.doc-licence summary::marker, .doc-licence summary::-webkit-details-marker { display: none }
.doc-licence summary::before { content: '+ '; color: var(--rust) }
.doc-licence[open] summary::before { content: '- ' }
.doc-licence pre {
  margin: .7rem 0 0;
  padding: 1rem 1.1rem;
  overflow-x: auto;
  background: var(--inset);
  border: 1px solid var(--edge-soft);
  border-radius: var(--r, 6px);
  font-family: var(--font-code);
  font-size: .72rem;
  line-height: 1.65;
  color: var(--muted);
  white-space: pre-wrap;
}

.doc-close {
  margin: 2.25rem 0 0 !important;
  padding-top: 1rem;
  border-top: 1px solid var(--edge-soft);
  font-size: .85rem !important;
}

/* The page you are on is the one that is not a link. */
.lp-foot nav .here { color: var(--fg) }

@media (max-width: 767px) {
  .doc { padding: 2.5rem 1.25rem 3.5rem }
  .doc-head h1 { font-size: 1.3rem }
}
