/* ── Heebo, self-hosted ───────────────────────────────────────────────────
   Self-hosted, not a CDN: this screen loads on a forecourt with bad signal, and a
   third-party origin costs an extra DNS lookup, TLS handshake and round trip before a
   single glyph appears. The CSP here is default-src 'self' anyway, so an external font
   would simply be blocked.

   Two subsets, Hebrew first — a Hebrew-only page never fetches the Latin file.
   The variable axis is what makes Heebo the right pick: 100-900 gives us 900 for the
   pressure number, which Assistant (max 800) and Rubik cannot provide.

   font-display: swap so the number is readable before the font lands. */
@font-face {
  font-family: "Heebo";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/heebo-hebrew.woff2") format("woff2");
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
@font-face {
  font-family: "Heebo";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/heebo-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
/* ─────────────────────────────────────────────────────────────────────────────
   לחץ אוויר — a single-purpose instrument.

   Written for one moment: standing at the air pump, one hand on the phone, sun on
   the screen, someone waiting behind you. Every decision below comes from that.

   · The NUMBER is the interface. It is not inside a card — it IS the screen.
   · Both units, always. Israeli pumps read PSI on some forecourts and BAR on others,
     and mental arithmetic at the pump is where mistakes happen.
   · Black on white, maximum contrast. In direct sunlight that beats any dark theme.
   · Nothing decorative competes with the number. Colour appears only to warn.
   ───────────────────────────────────────────────────────────────────────────── */
:root{
  --bg:#FFFFFF;
  --ink:#0B0D10;      /* 19.5:1 */
  --ink-2:#535A62;    /* 7.00:1 — AAA */
  --ink-3:#6A6F75;    /* 4.65:1 on the page ground — was #949BA3 at 2.81:1, which failed even 3:1 */
  --line:#8C8D8F;     /* 3.32:1 on white, 3.05:1 on the page ground — a border that carries meaning must be seen.
                         The old #E7E9EC was 1.22:1: invisible outdoors. */
  --line-dec:#E7E9EC; /* decoration only — never the sole carrier of meaning */
  --surface-2:#F4F5F7;
  --warn:#7B5000; --warn-bg:#FDF3E2;   /* 7.00:1 */
  --crit:#A33024; --crit-bg:#FDEDEB;   /* 7.00:1 */
  --good:#05673B; --good-bg:#E9F7F0;   /* 7.00:1 */
  --plate:#F5C518; --plate-blue:#12377E;

  /* ── brand ──────────────────────────────────────────────────────────
     Green, from Eden's mockup — but not the mockup's exact green.

     ⛔ The mockup button is #2E9E5B, which measures 3.41:1 against white. That fails AA
     for the label sitting on it, and this is a product used outdoors in direct sun, where
     ambient light raises the black level and makes a marginal ratio worse, not better.
     So the green splits in two by JOB rather than by taste:

       --brand         #1A8045  4.98:1 on white / 4.56:1 on the page ground
       --brand-bright  #3BA55C  5.53:1 ON NAVY — green text and icons inside dark sections,
                                where the same hue is legible and the mockup's tone survives

     ⚠️ Green is now BOTH the brand and the "working" verdict. That is a real collision and
     it is handled by shape, not by hue: every status is an icon in a filled disc plus a
     word, so it never depends on the reader distinguishing two greens. */
  --brand:#1A8045;        /* 4.98:1 on white, 4.56:1 on --surface-2 */
  --brand-deep:#146138;   /* pressed */
  --brand-bright:#3BA55C; /* on navy only — 5.53:1 there, 3.12:1 on white */
  --brand-bg:#E8F5EE;
  --navy:#0F1B2E;         /* white on it: 17.26:1 */
  --brand-line:#A9D8BE;   /* decoration only — 1.62:1 carries no meaning */
  --navy-2:#1A2942;
  --sans:"Heebo","Segoe UI",system-ui,Arial,sans-serif;
  --mono:"Cascadia Mono",Consolas,ui-monospace,monospace;
  --r:14px; --r-pill:999px;
  /* P0-4: 56px for the primary action, 48px floor for anything tappable. Hubert's
     field data puts 95% accuracy at 26.5px centre / 45.4px corners for a RELAXED user;
     ours has one hand, sun, and a running compressor. */
  --tap:48px; --tap-primary:56px;
  --e:cubic-bezier(.2,0,0,1); --e-out:cubic-bezier(.05,.7,.1,1);
  --t:180ms;
}
*{box-sizing:border-box}
:root{
  font-synthesis: none;              /* no faux-bold or faux-italic on Hebrew */
  font-variant-numeric: tabular-nums;/* 33 and 11 must occupy the same width */
  -webkit-text-size-adjust: 100%;
}
/* An <svg><use href="#..."> carries no intrinsic size and defaults to 300x150. Three
   components were destroyed by that before this rule existed; every icon now has a floor,
   and the per-component rules below still win. */
svg{width:20px;height:20px;flex:none;vertical-align:middle}
html,body{margin:0;padding:0}
body{
  background:var(--bg); color:var(--ink); font-family:var(--sans);
  font-size:19px; line-height:1.5;    /* 19px body = 20-22 arcmin at 450mm (ANSI/HFES 100) */
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  /* Outdoors and one-handed: keep the whole app inside the safe area. */
  padding:max(20px,env(safe-area-inset-top)) 20px max(24px,env(safe-area-inset-bottom));
  min-height:100dvh;
}
.screen{max-width:440px;margin:0 auto;display:flex;flex-direction:column}
[hidden]{display:none!important}
button{font:inherit;color:inherit;cursor:pointer}

/* ── first run ─────────────────────────────────────────────────────────── */
h1{font-size:32px;line-height:1.2;font-weight:800;margin:26px 0 10px}
.lede{color:var(--ink-2);font-size:18px;margin:0 0 30px;max-width:34ch}

/* The input IS a licence plate. Recognition beats any label — and on a real plate the
   blue EU strip sits on the LEFT, which in an RTL flex row means it must come last. */
.plate{
  position:relative;display:flex;align-items:stretch;
  background:linear-gradient(180deg,#FBDD52,#EFBC0A);
  border:2.5px solid #0B0D10;border-radius:12px;overflow:hidden;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.55), inset 0 -2px 4px rgba(0,0,0,.14), 0 2px 6px rgba(11,13,16,.16);
}
.plate input{
  flex:1;min-width:0;border:0;background:transparent;outline:none;
  font-family:var(--mono);font-size:clamp(30px,9vw,40px);font-weight:700;letter-spacing:.06em;
  text-align:center;color:#0B0D10;padding:16px 6px;
  direction:ltr;unicode-bidi:isolate;
}
.plate input::placeholder{color:#846700}
.plate .il{
  order:99;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;
  /* graphic replica, not reading text — the one exception to the 18px floor */
  background:var(--plate-blue);color:#fff;width:46px;font-size:15px;font-weight:700;letter-spacing:.5px;
}
.plate .il b{color:var(--plate);font-size:15px;line-height:1}
.cam{
  border:0;background:transparent;padding:0 14px;min-width:var(--tap);display:flex;
  align-items:center;justify-content:center;
  color:rgba(11,13,16,.5);transition:color var(--t) var(--e),transform var(--t) var(--e);
}
.cam svg{width:24px;height:24px}
.cam:hover{color:rgba(11,13,16,.85)}
.cam:active{transform:scale(.9)}

#go{
  margin-top:14px;width:100%;min-height:var(--tap-primary);padding:17px;border:0;border-radius:var(--r);
  background:var(--ink);color:#fff;font-size:18px;font-weight:700;
  transition:transform var(--t) var(--e),opacity var(--t) var(--e);
}
#go:active{transform:scale(.98)}
#go:disabled{opacity:.45}
/* The typed-entry button is secondary wherever .typed is applied — outlined, not filled.
   Written as #go.typed so it beats the base #go rule instead of quietly losing to it. */
#go.typed{ background:transparent; border:1.5px solid rgba(255,255,255,.28); color:#fff }
#go.typed:disabled{ opacity:.45 }

.ghost{
  margin-top:16px;width:100%;min-height:var(--tap);padding:14px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--bg);color:var(--ink-2);font-size:18px;font-weight:600;
  display:flex;align-items:center;justify-content:center;gap:9px;
  transition:background var(--t) var(--e),border-color var(--t) var(--e);
}
.ghost svg{width:18px;height:18px}
.ghost:hover{background:var(--surface-2);border-color:var(--ink-3)}
.ghost:active{transform:scale(.99)}

.err{margin-top:16px;padding:13px 15px;border-radius:var(--r);
  background:var(--crit-bg);color:var(--crit);font-size:18px;font-weight:600}

/* ── the answer ────────────────────────────────────────────────────────── */
/* One tap target, top of screen: says which car we are answering for, and swaps it. */
.carbar{
  display:flex;align-items:center;gap:10px;width:100%;
  border:0;border-bottom:2px solid var(--line);background:transparent;
  padding:6px 2px 14px;min-height:var(--tap);text-align:start;
}
.carbar .nm{font-size:18px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.carbar .tyre{font:600 18px/1 var(--mono);color:var(--ink-2);background:var(--surface-2);
  padding:5px 8px;border-radius:6px;direction:ltr;unicode-bidi:isolate;white-space:nowrap}
.carbar .sw{width:17px;height:17px;color:var(--ink-3);margin-inline-start:auto;flex:none}

/* THE NUMBER. clamp() keeps it enormous on a phone and sane on a laptop; the two axles
   share the row only when the pressures actually differ. */
.readout{display:flex;justify-content:center;gap:clamp(18px,7vw,52px);
  padding:clamp(22px,7vh,46px) 0 clamp(14px,3vh,22px)}
.axle{text-align:center;min-width:0}
.axle .lab{font-size:22px;font-weight:700;color:var(--ink);letter-spacing:0;margin-bottom:4px}
.axle .big{display:flex;align-items:baseline;justify-content:center;gap:8px;
  font-family:var(--sans);font-weight:900;color:var(--ink);
  font-size:clamp(64px,22vw,104px);line-height:.95;
  direction:ltr;unicode-bidi:isolate;font-variant-numeric:tabular-nums;
}
.axle .big i{font-family:var(--sans);font-style:normal;font-size:clamp(20px,6vw,28px);
  font-weight:700;color:var(--ink-2);letter-spacing:.01em}
.axle .alt{font-family:var(--mono);font-size:clamp(15px,4.5vw,20px);color:var(--ink-2);
  margin-top:8px;direction:ltr;unicode-bidi:isolate}
/* A changed number should be visibly new, but never counted up — the driver may already
   be reading it, and a moving digit is a misread waiting to happen. */
.axle.flip .big span{animation:lift 260ms var(--e-out)}
@keyframes lift{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
.axle.none .big{color:var(--ink-3)}

/* The load switch. Thumb-sized, two states, physical. */
.loadsw{
  position:relative;display:grid;grid-template-columns:1fr 1fr;
  background:var(--surface-2);border-radius:var(--r-pill);padding:5px;margin-top:6px;
}
.loadsw button{
  position:relative;z-index:1;border:0;background:transparent;border-radius:var(--r-pill);
  padding:18px 8px;font-size:19px;font-weight:700;color:var(--ink-2);
  transition:color var(--t) var(--e);
}
.loadsw button.on{color:var(--ink)}
.loadsw .knob{
  position:absolute;z-index:0;top:5px;bottom:5px;right:5px;width:calc(50% - 5px);
  background:var(--bg);border-radius:var(--r-pill);border:1px solid var(--line);
  transition:transform var(--t) var(--e);
}
/* RTL: the first tab sits on the RIGHT, so the knob starts there and slides LEFT. */
.loadsw[data-load="normal"] .knob{transform:translateX(0)}
.loadsw[data-load="loaded"] .knob{transform:translateX(-100%)}
.loadnote{font-size:18px;color:var(--ink-3);text-align:center;margin-top:10px;min-height:20px}

/* Where the number came from. Never hidden — an estimate must not look like a fact. */
.src{display:flex;align-items:center;justify-content:center;gap:7px;flex-wrap:wrap;
  margin-top:18px;font-size:18px}
.src .tag{display:inline-flex;align-items:center;gap:5px;padding:6px 11px;border-radius:var(--r-pill);
  font-weight:650}
.src .tag svg{width:14px;height:14px}
.src .ok{background:var(--good-bg);color:var(--good)}
.src .warn{background:var(--warn-bg);color:var(--warn)}
.src .crit{background:var(--crit-bg);color:var(--crit)}
.src .plainq{color:var(--ink-3)}

.rule{display:flex;gap:11px;margin-top:22px;padding:16px;border:1px solid var(--line);
  border-radius:var(--r);font-size:18px;line-height:1.6;color:var(--ink-2)}
.rule svg{width:19px;height:19px;flex:none;color:var(--ink-3);margin-top:2px}
.rule b{color:var(--ink)}

/* The no-answer state is a real screen, not an error. It has one clear next action. */
.nodata{text-align:center;padding:20px 0 4px}
.nodata .ic{width:40px;height:40px;color:var(--ink-3);margin-bottom:10px}
.nodata .n{font-size:22px;font-weight:700;margin-bottom:8px}
.nodata .d{color:var(--ink-2);font-size:18px;max-width:32ch;margin:0 auto}

.spin{width:26px;height:26px;border:3px solid var(--line);border-top-color:var(--ink);
  border-radius:50%;animation:spin .8s linear infinite;margin:44px auto}
@keyframes spin{to{transform:rotate(360deg)}}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:1ms!important;transition-duration:1ms!important}
}

/* Warm-tyre correction. Michelin's own guidance is +0.3 bar when the tyre is warm from
   driving; a driver who inflates to the cold number on a hot tyre is under-inflated by
   morning. Given as a sentence, never as a calculator — nobody does arithmetic beside a
   running compressor. */
.rule.hot{border-color:var(--warn);background:var(--warn-bg);color:var(--warn)}
.rule.hot b{color:var(--warn)}
.rule.hot svg{color:var(--warn)}

/* Cached answer. web.dev is explicit: do not use the word "offline" in the interface, do
   not signal state by colour alone, and stamp the data with when it was fetched. */
.saved{display:flex;align-items:center;justify-content:center;gap:8px;
  margin-top:18px;font-size:18px;color:var(--ink-2)}
.saved svg{width:17px;height:17px;color:var(--good);flex:none}

/* The placard route is offered where it is the entire answer, so it gets primary weight. */
.cta{display:flex;align-items:center;justify-content:center;gap:9px;width:100%;
  min-height:var(--tap-primary);margin-top:20px;padding:16px;border:0;border-radius:var(--r);
  background:var(--ink);color:#fff;font-size:18px;font-weight:700;
  transition:transform var(--t) var(--e)}
.cta svg{width:21px;height:21px}
.cta:active{transform:scale(.98)}
.wait{text-align:center;font-size:18px;color:var(--ink-2);margin-top:-24px}

/* ── air stations ───────────────────────────────────────────────────────────
   A LIST, not a map. Deliberate: the driver has one hand, sun on the screen and a queue
   behind them. Pinch-zooming a tile map one-handed is slower than reading three lines, the
   tiles are a network dependency exactly where the signal is worst, and the actual next
   action is not "look at a map" — it is "navigate there". So: distance, whether the pump is
   known to exist, and one tap into Waze. */
.backbar{display:flex;align-items:center;gap:10px;width:100%;min-height:var(--tap);
  border:0;border-bottom:2px solid var(--line);background:transparent;
  padding:6px 2px 14px;text-align:start;font-size:18px;font-weight:700}
.backbar svg{width:22px;height:22px;flex:none}
/* RTL: back points right */
[dir="rtl"] .backbar svg{transform:scaleX(-1)}

.st{display:grid;grid-template-columns:1fr auto;gap:4px 12px;align-items:center;
  padding:16px 2px;border-bottom:1px solid var(--line-dec)}
.st:last-child{border-bottom:0}
.st .nm{grid-column:1;font-size:18px;font-weight:700;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.st .ad{grid-column:1;font-size:16px;color:var(--ink-2)}
.st .dist{grid-column:2;grid-row:1;font:700 18px/1 var(--mono);color:var(--ink);
  direction:ltr;unicode-bidi:isolate;white-space:nowrap}
.st .acts{grid-column:1/-1;display:flex;gap:8px;margin-top:10px}
.st .acts a{flex:1;min-height:var(--tap);display:flex;align-items:center;justify-content:center;
  gap:8px;border:1px solid var(--line);border-radius:var(--r);text-decoration:none;
  font-size:17px;font-weight:600;color:var(--ink)}
.st .acts a svg{width:19px;height:19px;color:var(--ink-2)}
.st .acts a.go{background:var(--ink);color:#fff;border-color:var(--ink)}
.st .acts a.go svg{color:#fff}

/* State is never colour alone — icon + word + colour, per web.dev's guidance on status. */
.pump{display:inline-flex;align-items:center;gap:5px;font-size:15px;font-weight:650;
  padding:4px 9px;border-radius:var(--r-pill);border:1px solid}
.pump.yes{color:var(--good);background:var(--good-bg);border-color:var(--good)}
.pump.unk{color:var(--ink-2);background:var(--surface-2);border-color:var(--line)}
.pump.no{color:var(--crit);background:var(--crit-bg);border-color:var(--crit)}

.cta.air{background:var(--bg);color:var(--ink);border:2px solid var(--ink)}
.cta.air svg{color:var(--ink)}
.airnote{margin-top:18px;padding:15px;border:1px solid var(--line);border-radius:var(--r);
  font-size:16px;line-height:1.55;color:var(--ink-2)}

/* The status pill had no icon sizing, so the tick inherited the browser default and
   swallowed the row. Every `use`-based icon needs an explicit box — there is no sensible
   intrinsic size on a sprite reference. */
.pump svg{width:17px;height:17px;flex:none}
.pump{align-self:center;white-space:nowrap}
.st .nm{align-items:center}

/* ── "I filled up" → next check ─────────────────────────────────────────────
   The only reminder channel that works for everyone: a calendar file. Web cannot schedule
   a local notification (the Triggers API was abandoned), and iOS push needs the app
   installed to the home screen first — roughly a quarter of Israeli mobile traffic would
   never be reached. A .ics needs no server, no account and no permission. */
.filled{margin-top:22px;padding:16px;border:1px solid var(--line);border-radius:var(--r)}
.fillbtn{display:flex;align-items:center;justify-content:center;gap:9px;width:100%;
  min-height:var(--tap);border:0;background:transparent;color:var(--ink);
  font-size:18px;font-weight:700}
.fillbtn svg{width:21px;height:21px;color:var(--good)}
.fillnote{margin-top:12px;padding-top:14px;border-top:1px solid var(--line-dec);
  font-size:18px;line-height:1.55;color:var(--ink-2);text-align:center}
.fillnote b{color:var(--ink)}
.fillnote .cal{display:flex;align-items:center;justify-content:center;gap:8px;
  margin-top:12px;min-height:var(--tap);border:1px solid var(--line);border-radius:var(--r);
  text-decoration:none;color:var(--ink);font-size:17px;font-weight:600}
.chip-test{display:inline-flex;align-items:center;gap:6px;margin-top:10px;padding:6px 11px;
  border-radius:var(--r-pill);font-size:16px;font-weight:650}
.chip-test.warn{color:var(--warn);background:var(--warn-bg);border:1px solid var(--warn)}
.chip-test.crit{color:var(--crit);background:var(--crit-bg);border:1px solid var(--crit)}

/* the status chip sits inside a flex row with the car name — keep it from taking the row */
.chip-test{max-width:60%}
.chip-test svg{width:17px;height:17px}
.carbar{flex-wrap:wrap}
.carbar .nm{flex:1 1 auto;min-width:0}

/* The honest proportion, above the list rather than under it — at the bottom it reads as
   a disclaimer nobody scrolls to; at the top it frames everything below. */
.airsum{padding:14px 2px 16px;font-size:18px;line-height:1.55;color:var(--ink-2);
  border-bottom:2px solid var(--line)}
.airsum b{color:var(--ink)}
/* Freshness. A confirmation without a timestamp is indistinguishable from a guess. */
.when{font-size:16px;color:var(--ink-3)}
.when.good{color:var(--good);font-weight:650}
.when.bad{color:var(--crit);font-weight:650}

/* The axle diagram. Sized so the numbers inside it stay in the same league as the single
   big number — the drawing is scaffolding for them, never the subject. */
.cardia{width:min(340px,88vw);height:auto;display:block;margin:0 auto}
.dia-bar{text-align:center;font-family:var(--mono);font-size:18px;color:var(--ink-2);
  margin-top:6px;direction:ltr;unicode-bidi:isolate}
.readout:has(.cardia){display:block}

/* Empty-state illustrations sit in space rather than in a row, so they are bigger and
   lighter than the interface icons — and the global 20px default does not apply to them. */
.nodata .ic{width:64px;height:64px;color:var(--ink-3);stroke-width:2.2;margin-bottom:14px}
/* The pump pin is a filled marker: its colour comes from the state class around it, never
   from the symbol, so the icon can never disagree with the label beside it. */
.pump svg{width:18px;height:18px}

/* ── my cars ────────────────────────────────────────────────────────────────
   A saved car is the entire retention argument: the second visit has to cost zero taps.
   The strip only appears once there are two — one car needs no chooser. */
.garage{display:flex;gap:8px;overflow-x:auto;padding:2px 2px 14px;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.garage::-webkit-scrollbar{display:none}
.gcar{flex:0 0 auto;min-height:var(--tap);display:flex;flex-direction:column;
  align-items:flex-start;gap:2px;padding:10px 14px;border:1px solid var(--line);
  border-radius:var(--r);background:var(--bg);text-align:start;
  transition:border-color var(--t) var(--e),background var(--t) var(--e)}
.gcar.on{border-color:var(--ink);border-width:2px;padding:9px 13px}
.gcar .n{font-size:16px;font-weight:700;white-space:nowrap}
.gcar .p{font:700 15px/1 var(--mono);color:var(--good);direction:ltr;unicode-bidi:isolate}
.gcar .p.none{color:var(--ink-3)}
.gcar.add{color:var(--ink-2);justify-content:center;font-size:16px;font-weight:600}

/* ── tips ───────────────────────────────────────────────────────────────── */
.tip{border-bottom:1px solid var(--line-dec)}
.tip:last-child{border-bottom:0}
.tipq{display:flex;align-items:center;gap:11px;width:100%;min-height:var(--tap);
  border:0;background:transparent;padding:18px 2px;text-align:start;
  font-size:18px;font-weight:700;color:var(--ink)}
.tipq svg{color:var(--ink-3)}
.tipq .chev{margin-inline-start:auto;transition:transform var(--t) var(--e)}
.tip[open] .tipq .chev{transform:rotate(90deg)}
[dir="rtl"] .tipq .chev{transform:rotate(180deg)}
[dir="rtl"] .tip[open] .tipq .chev{transform:rotate(90deg)}
.tipa{padding:0 2px 20px;font-size:18px;line-height:1.65;color:var(--ink-2)}
.tipa b{color:var(--ink)}
.tipa ol,.tipa ul{margin:10px 0 0;padding-inline-start:22px}
.tipa li{margin-bottom:8px}
.tipsrc{display:block;margin-top:12px;font-size:15px;color:var(--ink-3)}

/* ════════════════════════════════════════════════════════════════════════════
   DESKTOP
   Until now there was no desktop layout at all — a 440px phone column centred in a
   1512px window, with 172px of empty white on each side. That does not read as a
   deliberate design; it reads as a page that failed to load properly.

   The fix is NOT to stretch the phone layout. The pump scenario is a phone scenario, and
   a 1200px-wide pressure reading helps nobody. What a desktop visitor is actually doing is
   different: they are at a keyboard, looking something up, with no compressor running. So
   the wide viewport gets a real page around the tool — a header that says what this is,
   and the tool itself sitting in a column that is comfortable rather than stranded.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── install ──────────────────────────────────────────────────────────────
   A bar, not a modal. A modal over the answer would block the one thing the driver
   opened the app for, at the exact second they are reading it off the screen. */
.install{
  display:flex; align-items:center; gap:12px; position:relative;
  margin:22px 0 4px; padding:16px 16px 16px 14px;
  background:var(--surface-2); border:1px solid var(--line-dec); border-radius:var(--r);
}
.install .ico{ width:30px; height:30px; flex:none; color:var(--ink-2) }
.install .itxt{ display:flex; flex-direction:column; gap:3px; min-width:0; flex:1 }
.install .itxt b{ font-size:17px; font-weight:700; color:var(--ink) }
.install .itxt span{ font-size:15px; line-height:1.45; color:var(--ink-2) }
.install .ib{
  flex:none; min-height:44px; padding:0 20px; border:0; border-radius:var(--r-pill);
  background:var(--ink); color:#fff; font:700 17px/1 var(--sans); cursor:pointer;
}
/* The dismiss sits in the corner and still answers to a 44px finger, because the
   invisible half of the target extends past the glyph. */
.install .ix{
  position:absolute; top:2px; inset-inline-start:2px;
  width:44px; height:44px; display:grid; place-items:center;
  background:none; border:0; color:var(--ink-3); cursor:pointer;
}
.install .ix svg{ width:17px; height:17px }

/* ── the iOS explainer ────────────────────────────────────────────────── */
.iossheet{
  position:fixed; inset:0; z-index:60; display:flex; align-items:flex-end;
  background:rgba(11,13,16,.55);
}
.iosbox{
  width:100%; background:var(--bg); border-radius:22px 22px 0 0;
  padding:26px 22px calc(26px + env(safe-area-inset-bottom));
  display:flex; flex-direction:column; gap:18px;
}
.iosbox > b{ font-size:21px; font-weight:800 }
.iossteps{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:16px }
.iossteps li{ display:flex; align-items:flex-start; gap:12px; font-size:17px; line-height:1.5 }
.istep{
  flex:none; width:28px; height:28px; border-radius:50%; background:var(--ink); color:#fff;
  display:grid; place-items:center; font-size:15px; font-weight:700;
  font-variant-numeric:tabular-nums;
}
/* Apple's own glyphs, inline in the sentence — the instruction people fail is
   "find the share button", not "tap it". */
.isvg{ width:19px; height:19px; vertical-align:-4px; margin:0 2px; color:#0A63CE }

/* ── legal ────────────────────────────────────────────────────────────────
   Required to be reachable from every page, so it is outside the screen switcher and
   survives whichever screen is showing. */
.legalbar{
  display:flex; justify-content:center; align-items:center; gap:9px; flex-wrap:wrap;
  padding:22px 20px calc(26px + env(safe-area-inset-bottom));
  font-size:15px; color:var(--ink-3);
}
.legalbar a{ color:var(--ink-2); text-decoration:underline; text-underline-offset:3px;
  padding:6px 2px; }


/* ── legal / accessibility documents ──────────────────────────────────────
   Long-form reading, which is a different problem from the instrument screen: a
   measured line length, a real heading hierarchy, and generous space between blocks. */
.dochead{ padding:18px 20px 0 }
.docback{
  display:inline-flex; align-items:center; min-height:44px; padding:0 4px;
  color:var(--ink-2); font-size:17px; text-decoration:none;
}
.doc{
  max-width:44rem; margin:0 auto; padding:12px 20px 8px;
}
.doc h1{ font-size:32px; font-weight:800; line-height:1.2; margin:10px 0 14px }
.doc h2{ font-size:22px; font-weight:700; line-height:1.3; margin:34px 0 12px }
.doc p{ font-size:18px; line-height:1.7; color:var(--ink); margin:0 0 14px }
.doc .lede{ font-size:20px; line-height:1.6; color:var(--ink-2) }
.docmeta{ font-size:16px; color:var(--ink-3) }
.doclist{ margin:0 0 14px; padding-inline-start:22px; display:flex; flex-direction:column; gap:12px }
.doclist li{ font-size:18px; line-height:1.65 }
.docwarn{
  display:flex; gap:12px; align-items:flex-start;
  margin:22px 0; padding:16px 16px; border-radius:var(--r);
  background:var(--crit-bg); border:1px solid var(--crit); color:var(--crit);
}
.docwarn svg{ width:24px; height:24px; flex:none; margin-top:2px }
.docwarn div{ font-size:17px; line-height:1.6; color:var(--ink) }
.doccontact{
  margin:16px 0; padding:16px; border-radius:var(--r);
  background:var(--surface-2); border:1px solid var(--line-dec);
}
.doccontact b{ font-size:17px; display:block; margin-bottom:6px }
.doccontact p{ font-size:17px; margin:0; color:var(--ink-2) }
.docnote{ font-size:16px !important; color:var(--ink-2); margin-top:26px !important }


/* ── the brand, applied ───────────────────────────────────────────────────
   Where it goes: the mark, and every control the driver ACTS on.
   Where it never goes: the readout. A blue pressure number would read as a state,
   and this screen only earns the right to use colour when it is saying something
   about the tyre. */
/* ⛔ NOT `#go`. That button carries class "typed" — the secondary, keyboard-entry route —
   but an ID selector outranks a class, so `#go{background:var(--brand)}` painted it solid
   green and the scan screen showed two identical primary buttons stacked on each other.
   The rule dates from when #go WAS the only action; the screen was rebuilt around .shoot
   since. Style by ROLE, never by id, or the next rebuild reintroduces this. */
.shoot{ background:var(--brand) }
.shoot:active{ background:var(--brand-deep) }
.cta.air{ border-color:var(--brand); color:var(--brand) }
.cta.air svg{ color:var(--brand) }
.cta.air:active{ background:var(--brand-bg) }
.gcar.on{ border-color:var(--brand); background:var(--brand-bg) }
.install .ib{ background:var(--brand) }
.install .ib:active{ background:var(--brand-deep) }
.backbar svg{ color:var(--brand) }
.doc a, .legalbar a{ color:var(--brand) }

/* One focus ring for the whole product, in the brand colour, and always visible.
   :focus-visible so a finger tap does not leave a ring behind it. */
a:focus-visible, button:focus-visible, input:focus-visible, summary:focus-visible{
  outline:3px solid var(--brand); outline-offset:2px; border-radius:6px;
}

/* ── the fuel-chain lettermark ────────────────────────────────────────────
   A fixed 34px square whatever the letters, so a column of stations scans as a column
   and not as ragged text. Monochrome on purpose — colour is spoken for by the pump. */
.chain{
  flex:none; display:inline-grid; place-items:center;
  width:34px; height:34px; border-radius:9px;
  background:var(--surface-2); border:1px solid var(--line-dec);
  font-size:15px; font-weight:800; color:var(--ink-2);
  letter-spacing:-.3px;
}
.chain-independent{ color:var(--ink-3); font-weight:600 }

/* ── the car outline ─────────────────────────────────────────────────────
   Sized in CSS, not by attribute, because an <svg><use> with no size falls back to
   300x150 and blows the bar apart — this codebase has been bitten by that three times. */
.carbar .sil{ width:56px; height:25px; flex:none; color:var(--ink-2) }
.carbar .sil.guess{ color:var(--line) }

/* ── the lockup ───────────────────────────────────────────────────────── */
.brand{ display:flex; align-items:center; gap:10px; text-decoration:none; color:var(--ink) }
.brand .mark{ width:30px; height:30px; color:var(--brand); flex:none }
.bname{ font-size:21px; font-weight:800; letter-spacing:0 }

.mobrand{
  display:flex; align-items:center; justify-content:center; gap:9px;
  padding:calc(18px + env(safe-area-inset-top)) 20px 2px;
}
.mobrand .mark{ width:26px; height:26px; color:var(--brand) }
.mobrand .bname{ font-size:19px; font-weight:800 }

/* ── motion ───────────────────────────────────────────────────────────────
   Two jobs only, and both are about comprehension rather than delight:

   1. When a screen replaces another, a short rise tells you a NEW thing arrived —
      without it the answer appears where the form was and the eye misses the swap.
   2. When the pressure figure changes because you switched load, it must be
      obvious that it CHANGED. Same digits appearing silently is the failure mode.

   No count-up on the number. It is the one thing the driver came for, and a
   500ms animation on it is 500ms of showing them a value that is not the answer.  */
@keyframes rise{ from{ opacity:0; transform:translateY(9px) } to{ opacity:1; transform:none } }
@keyframes flash{ 0%{ opacity:.35 } 100%{ opacity:1 } }
@keyframes sweep{ from{ stroke-dashoffset:var(--dash) } to{ stroke-dashoffset:0 } }
@keyframes spin{ to{ transform:rotate(360deg) } }

.screen:not([hidden]){ animation:rise .22s cubic-bezier(.2,.7,.3,1) both }
.big.changed span{ animation:flash .2s ease-out both }
.install:not([hidden]){ animation:rise .3s .15s cubic-bezier(.2,.7,.3,1) both }
.iossheet:not([hidden]) .iosbox{ animation:rise .26s cubic-bezier(.2,.7,.3,1) both }

/* The waiting state. A ring that fills once, in the shape of the mark, instead of a
   spinner: the driver is looking at a tyre being filled, which is what is happening. */
.loading{ display:flex; flex-direction:column; align-items:center; gap:14px; padding:34px 0 }
.loading .mk{ width:56px; height:56px; color:var(--brand); animation:spin 1.6s linear infinite }
.loading .lt{ font-size:17px; color:var(--ink-2) }

@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important;
  }
}


/* ── Eden's mockup, applied ───────────────────────────────────────────────
   Navy sections, green actions, white cards on a soft ground. Three things from the
   mockup are deliberately NOT copied verbatim:

   1. The mockup's green (#2E9E5B) measures 3.41:1 on white and cannot carry a white
      label. --brand is the same hue two steps darker so the button still reads in sun.
   2. The status pills keep an icon AND a word. In the mockup they are coloured discs,
      and a coloured disc alone is the one thing that fails for a red-green colourblind
      driver — who is exactly the person a green "pump works" dot is aimed at.
   3. Card shadows are kept faint and paired with a border. A shadow at 0.06 alpha is
      physically invisible at 100,000 lux, so the border is what actually holds the card
      together outdoors. */

body{ background:var(--surface-2) }
.screen{ background:var(--bg) }

/* The hero and every dark panel. White on this measures 17.26:1. */
.navy{ background:var(--navy); color:#fff }
.navy .lede, .navy .sub{ color:#C7D2E0 }
.navy .accent{ color:var(--brand-bright) }

/* ── actions ──────────────────────────────────────────────────────────── */
.shoot, .cta.primary{
  background:var(--brand); color:#fff; border:0;
  box-shadow:0 1px 2px rgba(15,27,46,.16);
}
.shoot:active, .cta.primary:active{ background:var(--brand-deep) }
.cta.air{
  background:var(--navy); color:#fff; border:0;
}
.cta.air svg{ color:var(--brand-bright) }
.cta.air:active{ background:var(--navy-2) }

/* ── cards ────────────────────────────────────────────────────────────── */
.card{
  background:var(--bg); border:1px solid var(--line-dec); border-radius:18px;
  padding:18px; box-shadow:0 1px 3px rgba(15,27,46,.06);
}

/* ── the identity chips under the car name ───────────────────────────────
   "2023 · Hybrid · SUV" in the mockup. They are metadata, so they are quiet: no fill,
   no colour, just a hairline. The only chip that earns colour is the match confirmation. */
.chips{ display:flex; flex-wrap:wrap; gap:7px; margin-top:8px }
.chip{
  font-size:15px; font-weight:600; color:var(--ink-2);
  border:1px solid var(--line-dec); border-radius:var(--r-pill); padding:5px 11px;
  background:var(--bg);
}
.chip.ok{
  color:var(--good); background:var(--good-bg); border-color:transparent;
  display:inline-flex; align-items:center; gap:6px;
}
.chip.ok svg{ width:15px; height:15px }

/* ── the fuel-chain mark ──────────────────────────────────────────────────
   Real artwork when we have it, the lettermark when we do not — the two are the same
   size and the same shape so a list never looks ragged where a logo is missing. */
.chain{
  flex:none; display:inline-grid; place-items:center; overflow:hidden;
  width:38px; height:38px; border-radius:10px;
  background:var(--bg); border:1px solid var(--line-dec);
  font-size:15px; font-weight:800; color:var(--ink-2); letter-spacing:-.3px;
}
.chain img{ width:100%; height:100%; object-fit:contain; padding:4px }
.chain-independent{ color:var(--ink-3); font-weight:600 }

/* ── status, by shape as well as colour ──────────────────────────────── */
.pump{ display:inline-flex; align-items:center; gap:6px; font-size:15px; font-weight:600 }
.pump svg{ width:17px; height:17px }
.pump.yes{ color:var(--good) }
.pump.no{ color:var(--crit) }
.pump.unk{ color:var(--warn); background:var(--warn-bg); border-color:transparent }


/* ═══ THE MOCKUP LAYOUT ═══════════════════════════════════════════════════
   Rebuilt to Eden's mockup rather than tinted toward it. What the previous version got
   wrong was not colour, it was STRUCTURE — and the reason it stayed wrong for so long is
   that it was verified by reading computed styles instead of looking at the page. The
   first real screenshot showed the card clipped off the right edge while every numeric
   check reported no horizontal overflow.  ⇒ shot.ps1 exists so that cannot happen again. */

body{ padding:0; background:var(--surface-2) }

/* ── the scan screen ─────────────────────────────────────────────────────
   Dark, because the plate and the scan brackets are the subject and a dark ground makes
   the yellow plate the brightest thing on the screen. */
.hero{
  background:var(--navy); color:#fff;
  padding:calc(26px + env(safe-area-inset-top)) 20px 34px;
  text-align:center;
}
.hero h1{ font-size:31px; font-weight:800; line-height:1.2; margin:0 0 8px; color:#fff }
.hero .sub{ font-size:17px; line-height:1.5; color:#B9C4D4; margin:0 auto 24px; max-width:30ch }

/* The scan frame. Brackets at the corners, not a full border: a closed rectangle reads as
   a text field, an open one reads as a viewfinder. */
.scanbox{
  position:relative; max-width:340px; margin:0 auto;
  padding:18px; border-radius:18px; background:rgba(255,255,255,.05);
}
.cnr{ position:absolute; width:26px; height:26px; border:3px solid var(--brand-bright) }
.cnr.tl{ top:0; left:0;  border-right:0; border-bottom:0; border-radius:12px 0 0 0 }
.cnr.tr{ top:0; right:0; border-left:0;  border-bottom:0; border-radius:0 12px 0 0 }
.cnr.bl{ bottom:0; left:0;  border-right:0; border-top:0; border-radius:0 0 0 12px }
.cnr.br{ bottom:0; right:0; border-left:0;  border-top:0; border-radius:0 0 12px 0 }

/* ── the two ways in ─────────────────────────────────────────────────────
   The camera is primary because that is the mockup and it is one tap. Typing stays a
   real, labelled button rather than a link: the camera fails in low light and behind a
   dirty plate, and at that moment a faint link is not a route, it is a dead end. */
.shoot{
  display:flex; align-items:center; justify-content:center; gap:10px;
  width:100%; max-width:340px; margin:20px auto 0; min-height:var(--tap-lg,56px);
  border:0; border-radius:var(--r-pill); background:var(--brand); color:#fff;
  font:700 19px/1 var(--sans); cursor:pointer;
}
.shoot:active{ background:var(--brand-deep) }
.shoot svg{ width:22px; height:22px }
.typed{
  display:block; width:100%; max-width:340px; margin:10px auto 0; min-height:48px;
  background:transparent; border:1.5px solid rgba(255,255,255,.28); border-radius:var(--r-pill);
  color:#fff; font:600 17px/1 var(--sans); cursor:pointer;
}
.typed:disabled{ opacity:.4 }
.trust{
  display:flex; align-items:center; justify-content:center; gap:7px;
  font-size:15px; color:#8E9CB0; margin:16px 0 0;
}
.trust svg{ width:15px; height:15px }

/* ── the four promises ───────────────────────────────────────────────── */
.feats{
  display:grid; grid-template-columns:1fr 1fr; gap:12px;
  padding:20px 16px 6px; max-width:520px; margin:0 auto;
}
.feat{
  background:var(--bg); border:1px solid var(--line-dec); border-radius:16px;
  padding:16px 14px; display:flex; flex-direction:column; gap:6px; text-align:center;
  align-items:center;
}
.feat .fi{
  width:44px; height:44px; border-radius:50%; background:var(--brand-bg);
  display:grid; place-items:center; margin-bottom:2px;
}
.feat .fi svg{ width:22px; height:22px; color:var(--brand) }
.feat b{ font-size:17px; font-weight:700 }
.feat span{ font-size:15px; line-height:1.45; color:var(--ink-2) }

#ask .ghost{ max-width:340px; margin:16px auto 30px }

/* The plate keeps its own chrome — it is a real object and the yellow is the fastest
   "yes, this is an Israeli plate" signal on the screen. */
.scanbox .plate{ margin:0 }


/* ── the tab bar ──────────────────────────────────────────────────────────
   Fixed to the bottom so the camera is reachable one-handed at any scroll position.
   The page gets bottom padding to match, or the last card sits under it — a fixed bar
   without that padding is the commonest way to make a footer unreachable. */
.tabbar{
  position:fixed; inset-inline:0; bottom:0; z-index:40;
  display:grid; grid-template-columns:repeat(5,1fr); align-items:end;
  background:var(--navy); border-top:1px solid rgba(255,255,255,.08);
  padding:8px 4px calc(8px + env(safe-area-inset-bottom));
}
.tab{
  display:flex; flex-direction:column; align-items:center; gap:4px;
  background:none; border:0; padding:6px 2px; min-height:var(--tap,48px);
  color:#8E9CB0; font:600 12px/1.2 var(--sans); cursor:pointer;
}
.tab svg{ width:22px; height:22px }
.tab.on{ color:var(--brand-bright) }

/* The camera sits above the bar's line, which is what makes it read as the primary
   action rather than a fifth tab. */
.fab{
  justify-self:center; width:58px; height:58px; margin-top:-22px;
  border-radius:50%; border:4px solid var(--navy); background:var(--brand);
  color:#fff; display:grid; place-items:center; cursor:pointer;
  box-shadow:0 4px 14px rgba(0,0,0,.35);
}
.fab svg{ width:26px; height:26px }
.fab:active{ background:var(--brand-deep) }

body{ padding-bottom:96px }
.legalbar{ padding-bottom:20px }

/* Desktop has room for real navigation, so the bar would be a phone affordance
   stranded on a 1400px screen. */

/* ── the answer card ──────────────────────────────────────────────────────
   Eden's mockup: everything the driver came for inside one white card, on a soft ground. */
.topbar{
  display:grid; grid-template-columns:var(--tap,48px) 1fr var(--tap,48px); align-items:center;
  padding:calc(6px + env(safe-area-inset-top)) 8px 6px; background:var(--bg);
  border-bottom:1px solid var(--line-dec);
}
.topbar .tt{ text-align:center; font-size:18px; font-weight:700 }
.tb{
  width:var(--tap,48px); height:var(--tap,48px); display:grid; place-items:center;
  background:none; border:0; color:var(--ink-2); cursor:pointer;
}
.tb svg{ width:21px; height:21px }

.rescard{ margin:14px 16px; padding:18px 16px 16px }
#res{ padding-bottom:8px }
#res .src, #res .rule, #res .filled, #res .saved, #res .ghost{ margin-inline:16px }

/* ── the car's identity ─────────────────────────────────────────────────── */
.carhead{
  display:flex; flex-direction:column; align-items:center; gap:6px;
  width:100%; background:none; border:0; padding:2px 0 6px; cursor:pointer;
}
.carhead .sil{ width:132px; height:60px; color:var(--ink-2) }
.carhead .sil.guess{ color:var(--line) }
.nmrow{ display:flex; align-items:center; justify-content:center; gap:10px; flex-wrap:wrap }
.carhead .nm{ font-size:22px; font-weight:800; color:var(--ink); text-align:center }
/* Bounded by HEIGHT, with width free: brand marks range from a square roundel to a wide
   wordmark, and forcing both into one box either crops the wordmark or floats the roundel
   in whitespace. */
.blogo{ height:26px; width:auto; max-width:96px; object-fit:contain; flex:none }

.rsep{ height:1px; background:var(--line-dec); margin:12px -16px 14px }

.rlabel{ text-align:center; font-size:16px; font-weight:600; color:var(--ink-2); margin-bottom:4px }
.rlabel span{ font-weight:400; color:var(--ink-3) }

/* ── the two numbers ──────────────────────────────────────────────────────
   A three-column grid with the drawing in the middle. The number columns are equal so
   31 and 9 do not sit in different places — `tabular-nums` handles the glyph widths,
   the grid handles the columns. */
.rowout{
  display:grid; grid-template-columns:1fr 1px 1fr; align-items:center;
  gap:14px; padding:10px 0 4px;
}
/* One pressure for both axles is one number, centred — not one number pushed to a side
   by a spacer that exists only because the two-axle case needed it. */
.rowout.one{ grid-template-columns:1fr; justify-items:center }
.rdiv{ align-self:stretch; background:var(--line-dec); margin:6px 0 }

.ax{ text-align:center; min-width:0 }
.ax .n{ display:flex; align-items:baseline; justify-content:center; gap:4px }
.ax .n span{
  font-size:clamp(44px,13vw,60px); font-weight:900; line-height:1; color:var(--ink);
  font-variant-numeric:tabular-nums; direction:ltr;
}
.ax .n i{ font-style:normal; font-size:17px; font-weight:700; color:var(--ink-2) }
.ax .l{ font-size:16px; font-weight:700; color:var(--ink); margin-top:2px }
.ax .b{ font-size:15px; color:var(--ink-3); direction:ltr; unicode-bidi:isolate }
.ax.none .n span{ color:var(--ink-3) }

/* ── the tyre it applies to ───────────────────────────────────────────────
   Named explicitly, because the whole promise of this product is that the number is for
   the size registered on THIS car — not the size the model usually ships with. */
.tyrerow{
  display:flex; align-items:center; justify-content:center; gap:8px;
  margin:14px -16px 0; padding:12px 16px;
  border-top:1px solid var(--line-dec); border-bottom:1px solid var(--line-dec);
  font-size:17px; font-weight:600; color:var(--ink);
}
.tyrerow svg{ width:20px; height:20px; color:var(--ink-3) }
.tyrerow .tyre{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; justify-content:center }
.tyrerow .tyre bdi{ direction:ltr; unicode-bidi:isolate; font-variant-numeric:tabular-nums }
.tw{ display:inline-flex; align-items:baseline; gap:6px }
.tw em{ font-style:normal; font-size:14px; font-weight:600; color:var(--ink-3) }

.rescard .cta.air{ margin-top:14px }

@media (min-width: 760px){ .tabbar{ display:none } body{ padding-bottom:0 } }

@media (min-width: 760px) {
  body {
    padding-top: 0;
    /* A faint ground behind the card so the column reads as placed, not abandoned. */
    background:
      radial-gradient(900px 420px at 50% -180px, #F4F6F8 0%, rgba(244,246,248,0) 70%),
      var(--bg);
  }

  .sitehead {
    display: flex !important; align-items: center; justify-content: center; gap: 10px;
    padding: 26px 0 22px; font-size: 17px; font-weight: 400; color: var(--ink-2);
  }
  .sitehead .mark { width: 30px; height: 30px; color: var(--brand) }
  .sitehead .sub { font-weight: 400; color: var(--ink-2) }

  /* The card. A border rather than a shadow — consistent with the rest of the system,
     and it survives being looked at in daylight. */
  /* Desktop shows the full header, so the compact phone lockup would be a second
     copy of the same name eight pixels above the first. */
  .mobrand { display: none }
  .iosbox { max-width: 520px; margin: 0 auto }

  .screen {
    max-width: 520px;
    border: 1px solid var(--line-dec);
    border-radius: 24px;
    background: var(--bg);
    padding: 32px 34px 34px;
    margin-bottom: 40px;
    box-shadow: 0 1px 2px rgba(11,13,16,.04), 0 12px 36px -12px rgba(11,13,16,.10);
  }

  /* With room to breathe, the entry screen can afford the scale the research asked for. */
  h1 { font-size: 38px }
  .lede { font-size: 20px }

  /* A pointer is precise; 56px targets are a touch-screen requirement, not a mouse one.
     Keeping them huge on desktop looks clumsy without helping anyone. */
  .ghost { min-height: 46px; font-size: 17px }
  .loadsw button { padding: 14px 8px }

  .sitefoot {
    display: block; text-align: center; padding: 0 0 48px;
    font-size: 15px; line-height: 1.7; color: var(--ink-3);
  }
  .sitefoot b { color: var(--ink-2); font-weight: 600 }
}

/* On a phone the chrome is pure cost — it pushes the number below the fold. Scoped to a
   max-width rather than relying on source order: the blanket rule sat after the desktop
   block and silently beat it. */
@media (max-width: 759px) {
  .sitehead, .sitefoot { display: none }
}

/* ── the cut-off strip ──────────────────────────────────────────────────────
   The saved-cars strip overflowed by 117px with no indication it scrolled — a car name
   simply ended mid-word at the edge. A mask fades the last few pixels so the row visibly
   continues, and scroll-snap makes a flick land on a card instead of between two. */
.garage {
  scroll-snap-type: x proximity;
  -webkit-mask-image: linear-gradient(to left, transparent 0, #000 28px);
          mask-image: linear-gradient(to left, transparent 0, #000 28px);
}
.gcar { scroll-snap-align: end }
/* No overflow, no fade — otherwise the last card looks clipped when it is not. */
.garage:not(.scrolls) {
  -webkit-mask-image: none;
          mask-image: none;
}

/* ═══ THE LANDING PAGE ═════════════════════════════════════════════════════
   A different job from the tool. The tool is read one-handed at a pump in eight seconds;
   this page is read at a desk by someone deciding whether to trust it. So it gets prose,
   a real heading hierarchy and a measured line length — and it still carries a working
   plate field in the hero, because a landing page whose call to action is "go to the
   tool" charges an arriving driver a page load before they can do the one thing they came
   for. */
body.land{ padding:0; background:var(--bg) }
.lwrap{ max-width:62rem; margin:0 auto; padding:0 20px }

/* ── header ─────────────────────────────────────────────────────────────── */
.lhead{
  display:flex; align-items:center; gap:18px;
  padding:14px 20px; border-bottom:1px solid var(--line-dec);
  position:sticky; top:0; background:var(--bg); z-index:30;
}
.lhead .brand{ margin-inline-end:auto }
.lnav{ display:none; gap:22px }
.lnav a{ color:var(--ink-2); text-decoration:none; font-size:17px; font-weight:600; padding:8px 0 }
.lnav a:hover{ color:var(--brand) }
.ltop{
  display:inline-flex; align-items:center; min-height:44px; padding:0 18px;
  border-radius:var(--r-pill); background:var(--brand); color:#fff;
  font-size:16px; font-weight:700; text-decoration:none;
}
@media (min-width:820px){ .lnav{ display:flex } }

/* ── hero ───────────────────────────────────────────────────────────────── */
.lhero{
  background:var(--navy); color:#fff; text-align:center;
  padding:46px 0 52px;
}
.lhero h1{
  font-size:clamp(30px,6vw,46px); font-weight:800; line-height:1.15;
  margin:0 0 12px; color:#fff;
}
.lhero h1 em{ font-style:normal; color:var(--brand-bright); display:block }
.lsub{
  font-size:clamp(17px,2.3vw,20px); line-height:1.55; color:#C7D2E0;
  margin:0 auto 26px; max-width:46ch;
}
.lsub b{ color:#fff; font-weight:600 }
.lform{ max-width:360px; margin:0 auto }
.lform .plate{ margin-bottom:14px }
.lform .shoot{ width:100%; margin:0 }
.land .trust{
  display:flex; align-items:center; justify-content:center; gap:7px;
  font-size:15px; color:#8E9CB0; margin:16px 0 0;
}
.land .trust svg{ width:15px; height:15px }

/* ── the four promises ───────────────────────────────────────────────────
   One column on a phone. Two on a tablet. Four across only when there is genuinely room
   for a readable measure in each — a 4-up grid at 900px gives 200px columns and turns
   every card into a ladder of two-word lines. */
.lfeat{
  display:grid; grid-template-columns:1fr; gap:14px;
  padding-top:34px; padding-bottom:10px;
}
@media (min-width:560px){ .lfeat{ grid-template-columns:1fr 1fr } }
@media (min-width:1000px){ .lfeat{ grid-template-columns:repeat(4,1fr) } }
.lfeat .feat{
  background:var(--bg); border:1px solid var(--line-dec); border-radius:16px;
  padding:20px 18px; display:flex; flex-direction:column; gap:8px; text-align:start;
  align-items:flex-start;
}
.lfeat .feat h2{ font-size:19px; font-weight:700; margin:0 }
.lfeat .feat p{ font-size:16px; line-height:1.6; color:var(--ink-2); margin:0 }
.lfeat .fi{
  width:46px; height:46px; border-radius:50%; background:var(--brand-bg);
  display:grid; place-items:center;
}
.lfeat .fi svg{ width:23px; height:23px; color:var(--brand) }

/* ── how it works ───────────────────────────────────────────────────────── */
.lhow{ background:var(--surface-2); margin-top:30px; padding:38px 0 42px }
.lhow h2, .lair h2, .lfaq h2{
  font-size:clamp(24px,4vw,32px); font-weight:800; margin:0 0 20px; text-align:center;
}
.steps{ list-style:none; margin:0; padding:0; display:grid; gap:14px; max-width:44rem; margin-inline:auto }
@media (min-width:760px){ .steps{ grid-template-columns:1fr 1fr; max-width:none } }
.steps li{
  display:grid; grid-template-columns:auto 1fr; grid-template-rows:auto auto;
  gap:2px 14px; align-items:start;
  background:var(--bg); border:1px solid var(--line-dec); border-radius:14px; padding:16px;
}
.sn{
  grid-row:1/3; width:34px; height:34px; border-radius:50%;
  background:var(--brand); color:#fff; display:grid; place-items:center;
  font-size:17px; font-weight:800; font-variant-numeric:tabular-nums;
}
.steps li b{ font-size:18px }
.steps li span:not(.sn){ font-size:16px; line-height:1.55; color:var(--ink-2) }

/* ── air stations ───────────────────────────────────────────────────────── */
.lair{ padding-top:40px; padding-bottom:8px; text-align:center }
.lair .lead{ font-size:18px; line-height:1.7; color:var(--ink-2); max-width:52ch; margin:0 auto 22px }
a.cta{ text-decoration:none }
.lair .cta{ max-width:320px; margin-inline:auto }

/* ── FAQ ──────────────────────────────────────────────────────────────────
   <details>, not a JS accordion. The answers are in the served HTML either way, which is
   what the FAQPage markup asserts and what an answer engine reads. */
.lfaq{ padding:44px 0 54px }
.lfaq #faqList, .lfaq .lq{ max-width:46rem; margin-inline:auto }
.lq{
  border:1px solid var(--line-dec); border-radius:14px; margin-bottom:10px;
  background:var(--bg); overflow:hidden;
}
.lq summary{
  display:flex; align-items:center; gap:12px; cursor:pointer; list-style:none;
  padding:16px 18px; font-size:18px; font-weight:700; min-height:var(--tap);
}
.lq summary::-webkit-details-marker{ display:none }
.lq summary span{ flex:1 }
.lq summary svg{ width:18px; height:18px; color:var(--ink-3); transition:transform var(--t) var(--e) }
.lq[open] summary svg{ transform:rotate(-90deg) }
.lq[open] summary{ border-bottom:1px solid var(--line-dec) }
.la{ padding:14px 18px 18px; font-size:17px; line-height:1.7; color:var(--ink-2) }

/* ── footer ─────────────────────────────────────────────────────────────── */
.lfoot{ background:var(--navy); color:#C7D2E0; padding:36px 0 8px; text-align:center }
.lfoot .brand{ justify-content:center; color:#fff; margin-bottom:14px }
.lfoot .brand .mark{ color:var(--brand-bright) }
.lfoot p{ font-size:16px; line-height:1.7; margin:0 auto; max-width:52ch }
.lfoot b{ color:#fff; font-weight:600 }
.lfoot .legalbar a{ color:var(--brand-bright) }
.lfoot .legalbar{ color:#6C7A8C }
