/* Product layer over the approved CSS. shared.css, search.css and results.css are
 * byte-identical copies of FWNI - DESIGN/screens (checked by test/product.test.cjs);
 * everything the live product needs beyond them is here, kept small. */

/* Page background follows the theme (the approved files paint a review backdrop). */
html[data-theme=light], html[data-theme=light] body { background: #f5ece4; }
html[data-theme=dark], html[data-theme=dark] body { background: #102b3a; }
body { margin: 0; }

/* The approved 390x844 phone frame becomes the page itself. */
.app.phone { width: 100%; max-width: none; height: auto; min-height: 100vh; min-height: 100dvh; overflow: visible;
  border-radius: 0; box-shadow: none; margin: 0 auto; }
/* OPEN DECISION "DESKTOP" (config.js): mobile layout centred at most 480px wide. */
html[data-desktop=centred-mobile] .app.phone { max-width: 480px; }
/* 'desktop-layout' (default): the same 480px column below the desktop breakpoint; desktop.css
 * takes over from 761px (F, 12 Oct 2026: the desktop bundle, ported as-is). */
html[data-desktop=desktop-layout] .app.phone { max-width: 480px; }
/* Before app.js runs, the remembered dark theme already applies (boot.js sets <html>). */
html[data-theme=dark] .app.phone { --bg:#102b3a; --ink:#f5ece4; --muted:#bcc6c9; --surface:#1a3948; --border:#68808a;
  --green:#8acf9e; --action:#f5ece4; --action-ink:#102b3a; --soft-ink:#e4ddd6; }
.app .results-view { min-height: 100vh; min-height: 100dvh; }

/* Footer: the prototype's placeholder buttons are real links in the product. */
.search-view .search-footer a { display: inline-flex; align-items: center; justify-content: center; min-width: 44px;
  min-height: 44px; font: 600 12.5px/1.4 Manrope, system-ui, sans-serif; padding: 7px; color: var(--muted, #586866);
  text-decoration: none; }
.search-view .search-footer a:focus-visible { outline: 3px solid var(--ink, #102B3A); outline-offset: 3px; }
@container phone (max-width:359px) { .search-view .search-footer a { font-size: 12px; padding: 4px; } }
.search-view .search-noscript { font-size: 14px; line-height: 1.5; text-align: center; margin: 0 0 16px; }

/* Appearance outer circle (CODER-HANDOVER "Coder investigation"): the trigger is a circle
 * (border-radius:50%), so its 3px focus outline at 3px offset paints a second circle around
 * the half-filled icon. app.js restores focus to it after a theme choice or panel close;
 * when that action came from a mouse/touch, the element carries data-pointer-focus and the
 * ring is not painted. Keyboard users keep the full approved ring. */
[data-pointer-focus]:focus-visible { outline: none !important; }
/* Headings receive focus only programmatically (tabindex=-1, to move screen readers to the
 * new screen); they are not controls, so no ring is drawn on them. */
h1[tabindex="-1"]:focus-visible, h2[tabindex="-1"]:focus-visible { outline: none; }

/* One quiet line under the summary (routing down; postcode starting point). */
.results-distance-notice { font-size: 13px; line-height: 1.45; color: var(--r-muted); text-align: center; margin: 0 0 8px !important; }
.results-summary + .results-distance-notice { margin-top: -2px !important; }
/* An unmeasured station shows nothing in the distance slot; keep the map icon aligned. */
.results-distance:empty { min-height: 18px; }
.results-pin-note { font-size: 12px !important; }
.results-feedback button[disabled] { opacity: .5; cursor: default; }
/* Four fuel pills (F, 6 Oct 2026: every car fuel is displayed): laid out by fuel-swipe.css
   (FWNI-037, F 12 Oct 2026: Petrol/Diesel first, "swipe for premium"; 2x2 rejected). */

/* Splash: an overlay above the search page, which stays in the document underneath. */
html.fwni-splash-pending body::after { content: ""; position: fixed; inset: 0; z-index: 99; background: #102b3a; }
.fwni-splash { position: fixed; inset: 0; z-index: 100; background: #102b3a; display: flex; align-items: center;
  justify-content: center; overflow: auto; }
.fwni-splash .splash-view { width: min(100vw, calc(100vh * 390 / 844), 480px); width: min(100vw, calc(100dvh * 390 / 844), 480px); flex: none; }

.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0; }

/* Station field placeholder "Search by station, retailer or fuel brand" (F, 12 Oct 2026) is
   about 285px wide at the approved 16px, but the field leaves at most 272px (340px input,
   52px icon side, 16px right), so it was cut off at every width. Only the placeholder is
   sized to fit (about 15px at 390px and wider, about 11.5px at 320px); typed text stays at
   16px, so iOS does not zoom the page on focus. Measured: 17.8px of width per px of type. */
.search-view #search-station::placeholder { font-size: 14px;
  font-size: min(15px, calc((min(340px, 100cqw - 42px) - 68px) / 18.2)); }

/* ---- F's iPhone test (12 Oct 2026, Safari, dark mode) ------------------------------------ */

/* Single taps everywhere: no double-tap-to-zoom wait on links and buttons. There are no
   hover styles in the product; any future one must sit inside a hover-capable media query, so a
   touch never needs a first tap to "hover" (a test checks this). */
a, button { touch-action: manipulation; }
/* Keep the last links clear of Safari's collapsed bottom toolbar: a tap at the very bottom
   edge first re-opens the toolbar, so the footer links needed a second tap. */
.search-view { padding-bottom: 56px; }
.app .results-view main { padding-bottom: 56px; }

/* Fuel row (FWNI-037): the row is moved by app.js (finger, pen or mouse drag, in both
   directions, and the line below as a button), not by the browser's own horizontal
   scrolling, which on iPhone swiped to premium but not back. Vertical page scrolling that
   starts on the row stays native (pan-y). */
.results-fuel-track { overflow-x: hidden; touch-action: pan-y; }
/* The line under the pills ("swipe for premium" / "swipe for regular") is a 44px button with
   the approved line's look. Equal space above (to the pills) and below (to the next box):
   the text sits centred in the button and the box below drops its own top margin. */
html :is(.results-view, .fwni-pump) button.results-fuel-hint[data-fuel-hint] { display: block; min-height: 44px; margin: 2px auto;
  padding: 0 12px; border: 0; background: transparent; font: 600 12.5px/1.3 Manrope, system-ui, sans-serif; color: var(--r-muted); }
.results-view .results-fuel-hint + :is(.results-selected-scope, .results-summary, .results-price-notice) { margin-top: 2px; }

/* Sort: one two-sided switch, "Price | Distance", the active side filled (no separate line). */
.results-view .results-sort-switch2 { display: inline-flex; border-radius: 22px; }
.results-view .results-sort-option { min-height: 44px; min-width: 92px; padding: 8px 16px; border: 1px solid var(--r-muted); background: transparent;
  font-size: 13px; line-height: 1.2; color: var(--r-ink); }
.results-view .results-sort-option:first-child { border-radius: 22px 0 0 22px; }
.results-view .results-sort-option:last-child { border-radius: 0 22px 22px 0; border-left: 0; }
.results-view .results-sort-option[aria-pressed=true] { background: var(--r-ink); color: var(--r-bg); font-weight: 700; }

/* The price column is centred against its own station card. */
.results-view:not(.results-desk) .results-station .results-identity { align-self: stretch; }
.results-view:not(.results-desk) .results-station .results-price-group { align-self: center; padding-top: 0; }
/* With no map button below it, an empty distance slot would only push the price up. */
.results-view .results-distance:empty:last-child { display: none; }

/* No-fuel notice: the same space above and below, so it never touches the first card. */
.results-view .results-price-notice { margin: 16px 0; }

/* Widening: only at the bottom of the results (F, 12 Oct 2026). Centred heading with even
   space above and below, the +2.5/+5/+10 miles choices, then the line beside Back to top. */
.results-view .results-widen.results-widen-bottom { margin-top: 24px; padding-top: 0; border-top: 1px solid var(--r-border); text-align: center; }
.results-view .results-widen-bottom h2 { margin: 20px 0; font-size: 18px; line-height: 1.3; font-weight: 700; }
.results-view .results-widen-bottom .results-scope-options > div { display: flex; gap: 8px; }
.results-view .results-widen-bottom .results-scope-options > div > button { flex: 1 1 0; min-width: 0; }
.results-view .results-widen-bottom .results-widen-reset { width: 100%; margin-top: 8px; }
.results-view .results-widen-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 16px; text-align: left; }
.results-view .results-widen-foot p { margin: 0; font-size: 13px; line-height: 1.45; color: var(--r-muted); }
.results-view .results-widen-foot-end { flex-direction: column; align-items: stretch; }
.results-view .results-widen-actions { display: flex; gap: 12px; }
.results-view .results-widen-actions > .results-back-to-top { flex: 1 1 0; }
.results-view .results-back-to-top { flex: none; min-height: 44px; padding: 8px 14px; border: 1px solid var(--r-muted); border-radius: 22px; background: transparent;
  font-size: 13px; line-height: 1.2; }
.results-view .results-add-place { margin-top: 24px; }

/* "Price right? No" -> thanks, and the Fuel Finder price report link (Fair Use). */
.results-view .results-feedback.results-feedback-sent { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 10px; min-height: 44px; }
.results-view .results-report-link { display: inline-flex; align-items: center; min-height: 44px; color: var(--r-ink); font-weight: 700;
  text-decoration: underline; text-underline-offset: 3px; }
.results-view .results-report-link:focus-visible { outline: 3px solid #cf654a; outline-offset: 3px; }

/* F, 13 Oct 2026: "No such place" sits under the place and station boxes, inside the form,
   so it takes the form's own 16px spacing above and below. */
.search-view .search-place-error{margin:0;padding:0 20px;font-size:14px;font-weight:800;line-height:1.5;color:var(--ink,#102B3A)}

/* F, 13 Oct 2026: type-ahead under the place box. The list floats over what is below it
   (nothing moves), in the box's own colours, one row per place: name, then what it is. */
.search-view .search-input-wrap .search-suggest{position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:30;margin:0;padding:6px 0;list-style:none;background:var(--surface,#fffaf5);color:var(--ink,#102b3a);border:1px solid var(--border,#b3b1a9);border-radius:18px;box-shadow:0 8px 24px #102b3a30;max-height:min(60vh,420px);overflow-y:auto;overscroll-behavior:contain}
.search-view .search-suggest[hidden]{display:none}
.search-view .search-suggest-option{display:flex;flex-direction:column;justify-content:center;gap:2px;min-height:48px;padding:8px 20px;cursor:pointer;text-align:left}
.search-view .search-suggest-option[aria-selected=true]{background:var(--bg,#f5ece4)}
@media (hover:hover){.search-view .search-suggest-option:hover{background:var(--bg,#f5ece4)}}
.search-view .search-suggest-name{font-size:16px;font-weight:700;line-height:1.3}
.search-view .search-suggest-detail{font-size:13px;line-height:1.3;color:var(--muted,#52616a)}
html[data-desktop=desktop-layout] .search-desk .search-suggest{border-radius:8px}

/* F, 16 Oct 2026: the page head knows the theme (boot.js); both logos are lazy, so the hidden one is never downloaded. */
html[data-theme=dark] .search-brand .logo-light,html:not([data-theme=dark]) .search-brand .logo-dark{display:none}
