/* Look Who's Talking — site styles.
 *
 * Hand-written rather than a framework or a CDN: the site is five static pages,
 * so a few hundred bytes of CSS is smaller, faster and has no external runtime
 * dependency. Tailwind's play CDN is documented as development-only and ships a
 * runtime compiler, which is why it was rejected — see specs/Project_Decisions.md.
 *
 * Mobile-first: most visitors arrive from the Play Store listing on a phone.
 */

:root {
  --ink: #1c1b1f;
  --ink-soft: #5a565e;
  --paper: #ffffff;
  --paper-soft: #f6f4f7;
  --line: #e3e0e6;
  --coral: #d1563f;
  --coral-ink: #ffffff;
  --teal: #16706b;
  --radius: 14px;
  --measure: 44rem;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #eceaf0;
    --ink-soft: #a9a4b0;
    --paper: #16151a;
    --paper-soft: #1e1d24;
    --line: #322f39;
    --coral: #e5806b;
    --coral-ink: #2a1109;
    --teal: #63c6bd;
  }
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3 { line-height: 1.2; margin: 0 0 0.6em; }
h1 { font-size: clamp(1.75rem, 5vw, 2.6rem); }
h2 { font-size: clamp(1.25rem, 3.4vw, 1.6rem); margin-top: 2.2em; }
h3 { font-size: 1.06rem; }
p { margin: 0 0 1em; }

a { color: var(--coral); }
a:hover { text-decoration: none; }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.92em;
  background: var(--paper-soft);
  padding: 0.1em 0.35em;
  border-radius: 5px;
  word-break: break-word;
}

.wrap { width: min(100% - 2.5rem, var(--measure)); margin-inline: auto; }
.wrap--wide { --measure: 62rem; }

/* ── Header ─────────────────────────────────────────────────────────────── */

.site-header {
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  background: var(--paper);
  z-index: 10;
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 3.75rem;
  flex-wrap: wrap;
}

.brand {
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
  font-size: 1.02rem;
}

.site-nav { display: flex; gap: 1.1rem; flex-wrap: wrap; }
.site-nav a { color: var(--ink-soft); text-decoration: none; font-size: 0.95rem; }
.site-nav a:hover, .site-nav a[aria-current="page"] { color: var(--coral); }

/* ── Hero ───────────────────────────────────────────────────────────────── */

.hero { padding: 3rem 0 1rem; text-align: center; }
.hero p.lede { font-size: 1.1rem; color: var(--ink-soft); }

.button {
  display: inline-block;
  background: var(--coral);
  color: var(--coral-ink);
  text-decoration: none;
  font-weight: 600;
  padding: 0.8rem 1.4rem;
  border-radius: 999px;
  border: 1px solid transparent;
}
.button[aria-disabled="true"] {
  background: var(--paper-soft);
  color: var(--ink-soft);
  border-color: var(--line);
  cursor: not-allowed;
}
.button--ghost { background: transparent; color: var(--coral); border-color: var(--line); }

.hero-art {
  margin: 2rem auto 0;
  max-width: 22rem;
  aspect-ratio: 9 / 16;
  display: grid;
  place-items: center;
  background: var(--paper-soft);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  color: var(--ink-soft);
  font-size: 0.9rem;
  padding: 1rem;
  text-align: center;
}

/* ── Sections and cards ─────────────────────────────────────────────────── */

section { padding: 1.5rem 0; }

.steps { counter-reset: step; list-style: none; padding: 0; display: grid; gap: 1rem; }
.steps li {
  counter-increment: step;
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem 1.1rem 1rem 3.2rem;
  position: relative;
}
.steps li::before {
  content: counter(step);
  position: absolute;
  left: 1rem;
  top: 1rem;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: var(--teal);
  color: var(--paper);
  display: grid;
  place-items: center;
  font-size: 0.85rem;
  font-weight: 700;
}
.steps strong { display: block; }

.grid { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 40rem) { .grid--2 { grid-template-columns: 1fr 1fr; } }

.card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.2rem;
  background: var(--paper);
}
.card h3 { margin-top: 0; }
.card .price { font-size: 1.6rem; font-weight: 700; margin: 0.2rem 0 0.6rem; }
.card ul { padding-left: 1.1rem; margin: 0 0 0.8rem; }
.card li { margin: 0.3rem 0; }
.card--featured { border-color: var(--coral); }

.notice {
  border: 1px solid currentColor;
  border-radius: var(--radius);
  padding: 0.85rem 1rem;
  margin: 1.25rem 0;
  background: var(--paper-soft);
}

.meta { color: var(--ink-soft); font-size: 0.9rem; }

.cta {
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.5rem;
  text-align: center;
  margin: 2rem 0;
}

details { border-bottom: 1px solid var(--line); padding: 0.8rem 0; }
summary { cursor: pointer; font-weight: 600; }
details p { margin-top: 0.6rem; }

/* ── Footer ─────────────────────────────────────────────────────────────── */

.site-footer {
  border-top: 1px solid var(--line);
  margin-top: 3rem;
  padding: 1.75rem 0 3rem;
  font-size: 0.92rem;
  color: var(--ink-soft);
}
.site-footer nav { display: flex; gap: 1.1rem; flex-wrap: wrap; margin-bottom: 0.6rem; }
.site-footer a { color: var(--ink-soft); }

ul, ol { padding-left: 1.15rem; }
li { margin: 0.35rem 0; }

/* ── Screenshot gallery ──────────────────────────────────────────────────────
   A horizontal scroller: phone screenshots keep their shape, and a tall stack of
   540x960 images would otherwise dominate the page. No JavaScript, because the
   whole site is hand-written with no build step, and a gallery is not a reason to
   introduce one. */

.gallery { margin: 1.2rem 0 0.6rem; }

.gallery__track {
  display: flex;
  gap: 0.9rem;
  overflow-x: auto;
  padding-bottom: 0.8rem;          /* room for the scrollbar, so it does not clip */
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.shot { margin: 0; flex: 0 0 auto; scroll-snap-align: start; }

.shot img {
  display: block;
  width: 216px;                    /* 540 / 2.5 — crisp on a 2x screen, small on disk */
  height: 384px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: #0f1117;             /* the app's own colour, so a slow image is not white */
}

/* A KEYBOARD USER CANNOT DRAG A SCROLLER. The track is focusable (tabindex in the
   markup) so the arrow keys scroll it; this makes that focus visible rather than
   invisible. */
/* A KEYBOARD USER CANNOT DRAG A SCROLLER. The track is focusable (tabindex in the
   markup) so the arrow keys scroll it — which is worth nothing if the focus ring is
   invisible.

   NOTE: the first version of this had a comment sitting between the two selectors,
   which made it ONE selector list and gave the spacer the focus rule's body. Two
   rules written as one, silently. */
.gallery__track:focus-visible {
  outline: 2px solid var(--coral);
  outline-offset: 3px;
}

/* A trailing spacer so the last screenshot is not flush against the edge when the
   row is scrolled to the end. */
.gallery__end { flex: 0 0 0.2rem; }

@media (min-width: 40rem) {
  .shot img { width: 270px; height: 480px; }
}

@media (prefers-reduced-motion: no-preference) {
  .gallery__track { scroll-behavior: smooth; }
}

/* ── Brand with logo (added 4 Nov 2026) ──────────────────────────────────────
   The icon is the Play Store icon, copied from store/icon_512.png. 512x512 at 28px
   display size is heavier than it needs to be, but it is the same file already
   published on Play, so the site and the store listing cannot drift apart. */
.brand { display: inline-flex; align-items: center; gap: 0.6rem; }
/* 28px read as an afterthought. 44px is a wordmark's height, which is what this is.
   The MARK (256px, 11 KB) rather than the 512px store icon: same artwork, half the
   bytes, and it is the file the app itself uses. */
.brand img {
  width: 44px; height: 44px;
  border-radius: 11px;
  display: block;
}

/* ── Carousel (added 4 Nov 2026, revised the same day) ──────────────────────
   Jack's feedback on the first version, all four points acted on:

   1. "the middle screenshot does not automatically enlarge" — it was scaling 0.92
      to 1.12, a 12% difference nobody can see. THE RATIO WAS WRONG, not the
      mechanism. Now 0.62 -> 1.0, which is unmistakable, and the base image is
      larger to begin with.
   2. "superimposed arrows to the left and right instead of a scroll bar" — the
      arrows are absolutely positioned over the images and the scroll bar is gone
      entirely (hidden on all three engines, because `scrollbar-width` alone leaves
      WebKit's).

   Scaling still cannot escape the row width, so the lightbox remains the real
   answer to readability; this is emphasis, not enlargement. */

.gallery { position: relative; }

/* The scaled-up slide needs vertical room, and `overflow-x: auto` on the track forces
   `overflow-y` to a scrolling value too — so without this padding the enlarged image
   is clipped top and bottom. */
.gallery__viewport { position: relative; overflow: hidden; margin: -1.4rem 0; }
.gallery__track {
  padding: 1.4rem 0;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;           /* Firefox */
  -ms-overflow-style: none;        /* legacy Edge/IE */
}
.gallery__track::-webkit-scrollbar { display: none; }   /* Chrome, Safari, Edge */

/* ⚠️ SCOPED TO `.js`. Without this the dimming applies unconditionally, and a browser
   with scripting off — or a script that fails — leaves EVERY screenshot dimmed with no
   active slide, because nothing adds `.is-active`. The carousel must look whole without
   JavaScript; the scaling is the enhancement, not the baseline. */
.js .shot {
  scroll-snap-align: center;
  transition: transform 260ms ease, opacity 260ms ease;
  transform: scale(0.62);
  opacity: 0.45;
}
.js .shot.is-active { transform: scale(1); opacity: 1; }

.shot img {
  display: block;
  width: 280px; height: 498px;
  cursor: zoom-in;
}
.shot figcaption {
  margin-top: 0.55rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink);
  text-align: center;
  width: 280px;
}

@media (prefers-reduced-motion: reduce) {
  .js .shot { transition: none; }
  .gallery__track { scroll-behavior: auto; }
}

/* ── Arrows, superimposed on the images ───────────────────────────────────── */
.carousel__arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: 3rem; height: 3rem;
  padding: 0;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.92);
  color: var(--ink);
  font-size: 1.5rem; line-height: 1;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.22);
  cursor: pointer;
  display: grid; place-items: center;
}
.carousel__arrow:hover { background: #fff; border-color: var(--coral); color: var(--coral); }
.carousel__arrow:disabled { opacity: 0.35; cursor: default; }
.carousel__arrow[data-carousel-prev] { left: 0.2rem; }
.carousel__arrow[data-carousel-next] { right: 0.2rem; }

@media (prefers-color-scheme: dark) {
  .carousel__arrow { background: rgba(30, 29, 36, 0.92); }
  .carousel__arrow:hover { background: #1e1d24; }
}

/* dots stay beneath the row */
.carousel__controls {
  display: flex; align-items: center; justify-content: center;
  gap: 0.75rem; margin-top: 0.9rem;
}
.dots { display: flex; gap: 0.4rem; }
.dots__dot {
  width: 0.5rem; height: 0.5rem; padding: 0;
  border-radius: 999px; border: 0;
  background: var(--line); cursor: pointer;
}
.dots__dot.is-active { background: var(--coral); width: 1.25rem; }

/* ── Lightbox (added 4 Nov 2026, revised the same day) ───────────────────────
   Jack: "it does open fully when clicked, but there's no centering of the image, and
   no obvious way back. Escape does work, but perhaps a back arrow might be more
   intuitive."

   So: flex centring stated explicitly rather than relying on `place-items` (which
   centres grid items but was evidently not landing), and TWO visible ways out — a
   back arrow at the top left and a close cross at the top right. Escape still works,
   and so does clicking the backdrop. */
.lightbox {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(8, 8, 10, 0.94);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 3.5rem 1rem 1.5rem;
}
.lightbox.is-open { display: flex; }
.lightbox img {
  display: block;
  margin: auto;
  max-width: min(92vw, 560px);
  max-height: calc(100vh - 6rem);
  width: auto; height: auto;
  border-radius: 14px;
  cursor: zoom-out;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
}
.lightbox__back,
.lightbox__close {
  position: absolute;
  top: 0.9rem;
  width: 2.75rem; height: 2.75rem;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.4);
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  font-size: 1.3rem; line-height: 1;
  cursor: pointer;
  display: grid; place-items: center;
}
.lightbox__back { left: 0.9rem; }
.lightbox__close { right: 0.9rem; font-size: 1.5rem; }
.lightbox__back:hover,
.lightbox__close:hover { background: rgba(255, 255, 255, 0.18); }

/* ── Hero image (added 4 Nov 2026) ───────────────────────────────────────────
   `.hero-art` was written for a DASHED PLACEHOLDER: a 9:16 box with centred text and
   a dashed border. Now that a real screenshot fills it, the dashed border and the
   fixed aspect-ratio are wrong — the border would frame the image as if it were still
   missing, and the aspect ratio fights the image's own.
   Overridden here rather than edited above, so the placeholder's intent stays
   readable in the history. */
.hero-art {
  aspect-ratio: auto;
  border: 0;
  padding: 0;
  display: block;
  max-width: 19rem;
}
.hero-art img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 22px;
  border: 1px solid var(--line);
  background: #0f1117;              /* the app's own colour, so a slow load is not white */
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.18);
}
