/*
Theme Name: Chatham Transit (Plumbline Child)
Theme URI: https://www.tomatillodesign.com/
Description: Chatham Transit Network child theme — brand tokens, custom components, and site-specific styles on Plumbline.
Author: Chris Liu-Beers @ Tomatillo Design
Author URI: https://www.tomatillodesign.com/
Template: plumbline
Version: 1.5.9
Requires at least: 6.9
Requires PHP: 8.2
Text Domain: plumbline-chatham
Domain Path: /languages
Update URI: false

License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

/* ============================================================
   Chatham Transit child styles
   Spacing sits on a 4px scale. Every colour pair used for text
   is contrast-verified (see _planning/03-design/design-rationale).
   ============================================================ */

:root{
  /* Mirrors of the plumbline_get_tokens overrides (trap: both places). */
  --pl-color-surface-page:#FAF8F6;
  --pl-color-surface-alt:#FFFFFF;
  --pl-color-text-primary:#1C1917;

  /* Type scale retune. Mirrored in ctn_child_tokens() — a PHP filter alone
     cannot reach the browser, because plumbline_type_scale_config is read at
     BUILD time and the front end serves the static parent tokens.css.

     --pl-text-sm was the only step in the parent scale that did not derive
     from --pl-type-base: a hardcoded 0.875rem (14px). It drives card
     descriptions and CTAs, footer body and links, copyright, entry meta,
     staff-card titles, search results and nav dropdown links — 59 nodes at
     14px on the homepage alone, including sub-menu links that were smaller
     than their own parent items. Deriving it would give 14.4px, which fixes
     nothing; 16px is a deliberate retune for an older, low-vision audience.
     Root is 16px, so these are rem-against-root, not against --pl-type-base. */
  --pl-text-sm:1rem;      /* 14   -> 16 */
  --pl-text-xs:0.8125rem; /* 11.5 -> 13 */

  --ctn-red:#B02010;
  --ctn-red-deep:#8C1A0D;
  --ctn-petrol:#0E4A5C;
  --ctn-petrol-deep:#0A3846;
  --ctn-petrol-wash:#E8F0F2;
  --ctn-red-wash:#F6E7E3;
  /* Sampled from the client illustration PNGs, not invented: #D0E5ED is the
     vehicle glass, #087888 the roof caps and ground swells. There is NO sand
     in the client set (that was the superseded AI set) — sand must not appear
     in an icon. --ctn-pale is the icon tint; --ctn-petrol-wash is NOT, at
     1.09:1 against the warm band it is invisible. */
  --ctn-pale:#CFE4E9;
  --ctn-petrol-mid:#2A6B7E;
  /* The ground the client's illustrations are drawn on. Sampled across all
     eight: #EAD8CC is the single most common pale tone in the set (the county
     shape, the road verges, the sand banks). Note this is NOT the #E8DFD5 the
     superseded AI manifest called "sand" — that value genuinely does not
     appear in the client artwork, which is why icons still must not use it.
     This one does, so the hero photo can sit on the same ground the drawings
     do. */
  --ctn-sand:#EAD8CC;
  /* The same tan lightened toward white, for use as a full-bleed BAND. At full
     strength sand is right for a small shape on white (the hero mat) and too
     heavy across a whole section. This keeps the white chooser cards reading
     as cards (1.25:1 against the band) and the red eyebrow at 5.50:1, which is
     actually better than the full-strength sand managed. */
  --ctn-sand-band:#F0E4DB;

  /* Phosphor arrow-right-bold as a CSS mask. Used where a decorative glyph is
     wanted but the parent block does not render one — the mask is monochrome,
     so background-color colours it exactly as currentColor would. */
  --ctn-arrow-right:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'><path d=%22M224.49%2C136.49l-72%2C72a12%2C12%2C0%2C0%2C1-17-17L187%2C140H40a12%2C12%2C0%2C0%2C1%2C0-24H187L135.51%2C64.48a12%2C12%2C0%2C0%2C1%2C17-17l72%2C72A12%2C12%2C0%2C0%2C1%2C224.49%2C136.49Z%22/></svg>");
  --ctn-tint:#F2EEEA;
  --ctn-ink:#1C1917;
  --ctn-muted:#5B534E;
  --ctn-line:#E4DFDA;
  --ctn-line-soft:#F0ECE8;
  --ctn-shadow:0 1px 2px rgba(28,25,23,.04),0 12px 32px -16px rgba(28,25,23,.18);

  /* Tighter section rhythm. Plumbline's defaults (standard 3–5rem, spacious
     4–7rem) double at every section boundary — on a large desktop that is
     160px+ of dead air between sections. Lower bounds trimmed, caps cut hard. */
  --pl-section-padding-compact:clamp(1.5rem, 2.5vw, 2rem);
  --pl-section-padding-standard:clamp(2.5rem, 4vw, 3.25rem);
  --pl-section-padding-spacious:clamp(3rem, 5vw, 4.25rem);
}

/* Seam-flattener, mobile/tablet only. Desktop rhythm is owned by the
   DESKTOP PAGE STRUCTURE block at the end of this file; ungated, this
   (0,2,0) selector silently beats every per-section override. */
@media(max-width:1199px){
  [data-pl-section-label] + [data-pl-section-label]{
    padding-top:clamp(1.25rem, 2.2vw, 1.9rem)}
}

h1,h2,h3{text-wrap:balance}
p{text-wrap:pretty}

/* ---- Utility bar ------------------------------------------------------ */
.ctn-util{background:var(--ctn-petrol);color:#fff;font-size:15px}
.ctn-util__wrap{max-width:var(--pl-content-max-width,74rem);margin:0 auto;
  padding:6px 24px;display:flex;gap:24px;align-items:center;min-height:44px}
.ctn-util a{color:#fff;text-decoration:none;font-weight:600;
  display:inline-flex;align-items:center;gap:7px}
.ctn-util a:hover{text-decoration:underline;color:#fff}
.ctn-translate{margin-left:auto;position:relative}
.ctn-util button.ctn-util__translate{background:none;border:0;padding:0;margin:0;
  color:#fff;font:inherit;font-weight:600;cursor:pointer;
  display:inline-flex;align-items:center;gap:7px;min-height:44px}
.ctn-util button.ctn-util__translate:hover{text-decoration:underline}
.ctn-util button.ctn-util__translate:focus-visible{outline:3px solid #fff;outline-offset:2px}
.ctn-translate__caret{margin-left:-2px;transition:transform .15s}
.ctn-util__translate[aria-expanded="true"] .ctn-translate__caret{transform:rotate(180deg)}
.ctn-translate__menu{position:absolute;right:0;top:calc(100% + 4px);z-index:60;
  margin:0;padding:6px;list-style:none;min-width:12.5rem;
  background:#fff;color:var(--ctn-ink);border:1px solid var(--ctn-line);
  border-radius:8px;box-shadow:var(--ctn-shadow)}
.ctn-translate__menu[hidden]{display:none}
.ctn-translate__menu li{margin:0}
.ctn-util .ctn-translate__menu a{display:flex;align-items:center;gap:8px;
  padding:9px 12px;border-radius:6px;color:var(--ctn-ink);font-weight:600;
  font-size:16px;text-decoration:none}
.ctn-util .ctn-translate__menu a:hover{background:var(--ctn-petrol-wash);color:var(--ctn-petrol);text-decoration:none}
.ctn-util .ctn-translate__menu a:focus-visible{outline:3px solid var(--ctn-petrol);outline-offset:-3px}
.ctn-util .ctn-translate__menu .ctn-translate__check{margin-left:auto;color:var(--ctn-petrol);flex:0 0 auto}
/* Google Language Translator's own footer widget: kept in the DOM (its
   dropdown.js initializes from it), never shown — the utility bar is the control. */
#glt-footer{display:none}

/* ---- Site-wide notice banner ------------------------------------------
   Red per client direction (white on #B02010 = 6.86:1, AA; on #8C1A0D
   deeper still). Urgency now differentiates by depth + icon (ⓘ vs ⚠). */
.ctn-alert{color:#fff}
.ctn-alert--normal{background:var(--ctn-red)}
.ctn-alert--urgent{background:var(--ctn-red-deep)}
.ctn-alert__wrap{max-width:var(--pl-content-max-width,74rem);margin:0 auto;
  padding:12px 24px;display:flex;gap:12px;align-items:flex-start}
.ctn-alert__icon{flex:0 0 auto;font-size:19px;line-height:1.5}
.ctn-alert__text{margin:0;font-size:16.5px;line-height:1.5}
.ctn-alert__text a{color:#fff;font-weight:600}
.ctn-alert + .ctn-alert{border-top:1px solid rgba(255,255,255,.25)}

/* ---- Header ----------------------------------------------------------- */
.pl-site-header{border-bottom:1px solid var(--ctn-line)}

/* Nav items keep to one line */
.pl-nav-menu > li > a{white-space:nowrap}

/* Book a Ride menu item styled as the primary action */
.pl-nav-menu .ctn-nav-cta > a{
  background:var(--ctn-red);color:#fff !important;border-radius:999px;
  padding:10px 22px;font-weight:700;white-space:nowrap}
.pl-nav-menu .ctn-nav-cta > a:hover,
.pl-nav-menu .ctn-nav-cta > a:focus{background:var(--ctn-red-deep);color:#fff}
/* Stay red even as the current page. Plumbline's unlayered
   `.pl-site-header .pl-nav-menu > li.current-menu-item > a` (0,3,2) painted
   the neutral-100 fill over the red (white on #f2ebea, 1.17:1, axe 2026-10-06),
   so these selectors carry the same prefix plus the CTA class (0,4,2). */
.pl-site-header .pl-nav-menu > li.ctn-nav-cta > a[aria-current],
.pl-site-header .pl-nav-menu > li.ctn-nav-cta.current-menu-item > a,
.pl-site-header .pl-nav-menu > li.ctn-nav-cta.current-menu-ancestor > a{
  background-color:var(--ctn-red);color:#fff !important;opacity:1}
.pl-site-header .pl-nav-menu > li.ctn-nav-cta.current-menu-item > a:hover,
.pl-site-header .pl-nav-menu > li.ctn-nav-cta.current-menu-item > a:focus{
  background-color:var(--ctn-red-deep);color:#fff !important}

/* ---- Buttons: pill shape sitewide ------------------------------------- */
.wp-block-button__link{
  border-radius:999px;font-weight:700;min-height:48px;
  display:inline-flex;align-items:center;justify-content:center;
  padding:.55em 1.6em}

/* Secondary button in the hero + booking app: petrol outline, not a second red */
/* !important: Plumbline paints button backgrounds at a precedence the child
   sheet cannot beat with specificity alone (layered/global styles). */
[data-pl-section-label="Hero"] .wp-block-button:not(.is-style-primary) .wp-block-button__link{
  background:transparent !important;color:var(--ctn-petrol) !important;
  border:2px solid var(--ctn-petrol) !important}
[data-pl-section-label="Hero"] .wp-block-button:not(.is-style-primary) .wp-block-button__link:hover{
  background:var(--ctn-petrol) !important;color:#fff !important}

/* ---- Big phone number (Book a Ride, Contact) --------------------------- */
.ctn-phone-xl{font-family:var(--pl-font-heading);font-weight:800;
  font-size:clamp(28px,4.6vw,44px);letter-spacing:-.02em;line-height:1.15}
.ctn-phone-xl a{color:var(--ctn-red);text-decoration:none}
.ctn-phone-xl a:hover{color:var(--ctn-red-deep);text-decoration:underline}

/* Section renamed "Booking app" -> "Trip Portal" on 31 Aug 2026, when Anna
   confirmed the Trip Portal is the one booking channel. The label is public
   HTML, Rivet's targeting key and the provenance key all at once, so it moves
   in three places at a time — this selector is one of them.
   The coming-soon line moved to the /trip-portal/ page, so this rule now only
   catches any trailing note under the button. */
[data-pl-section-label="Trip Portal"] .wp-block-buttons + p{
  color:var(--ctn-muted);font-size:16px}

/* ---- Chooser card CTAs read as buttons --------------------------------
   The visible CTA in a Plumbline card is span.pl-card__cta (presentation
   only); a.pl-card__link is an EMPTY STRETCHED OVERLAY that makes the whole
   card clickable — never paint it, or the card disappears behind a giant
   red shape. */
[data-pl-section-label="Service chooser"] .pl-card__cta,
[data-pl-section-label="Booking choices"] .pl-card__cta{
  display:inline-flex;align-items:center;justify-content:center;gap:.55em;
  background:var(--ctn-red);color:#fff;border-radius:999px;
  padding:13px 28px;font-weight:700;text-decoration:none;min-height:52px;
  align-self:flex-start;margin-top:18px}
/* The parent only renders a real arrow SVG when mediaType is "icon"
   (card/render.php), so a photo card's CTA has to grow its own. The span is
   already aria-hidden and the real control is the stretched a.pl-card__link,
   so a decorative glyph here adds nothing to the accessibility tree.

   Only where the parent drew none. Booking choices is an icon grid, so those
   buttons already carried a real .pl-card__cta-icon and this rule gave them a
   second arrow. Asking the CTA whether it already holds one keeps both grids
   right whichever mediaType they are switched to later. */
[data-pl-section-label="Service chooser"] .pl-card__cta:not(:has(.pl-card__cta-icon))::after,
[data-pl-section-label="Booking choices"] .pl-card__cta:not(:has(.pl-card__cta-icon))::after{
  content:"";width:1.05em;height:1.05em;flex:0 0 auto;background:currentColor;
  transition:transform .2s ease;
  -webkit-mask:var(--ctn-arrow-right) center/contain no-repeat;
          mask:var(--ctn-arrow-right) center/contain no-repeat}
[data-pl-section-label="Service chooser"] .pl-card__cta-icon,
[data-pl-section-label="Booking choices"] .pl-card__cta-icon{
  transition:transform .2s ease}
[data-pl-section-label="Service chooser"] .pl-card:hover .pl-card__cta::after,
[data-pl-section-label="Booking choices"] .pl-card:hover .pl-card__cta::after,
[data-pl-section-label="Service chooser"] .pl-card:hover .pl-card__cta-icon,
[data-pl-section-label="Booking choices"] .pl-card:hover .pl-card__cta-icon{
  transform:translateX(.15em)}
[data-pl-section-label="Service chooser"] .pl-card:hover .pl-card__cta,
[data-pl-section-label="Booking choices"] .pl-card:hover .pl-card__cta{
  background:var(--ctn-red-deep)}
[data-pl-section-label="Service chooser"] .pl-card:focus-within .pl-card__cta,
[data-pl-section-label="Booking choices"] .pl-card:focus-within .pl-card__cta{
  outline:3px solid var(--ctn-red);outline-offset:2px}

/* ---- Booking cutoffs: callout treatment -------------------------------- */
[data-pl-section-label="Booking cutoffs"] .pl-section__inner p,
[data-pl-section-label="Booking cutoffs"] p{
  background:#fff;border:1px solid var(--ctn-line);
  border-left:5px solid var(--ctn-red);border-radius:0 12px 12px 0;
  padding:18px 24px;box-shadow:var(--ctn-shadow);max-width:64ch}

/* ---- Site Facts: hours list ------------------------------------------- */
.ctn-facts{list-style:none;margin:0 0 12px;padding:0;max-width:460px}
.ctn-facts li{display:flex;gap:12px;padding:8px 0;
  border-bottom:1px solid var(--ctn-line-soft)}
.ctn-facts li:last-child{border-bottom:0}
.ctn-facts__k{color:var(--ctn-muted);flex:0 0 44%}
.ctn-facts__v{font-weight:600}
.ctn-facts__note{color:var(--ctn-muted);font-size:15px;margin:4px 0 0}

/* Shortcode wrapper paragraphs are empty once their div breaks out */
.pl-section__inner > p:empty{display:none}

/* ---- Fares section: centred header over the fare tables ----------------
   This band was archetype B (text left, object right), floated. Two goes at
   keeping it that way both failed on the same thing: the copy is a heading
   and two short sentences, and no amount of sizing makes that hold a column
   against an 11-band table. At 47% the table stood 580px tall beside four
   lines and left ~490px of dead space; splitting it in two and widening it
   to 62% halved the hole without closing it, and pushed both tables to the
   right edge with an empty lower-left quadrant.

   So this band is archetype A now, the same shape News & Notices uses
   further down: centred header, object running the full rail. The two
   tables fill the width edge to edge, which is what actually balances it.
   Tabular content stays left-aligned inside. */
@media(min-width:1000px){
  [data-pl-section-label="What it costs"] .pl-section__inner{text-align:center}
  [data-pl-section-label="What it costs"] .pl-section__inner > p{
    max-width:60ch;margin-inline:auto}
  [data-pl-section-label="What it costs"] .ctn-fares-split,
  [data-pl-section-label="What it costs"] .ctn-fares{text-align:left}
  [data-pl-section-label="What it costs"] .ctn-fares-split{margin-top:36px}
  [data-pl-section-label="What it costs"] .ctn-fares__note{
    margin:18px auto 0;text-align:center}
}

/* ---- Site Facts: fare table split in two ------------------------------
   Two tables, each carrying its own header row, rather than one
   four-column table whose header associations no screen reader can follow.
   They stack at narrow widths, where one column reads better anyway. */
.ctn-fares-split{display:grid;gap:20px}
@media(min-width:760px){
  .ctn-fares-split{grid-template-columns:repeat(2,minmax(0,1fr));
    gap:24px;align-items:start}
}

/* ---- Table base -------------------------------------------------------
   Shared chrome for every data table on the site: fares, the holiday
   schedule, board meeting dates. Was written once for .ctn-fares and is
   lifted here rather than copied three times. Modifiers below only carry
   what actually differs.

   Anna's own fare document runs two columns of bands side by side, which is
   a paper convention: on the web that means a four-column table whose header
   associations no screen reader can follow, and which cannot wrap on a
   phone. One column, tighter rhythm when the table is long. */
.ctn-table,.ctn-fares{overflow-x:auto;-webkit-overflow-scrolling:touch;
  border-radius:var(--pl-radius,12px);border:1px solid var(--ctn-line);
  box-shadow:var(--ctn-shadow);background:#fff}
.ctn-table table,.ctn-fares table{width:100%;border-collapse:collapse;margin:0}
.ctn-table caption{caption-side:top;text-align:left;
  font-family:var(--pl-font-heading);font-weight:700;font-size:17px;
  color:var(--ctn-ink);padding:16px 18px 0}
.ctn-table th,.ctn-fares th{background:var(--ctn-petrol);color:#fff;text-align:left;
  padding:12px 18px;font-family:var(--pl-font-heading);font-size:15px;
  letter-spacing:.02em}
.ctn-table td,.ctn-fares td{padding:12px 18px;border-top:1px solid var(--ctn-line-soft);
  vertical-align:top}

/* ---- Site Facts: fare table ------------------------------------------- */
.ctn-fares{max-width:560px}
.ctn-fares td:last-child{font-weight:700;font-variant-numeric:tabular-nums}
/* Eleven bands is a tall column; buy the height back from the row rhythm
   rather than from the type size, which this audience cannot spare. */
.ctn-fares tbody:has(tr:nth-child(9)) td{padding-top:9px;padding-bottom:9px}
.ctn-fares__note{color:var(--ctn-muted);font-size:16px;max-width:56ch}

/* ---- News & Notices: white cards on the warm band ----------------------
   The list layout put pills of differing widths on the rail edge, so titles
   started at three different x positions and grey pills vanished into the
   warm band. Cards join the page's existing language (chooser, testimonials),
   restore pill contrast on white, and give every title the same edge. */
.ctn-notice-list{display:grid;gap:20px}
@media(min-width:900px){
  .ctn-notice-list{grid-template-columns:repeat(3,minmax(0,1fr));gap:24px}
}
.ctn-notice-item{
  background:#fff;border:1px solid var(--ctn-line);
  border-radius:var(--pl-radius,12px);padding:24px;
  box-shadow:var(--ctn-shadow);
  display:flex;flex-direction:column;gap:10px;text-align:left}
.ctn-tag{font-family:var(--pl-font-heading);font-size:12px;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;padding:4px 11px;
  border-radius:999px;white-space:nowrap;align-self:flex-start;
  background:var(--ctn-tint);color:var(--ctn-muted)}
.ctn-tag--weather,.ctn-tag--service-alert{background:var(--ctn-red-wash);color:var(--ctn-red-deep)}
.ctn-tag--board-meeting,.ctn-tag--public-hearing{background:var(--ctn-petrol-wash);color:var(--ctn-petrol)}
/* Holiday closures. No-service borrows the red wash the alert types use;
   limited-service the petrol wash. Both stay legible without the pill, since
   the label itself says NO SERVICE / LIMITED SERVICE (WCAG 1.4.1). */
.ctn-tag--holiday-closure,.ctn-tag--no-service{background:var(--ctn-red-wash);color:var(--ctn-red-deep)}
.ctn-tag--limited-service{background:var(--ctn-petrol-wash);color:var(--ctn-petrol)}
.ctn-notice-item__title{font-size:19px;margin:0;line-height:1.3}
.ctn-notice-item__title a{text-decoration:none;color:var(--ctn-ink)}
.ctn-notice-item__title a:hover{color:var(--ctn-red)}
.ctn-notice-item__meta{color:var(--ctn-muted);margin:0;font-size:15.5px;line-height:1.5}
.ctn-notice-list__all{margin-top:28px;text-align:center}
.ctn-notice-list__all a{font-weight:600}

/* ---- Testimonials: quotes as cards ------------------------------------ */
[data-pl-section-label="What riders say"] .wp-block-quote{
  background:#fff;border:1px solid var(--ctn-line);
  border-radius:var(--pl-radius,12px);padding:28px;margin:0 0 20px;
  box-shadow:var(--ctn-shadow)}
[data-pl-section-label="What riders say"] .wp-block-quote p{
  font-family:var(--pl-font-heading);font-weight:600;font-size:20px;
  line-height:1.4;letter-spacing:-.01em;margin:0 0 12px}
[data-pl-section-label="What riders say"] .wp-block-quote p::before{
  content:"\201C";color:var(--ctn-red);font-size:32px;line-height:0;
  vertical-align:-.3em;margin-right:3px}
[data-pl-section-label="What riders say"] .wp-block-quote p::after{
  content:"\201D";color:var(--ctn-red);font-size:32px;line-height:0;
  vertical-align:-.3em;margin-left:2px}
[data-pl-section-label="What riders say"] .wp-block-quote cite{
  color:var(--ctn-muted);font-weight:600;font-style:normal;font-size:16px}

/* ---- Focus visibility -------------------------------------------------- */
.ctn-util a:focus-visible,.ctn-alert a:focus-visible{
  outline:3px solid #fff;outline-offset:2px}
a:focus-visible,button:focus-visible,.wp-block-button__link:focus-visible{
  outline:3px solid var(--ctn-red);outline-offset:2px}

/* ---- Phones ------------------------------------------------------------ */
@media(max-width:700px){
  .ctn-util__wrap{padding:4px 16px;gap:16px;flex-wrap:nowrap}
  .ctn-util a.ctn-util__tty{display:none}   /* TTY lives in the footer */
  .ctn-util__tlabel{display:none}       /* globe icon only; aria-label carries the name */
  .ctn-alert__wrap{padding:10px 16px}
  .ctn-alert__text{font-size:15.5px}
  .ctn-phone-xl{font-size:clamp(26px,9vw,36px)}
  .ctn-facts__k{flex-basis:50%}
  /* Primary CTAs go full width where they stand alone */
  [data-pl-section-label="Hero"] .wp-block-button,
  [data-pl-section-label="Trip Portal"] .wp-block-button{width:100%}
  [data-pl-section-label="Hero"] .wp-block-button__link,
  [data-pl-section-label="Trip Portal"] .wp-block-button__link{width:100%}
}

/* ---- Short laptops (1366×768 agency machines) -------------------------- */
@media(min-width:1061px) and (max-height:820px){
  [data-pl-section-label="Hero"],[data-pl-section-label="Trip Portal"]{
    --pl-section-spacing:2.5rem}
}

/* ---- News & Notices archive --------------------------------------------
   The homepage News section's language at archive scale: warm full-bleed
   band, white cards in a single reading column, type tags, and the expiry
   system made visible ("No longer active" on past notices). */
.ctn-archive{background:var(--ctn-band-warm);padding:48px 24px 64px}
.ctn-archive__inner{max-width:820px;margin-inline:auto}
.ctn-archive__header{display:grid;grid-template-columns:minmax(0,1fr) 190px;gap:32px;
  align-items:center;margin-bottom:32px}
.ctn-archive__header .pl-eyebrow{display:block;margin-bottom:10px}
.ctn-archive__lead{color:var(--ctn-muted);max-width:60ch;margin:10px 0 0}
.ctn-archive__art{display:block;width:100%;height:auto;justify-self:end}
@media(max-width:700px){
  .ctn-archive__header{grid-template-columns:1fr;gap:20px;text-align:center}
  .ctn-archive__lead{margin-inline:auto}
  .ctn-archive__art{max-width:150px;justify-self:center;order:-1}
}
.ctn-archive__list{display:grid;gap:14px}
/* Tag top-right, text down the left edge.
   It used to lead the row in a fixed 168px column, which solved title
   alignment but put a coloured pill between the reader and every headline,
   and cost 168px of the reading measure on a 820px page. Moving it to the
   corner gives every title the SAME left edge for free — the card's own
   padding — so the fixed column is no longer needed and the pill can size to
   its own label again.

   DOM order is unchanged (the tag still precedes the body), so the type is
   still announced before the headline; only the visual position moves. */
.ctn-archive .ctn-notice-item{
  display:grid;grid-template-columns:minmax(0,1fr) auto;
  column-gap:20px;row-gap:6px;align-items:start}
.ctn-archive .ctn-notice-item__body{grid-column:1;grid-row:1;min-width:0}
.ctn-archive .ctn-tag{
  grid-column:2;grid-row:1;justify-self:end;align-self:start;
  flex:0 0 auto;white-space:nowrap;line-height:1.25;padding-block:5px}
.ctn-archive .ctn-notice-item__title{font-size:20px;margin:0 0 4px}
/* .72 dropped the petrol tag to 4.11:1 and the meta to 3.76:1 (axe 2026-10-06); .88 keeps both above 4.5 */
.ctn-notice-item--past{opacity:.88}
.ctn-notice-item__past{
  display:inline-block;margin-left:8px;padding:1px 9px;border-radius:999px;
  border:1px solid var(--ctn-line);color:var(--ctn-muted);font-size:12.5px;
  font-family:var(--pl-font-heading);font-weight:600;letter-spacing:.03em}
.ctn-archive__pagination{margin-top:28px;text-align:center}
@media(max-width:700px){
  .ctn-archive{padding:32px 16px 44px}
  /* Not enough width for a title and a pill side by side; pill leads again. */
  .ctn-archive .ctn-notice-item{grid-template-columns:1fr;row-gap:10px}
  .ctn-archive .ctn-notice-item__body{grid-row:2}
  .ctn-archive .ctn-tag{grid-column:1;grid-row:1;justify-self:start}
}

/* ---- Display type scale (desktop) ---------------------------------------
   Body copy stays 18px for this audience; only the display sizes come down.
   Parent theme sizes live in @layer, so these unlayered rules win.

   Two corrections, 2026-08-21:

   1. The CAPS were never the problem; the FLOORS were. Written in vw, these
      clamps bottom out on a 1280px laptop — the width the client actually
      reviews on — where 1.4vw = 17.9px and h1 fell to 33.3px. That is BELOW
      the same page's mobile h1 (43.9px), which is backwards. Floors raised.

   2. `h3` was rescoped to `h3.wp-block-heading`. As a bare element selector
      it also caught .pl-card__title, which is an h3, and being unlayered it
      beat the parent's layered .pl-card__title{font-size:var(--pl-text-lg)}
      no matter the specificity — so our own shrink pass was capping card
      titles at 19px where the parent intended 22.5px. Scoping to the core
      heading block's class frees the card title back to the parent scale.
      Safe: the only level-3 headings in content are the four footer column
      headings, and those are pinned at 14px further down this file. */
@media(min-width:1200px){
  h1{font-size:clamp(36px, 2.8vw, 44px)}
  h2{font-size:clamp(28px, 2.2vw, 33px)}
  h3.wp-block-heading{font-size:clamp(20px, 1.5vw, 24px)}
}

/* ---- Card typography ----------------------------------------------------
   Plumbline already gives its ICON cards a fuller type treatment than its
   PHOTO cards (blocks.css: --pl-text-xl title / --pl-text-base description
   and CTA, versus --pl-text-lg / --pl-text-sm / --pl-text-sm). There is no
   reason a photo card should read smaller than an icon card, and the 14px
   description was the specific thing the client pointed at. Adopt the
   parent's own icon-card sizes for every card. */
.pl-card__description,
.pl-card__cta{font-size:var(--pl-text-base)}
/* Parent hardcodes 0.6875rem (11px) here, outside the token system. */
.pl-card-grid--media-icon .pl-card__meta{font-size:var(--pl-text-xs)}
/* Parent gives icon cards --pl-text-xl (28.1px), which at 1280 is the same
   size as an h2 — a card title should not tie with the section heading above
   it. Same step as a photo-card title instead. */
.pl-card-grid--media-icon .pl-card__title{font-size:var(--pl-text-lg)}

/* ---- FAQ block ---------------------------------------------------------- */
/* Plumbline renders the Show all control AFTER the items, where nobody sees
   it under twelve questions. Flex-order it to the top, styled as a small pill. */
.pl-faq__inner{display:flex;flex-direction:column}
.pl-faq__controls{order:-1;align-self:flex-end;margin:0 0 10px}
.pl-faq__toggle-all{
  background:transparent;border:2px solid var(--ctn-petrol);color:var(--ctn-petrol);
  border-radius:999px;padding:7px 18px;min-height:40px;cursor:pointer;
  font-family:var(--pl-font-heading);font-weight:700;font-size:14.5px}
.pl-faq__toggle-all:hover{background:var(--ctn-petrol);color:#fff}
.pl-faq__toggle-all:focus-visible{outline:3px solid var(--ctn-red);outline-offset:2px}

/* Answers read as a distinct pane: white against the warm question card.
   The OUTER .pl-faq-item__answer carries the block's padding, so the white
   goes there — on the inner it hugged the text and left warm gutters. */
details.pl-faq-item{overflow:hidden}
.pl-faq-item__answer{
  background:#fff;border-top:1px solid var(--ctn-line);
  padding:16px 20px 18px}
.pl-faq-item__answer-inner{background:transparent;padding:0}

/* ---- Footer ground ------------------------------------------------------
   The footer takes the tan band, site-wide.

   Two reasons it goes here rather than on a content section. The page had no
   floor: below the chooser, every remaining boundary — into News, into Open to
   the public, into the testimonials, into the footer — measures 1.06:1, which
   is invisible, so the page simply stopped rather than ended. And the previous
   pass flagged the footer's fifteen red links as a block of the loudest colour
   on the page with nothing containing them; a warm ground contains them.

   It also bookends: tan near the top for the one decision the page asks a
   reader to make, tan at the bottom as the base. Putting it on the
   testimonials instead would place the same colour twice inside the content
   flow and still leave the page ending on nothing.

   Deliberately NOT both — the testimonials sit directly above the footer, and
   two adjacent warm bands merge into one indistinct block.

   Contrast on the tan, all AA: headings 6.03:1, body and copyright 6.11:1,
   the red links 5.50:1. */
.pl-site-footer{background:var(--ctn-sand-band)}

/* ---- Footer column headings -------------------------------------------- */
/* Shortcode-bearing paragraphs can deliver as empty <p>s; a leading one
   pushes a column's heading off the shared baseline. */
.pl-footer-area p:empty{display:none}
.pl-footer-area > :is(h2,h3){margin-top:0}
.pl-footer-areas .pl-footer-area :is(h2,h3){
  font-family:var(--pl-font-heading);font-size:14px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;
  color:var(--ctn-muted);margin:0 0 14px}

/* ============================================================
   HOMEPAGE GROUND (formerly the texture block)
   Nothing is left of the texture system: the page-level layer
   went 2026-08-20, the hero blob 2026-08-21. What remains here
   is the band rhythm, which never depended on it.
   ============================================================ */

/* Homepage band rhythm: white page ground, warm muted bands.
   This is what functions.php's ctn_child_tokens() always intended
   ("warm page base with white muted bands") but never wired up.

   BOTH declarations are required and neither is optional:
   - the <section> element is the only full-bleed box in a Plumbline
     block, so the band colour must be painted there;
   - `.pl-block__surface` is the INNER element (max-width 1184px on a
     section, and the 544px text column on a split). Left painting, it
     draws a floating pale rectangle inside the band instead of a band. */
body.home [data-pl-section-style="muted"]{
  background:var(--ctn-band-warm)}
body.home [data-pl-section-style="muted"] .pl-block__surface{
  background:transparent}

/* The chooser band goes sand — the same ground as the hero mat and the client
   illustrations, so the page opens white, drops into the warm drawn ground for
   the one decision it is asking the reader to make, and returns to white.

   BOTH labels, always. "Two ways to ride" is the heading and "Service chooser"
   is the two cards; §3 binds them into one continuous band, so colouring one
   and not the other puts a seam through the middle of it. Same specificity as
   the muted rule above (0,2,1), so this has to stay below it. */
body.home [data-pl-section-label="Two ways to ride"],
body.home [data-pl-section-label="Service chooser"]{
  background:var(--ctn-sand-band)}

/* ---- Hero photograph ----------------------------------------------------
   The hero art slot carries the client's own photograph of a bus outside their
   office, mounted in a warm mat.

   It used to bleed off the right edge of the screen. That kept the photo big
   but read as unintentional — a picture butted against the viewport rather
   than a designed element, and the only thing on the site with its own rules.
   Everything else that holds media now sits in a tinted plate: the chooser
   cards, the Trip Portal split, the illustration splits. The hero joins them.

   The mat is not a rounded rectangle. It is the silhouette from the
   designer's hero-blob.svg — the swell that was mounted behind the bus
   illustration in the approved preview — masked out of a solid tint. So the
   photo is a clean rectangle and the thing it sits on is hand-drawn, which is
   where the warmth comes from. Masking the PHOTO into that shape was tried
   first and abandoned: an irregular edge works on a drawing, where you control
   what sits near it, but it ate the wheels and the front of the vehicle.

   Degrades honestly: without mask support the ::before paints as a plain
   rounded tint mat, which is the same design one step quieter. */

[data-pl-section-label="Hero"] .pl-split__media{margin:0}
/* The hero keeps the white page ground. It sat on the warm band while the mat
   was --ctn-tint, which had four points of contrast against warm and vanished;
   now the mat is --ctn-sand, which reads more strongly on white than it ever
   did on warm, so the hero can stay the brightest thing on the page. */
[data-pl-section-label="Hero"]{overflow-x:clip}

@media(min-width:1200px){
  [data-pl-section-label="Hero"] .pl-split__inner{
    grid-template-columns:minmax(0,0.92fr) minmax(0,1.08fr);
    align-items:center}

  [data-pl-section-label="Hero"] .pl-split__media{
    position:relative;
    overflow:visible;
    padding:26px 30px;
    border-radius:0}

  /* The mat. The inset is negative and deliberately uneven, for two reasons:
     the silhouette is asymmetric, so an even inset reads as a mistake rather
     than a drawing; and the designer put its high point right of centre, so an
     even inset piles the whole mass into the top-right corner and leaves a
     thin sliver down the left. Weighted toward the bottom-left to counter it. */
  [data-pl-section-label="Hero"] .pl-split__media::before{
    content:"";position:absolute;
    inset:-8px -22px -34px -30px;
    background:var(--ctn-sand);
    border-radius:24px;
    -webkit-mask:url("assets/hero-mat.svg") center/100% 100% no-repeat;
            mask:url("assets/hero-mat.svg") center/100% 100% no-repeat;
    z-index:0}

  [data-pl-section-label="Hero"] .pl-split__img{
    position:relative;z-index:1;
    max-width:none;width:100%;
    border-radius:14px;
    box-shadow:0 2px 6px rgba(28,25,23,.10),0 18px 44px -24px rgba(28,25,23,.32)}
}

@media(max-width:1199px){
  /* Same idea, no mask: at these widths the media column is narrow enough that
     the silhouette's lobes read as wobble rather than as a drawn edge. */
  [data-pl-section-label="Hero"] .pl-split__media{
    background:var(--ctn-sand);
    border-radius:18px;
    padding:14px;
    box-shadow:0 1px 2px rgba(28,25,23,.05),0 14px 36px -22px rgba(28,25,23,.26)}
  [data-pl-section-label="Hero"] .pl-split__img{border-radius:11px}
}

/* ============================================================
   DESKTOP PAGE STRUCTURE (>=1200px)
   Four systems, in order: rail, rhythm, band pairing, section layouts.
   ============================================================ */

:root{
  /* The warm band. Same value as --pl-color-surface-page, named separately
     so the band system is greppable and can be retuned without touching
     the token that PHP also mirrors. */
  --ctn-band-warm:#FAF8F6;
}

/* ---- §1  One alignment rail --------------------------------------------
   Site-wide, not homepage-only: the header and footer are global, and a
   header that realigns only on the homepage is worse than one that never
   realigns. To stage this to the homepage first, prefix each selector in
   this section with `body.home `.

   Before this block the page carried four different left edges at 1900px:
   logo at x=24 (pl-full-width), utility bar and alert at x=358 (1184px),
   footer at x=350 (1200px), and section content alternating 350/358 by
   block type. All of them now resolve to one number.

   min() guarantees a gutter at every width, so the rail never touches the
   viewport edge at the media-query boundary. */
@media(min-width:1200px){
  :root{--ctn-rail:min(1200px, calc(100vw - 96px))}

  /* .pl-site-header .pl-site-header__inner — two classes (0,2,0) to beat the
     parent's unlayered .pl-full-width{max-width:100%} (0,1,0). */
  /* 24px inline padding to match the text inset every section inner carries —
     the logo lands on the TEXT rail (x=294 @1900), not the box rail. */
  .pl-site-header .pl-site-header__inner{
    max-width:var(--ctn-rail);margin-inline:auto;padding-inline:24px}

  /* These two keep their 24px inline padding, so the rail is widened by
     exactly that much to put the TEXT edge on the rail, not the box edge. */
  .ctn-util__wrap,
  .ctn-alert__wrap{
    max-width:calc(var(--ctn-rail) + 48px);padding-inline:24px}

  .pl-section__inner,
  .pl-split__inner,
  .pl-card-grid__inner,
  .pl-icon-list__inner,
  .pl-faq__inner,
  .pl-footer-areas{max-width:var(--ctn-rail)}
}

/* Wider rail on large desktops. 1360px is a deliberate ceiling, not a
   preference: the chooser and hero illustrations are 480x480px natural and
   already upscale 1.33x at this rail. Do not raise it further until those
   assets are re-exported at >=1280px. */
@media(min-width:1600px){
  :root{--ctn-rail:min(1360px, calc(100vw - 120px))}
}

/* ---- §2  Vertical rhythm ------------------------------------------------
   Replaces the flat 82px seam that applied to every boundary on the page.
   Padding sits INSIDE each coloured band, so top and bottom are equal and
   the seam between two bands is a colour change rather than a gap.

   This also restores `spacingPreset` as a live lever at desktop widths —
   it was inert before, because the old sibling rule overrode every top
   edge regardless of preset. */
@media(min-width:1200px){
  /* Trimmed 2026-08-21: 36/52/72 -> 32/46/64. A light trim on purpose. Most
     of the height the client was reacting to was never in these gaps — it was
     in two oversized components (the chooser cards and the illustration
     splits), and those are fixed in §3b. Squeezing the bands further buys
     ~60px across the whole page and costs the band separation that makes the
     warm/white alternation legible, which is the "crowded" failure the client
     named in the same breath as the request. */
  .pl-section--spacing-compact,
  .pl-card-grid--spacing-compact,
  .pl-split--spacing-compact,
  .pl-icon-list--spacing-compact,
  .pl-faq--spacing-compact{--ctn-band-pad:32px}

  .pl-section--spacing-standard,
  .pl-card-grid--spacing-standard,
  .pl-split--spacing-standard,
  .pl-icon-list--spacing-standard,
  .pl-faq--spacing-standard{--ctn-band-pad:46px}

  .pl-section--spacing-spacious,
  .pl-card-grid--spacing-spacious,
  .pl-split--spacing-spacious,
  .pl-icon-list--spacing-spacious,
  .pl-faq--spacing-spacious{--ctn-band-pad:64px}

  [data-pl-section-label]{
    padding-top:var(--ctn-band-pad,52px);
    padding-bottom:var(--ctn-band-pad,52px)}

  /* The hero opens the page; it gets a shorter top and a longer bottom so it
     reads as an entrance rather than as the first of seven equal bands.
     Trimmed with the rest of the rhythm; the photo now supplies the presence
     the padding used to have to fake. */
  /* Bottom padding carries the gap between the white hero and the tan band
     below it. Kept on the hero rather than as a margin on the band, because a
     margin on a full-bleed coloured section collapses against its neighbour
     and the gap disappears at some widths. */
  [data-pl-section-label="Hero"]{padding-top:32px;padding-bottom:70px}
  /* Text column and photo meet in the middle rather than the photo hanging
     off a top-aligned row. */
  [data-pl-section-label="Hero"] .pl-split__inner{align-items:center}
}

/* ---- §3  Bind a header section to the block it introduces ---------------
   "Which one do you need?" and its two cards are separate sections. At the
   old uniform 82px the heading sat equidistant from its own cards and from
   the hero above, so it floated free. Collapsing the pair to a single 56px
   gap makes them read as one unit inside one warm band. */
@media(min-width:1200px){
  [data-pl-section-label="Two ways to ride"]{padding-bottom:0}
  /* Any list/grid/faq block directly continuing a section binds to it:
     the pair reads as one unit, not two bands drifting apart. */
  [data-pl-section-label] + :is(.wp-block-plumbline-icon-list,
    .wp-block-plumbline-faq, .wp-block-plumbline-card-grid){padding-top:16px}
  [data-pl-section-label]:has(+ :is(.wp-block-plumbline-icon-list,
    .wp-block-plumbline-faq, .wp-block-plumbline-card-grid)){padding-bottom:12px}
}

/* ---- §3b  Illustration plates -------------------------------------------
   The eight client illustrations are square-ish PNGs (0.92:1 to 2.39:1 ink,
   inside a square canvas) carrying 8-33% transparent margin on every edge.
   Dropped into a box that CROPS, two things go wrong at once: the drawing is
   trimmed top and bottom, and what survives floats in dead air left and right.
   That combination — not the box size on its own — is what read as "the image
   is HUGE and the fonts are tiny".

   The fix is a plate: a fixed box, a tinted ground, and object-fit:contain.
   contain means the box height governs every asset, so a 1.14:1 county map and
   a 2.39:1 street scene render at the SAME optical ink height instead of one
   towering over the other. It also makes the baked-in transparent margin
   harmless — it just becomes part of the plate — so no re-export is required
   for this to come good.

   §3b-i  Card plates: the chooser cards become horizontal bands. */
@media(min-width:1200px){
  /* Plate width is fluid, and it has to be. At the 1360 rail a card is 640px
     and a fixed 240px plate leaves a comfortable 344px of text. At the 1200
     rail the same card is 552px, the text column falls to 254px, and the CTA
     label wraps onto a second line inside its own pill — measured, on the
     1280px screen the client actually reviews on. 15vw reaches the full 240px
     from 1600 up and eases back to 192px at 1280, which keeps the CTA on one
     line and is 59px shorter per card into the bargain. */
  [data-pl-section-label="Service chooser"] .pl-card,
  [data-pl-section-label="Booking choices"] .pl-card{
    display:grid;grid-template-columns:clamp(168px, 15vw, 240px) minmax(0,1fr);
    align-items:center;background:#fff}

  [data-pl-section-label="Service chooser"] .pl-card__image,
  [data-pl-section-label="Booking choices"] .pl-card__image{
    aspect-ratio:auto;width:auto;height:100%;
    background:var(--ctn-tint);
    display:flex;align-items:center;justify-content:center}

  [data-pl-section-label="Service chooser"] .pl-card__img,
  [data-pl-section-label="Booking choices"] .pl-card__img{
    width:100%;height:100%;object-fit:contain;padding:16px}

  /* An ICON card in the same scope takes the same plate, so a card carrying a
     Phosphor mark and a card carrying an illustration read as siblings rather
     than as two different components. This is the whole point of the plate
     being a container treatment and not an image treatment. */
  [data-pl-section-label="Service chooser"] .pl-card__icon,
  [data-pl-section-label="Booking choices"] .pl-card__icon{
    align-self:stretch;height:100%;padding:0;
    background:var(--ctn-tint);
    display:flex;align-items:center;justify-content:center}
  /* Scaled to the plate rather than to the block's iconSize: the plate is
     ~192-240px and a 77px mark floats in it. Sizing here keeps iconSize as a
     meaningful editor lever everywhere else on the site. */
  [data-pl-section-label="Service chooser"] .pl-card__icon-svg,
  [data-pl-section-label="Booking choices"] .pl-card__icon-svg{
    width:clamp(72px, 9vw, 108px);height:clamp(72px, 9vw, 108px)}

  [data-pl-section-label="Service chooser"] .pl-card__body,
  [data-pl-section-label="Booking choices"] .pl-card__body{
    padding:24px 28px}

  /* Meta was doing no work in muted grey at 11.5px. At 13px in petrol it
     becomes the lead-time answer the card is really sorting riders by. */
  [data-pl-section-label="Service chooser"] .pl-card__meta,
  [data-pl-section-label="Booking choices"] .pl-card__meta{
    color:var(--ctn-petrol);font-weight:700;margin-bottom:6px}

  [data-pl-section-label="Service chooser"] .pl-card__description,
  [data-pl-section-label="Booking choices"] .pl-card__description{
    margin-bottom:16px}
}

/* Below the plate breakpoint the chooser cards stack and Plumbline's 16:10
   cover crop applies. Fit instead of crop, so a near-square mark (the
   Pittsboro TOD logo) shows whole. curb-pickup is exactly 16:10, so for it
   contain and cover render identically. */
@media(max-width:1199px){
  [data-pl-section-label="Service chooser"] .pl-card__img,
  [data-pl-section-label="Booking choices"] .pl-card__img{
    object-fit:contain}
}

/* §3b-ii  Split plates: the same language wherever an illustration meets a
   split. Without this, a square illustration renders at the full 624px
   half-rail — Book a Ride's "Trip Portal" split is 728px tall to show a
   drawing that occupies about two-thirds of its own canvas. The hero is
   excluded: it carries a photograph, which is cropped deliberately and wants
   no plate behind it. */
@media(min-width:1200px){
  [data-pl-section-label]:not([data-pl-section-label="Hero"]) .pl-split__media{
    aspect-ratio:16 / 9;background:var(--ctn-tint);
    border-radius:var(--pl-radius,12px);
    display:flex;align-items:center;justify-content:center}
  [data-pl-section-label]:not([data-pl-section-label="Hero"]) .pl-split__img{
    width:100%;height:100%;object-fit:contain;padding:20px}
  [data-pl-section-label]:not([data-pl-section-label="Hero"]) .pl-split__inner{
    align-items:center}
}

/* ---- §4  Section layouts ------------------------------------------------
   Two archetypes, alternating down the page, replacing seven identical
   left-aligned stacks:

     A  centred header over symmetric content   (chooser, news, testimonials)
     B  asymmetric two-column, text + object    (hero, fares, open-to-public)

   Reading down: B(hero) A B A B-mirrored A. The mirror on "Open to the
   public" (photo left) is a fixture attribute, not CSS — see changes.md #9. */
@media(min-width:1200px){

  /* A — chooser header */
  [data-pl-section-label="Two ways to ride"] .pl-section__inner{text-align:center}
  [data-pl-section-label="Two ways to ride"] .pl-section__inner > p{
    max-width:60ch;margin-inline:auto}

  /* A — news: centred header, list runs the full rail.
     The list keeps its full width deliberately. Narrowing and centring it
     introduced a third left edge that aligned with nothing; the full-width
     hairline rules do the structural work instead. */
  [data-pl-section-label="News & Notices"] .pl-section__inner{text-align:center}
  [data-pl-section-label="News & Notices"] .pl-section__inner > p:not(.ctn-notice-list__all){
    max-width:60ch;margin:0 auto 36px}
  [data-pl-section-label="News & Notices"] .ctn-notice-list,
  [data-pl-section-label="News & Notices"] .ctn-notice-list__all{text-align:left}

  /* B — fares: let the table reach its column edge.
     .ctn-fares carries max-width:560px globally, which stopped 88px short of
     its own grid column at the 1360px rail and so never lined up with the
     cards above it. Scoped override only; the table keeps its cap elsewhere. */
  [data-pl-section-label="What it costs"] .ctn-fares{max-width:none}

  /* A — testimonials: 3-up.
     Was three 1136px slabs holding one line each (line fill 82% / 68% / 54%,
     tapering visibly to the right). Equal-height columns with the cite pinned
     to the bottom edge. */
  [data-pl-section-label="What riders say"] .pl-section__inner{
    display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
    column-gap:28px;row-gap:0;align-items:stretch}
  [data-pl-section-label="What riders say"] .pl-section__inner > .pl-eyebrow,
  [data-pl-section-label="What riders say"] .pl-section__inner > h2{
    grid-column:1 / -1;text-align:center}
  [data-pl-section-label="What riders say"] .pl-section__inner > h2{
    margin-bottom:32px}
  [data-pl-section-label="What riders say"] .wp-block-quote{
    margin:0;height:100%;display:flex;flex-direction:column}
  [data-pl-section-label="What riders say"] .wp-block-quote cite{
    margin-top:auto;padding-top:10px}
}


/* ============================================================
   §5  INTERNAL DENSITY TRIMS (>=1200px)
   Between-block space, never between-sentence space. Body
   line-height (1.65), heading-to-paragraph gaps and tap targets
   are deliberately untouched — that is the line between
   "compact" and "crowded".
   ============================================================ */
@media(min-width:1200px){
  /* Section headings sat a full 32px off their own content. */
  [data-pl-section-label] > * > h2{margin-bottom:14px}
  [data-pl-section-label="What riders say"] .pl-section__inner > h2{margin-bottom:22px}

  /* News: lead and "see all" were both carrying more air than the cards. */
  [data-pl-section-label="News & Notices"] .pl-section__inner > p:not(.ctn-notice-list__all){
    margin:0 auto 22px}
  .ctn-notice-list{gap:18px}
  .ctn-notice-item{padding:18px 20px;gap:8px}
  .ctn-notice-list__all{margin-top:18px}

  /* Quote cards: 28px of padding around two lines of text. */
  [data-pl-section-label="What riders say"] .wp-block-quote{padding:22px}

  /* Fare rows: 54px -> 46px. Not lower — below that a five-row table stops
     being scannable for older eyes and starts reading as a spreadsheet. */
  .ctn-fares th{padding:10px 18px}
  .ctn-fares td{padding:9px 18px}

  /* Footer: 48px outer + 32px inner was 80px before the first heading. */
  .pl-footer-areas{padding-block:24px}
}

/* ============================================================
   §6  ICON SYSTEM
   Phosphor, customised for this site.

   What makes an icon look like it belongs here: the client's
   illustrations are filled mass with no outlines. Duotone with
   the tint re-opened to full opacity is ~50% inked and the tint
   follows the object's own body, which is the bridge. Rules:
   thin and light are banned outright; duotone at 38px and up;
   bold below that; regular stays exactly where the PARENT theme
   already uses it (CTA arrows, FAQ carets, nav search, back to
   top) — see inc/icons.php for why that boundary matters.
   Prefer circled forms for standalone marks, bare forms inline.
   The triangle is the only sharp-cornered shape in the set and
   fights the 20px radii in the artwork, so it appears exactly
   once: the urgent alert bar, where silhouette is the only
   thing separating urgent from normal.

   Phosphor duotone ships the tint as the FIRST <path>, carrying
   opacity="0.2" and no fill of its own, so it inherits
   currentColor at 20%. Checked across all 1512 duotone slugs:
   always first, always exactly one opacity attribute, always
   0.2. Two icons (cell-signal-none, wifi-none) have no tint
   path and render clean mono, which is correct. And `opacity=`
   appears in NO non-duotone entry, so path[opacity] is precise
   and a provable no-op on every other icon on the site.
   ============================================================ */

:root{
  /* The whole system is these two. Treatments override them, nothing else. */
  --ctn-icon-ink:var(--ctn-petrol);
  --ctn-icon-tint:var(--ctn-pale);
}

/* ---- T1  BRAND DUOTONE (the default, no class needed) ------------------
   Overrides the parent's .pl-icon-list-item__icon{color:text-primary}, which
   is why every icon on Rules of the Road was ink black. Child sheet is
   unlayered; parent blocks.css is in @layer, so this wins. */
.pl-card__icon,
.pl-icon-list-item__icon{color:var(--ctn-icon-ink)}
.pl-card__icon-svg path[opacity],
.pl-icon-list-item__icon-svg path[opacity]{fill:var(--ctn-icon-tint);opacity:1}

/* ---- T2  CAUTION DUOTONE ----------------------------------------------
   One red block per page. Red means prohibition or a deadline with a
   consequence; red never means good news. 58px floor, not 38px: the red wash
   is 1.14:1 on the warm band where the pale tint is 1.24:1, so it needs the
   extra size to register at all. */
.ctn-icons--caution{
  --ctn-icon-ink:var(--ctn-red-deep);
  --ctn-icon-tint:var(--ctn-red-wash)}

/* ---- T3  UTILITY MONO --------------------------------------------------
   No colour rule at all — bold weight, currentColor, inheriting whatever text
   it sits beside. That is exactly what lets one treatment work on the petrol
   utility bar, the red alert bar and inside every notice pill without a
   variant for each. A T1 icon on either dark bar would be petrol on petrol
   and disappear, which is why those two surfaces are mono only. */
.ctn-util svg,
.ctn-alert svg,
.ctn-tag svg{flex:0 0 auto}
.ctn-tag{display:inline-flex;align-items:center;gap:6px}
.ctn-util a svg{margin-right:1px}

/* The tint is a depth device, never a carrier. At 1.32:1 on white the disc is
   effectively invisible to a low-contrast-sensitivity reader — and that is
   fine, because the duotone main path still draws the complete contour over
   it at 9.2:1. Strip the tint and every icon still reads. That is the whole
   argument for building on duotone rather than fill: duotone degrades to a
   legible mono icon, fill degrades to a blob. */

/* ---- T4  COMPOSED: NEGATION OVERLAY ------------------------------------
   The "overlapping icons" case, and the one place on this site that genuinely
   needs it. Phosphor ships 36 -slash variants and none of them is knife-slash
   or wine-slash, which are exactly the two prohibitions Rules of the Road has
   to state. So the ring is composed over the object instead.

   Applied per BLOCK, not per item: a card or icon-list item carries one
   iconSlug and nothing else, and Rivet cannot deliver a per-card className —
   but it does pass className through on the card-grid / icon-list wrapper. A
   staffer turns this on by typing one class into Advanced -> Additional CSS
   class(es), and every item in that list gets a ring. That is the right
   granularity anyway: prohibition is a property of the list, not of one row.

   Accessible by construction: .pl-icon-list-item__icon already carries
   aria-hidden from the parent render template, and a pseudo-element is never
   in the accessibility tree. The copy beside each icon says "No ..." in words.

   The object drops to mid-petrol so the red ring reads clearly on top of it.
   #2A6B7E is 6.00:1 on white, #B02010 is 6.86:1 — both AA. */
:root{--ctn-negate-ring:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'><path d=%22M128%2C20A108%2C108%2C0%2C1%2C0%2C236%2C128%2C108.12%2C108.12%2C0%2C0%2C0%2C128%2C20Zm84%2C108a83.6%2C83.6%2C0%2C0%2C1-16.75%2C50.28L77.72%2C60.75A84%2C84%2C0%2C0%2C1%2C212%2C128ZM44%2C128A83.6%2C83.6%2C0%2C0%2C1%2C60.75%2C77.72L178.28%2C195.25A84%2C84%2C0%2C0%2C1%2C44%2C128Z%22/></svg>")}

.ctn-icons--negate{--ctn-icon-ink:var(--ctn-petrol-mid);--ctn-icon-tint:var(--ctn-pale)}
.ctn-icons--negate .pl-icon-list-item__icon,
.ctn-icons--negate .pl-card__icon{position:relative;width:fit-content}
/* The ring OVERHANGS the object and the object shrinks inside it. Sized 1:1
   and concentric, prohibit-bold's thick ring and wide slash cover most of a
   58px drawing, and five prohibitions render as five near-identical red
   discs — which is the same failure as the five identical black check-circles
   this replaced, just in a different colour. At 122%/78% the cigarette, the
   knife, the fist, the speaker and the glass are each legible inside the ring,
   which is the entire point of composing them. */
.ctn-icons--negate .pl-icon-list-item__icon::after,
.ctn-icons--negate .pl-card__icon::after{
  content:"";position:absolute;inset:-11%;
  width:122%;height:122%;
  background:var(--ctn-red);pointer-events:none;
  -webkit-mask:var(--ctn-negate-ring) center/contain no-repeat;
          mask:var(--ctn-negate-ring) center/contain no-repeat}
.ctn-icons--negate .pl-icon-list-item__icon-svg,
.ctn-icons--negate .pl-card__icon-svg{transform:scale(.78)}

/* The parent sets --pl-card-icon-size on card grids only; icon lists size
   through modifier classes alone, and it defines just sm/md/lg/xl — so
   iconSize "xs" and "xxl" silently fall back to 58px and the overlay geometry
   above has nothing to read. One source of truth for both blocks. */
.pl-icon-list--icon-xs{--pl-card-icon-size:29px}
.pl-icon-list--icon-sm{--pl-card-icon-size:38px}
.pl-icon-list--icon-md{--pl-card-icon-size:58px}
.pl-icon-list--icon-lg{--pl-card-icon-size:77px}
.pl-icon-list--icon-xl{--pl-card-icon-size:96px}
.pl-icon-list--icon-xxl{--pl-card-icon-size:115px}
.pl-icon-list-item__icon-svg{
  width:var(--pl-card-icon-size,58px);height:var(--pl-card-icon-size,58px)}

/* ============================================================
   §7  RULES OF THE ROAD — SECTION PANELS
   The page is eleven sections of near-identical texture: a
   heading, a list, a heading, a list. Alternating white and
   warm bands was too quiet to separate them, because the two
   grounds are four points apart.

   So the whole page becomes ONE warm ground, and each topic
   becomes a white panel on it, with a 4px top rail in the
   colour of its own register — petrol for what we ask and what
   we promise, red for what is not allowed. The rail matches
   the icon treatment inside the panel, so colour is saying the
   same thing twice rather than two different things.

   This is the site's existing card language (notice items,
   quote cards, chooser cards are all white-on-warm with a line
   and a shadow), not a new one.

   Four panels, each a heading section plus the list it
   introduces plus any closing note:

     What we ask of you  + Rider asks                    petrol
     What is not allowed + Not allowed + Refusal of...   red
     What we do for you  + Our commitments + Driver...   petrol
     Children and aides  (on its own)                    petrol

   The page h1 and the closing "Full policy" pointer stay on
   the bare ground — they frame the panels rather than being
   one.

   Scoping note: the panels key off section LABELS, like the
   rest of this file. Only the warm ground keys off the page
   slug, so if the slug ever changes the panels survive and the
   ground simply reverts to the theme's band alternation.
   ============================================================ */

body.page-rules-of-the-road [data-pl-section-label]{background:var(--ctn-band-warm)}

/* Which register each member belongs to. */
[data-pl-section-label="What we ask of you"],
[data-pl-section-label="Rider asks"],
[data-pl-section-label="What we do for you"],
[data-pl-section-label="Our commitments"],
[data-pl-section-label="Driver limits"],
[data-pl-section-label="Children and aides"]{--ctn-panel-accent:var(--ctn-petrol)}

[data-pl-section-label="What is not allowed"],
[data-pl-section-label="Not allowed"],
[data-pl-section-label="Refusal of service"]{--ctn-panel-accent:var(--ctn-red)}

/* Every panel member. The band padding goes to zero and the panel is painted
   on the INNER, which is the rail-width box — painting the section instead
   would run the panel edge to edge. Section padding then becomes the gap
   BETWEEN panels, which is what it should have been all along. */
[data-pl-section-label="What we ask of you"],
[data-pl-section-label="Rider asks"],
[data-pl-section-label="What is not allowed"],
[data-pl-section-label="Not allowed"],
[data-pl-section-label="Refusal of service"],
[data-pl-section-label="What we do for you"],
[data-pl-section-label="Our commitments"],
[data-pl-section-label="Driver limits"],
[data-pl-section-label="Children and aides"]{padding-block:0}

/* §3 binds a heading section to the block it introduces with 12px below and
   16px above. Both rules are (0,2,0) — the `:has()` takes the specificity of
   its argument — so a plain [data-pl-section-label="…"] reset at (0,1,0) loses
   to them, and the panel gets split by a 12px stripe of warm ground. These
   two counter it at matching specificity, in the same shape, later in the
   file. Without them the panels look like six boxes instead of three. */
[data-pl-section-label] + [data-pl-section-label="Rider asks"],
[data-pl-section-label] + [data-pl-section-label="Not allowed"],
[data-pl-section-label] + [data-pl-section-label="Our commitments"]{padding-top:0}

[data-pl-section-label="What we ask of you"]:has(+ .wp-block-plumbline-icon-list),
[data-pl-section-label="What is not allowed"]:has(+ .wp-block-plumbline-icon-list),
[data-pl-section-label="What we do for you"]:has(+ .wp-block-plumbline-icon-list){
  padding-bottom:0}

:is(
  [data-pl-section-label="What we ask of you"],
  [data-pl-section-label="Rider asks"],
  [data-pl-section-label="What is not allowed"],
  [data-pl-section-label="Not allowed"],
  [data-pl-section-label="Refusal of service"],
  [data-pl-section-label="What we do for you"],
  [data-pl-section-label="Our commitments"],
  [data-pl-section-label="Driver limits"],
  [data-pl-section-label="Children and aides"]
) > :is(.pl-section__inner, .pl-icon-list__inner){
  background:var(--pl-color-surface-alt,#fff);
  border-inline:1px solid var(--ctn-line);
  padding-inline:clamp(20px, 3vw, 36px);
  padding-block:6px}

/* Panel opens: top rail in the register colour. */
[data-pl-section-label="What we ask of you"],
[data-pl-section-label="What is not allowed"],
[data-pl-section-label="What we do for you"],
[data-pl-section-label="Children and aides"]{padding-top:26px}

:is(
  [data-pl-section-label="What we ask of you"],
  [data-pl-section-label="What is not allowed"],
  [data-pl-section-label="What we do for you"],
  [data-pl-section-label="Children and aides"]
) > .pl-section__inner{
  border-top:4px solid var(--ctn-panel-accent);
  border-radius:var(--pl-radius,12px) var(--pl-radius,12px) 0 0;
  padding-top:26px}

/* Panel closes. */
[data-pl-section-label="Rider asks"],
[data-pl-section-label="Refusal of service"],
[data-pl-section-label="Driver limits"],
[data-pl-section-label="Children and aides"]{padding-bottom:26px}

:is(
  [data-pl-section-label="Rider asks"],
  [data-pl-section-label="Refusal of service"],
  [data-pl-section-label="Driver limits"],
  [data-pl-section-label="Children and aides"]
) > :is(.pl-section__inner, .pl-icon-list__inner){
  border-bottom:1px solid var(--ctn-line);
  border-radius:0 0 var(--pl-radius,12px) var(--pl-radius,12px);
  padding-bottom:26px;
  box-shadow:var(--ctn-shadow)}

/* Children and aides is a panel of one, so it opens and closes on the same
   element and needs all four corners. */
[data-pl-section-label="Children and aides"] > .pl-section__inner{
  border-radius:var(--pl-radius,12px)}

/* The two closing notes are prose after a list, inside the same panel. A
   hairline separates them without opening the panel back up. */
[data-pl-section-label="Refusal of service"] > .pl-section__inner,
[data-pl-section-label="Driver limits"] > .pl-section__inner{
  border-top:1px solid var(--ctn-line-soft);
  padding-top:18px}

/* Panel headings carry the panel; they do not need extra air beneath them. */
:is(
  [data-pl-section-label="What we ask of you"],
  [data-pl-section-label="What is not allowed"],
  [data-pl-section-label="What we do for you"]
) h2{margin-bottom:0}

/* Below the rail breakpoint the inner has no max-width to centre against, so
   replacing its gutter with panel padding put the panel edges on the viewport
   edges — a full-bleed band, not a card, with its border and radius off
   screen. The gutter comes back as margin so the panel keeps its shape. */
@media(max-width:1199px){
  :is(
    [data-pl-section-label="What we ask of you"],
    [data-pl-section-label="Rider asks"],
    [data-pl-section-label="What is not allowed"],
    [data-pl-section-label="Not allowed"],
    [data-pl-section-label="Refusal of service"],
    [data-pl-section-label="What we do for you"],
    [data-pl-section-label="Our commitments"],
    [data-pl-section-label="Driver limits"],
    [data-pl-section-label="Children and aides"]
  ) > :is(.pl-section__inner, .pl-icon-list__inner){
    margin-inline:clamp(16px, 3vw, 32px)}
}

@media(max-width:700px){
  /* Panels still read on a phone, just tighter. */
  [data-pl-section-label="What we ask of you"],
  [data-pl-section-label="What is not allowed"],
  [data-pl-section-label="What we do for you"],
  [data-pl-section-label="Children and aides"]{padding-top:18px}
  [data-pl-section-label="Rider asks"],
  [data-pl-section-label="Refusal of service"],
  [data-pl-section-label="Driver limits"],
  [data-pl-section-label="Children and aides"]{padding-bottom:18px}
}

/* ============================================================
   §8  SEARCH OVERLAY
   Plumbline's modal shell and its script are kept — they
   already handle opening, the focus trap, Escape, backdrop
   clicks and returning focus to the trigger, and there was
   nothing wrong with any of that. What was dated was the
   contents: a titled dialog with a lone text field that threw
   you at a separate results page to find out whether anything
   matched.

   Now it is a command palette. It sits near the top of the
   screen rather than dead centre, the input IS the interface
   (no heading, no submit button competing with it), and
   results arrive under the cursor as you type. Enter still
   goes to the full results page when nothing is highlighted,
   so the old path survives for "show me everything" and for
   no-JS.
   ============================================================ */

.ctn-search{
  align-items:flex-start;
  padding:clamp(56px, 12vh, 132px) 20px 20px}
.ctn-search .ctn-search__panel{
  width:min(680px, 100%);max-width:none;padding:0;overflow:hidden;
  border-radius:18px;border:1px solid var(--ctn-line);
  background:#fff;
  box-shadow:0 4px 12px rgba(28,25,23,.06),0 32px 72px -28px rgba(28,25,23,.42)}

/* ---- the field ---------------------------------------------------------- */
.ctn-search__form{
  display:flex;align-items:center;gap:12px;
  padding:14px 14px 14px 18px;
  border-bottom:1px solid var(--ctn-line-soft)}
.ctn-search__icon{
  display:flex;flex:0 0 auto;color:var(--ctn-petrol);line-height:0}
.ctn-search__input{
  flex:1 1 auto;min-width:0;
  border:0;background:none;padding:8px 0;
  font-family:var(--pl-font-heading);
  font-size:21px;line-height:1.3;color:var(--ctn-ink);
  appearance:none}
.ctn-search__input::placeholder{color:var(--ctn-muted);font-weight:400}
.ctn-search__input:focus{outline:none}          /* the panel itself is the focus ring */
.ctn-search__input::-webkit-search-decoration,
.ctn-search__input::-webkit-search-cancel-button{appearance:none}
.ctn-search__close{
  flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;border-radius:999px;
  border:1px solid var(--ctn-line);background:#fff;color:var(--ctn-muted);
  cursor:pointer;transition:background .15s ease,color .15s ease}
.ctn-search__close:hover{background:var(--ctn-tint);color:var(--ctn-ink)}
.ctn-search__close:focus-visible{outline:3px solid var(--ctn-red);outline-offset:2px}

/* A hairline that runs while a request is in flight. Deliberately quiet: at
   this corpus size most searches return before it is ever noticed. */
.ctn-search__form::after{
  content:"";position:absolute;left:0;right:0;top:0;height:2px;
  background:linear-gradient(90deg,transparent,var(--ctn-red),transparent);
  opacity:0;transition:opacity .2s ease}
.ctn-search__panel.is-loading .ctn-search__form::after{opacity:1;animation:ctn-search-sweep 1.1s linear infinite}
.ctn-search__form{position:relative}
@keyframes ctn-search-sweep{from{transform:translateX(-100%)}to{transform:translateX(100%)}}
@media(prefers-reduced-motion:reduce){
  .ctn-search__panel.is-loading .ctn-search__form::after{animation:none}
}

/* ---- results ------------------------------------------------------------ */
.ctn-search__body{max-height:min(56vh, 460px);overflow-y:auto;overscroll-behavior:contain}
.ctn-search__results{list-style:none;margin:0;padding:6px}
.ctn-search__result{margin:0}
.ctn-search__link{
  display:block;padding:12px 14px;border-radius:12px;
  text-decoration:none;color:inherit}
.ctn-search__result.is-active .ctn-search__link{background:var(--ctn-petrol-wash)}
.ctn-search__result-head{
  display:flex;align-items:baseline;gap:10px;justify-content:space-between}
.ctn-search__result-title{
  font-family:var(--pl-font-heading);font-weight:700;
  font-size:17.5px;line-height:1.3;color:var(--ctn-ink);min-width:0}
.ctn-search__result-type{
  flex:0 0 auto;font-family:var(--pl-font-heading);font-size:11px;font-weight:700;
  letter-spacing:.07em;text-transform:uppercase;
  color:var(--ctn-petrol);background:var(--ctn-petrol-wash);
  border-radius:999px;padding:3px 9px}
.ctn-search__result-excerpt{
  display:block;margin-top:3px;
  font-size:15.5px;line-height:1.5;color:var(--ctn-muted)}
/* SearchWP-style term highlighting, on both the title and the snippet. */
.ctn-search__link mark{
  background:var(--ctn-red-wash);color:var(--ctn-red-deep);
  border-radius:3px;padding:0 2px;font-weight:inherit}

.ctn-search__message{
  margin:0;padding:22px 20px 26px;text-align:center;
  color:var(--ctn-muted);font-size:16px}
.ctn-search__message[hidden]{display:none}

/* ---- footer ------------------------------------------------------------- */
.ctn-search__footer{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:10px 16px;border-top:1px solid var(--ctn-line-soft);
  background:var(--ctn-band-warm)}
.ctn-search__hint{color:var(--ctn-muted);font-size:13px}
.ctn-search__hint-sep{opacity:.5;margin:0 4px}
.ctn-search__hint kbd{
  font-family:var(--pl-font-body);font-size:11.5px;
  border:1px solid var(--ctn-line);border-bottom-width:2px;border-radius:5px;
  background:#fff;padding:1px 6px;margin-right:2px;color:var(--ctn-ink)}
.ctn-search__all{
  flex:0 0 auto;font-size:14px;font-weight:700;color:var(--ctn-red);
  text-decoration:none;white-space:nowrap}
.ctn-search__all:hover{text-decoration:underline;color:var(--ctn-red-deep)}
.ctn-search__all[hidden]{display:none}

/* ---- phones -------------------------------------------------------------
   The keyboard eats most of a phone screen, so the palette goes to the top
   and the hint row — which needs a keyboard to act on — goes away. */
@media(max-width:700px){
  .ctn-search{padding:0}
  .ctn-search .ctn-search__panel{
    width:100%;min-height:100dvh;border:0;border-radius:0;box-shadow:none}
  .ctn-search__body{max-height:none;flex:1 1 auto}
  .ctn-search__input{font-size:18px}
  .ctn-search__hint{display:none}
  .ctn-search__footer{justify-content:flex-end}
}

/* ============================================================
   Client content, 31 August 2026
   Holiday schedule, board meetings, document downloads, and the
   long-form compliance pages. Tables reuse .ctn-table above.
   ============================================================ */

/* ---- Holiday schedule -------------------------------------------------- */
.ctn-holidays{max-width:none;margin-bottom:20px}
.ctn-holidays:last-of-type{margin-bottom:0}
.ctn-holidays td:first-child{white-space:nowrap;font-variant-numeric:tabular-nums}
.ctn-holidays td:last-child{width:1%;white-space:nowrap}
/* The pill is align-self:flex-start from .ctn-tag, which does nothing in a
   table cell — it needs to be inline-block to keep its own padding. */
.ctn-holidays .ctn-tag{display:inline-block}

/* Anna's two definitions. They carry the whole distinction between the two
   service levels, so they sit directly under the table, never on another
   page — this is the text an answer engine will quote. */
.ctn-holiday-key{margin:22px 0 0;max-width:64ch;
  display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:10px 16px;align-items:baseline}
.ctn-holiday-key dt{margin:0}
.ctn-holiday-key dd{margin:0;color:var(--ctn-ink)}
@media(max-width:600px){
  .ctn-holiday-key{grid-template-columns:minmax(0,1fr);gap:4px 0}
  .ctn-holiday-key dd{margin-bottom:14px}
}

/* The generated Q&A is an appendix, not a section competing with the tables:
   it exists mostly so answer engines have a question-shaped answer to lift.
   Quiet it down and run it two-up so it stops eating a screen of height.

   Not display:none, deliberately. Google requires FAQPage structured data to
   correspond to content a visitor can actually see, so hiding it outright
   would make the markup ineligible. Small and secondary is the compliant
   version of "out of the way". */
[data-pl-section-label="Common questions"] h2{
  font-family:var(--pl-font-heading);font-size:13px;font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;color:var(--ctn-muted);
  margin:0 0 14px}
.ctn-holiday-faq{display:grid;gap:16px;margin-top:0}
.ctn-holiday-faq__item h3{font-size:15.5px;margin:0 0 2px;line-height:1.4;
  font-weight:700}
.ctn-holiday-faq__item p{margin:0;color:var(--ctn-muted);font-size:15px;
  line-height:1.55}

/* The "not sure?" line closes the dates band rather than standing as its own
   section, so it needs a little air above it and a measure of its own. */
.ctn-holiday-callout{margin-top:26px;max-width:70ch}

/* ---- Board meeting schedule -------------------------------------------- */
.ctn-meetings{max-width:640px}
.ctn-meetings td:nth-child(2),
.ctn-meetings td:last-child{white-space:nowrap;font-variant-numeric:tabular-nums}
/* A board schedule is a record of when the board met, not only of when it
   will, so past meetings stay in the table — dimmed, not deleted. */
.ctn-meetings__past td{color:var(--ctn-muted)}

/* ---- Document downloads ------------------------------------------------
   Every link states type, size and that it opens in a new tab, in the link
   text itself: WCAG 3.2.5 wants the behaviour announced, not sprung. The
   full text of each procedure also lives on its own page, so a PDF is never
   the only route to the content. */
.ctn-doclist{list-style:none;margin:0;padding:0;display:grid;gap:12px;
  max-width:680px}
.ctn-doclist li{margin:0}
.ctn-doclink{display:flex;gap:14px;align-items:flex-start;
  background:#fff;border:1px solid var(--ctn-line);
  border-radius:var(--pl-radius,12px);padding:16px 20px;
  box-shadow:var(--ctn-shadow);text-decoration:none;color:var(--ctn-ink)}
.ctn-doclink:hover{border-color:var(--ctn-red);color:var(--ctn-red)}
.ctn-doclink:focus-visible{outline:3px solid var(--ctn-red);outline-offset:2px}
.ctn-doclink__icon{flex:0 0 auto;color:var(--ctn-red);line-height:1;margin-top:2px}
.ctn-doclink__label{font-weight:700;display:block;line-height:1.35}
.ctn-doclink__meta{display:block;color:var(--ctn-muted);font-size:15.5px;
  font-weight:400;margin-top:2px}

/* ---- Long-form compliance pages ----------------------------------------
   ADA, Title VI, Reasonable Modification. Measure comes from the section's
   own widthPreset:"narrow" (--pl-width-prose, 68ch), so nothing here sets a
   width. This is rhythm and the address blocks only. */
.ctn-doc h2{margin-top:2.2em}
.ctn-doc h2:first-child{margin-top:0}
.ctn-doc h3{margin-top:1.8em;font-size:20px}
.ctn-doc p + p{margin-top:1em}
.ctn-doc address,.ctn-addr{font-style:normal;background:#fff;
  border:1px solid var(--ctn-line);border-left:5px solid var(--ctn-red);
  border-radius:0 12px 12px 0;padding:18px 24px;
  box-shadow:var(--ctn-shadow);margin:20px 0;line-height:1.6}
.ctn-doc address strong,.ctn-addr strong{display:block}
/* Where a filing address has to be a paragraph rather than <address> — the
   governed block set has no address block — the class carries the treatment. */
.ctn-addr{max-width:52ch}

/* In-page contents for the longest documents. */
.ctn-toc{background:var(--ctn-tint);border-radius:var(--pl-radius,12px);
  padding:20px 24px;margin:0 0 32px}
.ctn-toc h2{font-size:15px;text-transform:uppercase;letter-spacing:.08em;
  margin:0 0 10px;color:var(--ctn-muted)}
.ctn-toc ol{margin:0;padding-left:1.2em;display:grid;gap:6px}

/* ---- Staff and board cards ---------------------------------------------
   Anna's board roster is 13 people, 9 of them a name and nothing else. A
   staff-card with no title, email or photo would otherwise render as a card
   that looks broken rather than one that is simply brief: collapse it to a
   name plate at the same rhythm as the others. */
[data-pl-section-label="Board members"] .pl-staff-card,
[data-pl-section-label="Our staff"] .pl-staff-card{min-height:0}
[data-pl-section-label="Board members"] .pl-staff-card__name{margin-bottom:0}
[data-pl-section-label="Board members"] .pl-staff-card__title:empty,
[data-pl-section-label="Our staff"] .pl-staff-card__title:empty{display:none}

/* ---- Data tables on a phone -------------------------------------------
   A three-column table at 375px pushes its last column off the right edge.
   For the fare table that is merely awkward; for the holiday schedule it
   hides the "NO SERVICE / LIMITED SERVICE" column, which is the entire
   reason a rider opened the page. So these two stack: each row becomes a
   card and each cell carries its own header from data-label.

   The fare table is deliberately NOT included — two columns fit at 375px,
   and distance/price reads better side by side. */
@media(max-width:600px){
  .ctn-holidays,.ctn-meetings{overflow-x:visible;border:0;box-shadow:none;
    background:transparent;border-radius:0}
  .ctn-holidays caption,.ctn-meetings caption{padding:0 0 12px}
  .ctn-holidays thead,.ctn-meetings thead{
    position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
    clip-path:inset(50%);white-space:nowrap}
  .ctn-holidays tr,.ctn-meetings tr{
    display:block;background:#fff;border:1px solid var(--ctn-line);
    border-radius:var(--pl-radius,12px);box-shadow:var(--ctn-shadow);
    padding:6px 4px;margin-bottom:12px}
  .ctn-holidays td,.ctn-meetings td{
    display:flex;gap:16px;justify-content:space-between;align-items:baseline;
    border-top:0;padding:7px 14px;white-space:normal}
  .ctn-holidays td::before,.ctn-meetings td::before{
    content:attr(data-label);flex:0 0 auto;
    font-family:var(--pl-font-heading);font-size:13px;font-weight:700;
    letter-spacing:.06em;text-transform:uppercase;color:var(--ctn-muted)}
  .ctn-holidays td:last-child,.ctn-meetings td:last-child{width:auto}
  .ctn-meetings__past td{color:var(--ctn-muted)}
}

/* ==== Book a Ride: density pass ========================================
   The page ran 3,325px at 1440 and said "Trip Portal" five times before a
   rider reached the booking cards. Nothing here changes what the page says
   beyond the card copy noted in the deploy kit; this is spacing, type scale
   and two structural merges.

   1. The icon plate is a home-page treatment. In a 2-up grid on this page it
      took 216px of a 558px card and squeezed the copy into a 342px column,
      so every description broke into seven ragged lines. Here the mark sits
      inline at the top of the body and the copy gets the whole card.
   2. "Book online" and "After you book" are heading-only bands introducing
      the band underneath. Two sets of section padding between a heading and
      its own content read as two separate topics; they close up into one.
   3. Six numbered steps in one column is 558px of scrolling for six short
      lines. Two columns of three at desktop.                              */
.page-book-a-ride [data-pl-section-label="Booking choices"] .pl-card{
  grid-template-columns:auto minmax(0,1fr);align-items:start}
.page-book-a-ride [data-pl-section-label="Booking choices"] .pl-card__icon{
  align-self:flex-start;height:auto;background:transparent;
  padding:26px 0 0 26px}
.page-book-a-ride [data-pl-section-label="Booking choices"] .pl-card__icon-svg{
  width:46px;height:46px}
.page-book-a-ride [data-pl-section-label="Booking choices"] .pl-card__body{
  padding:24px 28px 26px 18px}
.page-book-a-ride [data-pl-section-label="Booking choices"] .pl-card__title{
  font-size:var(--pl-text-lg);margin-bottom:6px}
/* p.pl-card__description + .pl-card: the parent's unlayered icon-grid rule
   (.wp-block-plumbline-card-grid.pl-card-grid--media-icon … p.pl-card__description,
   margin-bottom:0) outranks a plain class selector and left the CTA 2px under
   the copy. */
.page-book-a-ride [data-pl-section-label="Booking choices"] .pl-card p.pl-card__description{
  margin-bottom:14px}
.page-book-a-ride [data-pl-section-label="Booking choices"] .pl-card__cta{
  min-height:46px;padding:11px 22px;margin-top:2px}

/* Heading band + the band it introduces = one unit. */
.page-book-a-ride [data-pl-section-label="Book online"],
.page-book-a-ride [data-pl-section-label="After you book"]{padding-bottom:0}
.page-book-a-ride [data-pl-section-label="Booking choices"],
.page-book-a-ride [data-pl-section-label="Booking steps"]{padding-top:14px}

/* The tinted band under the steps came in at 22px top against 41px bottom,
   so the cards sat high in their own band. Match the two. */
.page-book-a-ride [data-pl-section-label="Cancellations and extra help"]{
  padding-block:2.875rem}

/* The page opener already carries the h1; the rest are signposts. */
.page-book-a-ride h2{font-size:clamp(23px,2.1vw,27px)}
.page-book-a-ride .ctn-phone-xl{font-size:clamp(26px,3vw,34px)}

@media(min-width:1000px){
  .page-book-a-ride [data-pl-section-label="Booking steps"] .pl-icon-list__items{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:48px;row-gap:14px;align-items:start}
}
