/*
 * The app's two typefaces, served from this site's own files: no request leaves for a font host.
 * Both are variable fonts under the SIL Open Font License, whose text is beside each file.
 */
@font-face {
  font-family: "Space Grotesk";
  src: url("../fonts/space-grotesk.ttf") format("truetype");
  font-weight: 300 700;
  font-display: swap;
}
@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../fonts/plus-jakarta-sans.ttf") format("truetype");
  font-weight: 200 800;
  font-display: swap;
}

/*
 * All brand values live in this one block. Rebranding the site is editing these tokens plus the
 * `site-config` script in each page — nothing else hardcodes a colour or a name.
 *
 * The colours are the app's: the light theme's here, the dark theme's below, role for role with
 * the design system in :core:designsystem. Change them there first.
 */
:root {
  --brand: #0369a1;
  --brand-strong: #027dbc;
  --accent: #7c3aed;
  --success: #05875f;
  --bg: #f8fafc;
  --surface: #ffffff;
  --ink: #131b2e;
  --ink-muted: #5b697e;
  --border: #e2e8f0;
  --glow: rgba(2, 132, 199, 0.18);
  --on-brand: #ffffff;
  --on-accent: #ffffff;
  --radius: 16px;
  --border-width: 1.5px;
  --max-width: 1080px;
  --mark: url("../images/assets/app-mark.svg");
  --font-body: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-heading: "Space Grotesk", var(--font-body);
}

@media (prefers-color-scheme: dark) {
  :root {
    --brand: #00f0ff;
    --brand-strong: #00f0ff;
    --accent: #dcb8ff;
    --success: #33fb0a;
    --bg: #0f131d;
    --surface: #171b26;
    --ink: #dfe2f1;
    --ink-muted: #b9cacb;
    --border: #263554;
    --glow: rgba(0, 240, 255, 0.22);
    --on-brand: #0f131d;
    --on-accent: #0f131d;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--font-heading); }

a { color: var(--brand); }

.wrap { max-width: var(--max-width); margin: 0 auto; padding: 0 24px; }

header.site {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 0;
}
header.site strong {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-heading);
  font-size: 1.1rem;
}
/* The name leads home, from every page; it keeps the look of a name, not of a link. */
header.site a.home { color: inherit; text-decoration: none; border-radius: 8px; }
header.site a.home:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
/* The app's mark, beside its name wherever the header is. */
header.site strong::before {
  content: "";
  width: 36px;
  height: 36px;
  flex: none;
  background: var(--mark) center / contain no-repeat;
}
header.site nav a { margin-left: 20px; text-decoration: none; font-weight: 500; }

.hero {
  padding: 72px 0 56px;
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 48px;
  align-items: center;
}
.hero h1 {
  font-size: clamp(2.1rem, 5vw, 3.4rem);
  line-height: 1.1;
  margin: 0 0 16px;
  letter-spacing: -0.02em;
}
.hero p.lede { font-size: 1.15rem; color: var(--ink-muted); margin: 0 0 28px; }

.badge img { height: 56px; width: auto; }

/* The way to Google Play, as Morseify's site has it: a pill in the signal gradient with the app's play
   mark, lifted by a soft halo. The official badge closes the page. */
.play-button, .play-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  border-radius: 999px;
  font-family: var(--font-heading);
  font-weight: 700;
  text-decoration: none;
  color: var(--on-brand);
  background: linear-gradient(135deg, var(--brand) 0%, var(--accent) 100%);
  box-shadow: 0 18px 44px var(--glow);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.play-button { padding: 16px 28px; font-size: 1.05rem; }
.play-pill { padding: 8px 16px; font-size: 0.9rem; box-shadow: 0 10px 24px var(--glow); }
.play-button:hover, .play-pill:hover { transform: translateY(-2px); box-shadow: 0 22px 50px var(--glow); }
.play-button:focus-visible, .play-pill:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.play-icon {
  width: 22px;
  height: 22px;
  flex: none;
  background: currentColor;
  -webkit-mask: url("../images/marks/play.svg") center / contain no-repeat;
  mask: url("../images/marks/play.svg") center / contain no-repeat;
}
.play-pill .play-icon { width: 18px; height: 18px; }
header.site nav a.play-pill { color: var(--on-brand); }
@media (prefers-reduced-motion: reduce) {
  .play-button, .play-pill { transition: none; }
  .play-button:hover, .play-pill:hover { transform: none; }
}

/* A screenshot keeps the phone's own shape, 1078 by 2399, at whatever width it is given. The hero's
   columns and the screenshots may shrink below their natural width, or two of them push the page
   wider than the window. */
.hero > * { min-width: 0; }
.shots { display: flex; gap: 16px; }
.shots img { flex: 1 1 0; min-width: 0; }
.shots img, .gallery img {
  height: auto;
  aspect-ratio: 1078 / 2399;
}
.shots img {
  width: 100%;
  max-width: 260px;
  border-radius: var(--radius);
  border: var(--border-width) solid var(--border);
  background: var(--surface);
  box-shadow: 0 0 32px var(--glow);
}

/* More of the app, in phone frames: three across, or one beside the next to swipe on a phone. */
.gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.gallery figure { margin: 0; }
.gallery img {
  display: block;
  width: 100%;
  border-radius: 28px;
  border: 6px solid var(--surface);
  outline: var(--border-width) solid var(--border);
  box-shadow: 0 0 32px var(--glow);
}
.gallery figcaption { margin-top: 12px; text-align: center; font-size: 0.9rem; color: var(--ink-muted); }
.gallery:focus-visible { outline: 2px solid var(--brand); outline-offset: 6px; border-radius: 8px; }

/* The page's last word: where to get the app. */
section.get { text-align: center; }
section.get p { color: var(--ink-muted); margin: 0 0 20px; }

section { padding: 56px 0; border-top: var(--border-width) solid var(--border); }
section h2 { font-size: 1.6rem; margin: 0 0 24px; letter-spacing: -0.01em; }

.features { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.card {
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
}
.card h3 { margin: 0 0 8px; font-size: 1.05rem; }
.card p { margin: 0; color: var(--ink-muted); font-size: 0.95rem; }

footer.site {
  border-top: var(--border-width) solid var(--border);
  padding: 32px 0 56px;
  color: var(--ink-muted);
  font-size: 0.9rem;
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: space-between;
}
footer.site a { margin-right: 16px; }

article.legal { padding: 48px 0 72px; max-width: 720px; }
article.legal h1 { font-size: 2rem; }
article.legal h2 { font-size: 1.25rem; margin-top: 32px; }
article.legal li { margin-bottom: 6px; }

@media (max-width: 820px) {
  .hero { grid-template-columns: 1fr; padding-top: 40px; }
  .features { grid-template-columns: 1fr; }
  .shots { justify-content: center; }
  /* Two 260px screenshots plus the gap overflow a phone viewport and push the page sideways.
     Sizing them against the viewport keeps both visible and the body free of horizontal scroll. */
  .shots img { max-width: min(260px, 44vw); }
  .gallery {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 68%;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding: 4px 4px 12px;
  }
  .gallery figure { scroll-snap-align: center; }
  header.site nav a.play-pill { display: none; }
}

/* ── The Path ──────────────────────────────────────────────────────────────
   Every Topic in order, as the app's Path draws it: a round node holding the Topic's symbol, set
   centre, right, centre, left in turn, ringed in the three signal colours in turn, with a mark on
   its rim; a card under it; and a dashed curve from under each card to the next node. The Topic to
   start is larger, haloed and headed "Up next". It sits in a box of its own height that scrolls,
   so the page stays short. Nothing moves. */
.path-intro { margin: 0 0 8px; color: var(--ink-muted); max-width: 640px; }
.trail-scroll {
  max-height: min(720px, 75vh);
  overflow-y: auto;
  overscroll-behavior: contain;
  margin-top: 24px;
  padding: 24px 20px 32px;
  background: var(--bg);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
}
.trail-scroll:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; }
.trail-canvas { position: relative; max-width: 560px; margin: 0 auto; }
.trail-canvas svg.links { position: absolute; top: 0; left: 0; overflow: visible; pointer-events: none; }
.link { fill: none; stroke-width: 5; stroke-linecap: round; stroke-dasharray: 7 16; }
.link.is-brand { stroke: var(--brand); }
.link.is-accent { stroke: var(--accent); }
.link.is-success { stroke: var(--success); }
.link.is-ahead { stroke: var(--border); }
.trail { list-style: none; margin: 0; padding: 0; position: relative; }
.stop { --node: 72px; --symbol-size: 32px; margin: 0 0 64px; }
.stop:last-child { margin-bottom: 0; }
.stop.is-next { --node: 92px; --symbol-size: 42px; }
.stop[data-accent="brand"] { --ring: var(--brand); }
.stop[data-accent="accent"] { --ring: var(--accent); }
.stop[data-accent="success"] { --ring: var(--success); }
.stop.is-premium { --ring: var(--border); }
.node-row { position: relative; height: var(--node); }
.stop.is-next .node-row { margin-top: 36px; }
.node {
  position: absolute;
  top: 0;
  left: calc((100% - var(--node)) / 2 * (1 + var(--bias)));
  width: var(--node);
  height: var(--node);
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--ring);
  color: var(--ring);
}
.stop.is-premium .node { color: var(--ink-muted); }
.stop.is-next .node { box-shadow: 0 0 0 6px var(--glow), 0 0 28px var(--glow); }
.symbol, .standing-icon {
  background: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat;
  mask: var(--icon) center / contain no-repeat;
}
.symbol { width: var(--symbol-size); height: var(--symbol-size); }
.standing {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--brand);
  color: var(--on-brand);
  border: 2px solid var(--bg);
}
.stop.is-premium .standing { background: var(--accent); color: var(--on-accent); }
.standing-icon { width: 16px; height: 16px; }
.callout {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  padding: 2px 10px;
  border-radius: 6px;
  font: 600 0.8rem/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--accent);
  background: var(--surface);
  border: var(--border-width) solid var(--accent);
}
/* A grid or flex child never shrinks below its longest word by itself, and some Kotlin names are long. */
.stop .card { margin-top: 16px; min-width: 0; }
.stop.is-next .card { border-color: var(--brand); box-shadow: 0 0 0 4px var(--glow); }
.stop .tag {
  display: inline-block;
  margin: 0 0 10px;
  padding: 2px 10px;
  border-radius: 6px;
  font: 600 0.8rem/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  background: var(--brand);
  color: var(--on-brand);
}
.stop.is-premium .tag { background: var(--accent); color: var(--on-accent); }
.stop .card h3 { font-family: var(--font-heading); }
.stop .keywords { margin: 4px 0 8px; font-size: 0.9rem; }
.stop .keywords .sep { margin: 0 0.5em; color: var(--ink-muted); }
.stop.is-premium .keywords code { color: var(--ink-muted); }
.stop .summary { margin: 0; }
.path code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
  color: var(--brand);
  overflow-wrap: anywhere;
}
