/*
  Miles landing page. One file, no web fonts, no scripts, no third parties:
  the Content-Security-Policy in firebase.json refuses anything not served
  from this site, so nothing can be added here that quietly reaches out.

  Colours are the app's own tokens (lib/global/app_colors.dart), so the page
  and the app read as one product.
*/

:root {
  --bg: #F7F9FC;
  --surface: #FFFFFF;
  --field: #F3F4F6;
  --border: #E5E7EB;
  --text: #111827;
  --muted: #6B7280;
  --accent: #0866FF;
  --accent-ink: #FFFFFF;

  /* The Apply button keeps the brand blue in both themes. The lighter dark-
     mode accent reads well as a stripe but leaves white text at 3.5:1, below
     the 4.5:1 minimum; #0866FF gives 4.8:1. */
  --button: #0866FF;
  --accent-soft: #EAF2FF;
  --green: #16A34A;
  --green-soft: #EAFBF0;
  --danger: #DC2626;
  --map-bg: #E8EEF6;
  --map-street: #FFFFFF;
  --map-highway: #FFFFFF;
  --shadow: 0 18px 40px rgba(17, 24, 39, 0.10);
  --glow: 0 18px 48px rgba(22, 163, 74, 0.22);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0B1220;
    --surface: #111A2B;
    --field: #182338;
    --border: #243049;
    --text: #F3F6FB;
    --muted: #9AA6BA;
    --accent: #3D86FF;
    --green: #22C55E;
    --green-soft: rgba(34, 197, 94, 0.14);
    --danger: #EF4444;
    --accent-soft: rgba(61, 134, 255, 0.16);
    --map-bg: #152036;
    --map-street: #22314D;
    --map-highway: #2D4066;
    --shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
    --glow: 0 18px 48px rgba(34, 197, 94, 0.22);
  }
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
}

html {
  scroll-behavior: smooth;
}

body {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
}

/* ---- Layout -------------------------------------------------------------- */

/* The pitch is the first screen, exactly; the affiliate form is below it. */
.page {
  flex: 1;
  width: 100%;
  max-width: 1120px;
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0 auto;
  padding: 40px 16px 24px;
  display: grid;
  gap: 48px;
  align-items: center;
  align-content: center;
}

@media (min-width: 900px) {
  .page {
    grid-template-columns: 1.1fr 0.9fr;
    padding: 36px 32px 16px;
    gap: 64px;
  }
}

/* ---- Pitch --------------------------------------------------------------- */

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.01em;
}

/* The mark is transparent, so it needs no tile, corners or shadow -- any of
   those would draw a box around it. */
.brand img {
  display: block;
}

/*
  Sized so each sentence fits on one line and the break falls between them.
  A sentence is ~10.35x its font size wide; the phone column is the viewport
  less 32px of gutter, so 8.6vw keeps "Every gig mile, tracked." on one line
  on any screen from 291px up. At 34px it needed 352px of a 343px column,
  and wrapped as "tracked. Every" -- the end of one thought and the start of
  the next on the same line.
*/
h1 {
  margin: 24px 0 0;
  font-size: clamp(26px, 8.6vw, 50px);
  line-height: 1.06;
  letter-spacing: -0.03em;
  font-weight: 850;
  text-wrap: balance;
}

/* Each sentence is kept whole where it fits, so the line break prefers the
   boundary between them over a break mid-sentence. */
.headline-line {
  display: inline-block;
}

/*
  Two columns: the text column tops out near 545px, and at 54px the first
  sentence was 552px -- 7px over. Capped at 50px (512px), and scaled with the
  viewport below the max width, where the column narrows. Placed after the
  base h1 rule on purpose; see the note on the short-screen block.
*/
@media (min-width: 900px) {
  h1 {
    font-size: clamp(34px, calc(5.1vw - 8px), 50px);
  }
}

.lede {
  margin: 18px 0 0;
  max-width: 34em;
  font-size: clamp(17px, 1.6vw, 19px);
  color: var(--muted);
}

.features {
  list-style: none;
  margin: 24px 0 0;
  padding: 0;
  display: grid;
  gap: 14px;
}

@media (min-width: 600px) {
  .features {
    grid-template-columns: 1fr 1fr;
    gap: 18px 28px;
  }
}

.features li {
  padding-left: 16px;
  border-left: 3px solid var(--accent);
}

.features strong {
  display: block;
  font-size: 15.5px;
  font-weight: 750;
}

.features span {
  display: block;
  margin-top: 2px;
  font-size: 14.5px;
  color: var(--muted);
}

/* ---- Store buttons ------------------------------------------------------- */

/*
  Apple's and Google's own badge artwork, downloaded from their marketing
  sites and served from here. Both forbid altering the badges or adding
  effects -- shadows, glows, animation -- so the links get no hover styling;
  only a focus ring, drawn around the link rather than on the badge.
*/
.stores {
  margin-top: 28px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* 48px: over Apple's 40px on-screen minimum, and the same for both badges,
   since Google's must be no smaller than any other store's beside it. */
.badge {
  display: inline-flex;
  border-radius: 9px;
}

.badge img {
  display: block;
  height: 48px;
  width: auto;
}

.badge:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

.store {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 24px;
  border-radius: 14px;
  font-size: 16px;
  font-weight: 750;
  text-decoration: none;
  border: 1.5px solid var(--border);
  color: var(--text);
  background: var(--surface);
}

.store-soon {
  color: var(--muted);
  cursor: default;
}

.origin {
  margin: 22px 0 0;
  font-size: 14px;
  color: var(--muted);
}

.origin a {
  display: inline-block;
  margin-left: 6px;
  color: var(--accent);
  font-weight: 700;
  text-decoration: none;
}

.origin a:hover {
  text-decoration: underline;
}

/* ---- The trip card ------------------------------------------------------- */

.demo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.card {
  width: 100%;
  max-width: 380px;
  padding: 20px;
  border-radius: 22px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}

/* The green edge is the app's verdict colour, so it belongs to the offer
   card alone -- a drive has no verdict. */
.card-trip {
  border: 2px solid var(--green);
  box-shadow: var(--glow);
}

.card-head {
  font-size: 18px;
  font-weight: 800;
}

.fields {
  margin-top: 16px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.label {
  font-size: 13px;
  font-weight: 700;
}

.value {
  padding: 11px 14px;
  border: 1px solid var(--border);
  border-radius: 14px;
  font-size: 17px;
  font-weight: 750;
}

.value em {
  font-style: normal;
  font-weight: 500;
  color: var(--muted);
}

.row {
  margin-top: 10px;
  padding: 10px 14px;
  border-radius: 12px;
  background: var(--field);
  display: grid;
  grid-template-columns: 1fr auto;
  row-gap: 2px;
  align-items: center;
}

.row-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 700;
}

.row-value {
  font-size: 16px;
  font-weight: 800;
}

.row-sub {
  grid-column: 1 / -1;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
}

.row-good {
  background: var(--green-soft);
}

.row-good .row-title,
.row-good .row-value {
  color: var(--green);
}

.log-button {
  margin-top: 14px;
  padding: 14px;
  border-radius: 16px;
  background: var(--text);
  color: var(--bg);
  text-align: center;
  font-size: 16px;
  font-weight: 800;
}

/* ---- The drive card ------------------------------------------------------ */

.track-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* The app's header pill: blue label, green dot while tracking is on. */
.auto-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--field);
  color: var(--accent);
  font-size: 12.5px;
  font-weight: 750;
}

.auto-pill i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--green);
}

.map {
  display: block;
  width: 100%;
  height: auto;
  margin-top: 12px;
}

.map-bg {
  fill: var(--map-bg);
}

.map-streets {
  fill: none;
  stroke: var(--map-street);
  stroke-width: 5;
}

.map-highway {
  fill: none;
  stroke: var(--map-highway);
  stroke-width: 11;
  stroke-linecap: round;
}

/* Drawn under the route in the card's own colour, the way map apps outline
   a route so it reads over the streets beneath it. */
.route-casing,
.route {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.route-casing {
  stroke: var(--surface);
  stroke-width: 10;
}

.route {
  stroke: var(--accent);
  stroke-width: 5;
}

/* Green where the drive began, red where it ended -- the app's own markers. */
.dot {
  stroke: var(--surface);
  stroke-width: 3;
}

.dot-start {
  fill: var(--green);
}

.dot-end {
  fill: var(--danger);
}

.track-stats {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
}

.track-miles {
  font-size: 24px;
  font-weight: 850;
  letter-spacing: -0.02em;
}

.track-miles em {
  font-style: normal;
  font-size: 15px;
  font-weight: 600;
  color: var(--muted);
}

.track-time {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
}

.classify {
  margin-top: 12px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.chip {
  padding: 10px;
  border-radius: 12px;
  background: var(--field);
  text-align: center;
  font-size: 14px;
  font-weight: 750;
}

.chip-work {
  background: var(--green-soft);
  color: var(--green);
}

/*
  Two columns: the cards overlap instead of stacking, which is what keeps
  the page to one screen -- stacked, the column would be nearly 700px tall.
  Both sit in the same grid cell; the drive card hugs the top-left and the
  trip card is pushed down and right, in front, so they read in the
  headline's order. The offset clears the bottom of the map with room to
  spare at every card width, so the route is never covered.
*/
@media (min-width: 900px) {
  .demo {
    display: grid;
    grid-template-areas: "stack";
  }

  .demo .card {
    grid-area: stack;
  }

  .card-track {
    width: min(310px, 78%);
    justify-self: start;
    align-self: start;
  }

  .card-trip {
    position: relative;
    z-index: 1;
    width: min(340px, 82%);
    justify-self: end;
    align-self: start;
    margin-top: 168px;
  }
}

/* ---- Affiliate applications --------------------------------------------- */

.affiliates {
  border-top: 1px solid var(--border);
  padding: 64px 16px 56px;
}

.aff-inner {
  max-width: 1056px;
  margin: 0 auto;
  display: grid;
  gap: 36px;
}

@media (min-width: 900px) {
  .affiliates {
    padding: 88px 32px 72px;
  }

  .aff-inner {
    grid-template-columns: 1fr 1fr;
    gap: 64px;
    align-items: start;
  }
}

.eyebrow {
  margin: 0;
  color: var(--accent);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.affiliates h2 {
  margin: 10px 0 0;
  font-size: clamp(26px, 3.4vw, 38px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: 850;
  text-wrap: balance;
}

.aff-points {
  list-style: none;
  margin: 26px 0 0;
  padding: 0;
  display: grid;
  gap: 16px;
}

.aff-points li {
  padding-left: 16px;
  border-left: 3px solid var(--green);
  font-size: 15.5px;
  color: var(--muted);
}

.aff-points strong {
  color: var(--text);
  font-weight: 750;
}

.aff-form {
  padding: 24px;
  border-radius: 22px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  display: grid;
  gap: 18px;
}

.field-block {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
  display: grid;
  gap: 8px;
}

.field-label {
  padding: 0;
  font-size: 14px;
  font-weight: 750;
}

/* 16px, not less: iOS Safari zooms the page into any smaller field. */
.aff-form input[type="text"],
.aff-form input[type="email"] {
  width: 100%;
  padding: 13px 14px;
  border-radius: 14px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-size: 16px;
}

.aff-form input::placeholder {
  color: var(--muted);
}

.aff-form input[type="text"]:focus,
.aff-form input[type="email"]:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.choice-row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

@media (min-width: 480px) {
  .choice-row {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* Real radio buttons, drawn as chips. The input stays in the page -- only
   invisible -- so it keeps keyboard focus, arrow keys and screen readers. */
.choice {
  position: relative;
}

.choice input {
  position: absolute;
  inset: 0;
  opacity: 0;
  margin: 0;
  cursor: pointer;
}

.choice span {
  display: block;
  padding: 11px 6px;
  border-radius: 12px;
  border: 1.5px solid var(--border);
  background: var(--bg);
  text-align: center;
  font-size: 14.5px;
  font-weight: 750;
}

.choice input:checked + span {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}

.choice input:focus-visible + span {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

.hint {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
}

.submit {
  min-height: 52px;
  border: 0;
  border-radius: 14px;
  background: var(--button);
  color: #FFFFFF;
  font: inherit;
  font-size: 16px;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(8, 102, 255, 0.28);
  transition: transform 120ms ease, box-shadow 120ms ease;
}

.submit:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 26px rgba(8, 102, 255, 0.34);
}

.submit:focus-visible {
  outline: 3px solid var(--text);
  outline-offset: 3px;
}

/* Shown once the mail app has been asked to open. It can't confirm the
   email was sent -- only the visitor's own Send button does that -- so it
   says what to do next rather than claiming success. */
.aff-status {
  display: grid;
  gap: 10px;
  padding: 14px;
  border-radius: 12px;
  background: var(--green-soft);
  color: var(--text);
  font-size: 14px;
}

/* An author display rule beats the browser's own [hidden] rule, so without
   this the box would show before anyone pressed Apply. */
.aff-status[hidden] {
  display: none;
}

.aff-status p {
  margin: 0;
}

.aff-status strong {
  color: var(--green);
}

.aff-status-alt {
  color: var(--muted);
  font-size: 13.5px;
}

/* Side by side in equal halves: as a wrapping row they split onto two
   lines on a phone by a single pixel. */
.aff-alt-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.aff-alt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 40px;
  padding: 0 14px;
  border-radius: 10px;
  border: 1.5px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  font-weight: 750;
  text-decoration: none;
  cursor: pointer;
}

.aff-alt:hover {
  border-color: var(--accent);
}

.aff-alt:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

/* The application exactly as it will be sent, so it can be checked, and
   copied by hand if the copy button isn't allowed to. */
.aff-preview {
  margin: 0;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--muted);
  font: inherit;
  font-size: 12.5px;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.aff-copied {
  color: var(--green);
  font-size: 13px;
  font-weight: 700;
}

.aff-copied:empty {
  display: none;
}

.fine {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--muted);
}

.fine a {
  color: var(--muted);
}

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

.footer {
  padding: 14px 16px 20px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 20px;
  font-size: 13px;
  color: var(--muted);
}

.footer a {
  color: var(--muted);
}

.footer a:hover {
  color: var(--text);
}

.legal {
  flex-basis: 100%;
  max-width: 62ch;
  margin: 2px auto 0;
  text-align: center;
  font-size: 11.5px;
  line-height: 1.5;
}

/* On a phone the line wraps anyway; break it after the copyright, so the
   two links stay together instead of "Terms" being orphaned. */
@media (max-width: 600px) {
  .footer span {
    flex-basis: 100%;
    text-align: center;
  }
}

/* ---- The 404 page -------------------------------------------------------- */

.lost {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 40px 16px;
  text-align: center;
}

.lost a {
  color: var(--accent);
  font-weight: 700;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .submit {
    transition: none;
  }
}

/*
  Kept last on purpose. Every rule in here overrides a base rule of equal
  specificity, and CSS resolves a tie in favour of whichever comes later in
  the file -- placed above the base rules, this block is silently ignored.
*/
/*
  Short laptop screens. A 1366x768 display -- still the most common Windows
  laptop -- leaves about 650px for the page once the browser's own toolbars
  are drawn, and the page is meant to be one screen. Tall screens keep the
  roomier spacing above; only the short ones tighten.
*/
@media (min-width: 900px) and (max-height: 820px) {
  .page {
    padding-top: 20px;
    padding-bottom: 8px;
    gap: 48px;
  }

  .brand img {
    width: 44px;
    height: 44px;
  }

  h1 {
    margin-top: 14px;
    font-size: clamp(32px, 3.4vw, 42px);
  }

  .lede {
    margin-top: 10px;
    font-size: 16.5px;
  }

  .features {
    margin-top: 16px;
    gap: 10px 24px;
  }

  .features span {
    font-size: 13.5px;
  }

  .stores {
    margin-top: 18px;
  }

  .origin {
    margin-top: 12px;
  }

  .card {
    padding: 16px;
  }

  .fields {
    margin-top: 12px;
  }

  .footer {
    padding: 8px 16px 12px;
  }
}
