/* BusLaneCheck — site styles */
:root {
  --navy: #0f2447;
  --navy-2: #16325f;
  --amber: #ffb400;
  --amber-dark: #e09b00;
  --ink: #1a2233;
  --muted: #5b6577;
  --line: #e3e8f0;
  --bg: #f6f8fb;
  --card: #ffffff;
  --green: #0f7b3d;
  --red: #c0272d;
  --radius: 14px;
  --shadow: 0 1px 2px rgba(15, 36, 71, 0.06), 0 8px 24px rgba(15, 36, 71, 0.07);
}

* { box-sizing: border-box; }
/* The site has one palette and no dark theme. Saying so stops a browser in dark mode from
   force-darkening UA-painted chrome — the search input's own background and the type="search"
   clear button — which would put our dark ink on a dark field. */
:root { color-scheme: light; }

/* Visible to a screen reader, not on screen. Used for the search box's live result count. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: var(--ink);
  background: var(--bg);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; }
a { color: var(--navy-2); }

.wrap { max-width: 1060px; margin: 0 auto; padding: 0 20px; }

/* Header */
.site-header {
  background: var(--navy);
  color: #fff;
  border-bottom: 4px solid var(--amber);
}
.site-header .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding-top: 14px; padding-bottom: 14px; flex-wrap: wrap;
}
.logo { display: flex; align-items: center; gap: 10px; text-decoration: none; color: #fff; font-weight: 800; font-size: 1.15rem; letter-spacing: -0.01em; }
.logo .badge {
  background: var(--amber); color: var(--navy); border-radius: 8px;
  padding: 2px 8px; font-size: 0.8rem; font-weight: 900; letter-spacing: 0.02em;
}
.site-nav { display: flex; gap: 18px; flex-wrap: wrap; }
.site-nav a { color: #d7e0f0; text-decoration: none; font-size: 0.95rem; font-weight: 600; }
.site-nav a:hover { color: #fff; }

/* Hero */
.hero {
  background: linear-gradient(180deg, var(--navy) 0%, var(--navy-2) 100%);
  color: #fff; padding: 56px 0 72px; text-align: center;
}
.hero h1 { font-size: clamp(1.7rem, 4.5vw, 2.7rem); margin: 0 0 12px; letter-spacing: -0.02em; line-height: 1.15; }
.hero p.sub { color: #c3cfe4; max-width: 640px; margin: 0 auto 30px; font-size: 1.08rem; }
.hero .amber { color: var(--amber); }

/* Search */
.searchbox { position: relative; max-width: 620px; margin: 0 auto; text-align: left; }
.searchbox input {
  width: 100%; padding: 17px 20px 17px 52px; font-size: 1.05rem;
  border-radius: var(--radius); border: 2px solid transparent; outline: none;
  box-shadow: var(--shadow); color: var(--ink); background: #fff;
}
/* The focus ring was `outline: none` plus an amber border. Amber on the white input is
   1.78:1 — WCAG 2.2 Focus Appearance wants 3:1 against what surrounds it — so a keyboard
   user landing on the site's primary control could barely see where they were. Keep the
   amber (it is the brand cue and it reads well against the navy hero) and add a navy ring
   outside it, which carries the contrast on every background the box sits on. */
.searchbox input:focus-visible {
  border-color: var(--amber);
  outline: 3px solid var(--navy-2);
  outline-offset: 2px;
}
/* Mouse users get the amber alone, as before — no ring on click. */
.searchbox input:focus { border-color: var(--amber); }
.searchbox .icon {
  position: absolute; left: 18px; top: 50%; transform: translateY(-50%);
  width: 22px; height: 22px; color: var(--muted); pointer-events: none;
}
.search-results {
  position: absolute; top: calc(100% + 8px); left: 0; right: 0; z-index: 50;
  background: #fff; border-radius: var(--radius); box-shadow: var(--shadow);
  overflow: hidden; display: none; max-height: 420px; overflow-y: auto;
  border: 1px solid var(--line);
}
.search-results.open { display: block; }
.search-results a {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 13px 18px; text-decoration: none; color: var(--ink);
  border-bottom: 1px solid var(--line);
}
.search-results a:last-child { border-bottom: 0; }
.search-results a:hover, .search-results a.active { background: #f2f6fd; }
.search-results .r-road { font-weight: 700; }
.search-results .r-city { color: var(--muted); font-size: 0.88rem; }
.search-results .r-loc { display: block; color: var(--muted); font-size: 0.78rem; margin-top: 1px; }
.search-results .r-hours {
  flex-shrink: 0; font-size: 0.8rem; font-weight: 700; color: var(--navy);
  background: #eef3fb; padding: 3px 10px; border-radius: 99px; white-space: nowrap;
}
.search-results .r-none { padding: 16px 18px; color: var(--muted); font-size: 0.95rem; }
/* A line above the results saying what they answer: a postcode's area, or the corrected
   spelling that was searched instead of what was typed. Not an option — it cannot be picked. */
.search-results .r-head {
  padding: 9px 18px; font-size: 0.82rem; color: var(--muted);
  background: #f7f9fc; border-bottom: 1px solid var(--line);
}
.search-results .r-head b { color: var(--ink); }
.search-results .r-none a { display: inline; padding: 0; border: 0; color: var(--navy-2); text-decoration: underline; }

/* Sections */
section.band { padding: 52px 0; }
section.band.alt { background: #fff; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
h2.section-title { font-size: 1.55rem; margin: 0 0 6px; letter-spacing: -0.01em; }
p.section-sub { color: var(--muted); margin: 0 0 28px; }

/* Cards */
.grid { display: grid; gap: 18px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 20px 22px; box-shadow: var(--shadow); text-decoration: none; color: var(--ink);
  display: flex; flex-direction: column; gap: 8px; transition: transform 0.12s ease, box-shadow 0.12s ease;
}
a.card:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(15,36,71,0.08), 0 14px 34px rgba(15,36,71,0.12); }
.card h3 { margin: 0; font-size: 1.08rem; }
.card .meta { color: var(--muted); font-size: 0.9rem; }
/* The towns inside an authority, on the browse-by-city cards. Deliberately quieter than
   .meta: the lane count is the fact, the town list is the recognition cue. */
.card .card-areas { color: var(--muted); font-size: 0.82rem; line-height: 1.45; opacity: 0.85; }
.pill {
  display: inline-block; font-size: 0.78rem; font-weight: 800; letter-spacing: 0.02em;
  padding: 3px 10px; border-radius: 99px; width: fit-content;
}
.pill.hours { background: #fff4d6; color: #7a5800; border: 1px solid #f0d896; }
.pill.type { background: #e8effc; color: var(--navy-2); border: 1px solid #cddcf5; }
.pill.live-on { background: #fdeaea; color: var(--red); border: 1px solid #f3c2c4; }
.pill.live-off { background: #e7f6ed; color: var(--green); border: 1px solid #bfe6cf; }
.pill.redroute { background: #fdeaea; color: var(--red); border: 1px solid #f3c2c4; }
.redroute-note {
  background: #fff6f6; border: 1px solid #f3c2c4; border-left: 4px solid var(--red);
  border-radius: 8px; padding: 12px 16px; margin: 0 0 22px; font-size: 0.95rem; line-height: 1.5;
}

/* Lane page */
.breadcrumbs { font-size: 0.88rem; color: var(--muted); margin: 22px 0 6px; }
.breadcrumbs a { color: var(--muted); text-decoration: none; }
.breadcrumbs a:hover { text-decoration: underline; }
.lane-head h1 { font-size: clamp(1.5rem, 4vw, 2.2rem); margin: 6px 0 8px; letter-spacing: -0.02em; line-height: 1.2; }
.lane-head .sub { color: var(--muted); font-size: 1.02rem; margin: 0 0 18px; }
.pills { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 22px; }

.facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px;
  margin: 0 0 26px;
}
.fact {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 16px 18px; box-shadow: var(--shadow);
}
.fact .label { font-size: 0.75rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); margin-bottom: 4px; }
.fact .value { font-weight: 700; font-size: 1.02rem; line-height: 1.4; }
.fact.hours-fact { border-left: 5px solid var(--amber); }
.fact.penalty-fact { border-left: 5px solid var(--red); }
.fact .value small { display: block; font-weight: 500; color: var(--muted); font-size: 0.85rem; }

.content-cols { display: grid; grid-template-columns: 2fr 1fr; gap: 28px; align-items: start; padding-bottom: 56px; }
/* Grid tracks default to min-content, so a wide child (the per-direction hours table,
   whose headers are nowrap) would stretch the column past the viewport instead of
   scrolling inside its own .table-scroll wrapper. */
.content-cols > * { min-width: 0; }
@media (max-width: 800px) { .content-cols { grid-template-columns: 1fr; } }

.prose { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 26px 30px; box-shadow: var(--shadow); }
.prose h2 { font-size: 1.25rem; margin: 26px 0 10px; }
.prose h2:first-child { margin-top: 0; }
.prose h3 { font-size: 1.05rem; margin: 20px 0 8px; }
.prose ul { padding-left: 22px; }
.prose li { margin: 4px 0; }
.prose .allowed li::marker { color: var(--green); }
.prose .notallowed li::marker { color: var(--red); }
/* Cap the measure — the column runs to ~78 characters a line, above the comfortable
   45–75 range. 58ch lands at ~71 real characters (`ch` is the wide `0` glyph, so it
   over-counts against average lowercase). */
.prose p { max-width: 58ch; }

/* Per-direction hours table inside the About section (see notesHtml in build.js) */
table.lane-dirs { border-collapse: collapse; width: 100%; font-size: 0.94rem; margin: 14px 0 4px; }
table.lane-dirs th {
  text-align: left; background: #f2f5fa; color: var(--navy); font-size: 0.76rem;
  letter-spacing: 0.05em; text-transform: uppercase; padding: 9px 12px;
  border-bottom: 2px solid var(--line); white-space: nowrap;
}
table.lane-dirs td { padding: 10px 12px; border-bottom: 1px solid #eef1f6; vertical-align: top; }
table.lane-dirs td:first-child { font-weight: 700; white-space: nowrap; }
table.lane-dirs tr:last-child td { border-bottom: 0; }
table.lane-dirs .muted-cell { color: var(--muted); font-style: italic; }
/* Narrow screens: stack each stretch as a labelled card rather than making the
   third column disappear behind a horizontal scroll most people never find. */
@media (max-width: 560px) {
  table.lane-dirs thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  table.lane-dirs, table.lane-dirs tbody, table.lane-dirs tr, table.lane-dirs td { display: block; width: auto; }
  table.lane-dirs tr {
    border: 1px solid var(--line); border-radius: 10px;
    padding: 4px 14px 10px; margin: 0 0 10px;
  }
  table.lane-dirs td, table.lane-dirs td:first-child { padding: 6px 0; border-bottom: 0; white-space: normal; }
  table.lane-dirs td::before {
    content: attr(data-label); display: block; font-size: 0.7rem; font-weight: 700;
    letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); margin-bottom: 1px;
  }
  table.lane-dirs td:first-child { font-size: 1.05rem; }
}
/* Provenance / enforcement-method footnote, demoted out of the lead paragraph. */
.prose p.prov {
  font-size: 0.86rem; color: var(--muted); border-top: 1px solid var(--line);
  padding-top: 10px; margin-top: 16px; max-width: none;
}

.sidebar { display: flex; flex-direction: column; gap: 18px; }
.side-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px 22px; box-shadow: var(--shadow); }
.side-card h3 { margin: 0 0 10px; font-size: 1rem; }
.side-card ul { margin: 0; padding-left: 18px; font-size: 0.95rem; }
.side-card li { margin: 6px 0; }
.btn {
  display: inline-block; background: var(--amber); color: var(--navy); font-weight: 800;
  padding: 12px 20px; border-radius: 10px; text-decoration: none; font-size: 0.98rem;
  border: 0; cursor: pointer;
}
.btn:hover { background: var(--amber-dark); }
.btn.ghost { background: transparent; border: 2px solid var(--navy); color: var(--navy); }

.notice {
  border-radius: var(--radius); padding: 14px 18px; font-size: 0.92rem; margin: 0 0 22px;
  border: 1px solid;
}
.notice.warn { background: #fff8e6; border-color: #f0d896; color: #6b4e00; }
.notice.info { background: #eef3fb; border-color: #cddcf5; color: #1f3c6e; }
/* Caveat attached to the "Who can use it" list where the council publishes no exemption
   list. All 41 of those lanes are also unverified, so they already carry the filled yellow
   banner at the top of the page — a second filled panel would read as the same warning
   repeated and dilute both. This one is a rule, not a box: it belongs to the list above it. */
.notice.warn-inline {
  background: transparent; border: 0; border-left: 3px solid #f0d896;
  border-radius: 0; color: var(--muted); padding: 2px 0 2px 14px; margin: -6px 0 20px;
  font-size: 0.88rem; line-height: 1.5;
}
.notice.warn-inline strong { color: #6b4e00; }

/* Sits above the city table: someone who searched a local area name ("Southall") needs to
   see they landed in the right place before scrolling a long list of road names. */
.areas-covered {
  margin: 0 0 20px; font-size: 0.92rem; line-height: 1.6; color: var(--muted);
  border-left: 3px solid var(--amber); padding: 2px 0 2px 14px;
}

/* FAQ */
details.faq {
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 4px 20px; margin-bottom: 10px; box-shadow: var(--shadow);
}
details.faq summary { font-weight: 700; cursor: pointer; padding: 12px 0; outline: none; }
details.faq summary:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; border-radius: 4px; }
details.faq p { margin: 0 0 14px; color: #37415a; }

/* Tables */
table.data { width: 100%; border-collapse: collapse; background: var(--card); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); font-size: 0.95rem; }
table.data th, table.data td { text-align: left; padding: 12px 16px; border-bottom: 1px solid var(--line); }
table.data th { background: var(--navy); color: #fff; font-size: 0.85rem; letter-spacing: 0.03em; }
table.data tr:last-child td { border-bottom: 0; }
table.data a { font-weight: 700; text-decoration: none; }
table.data a:hover { text-decoration: underline; }
table.data .seg { display: block; color: var(--muted); font-weight: 500; font-size: 0.8rem; margin-top: 2px; }

/* Narrow screens: stack each city-listing row as a labelled card. Four columns inside 390px
   left every cell one word per line — "Buses, / Taxis / (hackney / carriages / only —" — on
   the page a driver reaches from a city search. Same treatment, and the same reasoning, as
   the per-direction table on a lane page above: not a horizontal scroll, which most people
   never find. Scoped to .lane-list so the guides' comparison tables, which are short enough
   to survive as tables, are untouched. */
@media (max-width: 620px) {
  table.data.lane-list, table.data.lane-list tbody, table.data.lane-list tr, table.data.lane-list td { display: block; width: auto; }
  table.data.lane-list { box-shadow: none; background: none; }
  table.data.lane-list tr {
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow); padding: 6px 16px 12px; margin: 0 0 12px;
  }
  /* The header row, after the rule above — clipping the <th>s alone left the row itself in
     flow as an empty card above the first result. Each cell carries its own label below. */
  table.data.lane-list tr:first-child {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: 0;
    overflow: hidden; clip: rect(0 0 0 0); border: 0; box-shadow: none;
  }
  table.data.lane-list td { padding: 7px 0; border-bottom: 0; }
  table.data.lane-list td:first-child { font-size: 1.02rem; }
  table.data.lane-list td[data-label]::before {
    content: attr(data-label); display: block; font-size: 0.7rem; font-weight: 700;
    letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); margin-bottom: 1px;
  }
  /* The wrapper's scroll and clipping are pointless once the rows are cards, and the
     rounded corners would cut the shadow off the first and last one. */
  .table-scroll { overflow-x: visible; border-radius: 0; }
}
/* The qualifier under a "Who can use it" cell — "+3 more", or the warning that the council
   publishes no exemption list. Same treatment as .seg: it has to read as a note about the
   cell above it, never as another permitted vehicle in the list. */
table.data td small { display: block; color: var(--muted); font-weight: 500; font-size: 0.8rem; margin-top: 2px; }
.table-scroll { overflow-x: auto; border-radius: var(--radius); }

/* Footer */
.site-footer { background: var(--navy); color: #b9c6dd; margin-top: 0; padding: 40px 0 30px; font-size: 0.9rem; }
.site-footer a { color: #dfe8f6; }
.site-footer .cols { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 28px; margin-bottom: 24px; }
@media (max-width: 700px) { .site-footer .cols { grid-template-columns: 1fr; } }
.site-footer h4 { color: #fff; margin: 0 0 10px; font-size: 0.95rem; }
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin: 6px 0; }
.site-footer .legal { border-top: 1px solid rgba(255,255,255,0.15); padding-top: 18px; font-size: 0.82rem; color: #8fa0bd; }

/* Page hero (inner pages) */
.page-hero { background: linear-gradient(180deg, var(--navy) 0%, var(--navy-2) 100%); color: #fff; padding: 36px 0 44px; }
.page-hero h1 { margin: 6px 0 8px; font-size: clamp(1.5rem, 4vw, 2.2rem); letter-spacing: -0.02em; }
.page-hero p { color: #c3cfe4; margin: 0; max-width: 720px; }
.page-hero .breadcrumbs, .page-hero .breadcrumbs a { color: #9fb1ce; }
/* Body links in the hero. Without this they inherit the global link colour, which is
   --navy-2 — dark navy on the dark navy hero, i.e. invisible. Only /guides/ puts a link
   in hero prose today; the rule is here so the next page that does is not a bug. */
.page-hero p a { color: var(--amber); text-decoration: underline; text-underline-offset: 2px; }
.page-hero p a:hover { color: #ffc94d; }
.page-hero .searchbox { margin: 22px 0 0; }

main { min-height: 40vh; }
.section-pad { padding: 34px 0 56px; }

/* ---------------------------------------------------------------- fines / enforcement pages */
/* Tile count varies: a council that withheld income or holds no appeals data drops the
   matching tiles, so the row is laid out from data-count rather than a fixed 5. */
.stat-tiles { display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; }
.stat-tiles[data-count="1"] { grid-template-columns: 1fr; }
.stat-tiles[data-count="2"] { grid-template-columns: repeat(2, 1fr); }
.stat-tiles[data-count="3"] { grid-template-columns: repeat(3, 1fr); }
.stat-tiles[data-count="4"] { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 860px) { .stat-tiles, .stat-tiles[data-count] { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px) { .stat-tiles, .stat-tiles[data-count] { grid-template-columns: 1fr; } }
.tile { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; box-shadow: var(--shadow); }
.tile .num { font-size: 1.9rem; font-weight: 800; letter-spacing: -0.02em; color: var(--navy); line-height: 1.1; }
.tile.amber .num { color: var(--amber-dark); }
.tile .cap { color: var(--ink); font-size: 0.9rem; font-weight: 600; margin-top: 6px; }
.tile .cap small { display: block; color: var(--muted); font-weight: 500; font-size: 0.78rem; margin-top: 2px; }

.chart-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 26px; }
/* Councils that withheld income leave only the PCN chart — half a row looks broken. */
.chart-grid.single { grid-template-columns: 1fr; max-width: 640px; }
@media (max-width: 760px) { .chart-grid { grid-template-columns: 1fr; } }
.chart-card { margin: 0; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px 8px; box-shadow: var(--shadow); }
.chart-card figcaption { font-weight: 700; font-size: 0.98rem; margin-bottom: 8px; }
svg.chart { width: 100%; height: auto; display: block; }
svg.chart .bar { fill: var(--amber); }
svg.chart.navy .bar { fill: var(--navy-2); }
svg.chart .v { fill: var(--ink); font-size: 15px; font-weight: 700; font-family: inherit; }
svg.chart .l { fill: var(--muted); font-size: 14px; font-family: inherit; }
.chart-note { color: var(--muted); font-size: 0.9rem; margin: 14px 2px 0; max-width: 900px; }

/* Camera league table: name | proportional bar | this-year | 5-year */
table.data.league td.lg-num, table.data.league th.lg-num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
table.data.league .muted { color: var(--muted); }
table.data.league .lg-bar { width: 42%; padding-right: 6px; }
table.data.league .lg-bar .bar { display: block; height: 12px; border-radius: 6px; background: var(--amber); min-width: 3px; }
table.data.league .lg-name { font-weight: 600; }
@media (max-width: 620px) { table.data.league .lg-bar { display: none; } }

.side-card .downloads, .prose ul.lane-links { list-style: none; padding-left: 0; }
.side-card .downloads li, .prose ul.lane-links li { margin: 8px 0; }
.side-card .downloads .muted { color: var(--muted); font-size: 0.82rem; }
.fines-card { border-color: #cddcf5; background: #f5f8fe; }
.fines-banner a { font-weight: 700; }

/* National hub: the authority table is the comparison, so every column sorts. Numbers
   carry a small muted line (the year, the number of years) under the figure itself. */
table.data.sortable th[data-col] { cursor: pointer; user-select: none; white-space: nowrap; }
table.data.sortable th[data-col]:hover, table.data.sortable th[data-col]:focus-visible { color: var(--amber); }
table.data.sortable th[data-col]::after { content: '↕'; opacity: 0.35; margin-left: 6px; font-size: 0.8em; }
table.data.sortable th[aria-sort="ascending"]::after { content: '↑'; opacity: 1; }
table.data.sortable th[aria-sort="descending"]::after { content: '↓'; opacity: 1; }
table.data.league td small { display: block; color: var(--muted); font-weight: 500; font-size: 0.78rem; }
table.data.league td.lg-name small { font-weight: 500; }

.card.cta { border-color: var(--amber); background: #fffaf0; }
.card.cta h3 { color: var(--amber-dark); }
