/* commutemagic.com — the public site.
 *
 * ONE stylesheet for the landing page and the two legal pages, so the
 * marketing page and the policy the store links to cannot drift apart in
 * look. The palette is COPIED from mobile/src/theme.ts (the app's own
 * light/dark tokens) rather than invented: the site is the app's front
 * door and a visitor arrives at one after seeing the other.
 *
 * SIX TOKENS DELIBERATELY DIVERGE FROM theme.ts, and none may be "restored"
 * without redoing the arithmetic (2026-09-07). A phone screen is held at
 * arm's length in a cabin; a web page is read at any size on any monitor, and
 * WCAG AA is a promise the store listing and the policy pages have to keep.
 * Each of the six is the MINIMUM move along its own hue that reaches 4.5:1
 * against the exact background it is painted on -- the ratios are in the
 * comment beside each one. Apple's system blue, system indigo and system red
 * are all below 4.5:1 somewhere on this page; that is a fact about those
 * colours, not a thing to design around.
 *
 * The six, so the count can be checked rather than trusted: light --faint,
 * --accent and --ok; dark --faint, --danger and --night. (It said six while
 * seven diverged until dark --accent went back to systemBlue below.)
 *
 * ONE TOKEN HERE HAS NO theme.ts COUNTERPART AT ALL: --accent-fill. The app
 * never paints white on its accent, so it needs one blue where this site
 * needs two. The arithmetic is beside the token.
 *
 * EVERY RATIO IN THIS FILE NAMES THE GROUND IT WAS MEASURED ON. A token can
 * pass on --bg and fail on --card -- the two dark grounds are #000 and
 * #1c1c1e, which is about 0.9 of a ratio point apart at these luminances --
 * so "4.57:1" on its own is a conditional promise written as an absolute one.
 *
 * Deliberately plain: no build step, no framework, no CDN, no fonts to
 * fetch, no analytics. Caddy serves this directory as files.
 */

:root {
  color-scheme: light dark;
  --bg: #f2f2f7;
  --card: #ffffff;
  --text: #000000;
  --sub: #6d6d72;
  /* --faint's ONE use is the em-dash marker on .plain lists, which is doing a
     marker's job (those items are flex rows with no other bullet), so it is
     content and needs 4.5:1. theme.ts #8e8e93 gives 2.92:1 on --bg; a light
     ground leaves almost nothing between "passes AA" and --sub, so this lands
     a hair above it and the faint/sub tier is only really visible in dark.
     Both light grounds are clear: 4.55:1 on --bg, 5.07:1 on --card. */
  --faint: #6e6e73;
  /* theme.ts #007aff is 3.60:1 on --bg and 4.02:1 under the store button's
     white label; darkened until both clear. In light ONE value does every
     job -- 4.58:1 on --bg, 5.12:1 on --card, 5.12:1 under white -- so
     --accent-fill below is simply this. Dark cannot manage that; see there. */
  --accent: #006add;
  --accent-fill: var(--accent);
  /* theme.ts #248a3d on its own 12% tint is 3.78:1; now 4.57:1. The tint is
     the same colour, so it moves with it or the pair stops being a pair. */
  --ok: #207a36;
  --danger: #d70015;
  --night: #5856d6;
  --seam: #e5e5ea;
  --ok-tint: rgba(32, 122, 54, 0.12);
  --danger-tint: rgba(215, 0, 21, 0.10);
  --night-tint: rgba(88, 86, 214, 0.12);
  --shot-frame: #d6d6db;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000000;
    --card: #1c1c1e;
    --text: #ffffff;
    --sub: #8e8e93;
    /* theme.ts #636366 is 3.51:1 on --bg; this is 4.57:1 on --bg and only
       3.70:1 on --card. That second number does not bite today and is not
       left to luck either -- see the .card .plain rule further down, which is
       what keeps a marker inside a card off this token. */
    --faint: #757578;
    /* TWO BLUES, and that is arithmetic rather than taste. A link must clear
       4.5:1 on BOTH grounds this site paints -- --bg #000 and --card #1c1c1e
       -- which needs a relative luminance of at least 0.2277. The store
       button's white label must clear 4.5:1 against the fill under it, which
       caps that same luminance at 0.1833. The two ranges do not overlap, and
       luminance has no hue in it, so NO colour whatsoever can do both jobs.
       The single #0073e6 that used to do them was 4.59:1 on --bg but 3.72:1
       on --card: safe only while no <a> sat inside a .card, which is a
       promise about markup rather than about colour. Split, both hold
       unconditionally -- and the link half is systemBlue again. */
    --accent: #0a84ff;      /* links:  5.76:1 on --bg, 4.67:1 on --card */
    --accent-fill: #0073e6; /* button: white on it is 4.57:1 */
    --ok: #30d158;
    /* #ff453a on its own 14% tint is 4.27:1; now 4.55:1. */
    --danger: #ff564c;
    /* systemIndigo #5e5ce6 on its own 16% tint is 2.90:1 -- the worst pair on
       the site, and the reason this banner had to move a long way: 4.55:1. */
    --night: #8e8ded;
    --seam: #2c2c2e;
    --ok-tint: rgba(48, 209, 88, 0.14);
    --danger-tint: rgba(255, 86, 76, 0.14);
    --night-tint: rgba(142, 141, 237, 0.16);
    --shot-frame: #2c2c2e;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui,
    Roboto, "Helvetica Neue", sans-serif;
  -webkit-font-smoothing: antialiased;
}

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

.wrap { max-width: 62rem; margin: 0 auto; padding: 0 1.25rem; }
.narrow { max-width: 42rem; }

/* ---- top bar --------------------------------------------------------- */

.bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding: 1.1rem 0;
}
.brand {
  display: flex; align-items: center; gap: 0.55rem;
  font-weight: 700; font-size: 1.05rem; letter-spacing: -0.02em;
  color: var(--text); text-decoration: none;
}
.brand svg { width: 22px; height: 22px; display: block; }
.bar nav { display: flex; gap: 1.1rem; font-size: 0.95rem; }
.bar nav a { text-decoration: none; white-space: nowrap; }
.bar nav a:hover { text-decoration: underline; }

/* On a phone the bar is a name and one destination. The section links wrap
   the brand onto two lines and crowd the row; the sections are a scroll
   away regardless. */
@media (max-width: 34rem) {
  .bar nav a.section { display: none; }
}

/* ---- sections -------------------------------------------------------- */

section { padding: 2.5rem 0; }
section + section { border-top: 1px solid var(--seam); }

h1 {
  font-size: clamp(2rem, 6vw, 3rem); line-height: 1.08;
  letter-spacing: -0.03em; margin: 0 0 0.75rem;
}
h2 {
  font-size: 1.35rem; letter-spacing: -0.02em; margin: 0 0 1rem;
}
h3 { font-size: 1.05rem; margin: 0 0 0.35rem; }
p { margin: 0 0 1rem; }
.lede { font-size: 1.2rem; line-height: 1.45; color: var(--text); }
.sub { color: var(--sub); }
.small { font-size: 0.9rem; color: var(--sub); }
.label {
  font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.06em;
  font-weight: 600; color: var(--sub); margin: 0 0 0.6rem;
}
.num { font-variant-numeric: tabular-nums; }

/* ---- hero ------------------------------------------------------------ */

.hero { display: grid; gap: 2.5rem; align-items: center; }
@media (min-width: 56rem) {
  .hero { grid-template-columns: 1.05fr 0.95fr; }
}

.shot {
  width: 100%; max-width: 300px; height: auto; display: block;
  margin: 0 auto; border-radius: 20px;
  border: 1px solid var(--shot-frame);
}
figure { margin: 0; }
figcaption {
  margin-top: 0.6rem; text-align: center;
  font-size: 0.85rem; color: var(--sub);
}

/* ---- store buttons --------------------------------------------------- */

.stores { display: flex; flex-wrap: wrap; gap: 0.75rem; margin: 1.5rem 0 0; }
.store {
  display: flex; flex-direction: column; gap: 0.15rem;
  flex: 1 1 13rem;
  padding: 0.7rem 1.2rem; border-radius: 14px;
  background: var(--accent-fill); color: #ffffff; text-decoration: none;
  font-weight: 600;
}
/* No opacity here, and the arithmetic is quoted against the blue actually
   under the label. White at 85% is 3.30:1 over theme.ts's #007aff and 3.05:1
   over its #0a84ff -- the numbers that made the sub-label the least readable
   text on the page when this button still used the app's own blues. Darkening
   the fill to --accent-fill only lifts them to 4.14:1 in light and 3.72:1 in
   dark, both still under AA, so the opacity had to go either way. At full
   white the label sits at 5.12:1 in light and 4.57:1 in dark, and it is the
   line that says which store and what state the listing is in. The hierarchy
   the opacity was buying is already carried by the size and the weight. */
.store span { font-weight: 400; font-size: 0.8rem; }
.store.pending {
  background: var(--card); color: var(--sub);
  border: 1px solid var(--seam); font-weight: 600;
}

/* ---- grouped cards --------------------------------------------------- */

.cards { display: grid; gap: 1rem; }
@media (min-width: 44rem) { .cards.two { grid-template-columns: 1fr 1fr; } }
@media (min-width: 56rem) { .cards.three { grid-template-columns: repeat(3, 1fr); } }

.card {
  background: var(--card); border-radius: 16px; padding: 1.1rem 1.25rem;
}
.card p:last-child, .card ul:last-child { margin-bottom: 0; }

/* A verdict banner, drawn the way the app draws it. */
.banner {
  border-radius: 12px; padding: 0.6rem 0.85rem; font-weight: 600;
  display: inline-block; margin-bottom: 0.6rem;
}
.banner.clear { background: var(--ok-tint); color: var(--ok); }
.banner.morning { background: var(--danger-tint); color: var(--danger); }
.banner.tonight { background: var(--night-tint); color: var(--night); }

/* The one claim, drawn as the app draws a stat. */
.stat { display: flex; align-items: baseline; gap: 0.6rem; }
.stat b {
  font-size: 2.1rem; font-weight: 700; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums; color: var(--ok);
}
.stat .n { color: var(--sub); font-size: 0.95rem; }

ul { margin: 0 0 1rem; padding-left: 1.15rem; }
li { margin-bottom: 0.5rem; }
li:last-child { margin-bottom: 0; }

.plain { list-style: none; padding-left: 0; }
.plain li { display: flex; gap: 0.6rem; }
.plain li::before { content: "—"; color: var(--faint); }
/* The em-dash is the marker, so it is content and owes 4.5:1. --faint pays
   that on --bg and not on --card (dark: 4.57:1 against 3.70:1), and today
   every .plain list sits in the hero -- a promise resting on markup nobody
   has moved yet. Made structural instead: inside a card the marker steps up
   to --sub, which clears both grounds (5.22:1 on dark --card). The cost is
   that the quieter marker tier flattens into the text inside a card. The
   alternative -- lifting dark --faint to about #838386 so one value clears
   both -- costs that tier EVERYWHERE, on the only ground where faint and sub
   are told apart at all, to protect a page that does not exist. */
.card .plain li::before { color: var(--sub); }

/* ---- price ----------------------------------------------------------- */

.price { font-size: 1.6rem; font-weight: 700; letter-spacing: -0.02em; }
.price small { font-size: 0.95rem; font-weight: 400; color: var(--sub); }

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

footer {
  border-top: 1px solid var(--seam); padding: 2rem 0 3rem;
  color: var(--sub); font-size: 0.92rem;
}
footer a { color: var(--accent); }
footer nav { display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: 0.9rem; }

/* ---- the legal pages ------------------------------------------------- */

.doc { padding: 0 0 4rem; }
.doc h1 { font-size: 1.7rem; margin-bottom: 0.35rem; }
.doc h2 { font-size: 1.1rem; margin: 2rem 0 0.6rem; }
.doc .updated { color: var(--sub); font-size: 0.85rem; margin-bottom: 1.5rem; }
.doc .caps { text-transform: uppercase; font-weight: 600; }
