/* Parking Floor Finder — one stylesheet for every page.

   The look is a garage stairwell ("Stairwell B"): poured-concrete walls, floor numbers
   stencilled huge, and the blue of the app's own level sign (Theme.sign, 11/79/216),
   with curb yellow as a small accent only. No hazard stripes (Juan, Oct 14). The
   altimeter readouts are the measuring half of it.
   Direction and reasoning: site/README.md ▸ Design. */

@font-face {
  font-family: "Big Shoulders Display";
  src: url("fonts/big-shoulders.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible";
  src: url("fonts/atkinson-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible";
  src: url("fonts/atkinson-700.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/jetbrains-mono.woff2") format("woff2");
  font-weight: 100 800;
  font-display: swap;
}

:root {
  --brand: #0b4fd8;        /* the app icon's blue: fills (sign, buttons), same in both modes */
  --brand-dark: #083ca6;
  --sign: #0b4fd8;         /* blue for text and lines; lighter in dark mode to stay readable */
  --sign-dark: #083ca6;
  --sign-soft: #dfe5f3;
  --curb: #f2c230;
  --soot: #17181b;
  --ink: #17181b;
  --ink-2: #4c4f57;
  --line: #cfcbc2;
  --page: #e9e6df;
  --panel: #f4f2ed;
  --stencil: rgba(23, 24, 27, 0.07);
  --ok: #157f3b;
  --warn: #9a5b00;
  --exit: #138a4a;
  --radius: 4px;
  --max: 1080px;
  --display: "Big Shoulders Display", "Arial Narrow", Impact, sans-serif;
  --body: "Atkinson Hyperlegible", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  color-scheme: light dark;
}

/* The stairwell with the lights low. */
@media (prefers-color-scheme: dark) {
  :root {
    --sign: #4d82ff;
    --sign-dark: #3a6ff0;
    --sign-soft: #1b2335;
    --ink: #ecebe6;
    --ink-2: #a9a8a2;
    --line: #2e3036;
    --page: #141518;
    --panel: #1c1e22;
    --stencil: rgba(236, 235, 230, 0.06);
    --ok: #4cc27a;
    --warn: #e0a24a;
    --exit: #2fbf6c;
  }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background-color: var(--page);
  /* Poured concrete: a faint grain over the wall colour. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5 0 0 0 0 .5 0 0 0 0 .5 0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  color: var(--ink);
  font: 18px/1.55 var(--body);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--sign); text-underline-offset: 3px; }
a:hover { color: var(--sign-dark); }
img { max-width: 100%; display: block; }

.wrap { max-width: var(--max); margin: 0 auto; padding: 0 20px; position: relative; }
.narrow { max-width: 760px; }

/* Header and footer */

.site-header { border-bottom: 2px solid var(--ink); }
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 64px; }
.brand {
  display: flex; align-items: center; gap: 10px;
  color: var(--ink); text-decoration: none;
  font: 800 22px/1 var(--display); text-transform: uppercase; letter-spacing: 0.02em;
}
.brand:hover { color: var(--ink); }
.brand img { width: 32px; height: 32px; border-radius: 8px; }
.site-nav { display: flex; gap: 22px; }
.site-nav a {
  color: var(--ink-2); text-decoration: none;
  font: 700 17px/1 var(--display); text-transform: uppercase; letter-spacing: 0.06em;
}
.site-nav a:hover, .site-nav a[aria-current="page"] { color: var(--ink); }
@media (max-width: 420px) { .brand { font-size: 19px; } .site-nav { gap: 14px; } }

.site-footer { border-top: 2px solid var(--ink); margin-top: 72px; padding: 28px 0 40px; color: var(--ink-2); font-size: 15px; }
.site-footer .wrap { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px 24px; }
.site-footer nav { display: flex; flex-wrap: wrap; gap: 8px 18px; }
.site-footer a { color: var(--ink-2); }
.copyright { flex-basis: 100%; }

/* The stairwell's green EXIT sign: back to the street, at the top of the page. */
.exit-sign {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--ink-2); text-decoration: none; font-size: 15px;
}
.exit-word {
  font: 900 20px/1 var(--display); text-transform: uppercase; letter-spacing: 0.12em;
  color: #fff; background: var(--exit);
  padding: 7px 10px 6px; border-radius: 3px;
  box-shadow: 0 0 18px -2px color-mix(in srgb, var(--exit) 70%, transparent);
}
.exit-sign:hover { color: var(--ink); }

/* Type */

h1, h2, h3 { margin: 0 0 0.5em; }
h1, h2 {
  font-family: var(--display);
  font-weight: 900;
  text-transform: uppercase;
  line-height: 0.95;
  letter-spacing: 0.005em;
}
h1 { font-size: clamp(52px, 7.4vw, 92px); }
h2 { font-size: clamp(38px, 5vw, 58px); }
h3 { font-size: 20px; font-weight: 700; line-height: 1.25; }
p { margin: 0 0 1em; }
.lede { font-size: clamp(18px, 2.2vw, 21px); color: var(--ink-2); max-width: 34em; }
.eyebrow {
  display: inline-block;
  font: 500 13px/1 var(--mono); text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--soot); background: var(--curb);
  padding: 6px 8px; margin-bottom: 20px;
}

/* Hero: floor 1, the street */

.hero { padding: 64px 0 56px; overflow: hidden; }
.hero .wrap { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 56px; align-items: center; }
@media (max-width: 860px) {
  .hero { padding-top: 40px; }
  .hero .wrap { grid-template-columns: 1fr; gap: 40px; }
}

/* The level sign painted on the wall, with the app's notification over it and the
   barometer climb that put the number there. */

.wall-sign { margin: 0 auto; width: 100%; max-width: 380px; position: relative; }

.sign-plate {
  background: var(--brand);
  color: #fff;
  padding: 26px 28px 18px;
  border-radius: var(--radius);
  position: relative;
  box-shadow: 10px 10px 0 var(--soot);
}
@media (prefers-color-scheme: dark) { .sign-plate { box-shadow: 10px 10px 0 #000; } }
.sign-label { display: block; font: 800 26px/1 var(--display); text-transform: uppercase; letter-spacing: 0.2em; opacity: 0.9; }
.sign-number { display: block; font: 900 230px/0.8 var(--display); letter-spacing: -0.02em; margin: 14px 0 18px; }

.notif {
  display: flex; gap: 12px; align-items: flex-start;
  position: relative; z-index: 1;
  margin: 0 -14px -22px 34px;
  background: color-mix(in srgb, var(--panel) 92%, transparent);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  color: var(--ink);
  border-radius: 18px;
  padding: 12px 14px;
  font-size: 14px;
  line-height: 1.35;
  box-shadow: 0 14px 30px -14px rgba(0, 0, 0, 0.45);
}
.notif img { width: 28px; height: 28px; border-radius: 7px; flex: none; }
.notif strong { display: block; font-size: 15px; }

.trace { margin-top: 34px; }
.trace svg { width: 100%; height: auto; aspect-ratio: 320 / 96; display: block; overflow: visible; }
.trace-grid line { stroke: var(--line); stroke-width: 1; stroke-dasharray: 2 4; vector-effect: non-scaling-stroke; }
.trace-line {
  fill: none; stroke: var(--sign); stroke-width: 3; stroke-linejoin: round;
  stroke-dasharray: 1; stroke-dashoffset: 0;
}
.trace-dot { fill: var(--curb); stroke: var(--soot); stroke-width: 2; }
.trace-axis { display: flex; justify-content: space-between; margin-top: 8px; font: 500 12px/1 var(--mono); text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-2); }

/* The climb draws itself each time the sign comes into view (motion.js sets .in). */
.trace-dot { transform-box: fill-box; transform-origin: center; }
.motion .wall-sign:not(.in) .trace-line { stroke-dashoffset: 1; }
.motion .wall-sign:not(.in) .trace-dot { opacity: 0; }
.motion .wall-sign.in .trace-line { animation: climb 2.2s cubic-bezier(.5, 0, .3, 1) 0.3s both; }
.motion .wall-sign.in .trace-dot { animation: arrive 0.4s ease-out 2.4s both; }
@keyframes climb { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes arrive { from { opacity: 0; transform: scale(0.2); } to { opacity: 1; transform: scale(1); } }

/* Between floors: a painted line, labelled with the ramp down to the next floor. */

.ramp {
  height: 2px;
  position: relative;
  background: var(--ink);
}
.ramp span {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  font: 500 12px/1 var(--mono); text-transform: uppercase; letter-spacing: 0.08em; white-space: nowrap;
  color: var(--ink); background: var(--page);
  padding: 7px 12px 6px;
  border: 2px solid var(--ink);
  border-radius: var(--radius);
}

/* Sign-up and feedback forms */

.form { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 28px; max-width: 540px; }
.form input[type="email"], .form input[type="text"], .form textarea, .form select {
  flex: 1 1 240px;
  font: inherit;
  color: var(--ink);
  background: var(--panel);
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  padding: 12px 14px;
  min-width: 0;
}
.form input:focus, .form textarea:focus, .form select:focus { outline: 3px solid var(--curb); outline-offset: 2px; }
.stack { flex-direction: column; max-width: 620px; }
.stack label { font-size: 15px; font-weight: 700; margin-bottom: -4px; }
.form.stack input[type], .form.stack select, .form.stack textarea { flex: none; width: 100%; }
.stack textarea { min-height: 150px; resize: vertical; }
.hp { position: absolute; left: -9999px; }

.button {
  font: 800 20px/1 var(--display); text-transform: uppercase; letter-spacing: 0.06em;
  color: #fff; background: var(--brand);
  border: 2px solid var(--brand); border-radius: var(--radius);
  padding: 14px 20px 13px;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  box-shadow: 4px 4px 0 var(--ink);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.button:hover { background: var(--brand-dark); border-color: var(--brand-dark); color: #fff; }
.button:active { transform: translate(3px, 3px); box-shadow: 1px 1px 0 var(--ink); }
.button[disabled] { opacity: 0.6; cursor: default; }
.stack .button { align-self: flex-start; }

.form-status { flex-basis: 100%; font-size: 15px; margin: 4px 0 0; min-height: 1.5em; }
.form-status.ok { color: var(--ok); }
.form-status.error { color: var(--warn); }
.fineprint { font-size: 15px; color: var(--ink-2); margin-top: 10px; }

/* Floors (sections). Each has its number stencilled huge on the wall behind it. */

.section { padding: 72px 0; position: relative; overflow: hidden; }
.section-head { max-width: 680px; margin-bottom: 36px; position: relative; }

.floor-tag {
  position: absolute; right: 0; top: -40px;
  font: 900 clamp(200px, 30vw, 360px)/1 var(--display);
  color: var(--stencil);
  pointer-events: none; user-select: none;
}
.floor-tag.street::before { content: "Street level"; }
.floor-tag::before {
  content: "Floor";
  position: absolute; right: 0.1em; top: 0.18em;
  font-size: 0.14em; letter-spacing: 0.3em; text-transform: uppercase; white-space: nowrap;
}

.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; counter-reset: step; list-style: none; padding: 0; margin: 0; position: relative; }
@media (max-width: 820px) { .steps { grid-template-columns: 1fr; } }
.step { border-top: 2px solid var(--ink); padding: 18px 28px 0 0; }
.step::before {
  counter-increment: step;
  content: "0" counter(step);
  display: block;
  font: 500 14px/1 var(--mono); letter-spacing: 0.08em;
  color: var(--sign);
  margin-bottom: 14px;
}
.step p { color: var(--ink-2); margin: 0; }
@media (max-width: 820px) { .step { padding: 18px 0 26px; } }

/* Screenshots of the app (floor 3), each in a plain phone outline. On narrow screens
   they become a row you swipe through instead of three tiny phones. */

.screens { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; margin-top: 56px; position: relative; }
.screen { margin: 0; }
.phone {
  max-width: 290px;
  border: 7px solid var(--soot);
  border-radius: 46px;
  overflow: hidden;
  background: var(--soot);
  box-shadow: 10px 10px 0 color-mix(in srgb, var(--soot) 22%, transparent);
}
@media (prefers-color-scheme: dark) { .phone { border-color: #000; outline: 1px solid var(--line); box-shadow: none; } }
.phone img { width: 100%; height: auto; }
.screen figcaption { margin-top: 18px; max-width: 290px; font-size: 16px; line-height: 1.45; color: var(--ink-2); }
.screen figcaption span {
  display: block; margin-bottom: 6px;
  font: 500 13px/1 var(--mono); text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--sign);
}
@media (max-width: 820px) {
  .screens {
    grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: min(72%, 290px);
    gap: 20px; overflow-x: auto; scroll-snap-type: x mandatory;
    margin: 44px -20px 0; padding: 0 20px 18px; scroll-padding: 0 20px;
  }
  .screen { scroll-snap-align: start; }
}

.answers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; position: relative; }
@media (max-width: 820px) { .answers { grid-template-columns: 1fr; } }
.answer { background: var(--panel); border: 2px solid var(--ink); border-radius: var(--radius); padding: 20px 22px 22px; }
.answer .readout { font: 500 13px/1 var(--mono); text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-2); padding-bottom: 12px; margin-bottom: 14px; border-bottom: 1px dashed var(--line); }
.answer .big { font: 900 54px/0.95 var(--display); text-transform: uppercase; color: var(--sign); margin-bottom: 10px; }
.answer p { color: var(--ink-2); margin: 0; font-size: 17px; }

/* Street level (floor 1): what stays on the phone and what leaves it */

.ledger { display: grid; grid-template-columns: 1fr 1fr; border: 2px solid var(--ink); border-radius: var(--radius); background: var(--panel); position: relative; }
@media (max-width: 760px) { .ledger { grid-template-columns: 1fr; } }
.ledger-col { padding: 24px 26px; }
.ledger-col + .ledger-col { border-left: 2px solid var(--ink); }
@media (max-width: 760px) { .ledger-col + .ledger-col { border-left: 0; border-top: 2px solid var(--ink); } }
.ledger h3 { font: 900 26px/1 var(--display); text-transform: uppercase; letter-spacing: 0.02em; margin-bottom: 16px; }
.ledger ul { margin: 0 0 16px; padding-left: 1.1em; }
.ledger li { margin-bottom: 0.55em; }
.ledger-note { font-size: 15px; color: var(--ink-2); margin: 0; padding-top: 14px; border-top: 1px dashed var(--line); }
.level[data-floor="1"] .fineprint { margin-top: 18px; position: relative; }

/* The feature list follows straight on from the privacy summary, without a full floor's
   gap between them. */
.level[data-floor="1"] { padding-bottom: 0; }
.specs { padding-top: 28px; }
.points { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px 40px; padding: 0; margin: 0; list-style: none; }
@media (max-width: 680px) { .points { grid-template-columns: 1fr; } }
.points li { padding-left: 30px; position: relative; color: var(--ink-2); }
.points li::before { content: ""; position: absolute; left: 0; top: 0.5em; width: 10px; height: 10px; background: var(--brand); }

/* The altimeter rail: wide screens only. A ruler down the left edge, floor 4 at the top
   and the street at the bottom, like the page. Its marker walks down as the page scrolls;
   motion.js moves it and writes the height above the street. */

.rail { display: none; }
@media (min-width: 1260px) {
  .rail {
    display: block;
    position: fixed; left: 28px; top: 96px; bottom: 40px; width: 14px;
    z-index: 5; pointer-events: none;
  }
  .rail-ticks {
    position: absolute; inset: 0;
    border-left: 2px solid var(--ink);
    background: repeating-linear-gradient(to top, var(--ink) 0 1px, transparent 1px 12px) left / 8px 100% no-repeat;
    opacity: 0.55;
  }
  .rail-marker {
    position: absolute; left: -4px; top: 0;
    width: 22px; height: 4px; background: var(--curb);
    outline: 2px solid var(--soot);
    transform: translateY(calc(var(--down, 0) * (100vh - 136px)));
    will-change: transform;
  }
  .rail-floor {
    position: absolute; left: -22px;
    font: 500 11px/1 var(--mono); color: var(--ink-2);
    transform: translateY(-50%);
  }
  .rail-floor.f4 { top: 0; }
  .rail-floor.f3 { top: 33.333%; }
  .rail-floor.f2 { top: 66.667%; }
  .rail-floor.f1 { top: 100%; }
  .rail-readout {
    position: absolute; left: 30px; top: -17px;
    font: 500 12px/1.35 var(--mono); white-space: pre;
    color: var(--ink); background: var(--page);
    padding: 4px 6px; border: 1px solid var(--line);
  }
}

/* Scroll motion (home page). Only under html.motion, which motion.js sets when the
   visitor hasn't asked to reduce motion, so without it everything is simply there.
   Things slide in from the left like cars coming up the ramp, floor numbers rise into
   place, and each ramp line draws across before the next floor. It plays every time
   something comes into view, scrolling down or back up: motion.js resets an element
   once it is fully off screen and notes which side it left by (data-from), so floor
   numbers come down from above and ramp lines draw from the right on the way up. */

.motion [data-reveal] {
  transition: opacity 0.7s ease, transform 0.8s cubic-bezier(.2, .7, .2, 1);
}
.motion [data-reveal]:not(.in) { opacity: 0; transform: translateX(-48px); }
.motion [data-reveal="rise"]:not(.in) { transform: translateY(64px); }
.motion [data-reveal="rise"][data-from="above"]:not(.in) { transform: translateY(-64px); }

.motion [data-reveal="stagger"] { transition: none; }
.motion [data-reveal="stagger"]:not(.in) { opacity: 1; transform: none; }
.motion [data-reveal="stagger"] > * {
  transition: opacity 0.6s ease, transform 0.7s cubic-bezier(.2, .7, .2, 1);
  transition-delay: calc(var(--i, 0) * 110ms + 120ms);
}
.motion [data-reveal="stagger"]:not(.in) > * { opacity: 0; transform: translateX(-36px); }

.motion [data-reveal="ramp"] { transition: transform 0.9s cubic-bezier(.6, 0, .2, 1); transform-origin: left center; }
.motion [data-reveal="ramp"][data-from="above"] { transform-origin: right center; }
.motion [data-reveal="ramp"]:not(.in) { opacity: 1; transform: scaleX(0); }
.motion [data-reveal="ramp"] span { transition: opacity 0.4s ease 0.8s; }
.motion [data-reveal="ramp"]:not(.in) span { opacity: 0; transition-delay: 0s; }

/* Long-form pages: privacy, support */

.doc { padding: 48px 0 0; }
.doc h1 { font-size: clamp(48px, 7vw, 72px); }
.doc h2 { font-size: clamp(30px, 4vw, 38px); margin-top: 48px; }
.doc h3 { font-size: 19px; margin-top: 28px; }
.doc ul { padding-left: 1.2em; }
.doc li { margin-bottom: 0.4em; }
.doc .updated { font: 500 14px/1.4 var(--mono); color: var(--ink-2); }
.doc table { width: 100%; border-collapse: collapse; margin: 8px 0 20px; font-size: 16px; background: var(--panel); }
.doc th, .doc td { text-align: left; vertical-align: top; padding: 10px 12px; border-bottom: 1px solid var(--line); }
.doc th { font: 800 17px/1.2 var(--display); text-transform: uppercase; letter-spacing: 0.04em; border-bottom: 2px solid var(--ink); }
.table-scroll { overflow-x: auto; }
.callout { background: var(--panel); border-left: 8px solid var(--curb); border-radius: var(--radius); padding: 18px 20px; margin: 20px 0; }
.callout p:last-child { margin-bottom: 0; }

.faq details { border-bottom: 1px solid var(--line); padding: 4px 0; }
.faq summary { cursor: pointer; font-weight: 700; padding: 14px 0; list-style: none; position: relative; padding-right: 32px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; position: absolute; right: 4px; top: 10px; font: 500 22px/1.2 var(--mono); color: var(--ink-2); }
.faq details[open] summary::after { content: "−"; }
.faq details > div { padding: 0 0 16px; color: var(--ink-2); }
.faq details > div p:last-child { margin-bottom: 0; }

.skip { position: absolute; left: -9999px; }
.skip:focus { left: 12px; top: 12px; background: var(--page); padding: 8px 12px; border-radius: 8px; z-index: 10; }
