/* ==========================================================================
   Idea to Life — the static half of the page.

   There is no landing any more. `/` is the application, and this file dresses
   what continues below it: three steps, six questions, a footer. One page, one
   scroll, one product — so the rule here is that nothing may look like it came
   from a second site.

   That makes the boundary with `web/src/styles/app.css` the whole design of
   this file, and it is drawn hard:

     • That file owns the document. The palette, the type, the reset, the focus
       ring, the scrollbar and its reserved gutter, the ambient field, and every
       class down to and including `#root` — `.topbar`, `.page`, `.intro`,
       `.display`, `.lede` — are declared there and are not touched here. The
       markup above the story is a plain copy of the app's first screen that
       React throws away on mount; describing it twice is how you get a header
       that jumps at that moment.
     • This file owns `.skip`, `.wrap`, `.story` and everything under them. It
       declares no colour, no radius and no font of its own — it spends the
       variables app.css already put on `:root`, and the two values it genuinely
       needs that nothing else has are prefixed `--story-` so the two halves
       cannot drift apart without somebody noticing.

   `<link rel="stylesheet" href="/landing.css">` is written last, after the
   app's own, which means every selector here outranks its twin in that file.
   That is precisely why there are no twins.

   The scheme is dark. Not "dark by default" — dark. The app is built in one
   palette, the story sits inside the app's page, and a `prefers-color-scheme`
   block here would repaint the working surface above it, not just the reading
   below.
   ========================================================================== */

:root {
  /* The hairline that does all the dividing in this file. It is the only value
     of its own here — the width comes from the app, so the story cannot drift
     off the line the hero and the input box stand on. */
  --story-line: rgba(237, 234, 242, 0.08);

  /* app.css sets `--wrap` to the content column and pads `.page` by
     `--page-pad`; the story is outside `.page` and has to add that padding
     itself, so its box is the column plus both gutters. Same text edge, one
     source of truth. Values are only a fallback for a page without app.css,
     which is not a page this file will ever meet. */
  --story-wrap: calc(var(--wrap, 1180px) + 2 * var(--page-pad, 2rem));
}

/* --- the way in ---------------------------------------------------------- */
/* First thing a keyboard reaches, invisible to everyone else. Above the dialog
   scrim, because it is still the way out of the page. */

.skip {
  position: absolute;
  top: 0;
  left: -9999px;
  z-index: 80;
  padding: 0.7rem 1.1rem;
  border-radius: 0 0 12px 0;
  background: var(--surface-2);
  color: var(--text);
  text-decoration: none;
}

.skip:focus {
  left: 0;
}

/* --- the measure --------------------------------------------------------- */
/* Wider than the 720px the app works in, because three columns of prose want
   the room, and centred on the same axis so the page still reads as one. */

.wrap {
  width: min(var(--story-wrap), 100%);
  margin-inline: auto;
  padding-inline: var(--page-pad);
}

/* Every division in the file is one of these: a hairline the width of the
   text, then air. Not a change of ground — the moment the lower half has a
   background of its own it stops being the same page. */
.story__band > .wrap,
.siteFoot__in {
  border-top: 1px solid var(--story-line);
}

.story__band > .wrap {
  padding-block: clamp(2.75rem, 8vw, 5rem);
}

.story__h {
  margin: 0 0 clamp(1.5rem, 4vw, 2.25rem);
  font-size: clamp(1.5rem, 1.1rem + 1.7vw, 2.125rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  text-wrap: balance;
}

/* --- three steps --------------------------------------------------------- */
/* No boxes. On a ground this dark a card is a lighter rectangle drawn around
   each step, and three of them in a row read as a price table. The number, the
   line and the space between them are enough. */

.steps {
  counter-reset: step;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(1.75rem, 4vw, 2.5rem);
}

@media (min-width: 48rem) {
  .steps {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.step {
  counter-increment: step;
  min-width: 0;
}

.step::before {
  content: counter(step, decimal-leading-zero);
  display: block;
  margin-bottom: 0.85rem;
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.14em;
  color: var(--glow);
}

.step__t {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.3;
}

.step__d {
  margin: 0.55rem 0 0;
  color: var(--muted);
  font-size: 0.9375rem;
  line-height: 1.55;
  text-wrap: pretty;
}

/* --- questions ----------------------------------------------------------- */
/* <details>, so it answers without a line of script — which is not a nicety
   here: the site's CSP forbids an inline one, and a reader who arrives before
   the bundle does should still be able to open a question. */

.faq {
  border-top: 1px solid var(--story-line);
}

.qa {
  border-bottom: 1px solid var(--story-line);
}

/* `list-style` for Firefox's marker, `display: flex` for the WebKit triangle;
   between them the row is ours to draw. */
.qa__q {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-block: 1.15rem;
  list-style: none;
  cursor: pointer;
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  transition: color 0.18s ease;
}

.qa__q::-webkit-details-marker {
  display: none;
}

.qa__q:hover {
  color: var(--glow);
}

/* A plus that becomes a minus. Two bars in one box, and the upright one draws
   itself down to nothing — turning the plus 45° instead would leave a cross,
   which says "close" rather than "collapse". */
.qa__q::after {
  content: '';
  flex: none;
  width: 0.8125rem;
  height: 0.8125rem;
  margin-inline-start: auto;
  background-image: linear-gradient(var(--glow) 0 0), linear-gradient(var(--glow) 0 0);
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100% 1.5px, 1.5px 100%;
  transition: background-size 0.22s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.qa[open] .qa__q::after {
  background-size: 100% 1.5px, 1.5px 0;
}

/* 65ch, because a line of an answer running the full width of a wide monitor
   is one the eye loses on the way back. */
.qa__a {
  margin: 0;
  padding-block: 0 1.35rem;
  padding-inline-end: 2rem;
  max-width: 65ch;
  color: var(--muted);
  font-size: 0.9375rem;
  line-height: 1.6;
  text-wrap: pretty;
}

/* The answer arrives rather than appearing. The height is the browser's to
   animate or not; this is only the content, and only opacity and four pixels
   of it. */
.qa[open] .qa__a {
  animation: qa-open 0.28s cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
}

@keyframes qa-open {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
}

/* --- footer -------------------------------------------------------------- */

.siteFoot {
  color: var(--faint);
  font-size: 0.8125rem;
}

.siteFoot__in {
  display: flex;
  align-items: center;
  gap: 0.75rem 1.5rem;
  padding-block: clamp(1.5rem, 4vw, 2rem) clamp(2rem, 5vw, 3rem);
}

/* Pushed to the far end: the row now reads copyright first, language last. */
.siteFoot__copy {
  margin-inline-end: auto;
}

@media (max-width: 40rem) {
  .siteFoot__in {
    flex-direction: column;
    align-items: flex-start;
  }

}

/* --- the thirteen languages ---------------------------------------------- */
/* A <details> holding thirteen ordinary <a href="/xx/">. Not a scripted menu:
   the CSP forbids an inline script, and a crawler that cannot reach the other
   twelve pages from this one is a crawler that indexes one language. */

.siteFoot__lang {
  position: relative;
}

.siteFoot__langNow {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.35rem 0.8rem;
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--muted);
  list-style: none;
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease;
}

.siteFoot__langNow::-webkit-details-marker {
  display: none;
}

.siteFoot__langNow:hover {
  background: var(--surface-2);
  color: var(--text);
}

.siteFoot__langNow::after {
  content: '';
  width: 0.4rem;
  height: 0.4rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-0.1rem) rotate(45deg);
  transition: transform 0.18s ease;
}

.siteFoot__lang[open] .siteFoot__langNow::after {
  transform: translateY(0.08rem) rotate(225deg);
}

/* Upward, because it is the last thing on the page and there is nothing below
   it to open into. */
.langs {
  position: absolute;
  bottom: calc(100% + 0.5rem);
  left: 0;
  z-index: 5;
  min-width: 11rem;
  max-height: 60vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  list-style: none;
  margin: 0;
  padding: 0.375rem;
  display: grid;
  gap: 2px;
  border-radius: var(--r-card);
  background: var(--surface-2);
  box-shadow: var(--lift), 0 0 0 1px rgba(192, 169, 255, 0.08);
  animation: langs-open 0.16s ease backwards;
}

.langs a {
  display: block;
  padding: 0.4rem 0.625rem;
  border-radius: 10px;
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.langs a:hover {
  background: var(--surface-3);
  color: var(--text);
}

.langs a[aria-current='page'] {
  color: var(--glow);
}

@keyframes langs-open {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
}

/* --- reduced motion ------------------------------------------------------ */
/* app.css already flattens everything with an `!important` sweep, and this
   file is read after it. Naming the moving parts here costs nothing and means
   the rule survives that sweep being narrowed. */

@media (prefers-reduced-motion: reduce) {
  .qa[open] .qa__a,
  .langs {
    animation: none;
  }

  .qa__q,
  .qa__q::after,
  .siteFoot__langNow,
  .siteFoot__langNow::after {
    transition: none;
  }
}

/* --- print --------------------------------------------------------------- */

@media print {
  .skip,
  .siteFoot__lang {
    display: none;
  }
}
