/* HuntFix — huntfix.app
   Self-contained. No CDN, no webfonts, no analytics, no framework: the site
   should be able to make the same claim the app does — nothing leaves the
   phone, nothing leaves the browser. System fonts only, which also means it
   renders instantly and looks native on the device most visitors arrive on.

   ---------------------------------------------------------------------------
   THEMES

   The site is authored light-first and ships both. It picks up the visitor's
   own system setting on a first visit and remembers whatever they choose after
   that, exactly the way the app does (brief §45: light and dark are both
   requirements, because a screen that cannot be read in direct sun is no use
   on a hill).

   Every colour is a token. Nothing below the token block names a colour
   directly, so a theme is a list of values rather than a second stylesheet.

   Two accent tokens rather than one, and this is the part worth not undoing:

     --blaze-fill   backgrounds that carry white text, and solid marks
     --blaze-ink    accent *text* sitting on the page ground

   Both are the app's #FF6600 on the dark theme. On light they part company,
   and the reason is size rather than taste.

   **Fills stay #FF6600 on both themes.** Scott's call, and the right one: the
   buttons and the step badges are the site's biggest orange surfaces, they are
   what makes the page read as a New Zealand DOC sign, and they are the same
   colour as the app icon and the MARK TARGET button. White on #FF6600 is
   2.94:1, which is under WCAG's bar — worth knowing, and accepted knowingly on
   a large bold control that is doing brand work. Anyone who wants to trade the
   brand for the bar changes one token and nothing else.

   **Accent text darkens to #C24E00** (4.6:1 on the ground). The eyebrows, the
   SIGHT/RANGE/MARK/RECOVER labels and the card tags are 11–13px uppercase, and
   #FF6600 at that size on off-white is 2.8:1 — not a compliance quibble,
   genuinely hard to read. #C24E00 is the brightest orange that still clears AA
   for text that small.

   The screenshots keep the true #FF6600 whatever the theme, because those are
   photographs of the app and nothing in them may be adjusted. */

:root {
  color-scheme: light;

  --ground:      #FBFAF8;
  --ground-deep: #F3F1EC;
  --card:        #FFFFFF;
  --card-raised: #F7F5F1;
  --rule:        #E4E1DA;

  --blaze:       #FF6600;   /* the app's AccentColor — marks and reference */
  --blaze-fill:  #FF6600;   /* solid fills: the real thing, at real size */
  --blaze-hover: #E05A00;
  --blaze-ink:   #C24E00;   /* accent text on the ground */

  --ink:         #191713;
  --ink-muted:   #56534D;
  --ink-faint:   #736F68;   /* 4.8:1 on the ground — this is body-size text */
  --good:        #2E9E4B;
  --warn:        #B4690E;

  --nav-bg:      rgba(251, 250, 248, 0.88);
  --wash-1:      rgba(255, 102, 0, 0.10);
  --wash-2:      rgba(255, 102, 0, 0.05);
  --shadow-md:   0 14px 34px rgba(25, 23, 19, 0.10);
  --shadow-lg:   0 24px 60px rgba(25, 23, 19, 0.14);

  --wrap: 1080px;
  --radius: 16px;
  --radius-lg: 22px;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* The dark theme. Applied by the toggle, and by the no-JS fallback below for a
   visitor whose system asks for dark. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --ground:      #0A0A0B;
  --ground-deep: #050506;
  --card:        #141417;
  --card-raised: #1C1C21;
  --rule:        #2A2A31;

  --blaze:       #FF6600;
  --blaze-fill:  #FF6600;
  --blaze-hover: #E05A00;
  --blaze-ink:   #FF8534;

  --ink:         #F3F3F5;
  --ink-muted:   #A0A0AA;
  --ink-faint:   #70707C;
  --good:        #34C759;
  --warn:        #FF9F0A;

  --nav-bg:      rgba(10, 10, 11, 0.88);
  --wash-1:      rgba(255, 102, 0, 0.13);
  --wash-2:      rgba(255, 102, 0, 0.06);
  --shadow-md:   0 14px 34px rgba(0, 0, 0, 0.45);
  --shadow-lg:   0 30px 80px rgba(0, 0, 0, 0.60);
}

/* Without JavaScript the head snippet never runs and no data-theme is set, so
   a visitor whose system asks for dark would get the light theme. This mirrors
   the block above for that case only — it is deliberately not the primary
   mechanism, because the toggle has to be able to win. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;
    --ground:      #0A0A0B;
    --ground-deep: #050506;
    --card:        #141417;
    --card-raised: #1C1C21;
    --rule:        #2A2A31;
    --blaze-fill:  #FF6600;
    --blaze-hover: #E05A00;
    --blaze-ink:   #FF8534;
    --ink:         #F3F3F5;
    --ink-muted:   #A0A0AA;
    --ink-faint:   #70707C;
    --good:        #34C759;
    --warn:        #FF9F0A;
    --nav-bg:      rgba(10, 10, 11, 0.88);
    --wash-1:      rgba(255, 102, 0, 0.13);
    --wash-2:      rgba(255, 102, 0, 0.06);
    --shadow-md:   0 14px 34px rgba(0, 0, 0, 0.45);
    --shadow-lg:   0 30px 80px rgba(0, 0, 0, 0.60);
  }
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation: none !important; transition: none !important; }
}

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

a { color: var(--blaze-ink); text-decoration: none; }
a:hover { color: var(--blaze-hover); text-decoration: underline; }

img { max-width: 100%; }

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

/* Skip link — keyboard users should not have to tab the whole nav. */
.skip {
  position: absolute; left: -9999px;
  background: var(--blaze-fill); color: #fff;
  padding: 10px 16px; border-radius: 8px; font-weight: 600;
}
.skip:focus { left: 16px; top: 16px; z-index: 100; }

/* ---------- Navigation ---------- */

.nav {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; gap: 20px;
  padding: 16px 24px;
  background: var(--nav-bg);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--rule);
}
/* The wordmark carries the whole brand — there is no logotype beyond the icon
   and the name — so it is sized to be the first thing read, not the smallest. */
.nav .brand {
  display: flex; align-items: center; gap: 12px;
  color: var(--ink); font-weight: 800; font-size: 23px; letter-spacing: -0.02em;
}
.nav .brand:hover { text-decoration: none; }
.nav .brand img { border-radius: 22.37%; }
.nav-links { display: flex; gap: 20px; margin-left: auto; flex-wrap: wrap; }
.nav-links a { color: var(--ink-muted); font-size: 15px; }
.nav-links a:hover { color: var(--ink); text-decoration: none; }
.nav-links a[aria-current="page"] { color: var(--blaze-ink); }

@media (max-width: 860px) {
  .nav { flex-wrap: wrap; gap: 10px; }
  .nav-links { margin-left: 0; width: 100%; gap: 16px; }
  .nav-links a { font-size: 14px; }
}

/* ---------- Buttons ---------- */

.btn, .btn-ghost {
  display: inline-block;
  padding: 13px 26px;
  border-radius: 12px;
  font-weight: 700; font-size: 17px;
  min-height: 48px; line-height: 22px;
  letter-spacing: 0.01em;
}
.btn { background: var(--blaze-fill); color: #fff; }
.btn:hover { background: var(--blaze-hover); color: #fff; text-decoration: none; }
.btn-ghost { border: 1px solid var(--rule); color: var(--ink); }
.btn-ghost:hover { border-color: var(--blaze-fill); color: var(--blaze-ink); text-decoration: none; }

/* ---------- Hero ---------- */

.hero {
  padding: 72px 0 56px;
  background:
    radial-gradient(ellipse 60% 50% at 74% 10%, var(--wash-1), transparent 70%),
    radial-gradient(ellipse 55% 45% at 8% 88%, var(--wash-2), transparent 70%);
}
.hero-grid {
  display: grid; grid-template-columns: 1.05fr 0.95fr;
  gap: 56px; align-items: center;
}
.eyebrow {
  color: var(--blaze-ink); font-size: 13px; font-weight: 700;
  letter-spacing: 0.10em; text-transform: uppercase; margin: 0 0 14px;
}
h1 {
  font-size: clamp(34px, 5vw, 52px);
  line-height: 1.08; letter-spacing: -0.025em;
  margin: 0 0 20px; font-weight: 800;
}
.lede { font-size: 19px; color: var(--ink-muted); margin: 0 0 28px; }
.hero-cta { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.fineprint { font-size: 14px; color: var(--ink-faint); margin: 18px 0 0; }

.shot { width: 100%; height: auto; border-radius: 26px; display: block; }
.shot-wrap {
  border: 1px solid var(--rule); border-radius: 30px; padding: 8px;
  background: var(--card); max-width: 320px; margin: 0 auto;
  box-shadow: var(--shadow-lg);
}

@media (max-width: 860px) {
  .hero-grid { grid-template-columns: 1fr; gap: 40px; }
  .hero { padding: 48px 0 40px; }
}

/* ---------- The four-word strip ---------- */

.strip {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
  background: var(--rule);
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  /* Overrides the generic `section` padding: this container's background IS
     the divider showing through the 1px gaps, so padding here becomes a pale
     band above and below the columns rather than space. */
  padding: 0;
}
.strip > div { background: var(--ground); padding: 26px 24px; }
.strip b {
  display: block; font-size: 13px; margin-bottom: 6px;
  color: var(--blaze-ink); letter-spacing: 0.10em; text-transform: uppercase;
}
.strip span { color: var(--ink-muted); font-size: 15px; }
@media (max-width: 860px) { .strip { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .strip { grid-template-columns: 1fr; } }

/* ---------- Sections ---------- */

section { padding: 72px 0; }
h2 {
  font-size: clamp(26px, 3.4vw, 34px); line-height: 1.15;
  letter-spacing: -0.02em; margin: 0 0 12px; font-weight: 800;
}
.section-lede { color: var(--ink-muted); font-size: 18px; max-width: 62ch; margin: 0 0 36px; }
.center { text-align: center; margin-left: auto; margin-right: auto; }
.band { background: var(--card); border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.band-deep { background: var(--ground-deep); border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }

/* ---------- Feature cards ---------- */

.features-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px;
}
.features-grid article {
  background: var(--card); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: 24px;
}
.features-grid h3 { margin: 0 0 8px; font-size: 17px; font-weight: 700; }
.features-grid p { margin: 0; color: var(--ink-muted); font-size: 15px; }
.features-grid p + p { margin-top: 10px; }
.features-grid .tag {
  display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--blaze-ink); margin-bottom: 10px;
}

/* ---------- Screens ---------- */

.screens { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 24px; }
.screens figure { margin: 0; }
.screens img {
  width: 100%; height: auto; display: block;
  border-radius: 18px; border: 1px solid var(--rule);
  background: var(--card-raised);
}
.screens figcaption { color: var(--ink-muted); font-size: 14px; margin-top: 12px; }
.screens b { color: var(--ink); display: block; font-size: 15px; margin-bottom: 2px; }

/* ---------- The walkthrough ---------- */

.steps { display: grid; gap: 56px; margin-top: 44px; }
.step {
  display: grid; grid-template-columns: 300px 1fr; gap: 44px; align-items: center;
}
.step:nth-child(even) { grid-template-columns: 1fr 300px; }
.step:nth-child(even) .step-shot { order: 2; }
.step-shot img {
  width: 100%; height: auto; display: block;
  border-radius: 26px; border: 1px solid var(--rule); background: var(--card-raised);
  box-shadow: var(--shadow-lg);
}
.step-n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--blaze-fill); color: #fff; font-weight: 800; font-size: 15px;
  margin-bottom: 14px;
}
.step h3 { margin: 0 0 10px; font-size: 22px; font-weight: 700; letter-spacing: -0.01em; }
.step p { margin: 0 0 12px; color: var(--ink-muted); }
.step p:last-child { margin-bottom: 0; }
.step .readout {
  font-family: var(--mono); font-size: 14px; color: var(--ink);
  background: var(--card); border: 1px solid var(--rule);
  border-radius: 10px; padding: 12px 14px; margin-top: 16px;
}
.step .readout b { color: var(--blaze-ink); font-weight: 700; }
@media (max-width: 860px) {
  .step, .step:nth-child(even) { grid-template-columns: 1fr; gap: 24px; }
  .step:nth-child(even) .step-shot { order: 0; }
  .step-shot { max-width: 300px; }
}

/* ---------- Video clips ---------- */

.clips { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 28px; }
.clip figure { margin: 0; }
/* A phone recording is 1:2.17. Left at the column width it becomes a 1000px
   tower that swamps the page, so the clip is capped and centred and the
   caption runs full width underneath it. */
.clip video, .clip img.frames {
  width: 100%; max-width: 290px; margin: 0 auto; display: block; background: #000;
  border-radius: 24px; border: 1px solid var(--rule);
}
.clip figcaption { color: var(--ink-muted); font-size: 14px; margin-top: 12px; }
.clip b { color: var(--ink); display: block; font-size: 15px; margin-bottom: 2px; }

/* A stepped sequence used where a video is not available. */
.frame-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; }
.frame-strip img { width: 100%; border-radius: 10px; border: 1px solid var(--rule); background: #000; }

/* ---------- Honesty band ---------- */

.promises { list-style: none; padding: 0; margin: 28px 0 0; display: grid; gap: 16px; }
.promises li { padding-left: 26px; position: relative; color: var(--ink-muted); }
.promises li::before {
  content: ""; position: absolute; left: 0; top: 9px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--blaze-fill);
}
.promises b { color: var(--ink); }

.callout {
  background: var(--card); border: 1px solid var(--rule);
  border-left: 3px solid var(--blaze-fill);
  border-radius: var(--radius); padding: 22px 24px; margin: 28px 0;
}
.callout p:last-child { margin-bottom: 0; }
.callout p:first-child { margin-top: 0; }
.callout h3 { margin: 0 0 8px; font-size: 17px; }

/* ---------- Pricing ---------- */

.price-card {
  background: var(--card); border: 1px solid var(--rule);
  border-radius: var(--radius-lg); padding: 36px; max-width: 520px;
  margin: 0 auto; text-align: center;
}
.price { font-size: 40px; font-weight: 800; letter-spacing: -0.03em; margin: 0; }
.price em { font-size: 17px; font-weight: 400; color: var(--ink-muted); font-style: normal; }
.price-alt { color: var(--ink-muted); margin: 6px 0 0; font-size: 16px; }
.price-trial { color: var(--blaze-ink); font-weight: 700; font-size: 15px; margin: 10px 0 22px; }
.price-card ul { list-style: none; padding: 0; margin: 0 0 24px; text-align: left; display: grid; gap: 10px; }
.price-card li { padding-left: 26px; position: relative; color: var(--ink-muted); font-size: 15px; }
.price-card li::before { content: "\2713"; position: absolute; left: 0; color: var(--blaze-ink); font-weight: 700; }
.price-note {
  font-size: 14px; color: var(--ink-faint); text-align: left;
  border-top: 1px solid var(--rule); padding-top: 18px; margin: 0;
}

/* ---------- FAQ ---------- */

.faq-list { display: grid; gap: 10px; max-width: 780px; }
details {
  background: var(--card); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: 18px 22px;
}
summary { cursor: pointer; font-weight: 700; list-style: none; }
summary::-webkit-details-marker { display: none; }
summary::after { content: "+"; float: right; color: var(--blaze-ink); font-weight: 400; font-size: 20px; line-height: 1; }
details[open] summary::after { content: "\2212"; }
details p { color: var(--ink-muted); margin: 12px 0 0; font-size: 15px; }

/* ---------- Story / About ---------- */

.story { max-width: 68ch; }
.story p { color: var(--ink-muted); }
.story p.lead { color: var(--ink); font-size: 19px; }
.story h3 { margin: 34px 0 10px; font-size: 20px; font-weight: 700; }

@media (max-width: 900px) {
    }

/* ---------- Photo slots ---------- */
/* Two photographs Scott will drop in. Until the files exist the figure shows
   its own placeholder: the <img> is hidden by its onerror handler and the
   frame's background carries the note. Nothing 404s visibly, nothing shifts. */

.photo { margin: 0; }
.photo .frame {
  position: relative; width: 100%; overflow: hidden;
  border-radius: var(--radius-lg); border: 1px solid var(--rule);
  background:
    repeating-linear-gradient(135deg, var(--card-raised) 0 12px, var(--card) 12px 24px);
}
.photo .frame::before { content: ""; display: block; padding-top: 66.67%; }  /* 3:2 */
.photo .frame.portrait::before { padding-top: 125%; }                        /* 4:5 */
.photo .frame img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
}
/* The class selector above outranks the browser's own [hidden] rule, so the
   alt text of a missing photo kept rendering on top of the placeholder. Found
   in the render, not in the source. */
.photo .frame img[hidden] { display: none; }
.photo .frame .slot {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 6px; text-align: center;
  padding: 24px; color: var(--ink-faint); font-size: 13px; line-height: 1.5;
}
.photo .frame .slot b { color: var(--ink-muted); font-size: 14px; }
.photo .frame .slot code { font-family: var(--mono); font-size: 12px; color: var(--blaze-ink); }
/* Once the image loads it covers the slot; if it never loads the slot shows. */
.photo .frame img:not([hidden]) + .slot { display: none; }
.photo figcaption { color: var(--ink-faint); font-size: 13px; margin-top: 10px; }

/* ---------- Footer ---------- */

.foot { border-top: 1px solid var(--rule); padding: 44px 0 56px; background: var(--ground-deep); }
.foot-top { display: flex; flex-wrap: wrap; gap: 28px; justify-content: space-between; align-items: flex-start; }
.foot-brand { display: flex; gap: 12px; align-items: center; }
.foot-brand img { border-radius: 22.37%; }
.foot-brand b { display: block; }
.foot-brand span { color: var(--ink-faint); font-size: 14px; }
.foot-links { display: flex; flex-wrap: wrap; gap: 20px; }
.foot-links a { color: var(--ink-muted); font-size: 15px; }
.disclaimer {
  color: var(--ink-faint); font-size: 13px; margin: 32px 0 0;
  padding-top: 22px; border-top: 1px solid var(--rule); max-width: 78ch;
}

/* ---------- Long-form pages ---------- */

.doc { max-width: 74ch; padding: 56px 0 72px; }
.doc h1 { font-size: clamp(30px, 4vw, 40px); margin-bottom: 8px; }
.doc .updated { color: var(--ink-faint); font-size: 15px; margin: 0 0 40px; }
.doc h2 { font-size: 22px; margin: 40px 0 12px; }
.doc h3 { font-size: 17px; margin: 26px 0 8px; }
.doc h4 { font-size: 16px; margin: 22px 0 8px; color: var(--ink); }
.doc p, .doc li { color: var(--ink-muted); }
.doc strong { color: var(--ink); }
.doc ul { padding-left: 22px; }
.doc li { margin-bottom: 8px; }
.doc hr { border: 0; border-top: 1px solid var(--rule); margin: 40px 0; }
.doc code { font-family: var(--mono); font-size: 0.92em; color: var(--blaze-ink); }
.doc table { width: 100%; border-collapse: collapse; margin: 20px 0; font-size: 15px; }
.doc th, .doc td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--rule); color: var(--ink-muted); vertical-align: top; }
.doc th { color: var(--ink); font-weight: 700; }
.table-scroll { overflow-x: auto; }

/* Anchored headings should not hide under the sticky nav. */
:target { scroll-margin-top: 96px; }

::selection { background: var(--blaze-fill); color: #fff; }
:focus-visible { outline: 2px solid var(--blaze-fill); outline-offset: 3px; border-radius: 4px; }

/* ---------- Store badge (dormant until launch — see LAUNCH-KIT.md) ---------- */
.store-badges { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; margin: 22px 0 0; }
.store-badges img { height: 44px; width: auto; display: block; }
.store-badges a:hover { opacity: 0.85; }

/* ---------- Small print used inline ---------- */
.note {
  font-size: 14px; color: var(--ink-faint);
  border-left: 2px solid var(--rule); padding-left: 14px; margin: 18px 0;
}

/* ---------- App-appearance switch on the walkthrough ---------- */
/* The app ships light and dark (brief §45), and which one a hunter uses is a
   real choice — dark is easier on night vision, light is easier in direct sun.
   So the page shows both rather than deciding for the reader. */

.appearance-switch {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin: 0 0 44px;
}
.appearance-switch > span {
  font-size: 12px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-faint); margin-right: 4px;
}
.appearance-switch button {
  font: inherit; font-size: 15px; font-weight: 600;
  color: var(--ink-muted); background: var(--card);
  border: 1px solid var(--rule); border-radius: 999px;
  padding: 8px 18px; min-height: 40px; cursor: pointer;
}
.appearance-switch button:hover { color: var(--ink); border-color: var(--ink-faint); }
.appearance-switch button[aria-pressed="true"] {
  background: var(--blaze-fill); border-color: var(--blaze-fill); color: #fff;
}
.appearance-switch em {
  font-style: normal; font-size: 14px; color: var(--ink-faint);
  flex-basis: 100%;
}
@media (min-width: 720px) {
  .appearance-switch em { flex-basis: auto; margin-left: 8px; }
}

/* A pair of phones shown side by side, one appearance each. */
.pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; max-width: 640px; }
.pair figure { margin: 0; }
.pair img {
  width: 100%; height: auto; display: block; background: var(--card-raised);
  border-radius: 22px; border: 1px solid var(--rule);
}
.pair figcaption { color: var(--ink-muted); font-size: 14px; margin-top: 10px; text-align: center; }


/* ---------- Site theme toggle ---------- */
/* Sits at the end of the nav. Shows the icon for the theme you would switch
   TO, which is the convention people already read correctly from every other
   app. Hidden entirely without JavaScript, because a button that cannot do
   anything is worse than no button — see theme.js. */

.theme-toggle {
  display: none;
  align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: 0 0 40px;
  padding: 0; margin-left: 4px;
  background: transparent; color: var(--ink-muted);
  border: 1px solid var(--rule); border-radius: 50%;
  cursor: pointer;
}
html.js .theme-toggle { display: inline-flex; }
.theme-toggle:hover { color: var(--ink); border-color: var(--ink-faint); }
.theme-toggle svg { width: 18px; height: 18px; display: block; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }

@media (max-width: 860px) {
  .theme-toggle { margin-left: auto; }
}

/* A card sitting inside a banded section was the same colour as the band, in
   both themes, so it read as an outline rather than a card. Lift it one step.
   Caught in the render, not in the source. */
.band .features-grid article,
.band details,
.band .price-card,
.band .callout { background: var(--card-raised); }

/* ---------- Photographs ---------- */
/* Scott's own photographs, and the only images on the site that are not
   screenshots. Framed by aspect ratio with object-fit: cover, so nothing is
   cropped on disk and the framing stays a CSS decision — nudge object-position
   rather than re-cutting a file. See make-photos.sh. */

.hero-tight { padding-bottom: 32px; }

/* The full-width banner under the About headline.
   The source is 4:3, so a banner is a deep crop and where it sits matters. At
   40% and 60% the visible band runs from just above the horizon down past the
   tent pegs — the ranges, the camp and the man all intact. Tighter than this
   and it cut him off at the knees and took the bottom off the tent, which is
   what the first attempt did. Taller on a phone, where a wide strip would be a
   letterbox with nothing in it. */
.photo.banner { margin: 0 0 8px; }
.photo.banner .frame.wide::before { padding-top: 40%; }
.photo.banner .frame { border-radius: 0; border-left: 0; border-right: 0; }
.photo.banner .frame img { object-position: center 60%; }
.photo.banner figcaption {
  color: var(--ink-faint); font-size: 14px;
  margin: 14px auto 0; max-width: var(--wrap); padding: 0 24px;
}
@media (max-width: 860px) {
  .photo.banner .frame.wide::before { padding-top: 66%; }
}

/* Home page: the story and a face, side by side. */
.built-grid { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 56px; align-items: center; }
.built-grid .story { max-width: none; }
@media (max-width: 860px) {
  .built-grid { grid-template-columns: 1fr; gap: 32px; }
}

/* A full-bleed photograph used as a band between sections. Darker than
   anything else on the light theme, deliberately: it is the only place the
   site shows the country at night, which is when this app matters most and
   when a screen is all you have. */
.photo.band { margin: 0; }
.photo.band .frame { border-radius: 0; border-left: 0; border-right: 0; }
.photo.band .frame.night::before { padding-top: 44%; }
.photo.band .frame.night img { object-position: center 46%; }
.photo.band figcaption {
  color: var(--ink-faint); font-size: 14px;
  margin: 16px auto 8px; max-width: var(--wrap); padding: 0 24px;
}
.photo.band { padding-bottom: 8px; }
@media (max-width: 860px) {
  .photo.band .frame.night::before { padding-top: 72%; }
}

/* Screenshot strips inside the Features sections. Smaller than the walkthrough's
   phones, because here they are supporting the words rather than being the
   subject — the page was all text before, which is the wrong shape for an app
   that is mostly a thing you look at. */
/* auto-fit stretches the last row to fill, so a two-item strip rendered two
   470px phones. Cap the phone and let the column breathe around it. */
.screens-tight { grid-template-columns: repeat(auto-fit, minmax(160px, 220px)); gap: 24px 28px; margin-top: 28px; justify-content: start; }
.screens-tight figcaption { font-size: 13px; }
.screens-tight b { font-size: 14px; }

/* A photograph sitting inside a column rather than bleeding to the edges. */
.photo.inline { margin: 0 0 40px; }
.photo.inline .frame.wide-16::before { padding-top: 56.25%; }
.photo.inline figcaption {
  color: var(--ink-muted); font-size: 15px; margin-top: 14px; max-width: 68ch;
}
.photo.band .frame.pano::before { padding-top: 22%; }
@media (max-width: 860px) {
  .photo.band .frame.pano::before { padding-top: 46%; }
}

/* The "Who built it" section carries the app's credentials, so it is sized
   like a section of the argument rather than a footnote at the bottom. */
.built-grid .story h2 { margin-bottom: 16px; }
.built-grid .story .lead { font-size: 19px; color: var(--ink); }
.built-grid .story p { margin-bottom: 14px; }


/* ---------- The About story ---------- */
/* One column, not two. The old layout put the photographs in a sticky sidebar
   that sat still while the story scrolled past it, which read as two unrelated
   things happening at once. Now the text runs at a comfortable measure and the
   photographs break wider at the points in the story where they mean
   something — the country under "where the idea came from", the animals under
   the paragraph about the ground, the dog beside "about me". */

.story-flow { max-width: 900px; margin: 0 auto; }
.story-flow > p,
.story-flow > h3,
.story-flow > .callout { max-width: 68ch; margin-left: auto; margin-right: auto; }
.story-flow > p { color: var(--ink-muted); margin: 0 auto 18px; }
.story-flow > p.lead { color: var(--ink); font-size: 20px; margin-bottom: 26px; }
.story-flow > h3 { font-size: 22px; font-weight: 700; margin: 48px auto 14px; }
.story-flow > figure { margin: 44px auto; max-width: 900px; }
.story-flow > .callout { margin-top: 44px; }

/* Two portrait photographs side by side, so neither becomes a tower. */
.photo-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.photo-pair .pair-item { display: block; }
.photo-pair .frame-wrap { display: block; }
.pair-figure { margin: 44px auto; }
.pair-figure figcaption { color: var(--ink-faint); font-size: 13px; margin-top: 10px; }
@media (max-width: 620px) {
  .photo-pair { grid-template-columns: 1fr; }
}

/* ---------- The app mark, used as a mark ---------- */
/* There is no logotype beyond the icon and the name, so the icon does the work
   a logo would: it opens the hero, it sits on the thing being bought, and it is
   the first thing on the 404. Same corner radius as iOS uses, so it reads as an
   app icon rather than a rounded square. */
.hero-mark {
  display: block; width: 72px; height: 72px;
  border-radius: 22.37%; margin: 0 0 22px;
  box-shadow: var(--shadow-md);
}
.price-mark {
  width: 72px; height: 72px; border-radius: 22.37%;
  margin: 0 auto 18px; display: block;
  box-shadow: var(--shadow-md);
}
@media (max-width: 860px) {
  .hero-mark { width: 60px; height: 60px; margin-bottom: 18px; }
}
