/* Golf Fellow — the landing page's own layout layer.
 *
 * WHY THIS IS A SECOND FILE, NOT MORE OF `site.css`. `site.css` is the SHARED
 * layer: the token `:root`, `body`, `.wrap`, the sticky header, the footer and
 * the legal-document styles that `/privacy` and `/terms` also load. Everything
 * here is used by the landing page and by nothing else — the photo hero, the
 * phone frames, the alternating feature rows and the free-vs-subscription
 * table. Keeping them apart also keeps this page out of the way of the invite /
 * shared-scorecard work landing in `site.css` (PR #573): the two never touch
 * the same file.
 *
 * Load order is `site.css` then `landing.css`; every raw value below is copied
 * from the app's `src/theme/tokens.ts` exactly as `site.css`'s own header
 * explains, because a static site cannot call `useTheme()`.
 *
 * NO JAVASCRIPT. Every state on this page — the language switch, the nav, the
 * store button's disabled state — is a link, an anchor or an attribute. The
 * page renders and works with scripting off.
 */

:root {
  /* The pre-login SAND role (CLAUDE.md → Design system, recorded deviation
     2026-08-31), copied from `tokens.ts`'s light palette. It is the accent ON
     THE HERO PHOTOGRAPH for exactly the reason the app's sign-in flow uses it:
     a golf-green button disappears into the grass. Golf green stays the tint
     for every section below the fold, and errors are still red.

     PR #573 adds these same three names to `site.css` with these same values
     (both are copies of the same `tokens.ts` lines). If it lands first this
     block is a harmless identical re-declaration — it is NOT a second source
     of truth, and if the app's palette ever moves, both copies move with it. */
  --sand: #c7a55c;
  --on-sand: #1b1e1c; /* 7.2:1 on #c7a55c — contrast-pinned in buttonColors.test.ts */
  --sand-100: #f6efdf;

  /* The hero's dark ground. `accentStrong` from the light palette, dropped
     under the photograph as the scrim colour so the wordmark and the lede hold
     against a bright sky as well as against dark grass. */
  --scrim-900: #0d1a12;
}

/* ── skip link ──────────────────────────────────────────── */
.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--ground); color: var(--green-700);
  padding: 10px 16px; border-radius: var(--radius); z-index: 100;
}
.skip:focus { left: 12px; top: 12px; }

/* Keyboard focus is visible everywhere on this page, on light and on dark. */
a:focus-visible, .store-btn:focus-visible {
  outline: 2px solid var(--green-500);
  outline-offset: 3px;
  border-radius: var(--radius);
}
.hero a:focus-visible { outline-color: var(--sand); }

/* ── the language switch in the header ──────────────────── */
.site-head .lang {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 14px; color: var(--ink-600); white-space: nowrap;
}
.site-head .lang a { color: var(--ink-700); text-decoration: none; }
.site-head .lang a:hover { color: var(--green-600); }
.site-head .lang [aria-current="true"] { color: var(--ink-900); font-weight: 600; }

/* ── hero ───────────────────────────────────────────────── */
/* Overrides `site.css`'s light gradient hero: this one is a photograph. */
.hero.photo {
  position: relative;
  isolation: isolate;
  background: var(--scrim-900);
  color: #fff;
  padding: 64px 0 72px;
  overflow: hidden;
}

/* The photograph itself is an <img>, not a background-image, so it can be
   served as WebP through <picture> and carry real alt text. It is decorative
   here (the headline says everything it says), so its alt is empty and it is
   hidden from assistive technology. */
/* <picture> is an inline element, so left in flow it would contribute an empty
   line box above the hero's content. Taking it out of flow with the image
   removes that, and makes it the img's containing block. */
.hero.photo > picture { position: absolute; inset: 0; display: block; z-index: -2; }
.hero-photo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
  /* The master is a 853×1844 PORTRAIT frame. At desktop widths `cover` crops it
     to a horizontal band; 62% picks the band holding the green, the cliff line
     and the low sun rather than the empty sky. */
  object-position: center 62%;
  z-index: -2;
}
/* Enough scrim to hold white text, and not one percent more. The first pass
   stacked 0.72/0.42/0.84 vertically UNDER a 0.7→0.15 horizontal wash, which
   multiplies to ~0.92 opaque at the top left: rendered in Mobile Safari the
   photograph had become a flat dark-green field, which is the one thing a
   photographic hero must not be. These values were set by looking at it.

   The floor is legibility, not taste: the lede sits on the band around 40–60%,
   where the combined wash is ~0.45 over a mid-dark photo — comfortably past
   4.5:1 for `rgba(255,255,255,0.88)` text. The bottom stays heavier because the
   phone frame's light screen sits there and needs separating from the grass. */
.hero-scrim {
  position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(180deg, rgba(13, 26, 18, 0.58) 0%, rgba(13, 26, 18, 0.3) 45%, rgba(13, 26, 18, 0.72) 100%),
    linear-gradient(90deg, rgba(13, 26, 18, 0.42) 0%, rgba(13, 26, 18, 0) 72%);
}

.hero.photo .hero-grid {
  display: grid; gap: 40px; align-items: center;
  grid-template-columns: 1fr;
}
.hero.photo h1 {
  font-size: clamp(34px, 6vw, 58px);
  line-height: 1.05; letter-spacing: -0.025em;
  margin: 0 0 18px; max-width: 15ch; font-weight: 700;
  color: #fff;
  text-wrap: balance;
}
.hero.photo p.lede {
  font-size: clamp(18px, 2.3vw, 21px);
  color: rgba(255, 255, 255, 0.88);
  max-width: 44ch; margin: 0 0 28px;
}
.hero.photo .eyebrow {
  color: var(--on-sand); background: var(--sand);
  margin-bottom: 18px;
}

/* ── the call to action ─────────────────────────────────── */
.cta { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.cta-primary {
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--sand); color: var(--on-sand);
  font-size: 16px; font-weight: 600;
  padding: 14px 22px; border-radius: var(--radius);
  text-decoration: none; border: 1px solid var(--sand);
}
.cta-primary:hover { background: #d8b978; color: var(--on-sand); border-color: #d8b978; }

/* The SAME button, below the fold, is GOLF GREEN — and this is the design law,
   not a flourish. `sand` exists on this page for exactly the reason the app's
   sign-in screens use it: a green CTA disappears into a photograph of grass.
   The closing section has no photograph, so the exception does not reach it and
   the tint goes back to green (CLAUDE.md → Design system: "golf green is the
   tint and only the tint", plus the 2026-08-31 deviation, which is scoped to
   the pre-login photo screens and stops there).

   The first pass had the closing CTA in sand too — caught by rendering the page
   in Mobile Safari and seeing a gold button sitting on a plain light ground,
   where it reads as a second brand rather than the accent it is. */
.closing .cta { justify-content: center; }
.closing .cta-primary {
  background: var(--green-600); border-color: var(--green-600); color: #fff;
}
.closing .cta-primary:hover {
  background: var(--green-700); border-color: var(--green-700); color: #fff;
}

/* The App Store button in its HONEST unavailable state. There is no live App
   Store page for `id6799541546` yet (checked 2026-09-11: apps.apple.com 404s
   and the iTunes lookup API returns resultCount 0), so this is a label, not a
   link — no href, no official Apple badge artwork, nothing that pretends a
   download exists. Swapping it for the real thing is one line: give the <a> the
   href and drop `aria-disabled`. */
.hero.photo .store-btn[aria-disabled="true"] {
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.38);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.hero.photo .store-btn[aria-disabled="true"] .icon { opacity: 0.85; }
.hero.photo .store-note { color: rgba(255, 255, 255, 0.72); }

/* ── the phone frame ────────────────────────────────────── */
/* A device bezel drawn in CSS — no device artwork, no vendor imagery. */
.phone {
  width: 100%; max-width: 290px; margin: 0 auto;
  background: #10130f;
  border-radius: 42px; padding: 9px;
  box-shadow:
    0 0 0 1.5px rgba(255, 255, 255, 0.16),
    0 26px 60px rgba(13, 26, 18, 0.32),
    0 3px 10px rgba(13, 26, 18, 0.22);
}
.phone .screen {
  display: block; overflow: hidden;
  border-radius: 34px;
  background: var(--ink-100);
  /* Holds the row's height before the screenshot has loaded (or while it is
     still a placeholder path), so nothing jumps. 9:19.5 is the modern iPhone
     display ratio the simulator captures. */
  aspect-ratio: 9 / 19.5;
}
.phone img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: top center;
  background: var(--ink-100);
}
.phone-caption {
  margin: 14px 0 0; text-align: center;
  font-size: 13px; color: var(--ink-600);
}
.hero .phone-caption { color: rgba(255, 255, 255, 0.62); }

/* ── alternating feature rows ───────────────────────────── */
.feature { display: grid; gap: 32px; align-items: center; }
.feature + .feature { margin-top: 72px; }
.feature h3 {
  font-size: clamp(22px, 3vw, 28px); letter-spacing: -0.02em;
  margin: 10px 0 12px; text-wrap: balance;
}
.feature p { color: var(--ink-700); max-width: 46ch; margin: 0 0 14px; }
.feature p:last-child { margin-bottom: 0; }
.kicker {
  display: inline-block; font-size: 12px; font-weight: 700;
  letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--green-600);
}
.feature .tag {
  display: inline-block; margin-left: 8px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--green-700);
  background: var(--green-100); padding: 3px 8px; border-radius: 999px;
  vertical-align: 2px;
}
.feature ul { margin: 0; padding-left: 20px; color: var(--ink-700); }
.feature li { margin: 5px 0; }

/* A feature row with NO phone beside it.
 *
 * WHY ONE ROW HAS NO SCREENSHOT. Mánuðurinn is a leaderboard, and the only
 * account this repo may photograph has one friend who has not posted a score
 * this month — so the real capture is a board with a single name on it and two
 * thirds of the frame empty. Rendered inside the phone bezel that reads as a
 * broken screen, which is a worse lie about the feature than no picture at all.
 * A fuller board cannot be staged without writing rounds into another person's
 * account, so the honest move is to describe it and wait for a real one
 * (`web/img/README.md` records what the capture needs).
 *
 * So this is a deliberate band, not a hole where an image failed: full width,
 * its own card, centred measure. It also gives the page's rhythm somewhere to
 * breathe between five alternating phone rows. */
.feature.solo {
  grid-template-columns: 1fr;
  background: var(--ground);
  border: 1px solid var(--green-100);
  border-radius: var(--radius-lg);
  padding: 32px 28px;
  text-align: center;
}
.feature.solo .feature-text { max-width: 62ch; margin: 0 auto; }
.feature.solo p { max-width: none; }

@media (min-width: 880px) {
  .hero.photo .hero-grid { grid-template-columns: 1.05fr 0.95fr; gap: 56px; }
  .hero.photo .phone { max-width: 300px; margin-right: 0; }
  .feature { grid-template-columns: 1fr 1fr; gap: 64px; }
  /* `flip` puts the phone on the LEFT. The text still comes first in the
     DOM, so the reading order and the tab order never change. */
  .feature.flip .feature-media { order: -1; }
}

/* ── free vs. subscription ──────────────────────────────── */
.compare-wrap { overflow-x: auto; }
.compare {
  border-collapse: collapse; width: 100%; min-width: 420px;
  background: var(--ground);
  border: 1px solid var(--ink-300); border-radius: var(--radius-lg);
  overflow: hidden;
}
.compare th, .compare td {
  text-align: left; padding: 14px 16px;
  border-bottom: 1px solid var(--ink-100); font-size: 16px;
}
.compare thead th {
  font-size: 13px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-600); font-weight: 700; white-space: nowrap;
}
.compare thead th.premium { color: var(--green-600); }
.compare tbody th { font-weight: 500; color: var(--ink-900); }
.compare td { text-align: center; width: 22%; white-space: nowrap; color: var(--ink-700); }
.compare tbody tr:last-child th, .compare tbody tr:last-child td { border-bottom: 0; }
.compare .yes { color: var(--green-500); font-weight: 700; }
.compare .no { color: var(--ink-300); }
.compare col.premium-col { background: var(--green-100); }

/* On a phone the table must FIT, not scroll. `min-width: 420px` plus the wrap's
   24px gutters overflowed a 402px viewport by about 66px, which clipped the
   ÁSKRIFT column in half — and a half-visible column reads as broken, not as an
   invitation to swipe. Rendered in Mobile Safari; this is what fixed it.
   `.compare-wrap`'s `overflow-x: auto` stays as the safety net for a locale
   whose labels are longer than Icelandic's. */
@media (max-width: 560px) {
  .compare { min-width: 0; }
  .compare th, .compare td { padding: 12px 10px; font-size: 15px; }
  .compare thead th { font-size: 11px; letter-spacing: 0.03em; }
  .compare td { width: 23%; white-space: normal; }
}

.seam {
  display: grid; gap: 20px; margin: 0 0 32px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.seam .card p:first-of-type { margin-bottom: 8px; }
.price-note { margin: 20px 0 0; font-size: 15px; color: var(--ink-600); max-width: var(--measure); }

/* ── the closing call to action ─────────────────────────── */
.closing { text-align: center; }
.closing h2 { margin-bottom: 12px; }
.closing .section-lede { margin-left: auto; margin-right: auto; text-align: center; }
.closing .cta { justify-content: center; }
.closing .store-note { text-align: center; }

@media (max-width: 640px) {
  .hero.photo { padding: 40px 0 48px; }
  .feature + .feature { margin-top: 56px; }
  .phone { max-width: 250px; }
  .site-head .lang { font-size: 13px; }
}

/* At 360px the header has a mark, a wordmark, three nav links and a language
   switch. The nav links are the ones that go — every one of them is a jump to
   a section the reader reaches by scrolling anyway, whereas the language
   switch is the only way to the other locale. 520 and not 460: the header
   held everything down to 470 with the wordmark alone, and the mark beside it
   (`.brand img`, 28px + 10px gap) needs the other ~50 — measured, "EN" clipped
   at 470 with the mark and the old breakpoint. */
@media (max-width: 520px) {
  .site-head nav.sections { display: none; }
}
@media (max-width: 460px) {
  .wrap { padding: 0 16px; }
}

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

/* A label that only assistive technology reads — the compare table's empty
   corner header, which must not be blank for a screen reader. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

/* The text half of a feature row. It carries no styling of its own — it exists
   so each row has exactly two grid children, which is what lets `.flip` move
   the phone to the left column without touching the DOM order. `min-width: 0`
   stops a long unbroken word from widening the grid track. */
.feature-text { min-width: 0; }
