/* M1 Traffic — responsive, mobile-first stylesheet (2026 rebuild)
   Replaces: styles/main.css, mainslider, clock.css, cookiecuttr.css cruft.
   Single responsive column. No framework, no jQuery. */

:root{
  --brand:#0058a8;        /* UK motorway-sign blue */
  --brand-dark:#003f7d;
  --accent:#ffd200;       /* sign yellow */
  --ink:#1a1a1a;
  --muted:#5b6670;
  --line:#e2e6e9;
  --bg:#ffffff;
  --bg-soft:#f5f7f8;
  --maxw:1000px;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  font-size:17px;
  line-height:1.6;
  color:var(--ink);
  background:var(--bg-soft);
}
img{max-width:100%;height:auto}
a{color:var(--brand);text-decoration:none}
a:hover{text-decoration:underline}

.wrap{max-width:var(--maxw);margin:0 auto;padding:0 16px}

/* ---------- Header ---------- */
.site-header{background:var(--bg);border-bottom:1px solid var(--line)}
.site-header .wrap{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-top:12px;padding-bottom:12px}
.site-header img.logo{height:44px;width:auto}
.tagline{color:var(--muted);font-size:.9rem;margin:0}
@media (max-width:520px){.tagline{display:none}}

/* ---------- Nav (sticky top menu) ---------- */
.site-nav{background:var(--brand);position:sticky;top:0;z-index:200;box-shadow:0 2px 6px rgba(0,0,0,.14)}
.site-nav ul{max-width:var(--maxw);margin:0 auto;padding:0 8px;list-style:none;display:flex;flex-wrap:wrap;justify-content:flex-end}
.site-nav li{margin:0}
.site-nav a{display:block;color:#fff;padding:13px 18px;font-weight:600;font-size:1rem;text-decoration:none}
.site-nav a:hover,.site-nav a[aria-current="page"]{background:var(--brand-dark);text-decoration:none}
.nav-short{display:none}
@media (max-width:1023px){
  /* 01/09/2026: with 6 top-level items the FULL labels stop fitting below 1024px
     and the bar silently went to two rows between 600 and 900. Swapping to the
     SHORT labels here (padding unchanged) keeps it on one line all the way down
     to the phone rules below. Measured, not guessed - see the width sweep. */
  .nav-full{display:none}
  .nav-short{display:inline}
}
@media (max-width:560px){
  /* one line, short labels, evenly spread (fits 5 items) */
  .nav-full{display:none}
  .nav-short{display:inline}
  .site-nav ul{padding:0;flex-wrap:nowrap;justify-content:space-between}
  .site-nav a{padding:11px 6px;font-size:.8rem;white-space:nowrap}
}
@media (max-width:360px){
  .site-nav a{padding:10px 4px;font-size:.72rem}
}

/* ---------- Hero ---------- */
.hero{position:relative;background:#00305c}
.hero picture{display:block}
.hero img{display:block;width:100%;height:auto;object-fit:cover;max-height:300px}
.hero .hero-cap{position:absolute;left:0;bottom:0;right:0;padding:14px 16px;
  background:linear-gradient(to top,rgba(0,0,0,.62),rgba(0,0,0,0));color:#fff}
.hero .hero-cap h1,.hero .hero-cap .hero-cap__t{margin:0;font-weight:700;font-size:1.5rem;text-shadow:0 1px 3px rgba(0,0,0,.5)}
@media (max-width:520px){.hero .hero-cap h1,.hero .hero-cap .hero-cap__t{font-size:1.15rem}}

/* ---------- Main ---------- */
main{background:var(--bg)}
main .wrap{padding-top:22px;padding-bottom:32px}
main h1{font-size:1.7rem;line-height:1.25;margin:.2em 0 .5em}
main h2{font-size:1.3rem;margin:1.4em 0 .4em}
main h3{font-size:1.12rem;margin:1.2em 0 .3em}
main h4{font-size:1rem;margin:1.1em 0 .2em}
main p{margin:0 0 1em}
main ul{margin:0 0 1em;padding-left:1.3em}
main li{margin:.2em 0}
/* body images: give them breathing room so text/headings never touch them */
main img{margin:0 14px 12px 0;vertical-align:middle}
main h1 img,main h2 img,main h3 img{vertical-align:middle}
/* respect intended inline floats (e.g. the UKTN image) — float + padding + size cap; stack on mobile */
main img[style*="float: right"],main img[style*="float:right"]{float:right;margin:4px 0 12px 18px;max-width:45%;height:auto}
main img[style*="float: left"],main img[style*="float:left"]{float:left;margin:4px 18px 12px 0;max-width:45%;height:auto}
@media (max-width:520px){main img[style*="float"]{float:none !important;display:block;margin:0 auto 14px;max-width:100%}}
main iframe{max-width:100%}
.m1-sign{width:70px;height:35px}

/* Related box (folded-in former sidebar) */
.related{margin-top:28px;padding:16px 18px;background:var(--bg-soft);border:1px solid var(--line);border-radius:8px}
.related h3:first-child{margin-top:0}

/* ---------- Ad slots (TEST placeholders — fixed, tidy, never dominate) ---------- */
.ad-slot{margin:18px auto;height:90px;max-width:728px;
  display:flex;align-items:center;justify-content:center;
  background:repeating-linear-gradient(45deg,#fafafa,#fafafa 10px,#f2f2f2 10px,#f2f2f2 20px);
  border:1px dashed #cfd6da;border-radius:8px}
.ad-slot__label{font-size:.68rem;letter-spacing:.09em;text-transform:uppercase;color:#9aa4ac}
/* when real AdSense goes live: collapse any unfilled unit so no empty gap */
ins.adsbygoogle[data-ad-status="unfilled"]{display:none !important}

/* ---------- News (RTN engine injects between markers) ---------- */
#column_l_trafficnews{margin:14px 0}
#column_l_trafficnews > div > *{margin-left:auto !important;margin-right:auto !important}
.warnbar{display:block;max-width:100%;height:auto;margin:8px auto}

/* ---------- Footer ---------- */
.site-footer{background:var(--brand-dark);color:#cfe0f2;font-size:.92rem}
.site-footer .wrap{padding-top:24px;padding-bottom:28px;text-align:center}
.site-footer a{color:#fff}
.site-footer nav{margin-bottom:12px;line-height:2}
.site-footer .social img{height:36px;width:auto;margin-right:6px;vertical-align:middle}
.site-footer .fine{color:#9db8d6;font-size:.85rem;margin-top:10px}

/* ---------- Vertical M1 junction map ---------- */
.m1map{max-width:620px;margin:20px auto;font-size:.98rem}
.m1map__end{text-align:center;font-weight:600;margin:0;padding:12px;border-radius:8px;
  background:var(--brand);color:#fff}
.m1map__end--bottom{margin-top:0}
.m1map__dir{display:inline-block;font-weight:800;letter-spacing:.06em;margin-right:8px}
.m1map__list{list-style:none;margin:0;padding:0 0 0 4px;position:relative}
/* the motorway line */
.m1map__list::before{content:"";position:absolute;left:31px;top:0;bottom:0;width:6px;
  background:var(--brand);border-radius:3px}
.m1map__jn{position:relative;display:flex;align-items:center;gap:12px;
  padding:9px 0 9px 0;min-height:44px}
.m1map__badge{position:relative;z-index:1;flex:0 0 auto;width:46px;height:32px;
  display:flex;align-items:center;justify-content:center;
  background:var(--brand);color:#fff;font-weight:700;font-size:.82rem;
  border:2px solid #fff;border-radius:6px;box-shadow:0 0 0 2px var(--brand)}
.m1map__info{display:flex;flex-direction:column;line-height:1.3}
.m1map__road{font-weight:700;color:var(--brand-dark)}
.m1map__place{color:var(--muted);font-size:.9rem}
.m1map__note{margin:14px 0 0;font-size:.85rem;color:var(--muted);text-align:center}

/* ---------- Scrolling news ticker (blue band under hero) ---------- */
.ticker{background:var(--brand);color:#fff;overflow:hidden;white-space:nowrap;
  border-top:3px solid var(--accent);border-bottom:3px solid var(--accent)}
.ticker__track{display:inline-flex;will-change:transform;
  animation:ticker 28s linear infinite}
.ticker__item{padding:10px 45px;font-weight:600;font-size:.98rem;line-height:1.3}
.ticker:hover .ticker__track{animation-play-state:paused}
@keyframes ticker{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}

/* page-title M1 sign (sits inline next to the h1) */
.pagesign{height:40px;width:auto;vertical-align:middle;margin:0 12px 4px 0 !important;float:none !important;display:inline !important}
/* footer FREE line */
.site-footer .freeline{font-weight:700;color:#fff;margin:0 0 8px}


/* ---------- Dropdown sub-navigation ----------
   PORTED VERBATIM FROM m25traffic.co.uk/assets/site.css, 29/08/2026.
   Includes JC's 15/08 phone rule: submenus are NOT rendered on phones,
   so the nav stays one line and the hero is not pushed down. */
.site-nav li.has-sub{position:relative}
.site-nav li.has-sub>a::after{content:"";display:inline-block;margin-left:7px;
  border:5px solid transparent;border-top-color:currentColor;vertical-align:2px}
.site-nav .subnav{position:absolute;top:100%;left:0;min-width:230px;margin:0;padding:6px 0;
  list-style:none;display:none;flex-direction:column;background:var(--brand-dark);
  box-shadow:0 6px 16px rgba(0,0,0,.28);border-radius:0 0 6px 6px;z-index:250}
.site-nav li.has-sub:hover>.subnav,
.site-nav li.has-sub:focus-within>.subnav{display:flex}
.site-nav .subnav a{padding:11px 18px;font-weight:500;white-space:nowrap}
.site-nav .subnav a:hover,.site-nav .subnav a:focus{background:#00305c;text-decoration:none}

/* MOBILE: no hover, no floating panel. The group expands in flow so it
   is tappable and scannable - NOT one long endless dropdown. */
@media (max-width:760px){
  .site-nav ul{justify-content:center}
  .site-nav li.has-sub{position:static}
  .site-nav .subnav{position:static;min-width:0;display:flex;flex-direction:row;
    flex-wrap:wrap;justify-content:center;background:var(--brand-dark);
    box-shadow:none;border-radius:0;width:100%;padding:2px 0}
  .site-nav .subnav a{padding:10px 12px;font-size:.92rem}
  .site-nav li.has-sub>a::after{display:none}
}

/* ============================================================================
   MOBILE NAV - RECLAIM THE FIRST SCREEN (15/08/2026, JC: "menu on mobile
   takes up too much space")
   ROOT CAUSE: the <=760px block above sets .subnav{display:flex} with NO
   hover/focus condition, so on a phone every sub-link is PERMANENTLY EXPANDED
   inside the nav - a large share of the first screen, above the hero, before
   the visitor sees a word of traffic news.
   FIX: on phones the submenu is not rendered at all. "Services" and "Maps" stay
   normal links to their hub pages, which list everything - and the footer lists
   them too. Nothing becomes unreachable; the nav stops shouting.
   ⭐ This is the 10-second window: on mobile (~77% of revenue) the nav was
   spending it on itself.
   ============================================================================ */
@media (max-width:760px){
  .site-nav .subnav{display:none !important}
  .site-nav li.has-sub:hover>.subnav,
  .site-nav li.has-sub:focus-within>.subnav{display:none !important}
  /* the caret implied a dropdown that no longer opens here */
  .site-nav li.has-sub>a::after{display:none}
  /* tighter bar: less chrome, same tap target (>=44px high) */
  .site-nav a{padding:12px 10px}
}


/* ---------- NAV FIT (29/08/2026) ----------
   The mobile bar was authored for 5 items ("fits 5 items"). It now carries 6.
   Two changes, both additive:
   1. 1px less horizontal padding buys 12px - the bar was 7px over at 390px.
   2. overflow-x on the UL means the NAV may scroll, but the PAGE never does,
      however many items are added later. Measured, not assumed. */
@media (max-width:560px){
  .site-nav ul{overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
  .site-nav ul::-webkit-scrollbar{display:none}
  .site-nav a{padding:11px 5px}
}


/* ############################################################################
   HERO CROP BOX + BRAND PLATE
   PORTED FROM m25traffic.co.uk/assets/site.css on 29/08/2026, unchanged except
   for the image path. JC's rule, in his own words in that file:
   "the brand plate overlaid in CSS, never baked into the photo."
   M3 DIVERGES HERE (01/09/2026). The M6/M25 plate is 641x116 = 5.5:1. JC's M3
   artwork is 987x286 trimmed = 3.45:1 - a genuinely different shape, not a
   resize. The aspect-ratio below is set to the artwork so the plate renders at
   its own proportions; left at 5.5:1 it letterboxes and the .co.uk goes unreadable.
   JC chose this by looking at both renders. If the artwork is ever re-cut, this
   ratio must move with it - the comment and the rule below must agree.
   ############################################################################ */
.hero img{display:block;width:100%;aspect-ratio:16/5;height:auto;
  max-height:min(300px,42vh);object-fit:cover;object-position:center center}
@media (max-width:520px){.hero img{aspect-ratio:16/7}}
.hero::after{
  content:""; position:absolute; z-index:2; pointer-events:none;
  background-repeat:no-repeat; background-size:contain;
  top:10px; right:14px;
  width:min(30%,260px);
  aspect-ratio:987/286;
  background-image:url(/images/m3-plate.webp);
  background-position:right top;
}
.hero .hero-cap{z-index:3}
@media (max-width:520px){.hero::after{width:min(46%,190px); top:7px; right:8px}}
@media (max-width:360px){.hero::after{width:min(52%,160px)}}


/* ############################################################################
   LIVE NEWS TICKER (.nt) - PORTED VERBATIM FROM m25traffic.co.uk on 29/08/2026.
   Fills only when "newsTicker": true is set for m3traffic in config/sites.json
   AND the page carries the <!--RTNNEWSTICKER--> pair. Both are required -
   see CalNews v2.3.3 Program.cs line 376.
   ############################################################################ */
/* ============================================================================
   LIVE NEWS TICKER (.nt) — ABOVE THE MENU   (15/08/2026, JC spec)
   A scrolling headline strip between the site header and the main nav: three
   latest incidents, three active roadworks, three planned. Darker blue than the
   nav so it reads as a separate live band rather than part of the menu.
   ⚠ Every entry carries its REPORTED TIME IN FRONT. An undated headline implies
   "now", which we cannot know.
   ⚠ Renders nothing at all when there is no news — see NewsTicker.cs.
   ============================================================================ */
.nt{
  background:#00305c;               /* a shade darker than --brand (#0058a8) */
  color:#fff;
  overflow:hidden;
  white-space:nowrap;
  border-bottom:2px solid var(--accent);
}
.nt__track{display:inline-flex;will-change:transform;animation:ntscroll 70s linear infinite}
.nt:hover .nt__track,
.nt:focus-within .nt__track{animation-play-state:paused}
@keyframes ntscroll{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}

.nt__item{display:inline-flex;align-items:baseline;gap:.5rem;
  padding:8px 26px;font-size:.9rem;line-height:1.35;
  border-right:1px solid rgba(255,255,255,.18)}

/* ⭐ 17/08/2026 (JC): TWO PILLS, THEN THE WORDS, THEN THE TIME.
   The strip is narrow. One long tag ("LIVE Roadworks") ate the width the summary
   needs, so LIVE and the CATEGORY are now separate pills:
     [ LIVE ]  [ Incident ]  summary text …  14:32
   LIVE is one fixed red so the eye locks onto it without reading; the category
   pill carries its own colour, matching the cards and section headers.
   ⚠ Two different reds sitting side by side would read as one blob, so the
   INCIDENT pill is inverted (white pill, red text) against the solid red LIVE. */
.nt__live{flex:0 0 auto;font-size:.7rem;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;padding:2px 7px;border-radius:3px;
  background:#d62828;color:#fff;
  box-shadow:0 0 0 1px rgba(255,255,255,.35) inset}

/* Category pill: colour carries the state, exactly as on the map template. */
.nt__tag{flex:0 0 auto;font-size:.7rem;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;padding:2px 7px;border-radius:3px;color:#fff}
.nt__item--inc .nt__tag{background:#fff;color:#a51f1f}  /* incident  — inverted red */
.nt__item--act .nt__tag{background:#f0a500;color:#241a05} /* roadworks — amber      */
.nt__item--pln .nt__tag{background:#2d6ca8;color:#fff}  /* planned   — blue         */

/* The reported time — now the LAST thing in every entry. It is what proves the
   headline is current, so it stays prominent, but it no longer delays the words. */
.nt__time{font-weight:700;font-variant-numeric:tabular-nums;color:#ffd54a;flex:0 0 auto}
.nt__time::before{content:"·";color:rgba(255,255,255,.45);margin-right:.5rem}

.nt__txt{color:#fff;font-weight:500}
.nt__item--all{border-right:0}
.nt__item--all a{color:#ffd54a;font-weight:700;text-decoration:underline}

/* Mobile: mobile is ~77% of revenue, so the strip must not shout. Slightly
   smaller, tighter, and it still scrolls. */
@media (max-width:560px){
  .nt__item{padding:7px 16px;font-size:.82rem;gap:.4rem}
  .nt__tag,.nt__live{font-size:.62rem;padding:1px 5px}
}
/* Anyone who has asked for less motion gets a static, readable strip instead of
   a moving one — the headlines still show, they simply do not scroll. */
/* ⭐ CHANGED 17/08/2026 (JC): THE NEWS TICKER NOW SCROLLS ON EVERY DEVICE AND BROWSER.
   It used to sit inside @media (prefers-reduced-motion:reduce) with animation:none.
   🛑 WHY THAT WAS WRONG - not the accessibility intent, the INCONSISTENCY:
   the FOOTER marketing strip (.ticker__track) was never gated, so on any machine
   with Windows "Animation effects" off, the UNIMPORTANT strip slid and the LIVE
   NEWS strip froze. Exactly backwards, and it made the page look broken while
   telling drivers it was live. JC spotted it by asking why one moved and not the
   other. Measured 17/08: no-preference -> translateX -63 to -292 in 4s; reduce ->
   animation-name:none, no movement at all.
   ⚠ SAME SETTING, SAME SITE, EARLIER LESSON: see the .cone note above - that
   setting is common on Windows and had already made the footer cones vanish.
   ☐ OPEN, JC's call: content that auto-moves for more than 5 seconds should have a
   way to stop it. It pauses on HOVER, which does nothing on a phone - and mobile is
   ~77% of revenue. A visible pause control would make this more accessible than the
   old gate ever was, because the gate only helped people who had set the flag and
   left everyone else with motion they could not stop. NOT built - flagged once. */
@media (prefers-reduced-motion:reduce){
  /* .nt__track deliberately NOT listed here any more - see the note above. */
  .ticker__track,.nt__track{animation-duration:120s}   /* gentler, not stopped */
}

/* Ticker now sits between the hero and the status band (JC, 15/08). It no
   longer butts against the nav, so the top border returns and the bottom one
   goes — the status band immediately below supplies its own top rule. */
.nt{border-top:2px solid var(--accent);border-bottom:0}

/* Site-news strip — RELOCATED 15/08/2026 (JC) to sit between the body and the
   footer, and recoloured to match the live news ticker. Two scrolling strips in
   one eyeful competed; separated, each has its own job:
     · .nt   (under the hero) = LIVE traffic headlines
     · .ticker (above footer) = OUR site messages
   Same darker blue as .nt, keeping the yellow rules top and bottom. */
.ticker{background:#00305c;
  border-top:3px solid var(--accent);border-bottom:3px solid var(--accent)}


/* PORTED VERBATIM FROM m25traffic.co.uk/assets/site.css, 29/08/2026,
   including JC's measured note on why the badge sits OUTSIDE the heading. */
/* ============================================================================
   ROAD BADGE — the blue motorway-sign block that sits in front of a page heading.
   JC, 23/08/2026: "the blue rectangle is a quick visual motorway-sign type image
   ... immediately tunes to the visitor's brain 'yes it looks like this is a
   motorway site' - and hence reduces bounce rate."
   Same argument as the hero: DENSITY CARRIES SCOPE. Judged on what it signals in
   one second, not on legibility.

   ⭐ TEXT, NOT AN IMAGE. It renders identically at any size, needs no file, costs
   no request, and the road number comes from the markup - so one rule serves every
   site in the estate and there is no per-road GIF to forget to make.
   ⚠ RECONSTRUCTED FROM A SCREENSHOT OF M5, not copied from M5's stylesheet. The
   blue is sampled exactly (#0058a8, which is already --brand). If M5's own CSS is
   to hand, diff it against this and take M5's numbers - matching the estate matters
   more than my reconstruction being close.
   ============================================================================ */
.roadbadge{
  display:inline-block; vertical-align:middle;
  background:var(--brand); color:#fff;
  font-weight:800; font-size:.95em; line-height:1;
  padding:.34em .62em; margin:0 .55em .12em 0;
  border:2px solid #fff; border-radius:7px;
  box-shadow:0 0 0 2px var(--brand);   /* blue outside the white keyline, as on a real sign */
  letter-spacing:.01em;
}
h1 .roadbadge,h2 .roadbadge{font-size:.8em}
/* ⭐ THE BADGE SITS BESIDE THE HEADING, NOT INSIDE IT (23/08/2026).
   Measured, not assumed - this is what a crawler reads as the heading text:
     GIF inside the heading   -> "M4 motorway sign M4 Roadworks"   (alt text pollutes it)
     badge inside the heading -> "M4 M4 Roadworks"                 (road number twice)
     badge OUTSIDE it         -> "M4 Roadworks"                    (clean)
   Identical to the eye, and the heading says exactly what it means. The badge is
   decoration and now sits in the markup as decoration. */
.pagehead{display:flex;align-items:center;gap:.55em;flex-wrap:nowrap}
.pagehead h2{margin:.2em 0 .5em}
.pagehead .roadbadge{margin:0;flex:none;font-size:1rem}
@media (max-width:400px){.pagehead .roadbadge{font-size:.85rem}}


/* PORTED VERBATIM FROM m25traffic.co.uk/assets/site.css, 29/08/2026 -
   the columned footer, darker blue, road cone each side. */
/* ============================================================================
   MAIN FOOTER — CAL BRAND FOOTER   (approved 17/08/2026, JC)
   ----------------------------------------------------------------------------
   Category links in VERTICAL COLUMNS, a road cone each side, the network
   statement and an auto-updating copyright year.
   ⭐ WHY A GRID WITH auto-fit: TNE is a HUB heading for hundreds of pages.
      Adding a fifth section later needs NO CSS CHANGE - it just becomes another
      column, and collapses to one-per-row on a phone.
   ⭐ align-items:start so unequal-length columns line up on their HEADINGS
      rather than floating to their middles.
   ⚠ This is BRAND design, not per-site design (durable rule, 15/08). When it
     rolls to M5/M6/M60 and then the earners, only the link lists change.
   ============================================================================ */
.ft{background:#00305c;color:#cfe0f2;position:relative;overflow:hidden;
    border-top:3px solid var(--accent)}
.ft__wrap{max-width:var(--maxw);margin:0 auto;padding:26px 20px 22px;position:relative;z-index:2}

.ft__cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:22px 26px;text-align:left;align-items:start}
.ft__h{font-size:.72rem;font-weight:800;letter-spacing:.10em;text-transform:uppercase;
  color:#ffd54a;margin:0 0 9px;padding-bottom:6px;border-bottom:1px solid rgba(255,255,255,.22)}
.ft__cols ul{list-style:none;margin:0;padding:0}
.ft__cols li{margin:0 0 6px;line-height:1.45}
.ft__cols a{color:#fff;text-decoration:none;font-size:.9rem;
  display:inline-block;padding:2px 0;border-bottom:1px solid transparent}
.ft__cols a:hover,.ft__cols a:focus{border-bottom-color:#ffd54a;text-decoration:none}

/* STATEMENT + COPYRIGHT - centred, and deliberately NOT LINKS.
   ⭐ JC's rule of 15/08: "statement in the site-wide footer (editorial, not
   linking); the LIST OF SITES on ONE page only." An identical cross-domain link
   in the footer of all 31 pages reads as a link scheme. The hub is linked from
   About Us instead. */
.ft__rule{border:0;border-top:1px solid rgba(255,255,255,.22);margin:20px 0 14px}
.ft__free{text-align:center;margin:0 0 2px;font-size:.85rem;color:#9db8d6}
.ft__stmt{text-align:center;margin:0 0 6px;font-size:.95rem;color:#fff;font-weight:600}
.ft__copy{text-align:center;margin:0;font-size:.85rem;color:#9db8d6}
.ft__nh{text-align:center;margin:8px 0 0;font-size:.8rem;color:#9db8d6}
.ft a{color:#fff}
/* 01/09/2026: the licence link in the credit line inherits the muted credit colour
   instead of the white of a normal footer link - present and clickable, but not a
   signpost. JC: "do the link subtly". */
.ft__nh a{color:inherit;text-decoration:none;border-bottom:1px solid rgba(157,184,214,.35)}
.ft__nh a:hover{color:#fff;border-bottom-color:#fff}

/* CONES - bottom corners. Hidden under 700px so they never crowd the links.
   ⚠ Do NOT gate these on prefers-reduced-motion: the SVG already handles it
   correctly by rendering the beacon PERMANENTLY LIT rather than hiding it. */
.ft .cone{position:absolute;bottom:8px;z-index:1;pointer-events:none;display:block;
  height:104px;width:auto}
.ft .cone--l{left:16px}
.ft .cone--r{right:16px}
@media (max-width:1080px){.ft .cone{height:78px}}
@media (max-width:820px){.ft__wrap{padding-left:16px;padding-right:16px}}
@media (max-width:700px){.ft .cone{display:none}}


/* PORTED VERBATIM FROM m25traffic.co.uk/assets/site.css, 29/08/2026 -
   the live status band. Markup without its stylesheet renders as a run-on
   line of blue text; caught in preview before upload. */
/* ---------- Live status strip (written by CAL-RTN into the marker) ---------- */
.cs{background:var(--brand);border-top:3px solid var(--accent);border-bottom:3px solid var(--accent)}
.cs__inner{max-width:var(--maxw);margin:0 auto;padding:0 8px;display:flex;align-items:stretch;gap:1px}
.cs__item{flex:1 1 0;display:flex;align-items:center;gap:12px;padding:11px 14px;min-width:0;
  color:#fff;text-decoration:none}
.cs__item+.cs__item{box-shadow:inset 1px 0 0 rgba(255,255,255,.22)}
.cs__item:hover{background:rgba(0,0,0,.18);text-decoration:none}
.cs__num{font-size:2.1rem;line-height:1;font-weight:800;flex:none;letter-spacing:-.02em}
.cs__lab{display:block;font-size:.68rem;font-weight:800;letter-spacing:.09em;text-transform:uppercase;
  opacity:.9;line-height:1.3}
.cs__sub{display:block;font-size:.88rem;line-height:1.3;opacity:.95}
.cs--bad .cs__num{color:#ff8f8f}
.cs--warn .cs__num{color:var(--accent)}
.cs--ok .cs__num,.cs--ok .cs__tick{color:#7ee2a8}
.cs__tick{font-size:1.9rem;line-height:1;flex:none}
.cs__time{max-width:var(--maxw);margin:0 auto;padding:0 22px 8px;font-size:.72rem;
  color:rgba(255,255,255,.75);text-align:center}
@media (max-width:760px){
  .cs__inner{flex-direction:column;gap:0;padding:0}
  .cs__item{padding:9px 14px}
  .cs__item+.cs__item{box-shadow:inset 0 1px 0 rgba(255,255,255,.22)}
  .cs__num{font-size:1.8rem}
  .cs__time{padding:2px 14px 8px}
}

/* Interchange rows read "M6 MOTORWAY" — bigger, greener, harder to miss. They break the
   junction rail up visually AND give a stronger, more descriptive anchor for the cross-site links. */
.jmap__jn--connect .jmap__road{font-size:1.12rem;font-weight:800;letter-spacing:.02em;color:#00703c}
.jmap__jn--connect .jmap__road a{color:#00703c;text-decoration:underline;text-underline-offset:3px}
.jmap__jn--connect .jmap__road a:hover{color:#00512b}
.jmap__jn--connect{background:#f2f9f4;border-radius:6px}

/* Count-free state: shown until CAL-RTN can supply real counts. Same three doorways,
   same look, no numbers — because a placeholder number would be a fabricated number.
   A chevron replaces the count so the panel still has a visual anchor on the left. */
.cs--none{gap:10px}
.cs--none .cs__wrap{min-width:0}
.cs--none:before{content:"\203A";font-size:1.9rem;line-height:1;font-weight:800;
  color:var(--accent);flex:none;opacity:.9}
.cs--none .cs__lab{font-size:.72rem}
.cs--none .cs__sub{font-size:.92rem}

/* ---------- Quick-links variant of the status band ----------
   Used until CAL-RTN can write real counts into the RTNSTATUSSTRIP marker.
   Deliberately reads as NAVIGATION, not as a status readout: icons, fuller
   labels, a descriptive second line. An empty-looking status bar reads as
   broken; a quick-links bar is useful whether or not there is news today.
   When the engine supplies counts, .cs--links is dropped and the count-led
   version (large number + label) takes over with no other change. */
.cs--links .cs__item{gap:13px;padding:12px 16px;align-items:center}
.cs--links .cs__ico{width:26px;height:26px;flex:none;fill:var(--accent);opacity:.95}
.cs--links .cs__lab{font-size:.82rem;letter-spacing:.05em;margin-bottom:1px}
.cs--links .cs__sub{font-size:.9rem;opacity:.92}
.cs--links .cs__item:hover{background:rgba(0,0,0,.2)}
.cs--links .cs__item:hover .cs__ico{opacity:1}
@media (max-width:760px){
  .cs--links .cs__item{padding:11px 14px}
  .cs--links .cs__ico{width:22px;height:22px}
}

/* --- from TNE site.css lines 461-556 --- */
/* ============================================================================
   LIVE NEWS TICKER (.nt) — ABOVE THE MENU   (15/08/2026, JC spec)
   A scrolling headline strip between the site header and the main nav: three
   latest incidents, three active roadworks, three planned. Darker blue than the
   nav so it reads as a separate live band rather than part of the menu.
   ⚠ Every entry carries its REPORTED TIME IN FRONT. An undated headline implies
   "now", which we cannot know.
   ⚠ Renders nothing at all when there is no news — see NewsTicker.cs.
   ============================================================================ */
.nt{
  background:#00305c;               /* a shade darker than --brand (#0058a8) */
  color:#fff;
  overflow:hidden;
  white-space:nowrap;
  border-bottom:2px solid var(--accent);
}
.nt__track{display:inline-flex;will-change:transform;animation:ntscroll 70s linear infinite}
.nt:hover .nt__track,
.nt:focus-within .nt__track{animation-play-state:paused}
@keyframes ntscroll{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}

.nt__item{display:inline-flex;align-items:baseline;gap:.5rem;
  padding:8px 26px;font-size:.9rem;line-height:1.35;
  border-right:1px solid rgba(255,255,255,.18)}

/* ⭐ 17/08/2026 (JC): TWO PILLS, THEN THE WORDS, THEN THE TIME.
   The strip is narrow. One long tag ("LIVE Roadworks") ate the width the summary
   needs, so LIVE and the CATEGORY are now separate pills:
     [ LIVE ]  [ Incident ]  summary text …  14:32
   LIVE is one fixed red so the eye locks onto it without reading; the category
   pill carries its own colour, matching the cards and section headers.
   ⚠ Two different reds sitting side by side would read as one blob, so the
   INCIDENT pill is inverted (white pill, red text) against the solid red LIVE. */
.nt__live{flex:0 0 auto;font-size:.7rem;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;padding:2px 7px;border-radius:3px;
  background:#d62828;color:#fff;
  box-shadow:0 0 0 1px rgba(255,255,255,.35) inset}

/* Category pill: colour carries the state, exactly as on the map template. */
.nt__tag{flex:0 0 auto;font-size:.7rem;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;padding:2px 7px;border-radius:3px;color:#fff}
.nt__item--inc .nt__tag{background:#fff;color:#a51f1f}  /* incident  — inverted red */
.nt__item--act .nt__tag{background:#f0a500;color:#241a05} /* roadworks — amber      */
.nt__item--pln .nt__tag{background:#2d6ca8;color:#fff}  /* planned   — blue         */

/* The reported time — now the LAST thing in every entry. It is what proves the
   headline is current, so it stays prominent, but it no longer delays the words. */
.nt__time{font-weight:700;font-variant-numeric:tabular-nums;color:#ffd54a;flex:0 0 auto}
.nt__time::before{content:"·";color:rgba(255,255,255,.45);margin-right:.5rem}

.nt__txt{color:#fff;font-weight:500}
.nt__item--all{border-right:0}
.nt__item--all a{color:#ffd54a;font-weight:700;text-decoration:underline}

/* Mobile: mobile is ~77% of revenue, so the strip must not shout. Slightly
   smaller, tighter, and it still scrolls. */
@media (max-width:560px){
  .nt__item{padding:7px 16px;font-size:.82rem;gap:.4rem}
  .nt__tag,.nt__live{font-size:.62rem;padding:1px 5px}
}
/* Anyone who has asked for less motion gets a static, readable strip instead of
   a moving one — the headlines still show, they simply do not scroll. */
/* ⭐ CHANGED 17/08/2026 (JC): THE NEWS TICKER NOW SCROLLS ON EVERY DEVICE AND BROWSER.
   It used to sit inside @media (prefers-reduced-motion:reduce) with animation:none.
   🛑 WHY THAT WAS WRONG - not the accessibility intent, the INCONSISTENCY:
   the FOOTER marketing strip (.ticker__track) was never gated, so on any machine
   with Windows "Animation effects" off, the UNIMPORTANT strip slid and the LIVE
   NEWS strip froze. Exactly backwards, and it made the page look broken while
   telling drivers it was live. JC spotted it by asking why one moved and not the
   other. Measured 17/08: no-preference -> translateX -63 to -292 in 4s; reduce ->
   animation-name:none, no movement at all.
   ⚠ SAME SETTING, SAME SITE, EARLIER LESSON: see the .cone note above - that
   setting is common on Windows and had already made the footer cones vanish.
   ☐ OPEN, JC's call: content that auto-moves for more than 5 seconds should have a
   way to stop it. It pauses on HOVER, which does nothing on a phone - and mobile is
   ~77% of revenue. A visible pause control would make this more accessible than the
   old gate ever was, because the gate only helped people who had set the flag and
   left everyone else with motion they could not stop. NOT built - flagged once. */
@media (prefers-reduced-motion:reduce){
  /* .nt__track deliberately NOT listed here any more - see the note above. */
  .ticker__track,.nt__track{animation-duration:120s}   /* gentler, not stopped */
}

/* Ticker now sits between the hero and the status band (JC, 15/08). It no
   longer butts against the nav, so the top border returns and the bottom one
   goes — the status band immediately below supplies its own top rule. */
.nt{border-top:2px solid var(--accent);border-bottom:0}

/* Site-news strip — RELOCATED 15/08/2026 (JC) to sit between the body and the
   footer, and recoloured to match the live news ticker. Two scrolling strips in
   one eyeful competed; separated, each has its own job:
     · .nt   (under the hero) = LIVE traffic headlines
     · .ticker (above footer) = OUR site messages
   Same darker blue as .nt, keeping the yellow rules top and bottom. */
.ticker{background:#00305c;
  border-top:3px solid var(--accent);border-bottom:3px solid var(--accent)}

/* --- from TNE site.css lines 558-584 --- */
/* ============================================================================
   NEWS COLUMN — FILTER BAR / COUNT / PAGER ALIGNMENT   (17/08/2026, JC)
   ----------------------------------------------------------------------------
   ⚠ WHY THIS OVERRIDE EXISTS, AND WHY IT NEEDS `body` IN FRONT.
   CalNews writes its own stylesheet INTO the page, scoped `#calnews .cn-…`.
   Two consequences, both measured on the live page on 17/08/2026:
     1. An ID selector beats a plain class, so the rules above in this file
        never applied to these three boxes at all.
     2. That inline block sets `margin:14px 0`, which resets left/right margin
        to ZERO — killing the `margin:auto` centring outright.
   Result: filter bar, green count band and pager all sat hard LEFT at x=156
   while the news cards sat centred at x=228 — the misalignment JC spotted.
   `body #calnews …` outranks it cleanly without touching the generator.
   ⭐ max-width is in rem, NOT ch: `ch` resolves against each element's OWN
   font-size, and .cn-count is set at .95rem — which is exactly why it was
   17px narrower than everything else even before the margin bug.
   ⭐ VERIFIED by rendering the real page: desktop 1280px → all four edges land
   at x=228 / right=964 (cards 228.3 / 963.7). Phone 390px → x=16, w=358, all
   four identical. Mobile was ALREADY correct; this only changes desktop.
   ☐ PROPER FIX belongs in FilterAssets.cs at the next app version; this
   override then becomes redundant and should be deleted, not left to rot.
   ============================================================================ */
body #calnews .cn-filters,
body #calnews .cn-count,
body #calnews .cn-pager,
body #calnews .cn-nomatch{margin-left:auto;margin-right:auto;max-width:var(--newsw)}


/* --- from TNE site.css lines 617-666 --- */
/* ============================================================================
   MAIN FOOTER — CAL BRAND FOOTER   (approved 17/08/2026, JC)
   ----------------------------------------------------------------------------
   Category links in VERTICAL COLUMNS, a road cone each side, the network
   statement and an auto-updating copyright year.
   ⭐ WHY A GRID WITH auto-fit: TNE is a HUB heading for hundreds of pages.
      Adding a fifth section later needs NO CSS CHANGE - it just becomes another
      column, and collapses to one-per-row on a phone.
   ⭐ align-items:start so unequal-length columns line up on their HEADINGS
      rather than floating to their middles.
   ⚠ This is BRAND design, not per-site design (durable rule, 15/08). When it
     rolls to M5/M6/M60 and then the earners, only the link lists change.
   ============================================================================ */
.ft{background:#00305c;color:#cfe0f2;position:relative;overflow:hidden;
    border-top:3px solid var(--accent)}
.ft__wrap{max-width:var(--maxw);margin:0 auto;padding:26px 20px 22px;position:relative;z-index:2}

.ft__cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:22px 26px;text-align:left;align-items:start}
.ft__h{font-size:.72rem;font-weight:800;letter-spacing:.10em;text-transform:uppercase;
  color:#ffd54a;margin:0 0 9px;padding-bottom:6px;border-bottom:1px solid rgba(255,255,255,.22)}
.ft__cols ul{list-style:none;margin:0;padding:0}
.ft__cols li{margin:0 0 6px;line-height:1.45}
.ft__cols a{color:#fff;text-decoration:none;font-size:.9rem;
  display:inline-block;padding:2px 0;border-bottom:1px solid transparent}
.ft__cols a:hover,.ft__cols a:focus{border-bottom-color:#ffd54a;text-decoration:none}

/* STATEMENT + COPYRIGHT - centred, and deliberately NOT LINKS.
   ⭐ JC's rule of 15/08: "statement in the site-wide footer (editorial, not
   linking); the LIST OF SITES on ONE page only." An identical cross-domain link
   in the footer of all 31 pages reads as a link scheme. The hub is linked from
   About Us instead. */
.ft__rule{border:0;border-top:1px solid rgba(255,255,255,.22);margin:20px 0 14px}
.ft__free{text-align:center;margin:0 0 2px;font-size:.85rem;color:#9db8d6}
.ft__stmt{text-align:center;margin:0 0 6px;font-size:.95rem;color:#fff;font-weight:600}
.ft__copy{text-align:center;margin:0;font-size:.85rem;color:#9db8d6}
.ft__nh{text-align:center;margin:8px 0 0;font-size:.8rem;color:#9db8d6}
.ft a{color:#fff}
/* 01/09/2026: the licence link in the credit line inherits the muted credit colour
   instead of the white of a normal footer link - present and clickable, but not a
   signpost. JC: "do the link subtly". */
.ft__nh a{color:inherit;text-decoration:none;border-bottom:1px solid rgba(157,184,214,.35)}
.ft__nh a:hover{color:#fff;border-bottom-color:#fff}

/* CONES - bottom corners. Hidden under 700px so they never crowd the links.
   ⚠ Do NOT gate these on prefers-reduced-motion: the SVG already handles it
   correctly by rendering the beacon PERMANENTLY LIT rather than hiding it. */
.ft .cone{position:absolute;bottom:8px;z-index:1;pointer-events:none;display:block;
  height:104px;width:auto}
.ft .cone--l{left:16px}
.ft .cone--r{right:16px}
@media (max-width:1080px){.ft .cone{height:78px}}
@media (max-width:820px){.ft__wrap{padding-left:16px;padding-right:16px}}
@media (max-width:700px){.ft .cone{display:none}}




/* Sister-site links in the site-message strip (JC, 21/08/2026). */
.ticker__item a{color:#ffd54a;font-weight:700;text-decoration:underline}
.ticker__item a:hover{color:#fff}

/* ============================================================================
   ROAD BADGE — the blue motorway-sign block that sits in front of a page heading.
   JC, 23/08/2026: "the blue rectangle is a quick visual motorway-sign type image
   ... immediately tunes to the visitor's brain 'yes it looks like this is a
   motorway site' - and hence reduces bounce rate."
   Same argument as the hero: DENSITY CARRIES SCOPE. Judged on what it signals in
   one second, not on legibility.

   ⭐ TEXT, NOT AN IMAGE. It renders identically at any size, needs no file, costs
   no request, and the road number comes from the markup - so one rule serves every
   site in the estate and there is no per-road GIF to forget to make.
   ⚠ RECONSTRUCTED FROM A SCREENSHOT OF M5, not copied from M5's stylesheet. The
   blue is sampled exactly (#0058a8, which is already --brand). If M5's own CSS is
   to hand, diff it against this and take M5's numbers - matching the estate matters
   more than my reconstruction being close.
   ============================================================================ */
.roadbadge{
  display:inline-block; vertical-align:middle;
  background:var(--brand); color:#fff;
  font-weight:800; font-size:.95em; line-height:1;
  padding:.34em .62em; margin:0 .55em .12em 0;
  border:2px solid #fff; border-radius:7px;
  box-shadow:0 0 0 2px var(--brand);   /* blue outside the white keyline, as on a real sign */
  letter-spacing:.01em;
}
h1 .roadbadge,h2 .roadbadge{font-size:.8em}
/* ⭐ THE BADGE SITS BESIDE THE HEADING, NOT INSIDE IT (23/08/2026).
   Measured, not assumed - this is what a crawler reads as the heading text:
     GIF inside the heading   -> "M4 motorway sign M4 Roadworks"   (alt text pollutes it)
     badge inside the heading -> "M4 M4 Roadworks"                 (road number twice)
     badge OUTSIDE it         -> "M4 Roadworks"                    (clean)
   Identical to the eye, and the heading says exactly what it means. The badge is
   decoration and now sits in the markup as decoration. */
.pagehead{display:flex;align-items:center;gap:.55em;flex-wrap:nowrap}
.pagehead h2{margin:.2em 0 .5em}
.pagehead .roadbadge{margin:0;flex:none;font-size:1rem}
@media (max-width:400px){.pagehead .roadbadge{font-size:.85rem}}

/* ---------- Sub-menu nav, taken from TNE (M1 has no dropdowns; M25 has 24 pages) ----------
   🛑 REPAIRED 24/08/2026. This block arrived here on 23/08 with THREE opening lines
   lost in the transplant: two `@media (max-width:760px){` openers and the `/*` of the
   comment below. The consequence was not a cosmetic one - `display:none !important`,
   written for phones, was applying at EVERY width, so the Services, Maps and About
   dropdowns never opened on any device, and the caret never appeared. The markup was
   correct throughout. Restored verbatim from TNE's site.css, the source it came from.
   ⭐ THE HOVER REVEAL WAS ALSO MISSING - only :focus-within survived, so a mouse user
   could never open a menu at all. Same family as the stray `/` that killed the navy
   footer the same night: a transplant that loses a delimiter fails silently and looks
   like a design decision.
   ------------------------------------------------------------------------------- */
.site-nav li.has-sub{position:relative}

/* ============================================================================
   "THE ROAD IN NUMBERS" — replaces the four self-descriptive benefit boxes.
   JC, 23/08/2026: that space should put the home page in context about the M25,
   "not about it being a responsive website". Statistical, factual, quotable,
   sourced to DfT.
   ⭐ It also sits exactly where a reader has finished the news and is deciding
   whether to come back. Give them something about their road, not about us.
   ============================================================================ */
.roadfacts{margin:34px 0 10px;padding:26px 20px;background:var(--bg-soft);
  border:1px solid var(--line);border-radius:10px}
.roadfacts h3{margin:0 0 .3em;font-size:1.35rem}
.roadfacts__lede{margin:0 0 20px;color:var(--muted)}
.roadfacts__grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
@media (max-width:900px){.roadfacts__grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.roadfacts__grid{grid-template-columns:1fr;gap:14px}}
.fact{background:var(--bg);border:1px solid var(--line);border-top:4px solid var(--brand);
  border-radius:8px;padding:14px 15px 16px}
.fact__n{margin:0;font-size:2rem;line-height:1;font-weight:800;color:var(--brand);letter-spacing:-.02em}
.fact__l{margin:.3em 0 .6em;font-size:.74rem;font-weight:800;letter-spacing:.09em;
  text-transform:uppercase;color:var(--muted)}
.fact__s{margin:0;font-size:.93rem;line-height:1.45}
.roadfacts__why{margin:22px 0 0;padding:14px 16px;background:var(--bg);
  border-left:4px solid var(--accent);border-radius:0 6px 6px 0}
.roadfacts__src{margin:14px 0 0;font-size:.82rem;color:var(--muted)}
/* ⭐ The licence link is an ATTRIBUTION, not a recommendation. OGL v3.0 asks for a
   link to the licence "where possible", so it stays - but it is styled as a footnote
   rather than a call to action, and carries rel="license nofollow" so it does not
   pass authority off the biggest earner on all 24 pages. */
.roadfacts__src a{color:var(--muted);text-decoration:underline;text-underline-offset:2px}
.roadfacts__src a:hover{color:var(--brand)}
