/* Pocket Speedometer — web. Editorial / typographic design, warm paper palette,
   IBM Plex, terracotta as a warning accent only. Mirrors the iOS app's language. */

:root {
  --bg: #F5F0E6;          /* warm cream */
  --surface: #EFE8DA;
  --edge: #EBE3D2;
  --text: #1A1817;        /* warm charcoal */
  --text-2: #6B655B;      /* warm stone */
  --hairline: #D8D0BE;
  --accent: #B8391E;      /* terracotta */
  --positive: #4A6B3C;
  --sans: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1A1817;
    --surface: #252320;
    --edge: #100E0C;
    --text: #F5F0E6;
    --text-2: #9A9388;
    --hairline: #3A3631;
    --accent: #D85638;
    --positive: #7A9A6B;
  }
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }

html {
  height: 100%;
  background:
    radial-gradient(120% 90% at 50% 38%, var(--bg) 0%, var(--edge) 140%);
  color: var(--text);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}

/* The instrument fills the first screen via .app's 100svh; the landing prose
   below it grows the page naturally. `overflow-x: clip` keeps any wide content
   from causing sideways scroll without auto-promoting overflow-y (which would
   turn body into its own scroll container — unwanted on iOS). */
body {
  min-height: 100%;
  overflow-x: clip;
}

.app {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100svh;
  max-width: 540px;
  margin: 0 auto;
  padding: max(12px, env(safe-area-inset-top)) 22px max(14px, env(safe-area-inset-bottom));
}

/* ---- Top strip ---- */
.strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 10px;
  border-bottom: 1px solid color-mix(in srgb, var(--text) 14%, transparent);
}
.brand { display: flex; align-items: center; gap: 9px; }
.bar { width: 22px; height: 2px; background: var(--accent); display: inline-block; }
.brand-name {
  font-size: 11px; font-weight: 500; letter-spacing: 0.18em; text-transform: uppercase;
  color: color-mix(in srgb, var(--text) 60%, transparent);
}
.gps {
  display: flex; align-items: center; gap: 7px;
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-2); font-family: var(--mono);
}
.gps-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--text-2); opacity: 0.4; transition: background .3s, opacity .3s;
}
.gps-dot.live { background: var(--positive); opacity: 1; box-shadow: 0 0 0 0 var(--positive); }
.gps-dot.weak { background: var(--accent); opacity: 1; }

/* ---- Mode switcher ---- */
.switcher {
  display: flex; align-self: center; gap: 2px;
  margin: 16px 0 4px;
  background: color-mix(in srgb, var(--text) 6%, transparent);
  border-radius: 999px; padding: 3px;
}
.seg {
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--sans); font-size: 12px; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-2); padding: 7px 18px; border-radius: 999px;
  transition: color .2s, background .2s;
}
.seg.active { color: var(--text); background: var(--bg); box-shadow: 0 0 0 1px var(--hairline); }

/* ---- Stage ---- */
.stage {
  position: relative; flex: 1;
  display: flex; align-items: center; justify-content: center;
  min-height: 0;
}
.dial { width: 100%; height: 100%; display: block; }

.readout {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  pointer-events: none;
}
.readout .unit, .readout { pointer-events: none; }
.unit { pointer-events: auto; }

.speed {
  font-family: var(--mono); font-weight: 300;
  font-variant-numeric: tabular-nums; line-height: 0.9;
  letter-spacing: -0.02em; color: var(--text);
}
.unit {
  display: inline-flex; align-items: center; gap: 4px;
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--sans); font-weight: 500; text-transform: uppercase;
  color: var(--text); letter-spacing: 0.16em;
  padding: 6px 4px; margin-top: 2px;
}
.unit .chev { opacity: 0.55; transition: opacity .3s; }
.unit.pulse .chev { animation: chevpulse 0.95s ease-in-out infinite; }
@keyframes chevpulse { 0%,100% { opacity: 0.5; } 50% { opacity: 1; } }

.caption {
  font-family: var(--sans); font-size: 11px; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--text-2);
  margin-top: 10px; opacity: 0; transition: opacity .25s; height: 13px;
}
.caption.show { opacity: 1; }
.caption.error { color: var(--accent); letter-spacing: 0.08em; text-transform: none; font-weight: 400; opacity: 1; }

/* Detecting-state dots — three dots that step in one at a time, the small
   "I'm looking" tell that a satellite-grade fix takes a beat. The pseudo
   reserves room for all three so the caption never shifts horizontally; the
   `content` property snaps between keyframes (it's not interpolatable),
   which is exactly the typewriter feel we want. */
.caption.detecting::after {
  content: '.';
  display: inline-block;
  width: 1.6ch;
  text-align: left;
  margin-left: 0.1em;
  animation: cap-dots 1.4s linear infinite;
}
@keyframes cap-dots {
  0%   { content: '.'; }
  33%  { content: '..'; }
  66%  { content: '...'; }
}
@media (prefers-reduced-motion: reduce) {
  .caption.detecting::after { animation: none; content: '…'; }
}

/* Analog: readout sits low in the dial opening */
.mode-analog .readout { bottom: 16%; }
.mode-analog .speed { font-size: clamp(40px, 14vw, 76px); }
.mode-analog .unit { font-size: clamp(13px, 3.4vw, 17px); }

/* Digital: remove the dial from layout (not just hidden — else it shoves the
   readout sideways) and centre the number in the stage. */
.mode-digital .dial { display: none; }
.mode-digital .readout { top: 50%; transform: translate(-50%, -50%); }
.mode-digital .speed { font-size: clamp(120px, 42vw, 240px); }
.mode-digital .unit { font-size: clamp(16px, 4.4vw, 22px); }
.mode-digital .caption { margin-top: 14px; }

/* First-run unit hint bubble */
.hint {
  position: absolute; bottom: 8%;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--hairline); border-radius: 10px;
  font-size: 12px; font-weight: 500; letter-spacing: 0.02em;
  padding: 8px 12px; pointer-events: none;
  animation: hintin .3s ease both;
}
.hint::after {
  content: ""; position: absolute; top: -6px; left: 50%; transform: translateX(-50%);
  border-left: 7px solid transparent; border-right: 7px solid transparent;
  border-bottom: 6px solid var(--surface);
}
@keyframes hintin { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---- Stats ---- */
.stats {
  display: flex; justify-content: space-between;
  border-top: 1px solid color-mix(in srgb, var(--text) 12%, transparent);
  padding-top: 14px; margin-top: 6px;
}
.stat { display: flex; flex-direction: column; gap: 3px; flex: 1; }
.stat:nth-child(2) { align-items: center; }
.stat:nth-child(3) { align-items: flex-end; }
.stat-val { font-family: var(--mono); font-weight: 400; font-size: 20px; font-variant-numeric: tabular-nums; }
.stat-cap { font-size: 10px; font-weight: 500; letter-spacing: 0.2em; text-transform: uppercase; color: var(--text-2); }

/* ---- Footer ---- */
.foot {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 12px; font-size: 11px; color: var(--text-2);
  letter-spacing: 0.04em;
}
.tagline { font-weight: 500; }
.store { font-family: var(--mono); opacity: 0.85; }
.foot-link {
  font-family: var(--mono);
  color: var(--text-2); text-decoration: none;
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 1px;
  transition: color .2s, border-color .2s;
}
.foot-link:hover { color: var(--text); border-bottom-color: var(--text); }

/* ---- Desktop card ----
   Hidden by default; revealed on hover-capable + fine-pointer devices, where
   real GPS is rare and the speedometer would either sit at zero or hallucinate
   speed from position jitter. The CSS swap also hides the instrument elements
   on the same query so the layout collapses cleanly to brand → card → footer. */
.desktop-card { display: none; }

@media (hover: hover) and (pointer: fine) {
  .switcher, .stage, .stats { display: none; }
  .gps { opacity: 0.5; }

  .desktop-card {
    display: flex; flex: 1;
    flex-direction: column; align-items: center; justify-content: center;
    text-align: center; gap: 14px;
    padding: 24px 12px;
    max-width: 380px; margin: 0 auto;
  }

  .desktop-eyebrow {
    font-family: var(--sans); font-size: 11px; font-weight: 500;
    letter-spacing: 0.22em; text-transform: uppercase;
    color: var(--accent);
    margin: 0;
  }
  .desktop-headline {
    font-family: var(--sans); font-weight: 300;
    font-size: clamp(24px, 3vw, 30px);
    line-height: 1.2; letter-spacing: -0.01em;
    color: var(--text);
    margin: 4px 0 0;
  }
  .desktop-body {
    font-family: var(--sans); font-size: 14px; font-weight: 300;
    line-height: 1.55; color: var(--text-2);
    margin: 0; max-width: 320px;
  }
  .desktop-qr {
    width: clamp(180px, 22vw, 240px);
    height: auto;
    margin-top: 10px;
    color: var(--text);
    background: var(--bg);
    border: 1px solid var(--hairline);
    border-radius: 8px;
    padding: 14px;
    /* SVG paths inherit currentColor, so dark mode flips the QR automatically.
       The light card background gives the scanner a high-contrast quiet zone. */
  }
  @media (prefers-color-scheme: dark) {
    .desktop-qr { background: var(--surface); }
  }
  .desktop-url {
    font-family: var(--mono); font-size: 12px;
    letter-spacing: 0.06em; color: var(--text-2);
    margin: 6px 0 0;
  }

  /* Bigger canvas on desktop — the .app's 540px max-width is too narrow when
     the user can use the whole window. */
  .app { max-width: 720px; }
}

@media (max-height: 680px) {
  .switcher { margin: 10px 0 0; }
}

/* ============================================================
   Craft details — print/instrument language, hand-considered.
   ============================================================ */

/* Paper grain: a faint fractal-noise wash so the cream reads as stock, not flat
   #F5F0E6. Sits above everything but ignores pointer events. */
body::after {
  content: "";
  position: fixed; inset: 0; z-index: 60; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
  opacity: 0.05; mix-blend-mode: soft-light;
}

/* Corner crop marks — the instrument sits inside a registered plate, like a
   trimmed print. Four L's, drawn with two borders each. */
.plate { position: absolute; inset: 1.5% 0; pointer-events: none; }
.plate i {
  position: absolute; width: 13px; height: 13px;
  border: 0 solid color-mix(in srgb, var(--text) 26%, transparent);
}
.plate i:nth-child(1) { top: 0; left: 0;     border-top-width: 1px;    border-left-width: 1px; }
.plate i:nth-child(2) { top: 0; right: 0;    border-top-width: 1px;    border-right-width: 1px; }
.plate i:nth-child(3) { bottom: 0; left: 0;  border-bottom-width: 1px; border-left-width: 1px; }
.plate i:nth-child(4) { bottom: 0; right: 0; border-bottom-width: 1px; border-right-width: 1px; }

/* Live GPS pulse — a quiet radar ping on the status dot. */
.gps-dot.live { position: relative; }
.gps-dot.live::after {
  content: ""; position: absolute; inset: -3px; border-radius: 50%;
  border: 1px solid var(--positive); opacity: 0;
  animation: ping 2.4s ease-out infinite;
}
@keyframes ping {
  0%   { transform: scale(0.6); opacity: 0.7; }
  70%  { transform: scale(2.2); opacity: 0; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .gps-dot.live::after { animation: none; } }

/* Serial / model mark in the footer — gives it the feel of a numbered product
   rather than a template. */
.foot-right { display: inline-flex; align-items: center; gap: 8px; }
.serial {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em;
  color: var(--text); padding: 2px 7px; border-radius: 999px;
  border: 1px solid var(--hairline);
}
.foot .dot { opacity: 0.4; }

/* ============================================================
   Landing prose — sits below the speedometer for first-time visitors.
   Editorial column, generous line-height, paper palette inherited.
   ============================================================ */

.page {
  max-width: 620px;
  margin: 0 auto;
  padding: 64px 26px 96px;
  position: relative;
  z-index: 1;
}

/* When installed to the home screen, the home-screen icon should open a clean
   instrument with no prose to scroll past. Web visitors still see everything. */
@media (display-mode: standalone) {
  .page { display: none; }
}

.prose h2 {
  font-family: var(--sans);
  font-size: 12px; font-weight: 500;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--text);
  margin: 0 0 18px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--hairline);
}

.prose h2:not(:first-child) { margin-top: 56px; }

.prose h3 {
  font-family: var(--sans);
  font-size: 16px; font-weight: 500;
  color: var(--text);
  margin: 28px 0 8px;
  letter-spacing: -0.005em;
}

.prose p {
  font-family: var(--sans);
  font-size: 16px; font-weight: 300;
  line-height: 1.7;
  color: var(--text);
  margin: 0 0 14px;
}

.prose p em {
  font-style: italic;
  color: var(--text);
}

/* Colophon — a thin line of marginalia at the foot of the page, in the same
   spirit as the .foot strip inside the instrument. */
.colophon {
  margin-top: 64px;
  padding-top: 18px;
  border-top: 1px solid var(--hairline);
  display: flex; align-items: center; gap: 10px;
  font-family: var(--mono);
  font-size: 11px; letter-spacing: 0.06em;
  color: var(--text-2);
}
.colophon a { color: var(--text-2); text-decoration: none; border-bottom: 1px solid var(--hairline); padding-bottom: 1px; }
.colophon a:hover { color: var(--text); border-bottom-color: var(--text); }
.colophon .sep { opacity: 0.45; }

@media (max-width: 480px) {
  .page { padding: 48px 22px 72px; }
  .prose p { font-size: 15px; }
  .prose h3 { font-size: 15px; }
}
