/* ==========================================================================
   rsa-school design system v2: the bespoke service and index pages.

   Loaded after tokens.css and school.css, and ONLY by the five pages that
   declare designSheet: "bespoke":

     /edt-driving-lessons
     /automatic-driving-lessons
     /driving-test-lessons
     /areas
     /test-centres

   Because nothing else loads this sheet, a rule here is already scoped to
   that family: it can safely re-tune a shared sm- class without reaching
   another family's pages. school.css, tokens.css and base.njk are not
   touched by this work.

   Two kinds of rule live here and they are kept apart on purpose:

     1. Family tuning of classes school.css already owns (section 1). Each
        one says why the shared value does not fit a service page.
     2. Modules these five pages need and the town pages do not (sections 3
        onward), under bk- names. Where a name is a JavaScript contract it
        keeps its original name and is marked CONTRACT.

   Reuse before invention: the hero, eyebrow, cards, split, stops, tickets,
   reviews, FAQ, sign, plate, band, places and figures all come from
   school.css unchanged.
   ========================================================================== */

/* ==========================================================================
   1. Family tuning of shared classes
   ========================================================================== */

/* A town h1 is two stacked words ("Driving Lessons in" / "Swords") and 15ch
   holds it. A service page h1 is a sentence of six to eight words, and at
   15ch every one of them wrapped to its own line. */
.sm-hero h1 { max-width: 22ch; }

/* The pack's own price figure is clamp(44px, 4.6vw, 64px) at weight 900.
   school.css sets a ticket price at --fs-num-xs (40px) because a town page
   carries five narrow tickets beside a separate headline figure. These pages
   have no headline figure: the ticket price IS the page's display numeral, so
   it is set at the size the pack asks for. */
.sm-ticket__price {
  font-size: clamp(44px, 4.8vw, 68px);
  font-weight: var(--fw-plate);
}

/* The amount a ticket saves, under the price. Not a second price, so it is
   not set at price size. */
.bk-ticket__save {
  display: block;
  margin-top: var(--space-4);
  font-size: var(--fs-small);
  font-weight: var(--fw-bold);
  color: var(--rsa-sign-green);
}
.sm-ticket--best .bk-ticket__save { color: var(--rsa-road-black); }

/* Column counts picked from the item count, not from the width.
   Finding 17: auto-fit chooses columns from the available width and strands a
   short last row, and nothing else in the harness notices. Every item count
   these five pages actually render is pinned here, to a column count where
   the last row is short by at most one.
     3 -> 3   4 -> 4   5 -> 3 (3+2)   6 -> 3 (3+3)   8 -> 4 (4+4)
     9 -> 3   25 -> 5
   Counts of one and two are left alone: a two-item row is not a grid. */
@media (min-width: 769px) {
  .sm-places:has(> :nth-child(3):last-child),
  .sm-places:has(> :nth-child(5):last-child),
  .sm-places:has(> :nth-child(6):last-child),
  .sm-cards:has(> :nth-child(9):last-child) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .sm-places:has(> :nth-child(4):last-child),
  .sm-places:has(> :nth-child(8):last-child) {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  .sm-cards:has(> :nth-child(25):last-child) {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

/* A road-stop list of nine fault categories or twelve lessons is the section,
   so it gets a reading measure rather than the full container width. */
.sm-stops { max-width: 68ch; }

/* The lead paragraph under a section heading. Rule 20: a section intro has a
   margin-top so it does not sit flush against the heading above it. */
.sm-section .sm-lede { margin-top: var(--space-12); }

/* ==========================================================================
   2. Hero additions
   ========================================================================== */

/* The breadcrumb's last crumb. Wrapped in its own span rather than left as a
   bare text node: trailing text merges into whatever follows and the parity
   gate then reads the crumb and the next eyebrow as one phrase. */
.sm-crumb__sep { margin: 0 var(--space-3); color: var(--rsa-slate); }
.sm-crumb__current { color: var(--color-text); font-weight: var(--fw-semi); }

/* The hero aside holds the page's own photograph on the green offset block,
   with a learner plate welded to the frame's corner. The plate is the pack's
   physical object at inline size; it carries no text of its own and is hidden
   from assistive tech. */
.bk-hero-aside { position: relative; }
.bk-hero-aside .sm-plate {
  position: absolute;
  right: calc(var(--space-6) * -1);
  top: calc(var(--space-6) * -1);
  z-index: 3;
  width: 56px;
  height: 56px;
  font-size: 30px;
  transform: rotate(-6deg);
}

/* The one-line claim some heroes carry under the buttons. One element, one
   sentence: it is a sentence on the live page and splitting it would split
   the words. */
.bk-herostat {
  display: block;
  margin-top: var(--space-16);
  padding-top: var(--space-10);
  border-top: 1px solid var(--rsa-line-16);
  max-width: 46ch;
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-bold);
  color: var(--color-text);
}

/* A figure set inside a sentence, where the number is the sentence. The pack:
   "Real numbers, big. Prices, lesson counts and rules are the content."
   Inline, so the words keep their order and the sentence stays one phrase. */
.bk-figure {
  font-family: var(--font-display);
  font-size: clamp(44px, 5vw, 68px);
  font-weight: var(--fw-plate);
  line-height: 0.8;
  letter-spacing: var(--ls-tighter);
  color: var(--color-accent);
}

/* The hero search field on /areas. CONTRACT: #area-search is queried by the
   page's own filter script. Field furniture matches the lead form's. */
.bk-search {
  width: 100%;
  max-width: 560px;
  margin-top: var(--space-16);
  padding: var(--space-10) var(--space-12);
  background: var(--color-panel);
  border: 1px solid var(--color-field-border);
  border-radius: var(--radius-xs);
  font-family: var(--font-body);
  font-size: var(--fs-body-lg);
  color: var(--color-text);
}
.bk-search::placeholder { color: var(--color-placeholder); }
.bk-search:focus { border-color: var(--color-accent); outline: none; }

/* The no-results line. Visibility is owned by the filter script, which sets
   style.display, so no rule here may set display. */
.bk-noresults {
  padding: var(--space-24) var(--gutter);
  text-align: center;
  color: var(--color-text-muted);
}
.bk-noresults a { color: var(--color-accent); }

/* ==========================================================================
   3. Card icon
   ========================================================================== */

/* The emoji the live cards carry. They are content, not furniture, so they
   are kept rather than redrawn, and set at object size so a card leads with
   something rather than with a 15px title. */
.bk-card__icon {
  display: block;
  margin-bottom: var(--space-8);
  font-size: 32px;
  line-height: 1;
}

/* ==========================================================================
   4. The syllabus list (EDT) and the fault list (pretest)
   ========================================================================== */

/* Twelve lessons and nine fault categories are both numbered sequences, so
   they take the pack's road-stop list: a dashed vertical line with a punched
   green roundel per stop. The lesson rows then open, as they do on the live
   page, with native details rather than a click handler. */
.bk-stop--open { margin-bottom: var(--space-8); }

.bk-lesson {
  border-top: 1px solid var(--rsa-line-12);
  border-bottom: 1px solid var(--rsa-line-12);
}
.bk-lesson + .bk-lesson { border-top: 0; }

/* The question row. Grid, so the phase tag sits hard against the toggle disc
   rather than floating in the middle of the row. */
.bk-lesson__q {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto 32px;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-10) 0;
  font-family: var(--font-display);
  font-size: var(--fs-h4);
  font-weight: var(--fw-black);
  color: var(--color-text);
  cursor: pointer;
  list-style: none;
}
.bk-lesson__q::-webkit-details-marker { display: none; }
.bk-lesson__q::after {
  content: "+";
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-round);
  background: var(--color-panel-raised);
  color: var(--color-accent);
  font-weight: var(--fw-black);
}
.bk-lesson[open] .bk-lesson__q::after {
  content: "\2212";
  background: var(--color-accent);
  color: var(--color-on-accent);
}

/* The phase tag, sheared on the pack's 6px slant like a lane chip. Amber is
   the caution step, blue is not in the palette, so the three phases are told
   apart by green, chalk and amber, which is the pack's own card trio. */
.bk-phase {
  padding: var(--space-3) var(--space-6) var(--space-2) var(--space-4);
  border-radius: var(--radius-xs);
  clip-path: polygon(0 0, 100% 0, calc(100% - 6px) 100%, 0 100%);
  font-family: var(--font-display);
  font-size: var(--fs-micro);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  white-space: nowrap;
}
.bk-phase--foundation { background: var(--color-accent); color: var(--color-on-accent); }
.bk-phase--intermediate { background: var(--rsa-chalk); color: var(--rsa-road-black); }
.bk-phase--advanced { background: var(--color-star); color: var(--rsa-road-black); }

.bk-lesson__body {
  padding: 0 var(--space-24) var(--space-14) 0;
  font-size: var(--fs-body-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
}

/* The lesson length, welded to the end of the body text. It stays inside the
   same element as the copy, because on the live page it is part of that one
   block of text and separating the two would split the phrase. */
.bk-dur {
  display: inline-block;
  margin-left: var(--space-6);
  padding: var(--space-2) var(--space-5);
  background: var(--color-panel-raised);
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: var(--fs-micro);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--color-text);
}

/* ==========================================================================
   5. The EDT progress tracker
   ========================================================================== */

/* CONTRACT: #edtProgress, .progress-step, data-lesson, #edtProgressMsg and
   the state classes .done and .current are all read or written by the page's
   own script, and the chosen lesson is kept in localStorage under edtLesson.
   None of those names changes. The tiles are the pack's EDT tracker: twelve
   3/4 tiles in one row, the selected one solid green with a ring. */
.bk-tracker {
  margin-top: var(--space-16);
  padding: var(--pad-panel);
  background: var(--color-panel);
  border: 1px solid var(--rsa-line-08);
  border-top: var(--rule-green-top);
  border-radius: var(--radius-xs);
}
.bk-tracker__prompt {
  margin-bottom: var(--space-10);
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-bold);
  color: var(--color-text);
}

.bk-track {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-3);
}

.progress-step {
  aspect-ratio: 3 / 4;
  display: grid;
  place-items: center;
  background: var(--rsa-track);
  border-radius: var(--radius-xs);
  color: var(--color-track-text);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-weight: var(--fw-black);
  cursor: pointer;
  transition: background var(--dur-fast), color var(--dur-fast);
}
.progress-step::after { content: attr(data-lesson); }
.progress-step:hover { background: var(--rsa-graphite); color: var(--color-text); }
.progress-step.done { background: var(--rsa-sign-green); color: var(--rsa-white); }
.progress-step.current {
  background: var(--color-accent);
  color: var(--color-on-accent);
  box-shadow: var(--ring-roundel);
}

/* The legend under the tiles: first, then two to eight in order, then nine to
   twelve in any order. Three cells topped by a solid green rule, a solid
   chalk rule and a dashed chalk rule, which is the pack's own legend. */
.bk-track__labels {
  display: flex;
  justify-content: space-between;
  margin-top: var(--space-6);
  font-size: var(--fs-caption);
  color: var(--color-text-muted);
}

.bk-track__msg {
  min-height: 3.2em;
  margin-top: var(--space-10);
  max-width: 64ch;
  font-size: var(--fs-body-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-accent);
}

.bk-tracker__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-10);
  margin-top: var(--space-12);
}
.bk-tracker__note { font-size: var(--fs-small); color: var(--color-text-muted); }

/* ==========================================================================
   6. The manual and automatic comparison table
   ========================================================================== */

/* Genuinely tabular, so it stays a table. The automatic column is the one the
   page is about, so it carries the green rule and the green figures; the pack
   says the selected choice changes ground, not just text colour. */
.bk-compare { width: 100%; overflow-x: auto; }
.bk-compare table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-body-sm);
}
.bk-compare th,
.bk-compare td {
  padding: var(--space-8) var(--space-10);
  text-align: center;
  border-bottom: 1px solid var(--rsa-line-08);
}
.bk-compare th {
  font-family: var(--font-display);
  font-size: var(--fs-label);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--color-text);
  border-bottom: 2px solid var(--rsa-line-22);
}
.bk-compare th:first-child,
.bk-compare td:first-child {
  text-align: left;
  color: var(--color-text);
  font-weight: var(--fw-bold);
}
.bk-compare td { color: var(--color-text-muted); }
.bk-compare .bk-col--auto {
  background: var(--color-panel-raised);
  border-left: var(--rule-green);
  color: var(--color-accent);
  font-weight: var(--fw-bold);
}
.bk-compare thead .bk-col--auto { color: var(--color-accent); }
.bk-footnote {
  margin-top: var(--space-10);
  font-size: var(--fs-caption);
  color: var(--color-text-faint);
}

/* ==========================================================================
   7. The test centre selector (pretest)
   ========================================================================== */

/* CONTRACT: #centreSelect and #centreInfo are bound by the page's own script,
   which also writes .addr, .centre-faults and .centre-routes into the result
   card. Those three names appear in no template, so nothing styles them
   unless this sheet does. The select itself reuses .lead-form-select from
   school.css rather than inventing a second field style.
   The result card is black, because the pack says an interactive module's
   result card always is. */
.bk-centre {
  margin-top: var(--space-12);
  background: var(--color-bg-deep);
  border: 1px solid var(--rsa-line-12);
  border-top: var(--rule-green-top);
}
.bk-centre h3 { margin-bottom: var(--space-5); }
.bk-centre .addr {
  margin-bottom: var(--space-12);
  font-size: var(--fs-body-sm);
  color: var(--color-text-muted);
}
.bk-centre .centre-faults {
  padding: var(--space-10) 0;
  border-top: 1px solid var(--rsa-line-08);
  border-bottom: 1px solid var(--rsa-line-08);
}
.bk-centre .centre-faults h4 {
  margin-bottom: var(--space-6);
  font-family: var(--font-display);
  font-size: var(--fs-label);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--color-accent);
}
.bk-centre .centre-faults ol {
  margin: 0;
  padding-left: var(--space-10);
  font-size: var(--fs-body-sm);
  color: var(--color-text-body);
}
.bk-centre .centre-faults li { padding: var(--space-2) 0; }
.bk-centre .centre-routes {
  margin: var(--space-10) 0 0;
  font-size: var(--fs-body-sm);
  color: var(--color-text-muted);
}
.bk-centre .centre-routes strong { color: var(--color-text); }

/* ==========================================================================
   8. The test day checklist (pretest)
   ========================================================================== */

/* The pack's paper surface, and the only light ground in the system: a tilted
   chalk card with a red header strip and a tickable box per row. */
.bk-checklist {
  position: relative;
  background: var(--rsa-chalk);
  color: var(--rsa-road-black);
  /* The pack's red header strip, as a rule rather than a padded bar: the live
     page gives the card no title of its own and writing one would be writing
     copy. */
  border-top: 12px solid var(--color-action);
  border-radius: var(--radius-md);
  box-shadow: 0 40px 80px rgba(0, 0, 0, 0.6);
  transform: rotate(-1.5deg);
}
.bk-checklist__list { margin: 0; padding: var(--space-10) var(--space-14) var(--space-14); list-style: none; }
.bk-checklist__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-8);
  padding: var(--space-8) 0;
  border-bottom: 1px solid rgba(11, 11, 12, 0.1);
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-medium);
}
.bk-checklist__item:last-child { border-bottom: 0; }

/* The box is drawn, never a text glyph: a tick written as a character makes
   the item read as "checked" to anything parsing the text. */
.bk-check {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  border: 2px solid var(--rsa-road-black);
  border-radius: var(--radius-sm);
  background: transparent;
}

/* The plate beside the checklist, tilted the other way so the two objects do
   not look like one panel. */
.bk-checklist-aside {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-16);
}
.bk-checklist-aside .sm-plate {
  width: 72px;
  height: 72px;
  font-size: 40px;
  transform: rotate(5deg);
}

/* ==========================================================================
   9. The district accordion (/areas)
   ========================================================================== */

/* CONTRACT: .accordion-item and data-district are read by the page's filter
   script, and .area-link is read for its text. The rows are native details,
   so the 184 area links are reachable with no JavaScript at all, which the
   live page's hidden attribute prevents.
   Note the hidden-attribute trap in findings-to-log: a never-cleared hidden
   is exactly what left another site's panels dead, and details has no such
   state to leave behind. */
.bk-districts {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  margin-top: var(--space-20);
}

.bk-district {
  background: var(--color-panel);
  border: 1px solid var(--rsa-line-08);
  border-left: var(--rule-green);
  border-radius: var(--radius-xs);
}
.bk-district[open] { background: var(--color-panel-raised); }

.bk-district__q {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto 32px;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-10) var(--space-14);
  cursor: pointer;
  list-style: none;
}
.bk-district__q::-webkit-details-marker { display: none; }
.bk-district__q::after {
  content: "+";
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-round);
  background: var(--color-bg-deep);
  color: var(--color-accent);
  font-family: var(--font-display);
  font-weight: var(--fw-black);
}
.bk-district[open] .bk-district__q::after {
  content: "\2212";
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.bk-district__name {
  font-family: var(--font-display);
  font-size: var(--fs-h4);
  font-weight: var(--fw-black);
  letter-spacing: -0.01em;
  color: var(--color-text);
}
.bk-district__count {
  font-size: var(--fs-caption);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-eyebrow-sm);
  text-transform: uppercase;
  color: var(--color-accent);
}

.bk-district__body { padding: 0 var(--space-14) var(--space-14); }

/* CONTRACT: .area-link. Styled as a place link, since every one of them has a
   page of its own. */
.area-link { min-width: 0; }

/* The county cards outside Dublin. A card per county, lead green edge, with
   the test centre link and the town list inside. */
.bk-county__count {
  margin: 0 0 var(--space-6);
  font-family: var(--font-display);
  font-size: var(--fs-caption);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-eyebrow-sm);
  text-transform: uppercase;
  color: var(--color-accent);
}
.bk-county__tc {
  margin: 0 0 var(--space-8);
  padding-bottom: var(--space-8);
  border-bottom: 1px solid var(--rsa-line-08);
  font-size: var(--fs-small);
  color: var(--color-text-muted);
}
.bk-county__tc a { color: var(--color-text); font-weight: var(--fw-semi); }
.bk-county__tc a:hover { color: var(--color-accent); }
.bk-county__list {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-body-sm);
  color: var(--color-text-body);
}
.bk-county__list li {
  padding: var(--space-2) 0 var(--space-2) var(--space-10);
  position: relative;
}
.bk-county__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 5px;
  height: 5px;
  border-radius: var(--radius-round);
  background: var(--color-accent);
}

/* ==========================================================================
   10. The county jump bar (/test-centres)
   ========================================================================== */

/* A chip row rather than a nav list, sheared on the pack's slant. Sticky just
   under the header, which is 84px at desktop and 72px below the tablet break,
   so the bar never slides under it. */
.bk-countynav {
  position: sticky;
  top: 84px;
  z-index: 10;
  padding: var(--space-6) 0;
  background: var(--color-bg-deep);
  border-top: 1px solid var(--rsa-line-08);
  border-bottom: 1px solid var(--rsa-line-16);
}
.bk-countynav__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}
.bk-countynav a {
  padding: var(--space-4) var(--space-8) var(--space-3);
  background: var(--color-panel);
  border: 1px solid var(--rsa-line-12);
  border-radius: var(--radius-xs);
  clip-path: polygon(0 0, 100% 0, calc(100% - 6px) 100%, 0 100%);
  font-family: var(--font-display);
  font-size: var(--fs-micro);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-eyebrow-sm);
  text-transform: uppercase;
  color: var(--color-text-body);
  text-decoration: none;
  transition: background var(--dur-fast), color var(--dur-fast);
}
.bk-countynav a:hover { background: var(--color-accent); color: var(--color-on-accent); }

/* ==========================================================================
   11. Closing notes
   ========================================================================== */

/* The authority line that closes /automatic-driving-lessons. Not a section:
   it carries no heading, so giving it one of its own would mean writing copy
   that is not on the live page. It sits in a bare wrap instead, under the
   page's own hairline. */
.bk-authority {
  max-width: 72ch;
  margin: 0 auto;
  padding: var(--space-20) 0;
  border-top: 1px solid var(--rsa-line-08);
  font-size: var(--fs-small);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
  text-align: center;
}
.bk-authority a { color: var(--color-accent); }

/* A dashed road line used as a plain divider, the pack's grey variant. */
.bk-road {
  height: 4px;
  margin: var(--space-20) 0;
  background: repeating-linear-gradient(90deg, var(--rsa-line-25) 0 22px, transparent 22px 36px);
}

/* ==========================================================================
   13. Smaller pieces
   ========================================================================== */

/* The pretest hero carries a second heading under the h1 on the live page.
   It is a subhead, so it is set below h1 and above the lede rather than at
   full section-heading size. */
.bk-hero__h2 {
  max-width: 24ch;
  font-size: var(--fs-h2-sm);
  margin-bottom: var(--space-12);
}

/* A framed photograph that is not on an offset block, used where another
   photograph in the same section already carries one. */
.bk-aside-photo {
  width: 100%;
  height: auto;
  border: 8px solid var(--rsa-chalk);
  border-radius: var(--radius-xs);
  box-shadow: var(--shadow-card-hover);
}

/* A place link that names the place and says where the link goes, because the
   live card says both. The arrow comes from .sm-place::after. */
.bk-place__name { min-width: 0; }
.bk-place__go {
  margin-left: auto;
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semi);
  color: var(--color-accent);
  white-space: nowrap;
}

/* CONTRACT names that carry no appearance of their own, listed so a rename is
   noticed and so no class on these pages is left with no rule at all.
   .accordion-item: queried by the /areas filter script.
   .county-card and .county-locations: the same script reads both.
   .progress-step is styled in section 5, .area-link in section 9. */
.accordion-item { min-width: 0; }
.county-card { min-width: 0; }
.county-locations { min-width: 0; }

/* ==========================================================================
   14. Narrow viewports
   ========================================================================== */

@media (max-width: 1100px) {
  /* The twelve tracker tiles stop holding a numeral at this width. */
  .bk-track { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}

@media (max-width: 768px) {
  .sm-hero h1 { max-width: none; }

  .bk-countynav { top: 72px; }

  .bk-compare { overflow-x: auto; }
  .bk-compare table { min-width: 460px; }

  /* A tilted paper card clips its own corner against a 20px gutter. */
  .bk-checklist { transform: none; }

  .bk-hero-aside .sm-plate {
    width: 44px;
    height: 44px;
    font-size: 24px;
  }

  .bk-lesson__q,
  .bk-district__q { grid-template-columns: minmax(0, 1fr) 32px; }
  /* The phase tag drops to its own line rather than squeezing the title. */
  .bk-phase { grid-column: 1 / -1; justify-self: start; }

  .bk-tracker { padding: var(--space-16); }
}

@media (max-width: 480px) {
  .bk-track { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .bk-track__labels { font-size: var(--fs-micro); }
}

/* ==========================================================================
   15. Review and ticket trim
   ========================================================================== */

/* The meaning line under the hero's headline figure. The pack's green fact
   band sets the figure huge and the words beside it small, and the hero aside
   is the same shape in a card. */
.bk-stat__meaning {
  margin: var(--space-6) 0 0;
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-medium);
  color: var(--color-text-body);
}

/* The pack's PASSED tag. Go Green with dark type, tracked caps, 2px radius. */
.bk-passed {
  margin-left: auto;
  flex: 0 0 auto;
  padding: var(--space-3) var(--space-4) var(--space-2);
  background: var(--color-accent);
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: var(--fs-micro);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-eyebrow-sm);
  color: var(--color-on-accent);
}
/* On the one red featured card the green tag would be a third colour, so it
   inverts to chalk on black instead. */
.sm-review--feature .bk-passed { background: var(--color-bg-deep); color: var(--rsa-white); }

/* The verification link that closes each review. */
.bk-verify {
  margin-top: var(--space-8);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semi);
  color: var(--color-accent);
  text-decoration: none;
}
.bk-verify:hover { text-decoration: underline; }
.sm-review--feature .bk-verify { color: var(--rsa-white); }

/* The best-value chip on the green ticket: black on green, which is the
   pack's own pairing for it. */
.bk-badge {
  align-self: flex-start;
  margin-bottom: var(--space-6);
  padding: var(--space-3) var(--space-5) var(--space-2);
  background: var(--rsa-road-black);
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: var(--fs-micro);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-eyebrow-sm);
  text-transform: uppercase;
  color: var(--rsa-chalk);
}

/* Running copy that follows a row of place links rather than a heading. */
.bk-prose--after-places { margin-top: var(--space-20); }

/* ==========================================================================
   16. Three names the live /areas markup already carried
   ========================================================================== */

/* A district that holds a test centre says so in its own row, and names the
   centres underneath. Both are live copy, so both keep their live class
   names and simply get a rule. */
.tc-badge {
  margin-left: var(--space-5);
  padding: var(--space-2) var(--space-5) 1px;
  background: var(--color-star);
  border-radius: var(--radius-xs);
  clip-path: polygon(0 0, 100% 0, calc(100% - 6px) 100%, 0 100%);
  font-family: var(--font-display);
  font-size: var(--fs-micro);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-eyebrow-sm);
  text-transform: uppercase;
  color: var(--rsa-road-black);
  white-space: nowrap;
}

.tc-note {
  margin: 0 0 var(--space-10);
  padding-bottom: var(--space-8);
  border-bottom: 1px solid var(--rsa-line-08);
  font-size: var(--fs-small);
  font-weight: var(--fw-bold);
  color: var(--color-accent);
}

/* An area with no page of its own. It is a span, not a link, on the live page
   too, so it must not look clickable: no arrow, no hover, and the pill shape
   the system uses for exactly this case. See the Nearby areas note in
   degradation-rules.md. */
.area-link--nopage {
  justify-content: flex-start;
  background: transparent;
  border: 1px dashed var(--rsa-line-16);
  border-radius: 100px;
  color: var(--color-text-muted);
  font-weight: var(--fw-medium);
  cursor: default;
}
.area-link--nopage::after { content: none; }
.area-link--nopage:hover {
  background: transparent;
  border-color: var(--rsa-line-16);
  transform: none;
  box-shadow: none;
}

/* ==========================================================================
   17. Overflow guards
   ========================================================================== */

/* A 1fr grid track is min-content sized by default, so a scrolling table
   inside one widens the track instead of scrolling, and the whole page gains
   a horizontal scrollbar at phone width. Both ends of that need fixing: the
   track has to be allowed to shrink, and the scroller has to be capped. */
.sm-split > * { min-width: 0; }
.bk-compare { max-width: 100%; min-width: 0; }

/* ==========================================================================
   18. The district area lists
   ========================================================================== */

/* A district holds anything from 1 to 22 area links, and a wrapping auto-fit
   grid strands a short last row on most of those counts: finding 17. There is
   no column count that avoids it for 22 (only 2 and 11 divide it), so these
   lists are pinned to two columns, where the final row holds one item or two
   whatever the count and is therefore never short by more than one. Rows, not
   CSS columns: a real grid resolves grid-template-columns to its used value,
   which is what the phone-width collapse check reads.
   The test centre lists on /test-centres stay an auto-fit grid: their counts
   are 3 to 8 and the column pins in section 1 cover every one of them. */
.bk-district__body .sm-places {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (max-width: 768px) {
  .bk-district__body .sm-places { grid-template-columns: 1fr; }
}

/* ==========================================================================
   19. The county index (/test-centres), finding 2
   ========================================================================== */

/* The page ran as 26 consecutive sections of one archetype, 352 to 490px each,
   with two grounds alternating and lane markers 01 to 26. The pack forbids the
   same archetype twice in a row, so 26 in a row is the worst case of it on the
   site, and nothing in the harness could see it: every section was individually
   correct.
   Dublin keeps the full measure. The other 25 counties become a two-up grid
   from 1100px, so the page reads as 13 rows rather than 25 bands, and the
   grounds now cycle three ways in the template, which turns the stripes into a
   chequer. The 2px gaps ARE the hairlines, which is the pack's own construction
   for cells that sit side by side (section 3.11): no cell borders, a Line
   ground behind, and each cell painting its own near-black over it.
   The ids, the order, the lane markers and the jump-bar anchors are untouched,
   so every anchor in the sticky nav still lands on its county. */
@media (min-width: 1100px) {
  .bk-counties {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px;
    background: var(--rsa-line-10);
  }
  /* Every cell paints a ground, including the ones the template leaves plain:
     a transparent cell would let the 2px Line ground flood the whole panel
     instead of showing as a hairline. */
  .bk-counties > .sm-section { background: var(--color-bg); padding: var(--space-24) 0; }
  .bk-counties > .sm-section--surface { background: var(--color-panel); }
  .bk-counties > .sm-section--deep { background: var(--color-bg-deep); }
  /* 25 is odd, and two columns would stand the last county on its own in a
     half-empty row, which reads as a fault rather than a grid (finding 17).
     Wicklow takes the full row deliberately instead, and closes the set. */
  .bk-counties > .sm-section:last-child { grid-column: 1 / -1; }
  /* One centre per line in a half-width cell. The count-based rules in section
     1 above are written with :has(), which contributes its argument's
     specificity, so they land at three classes and a plain two-class selector
     loses to them: Clare's three centres stayed in three columns inside a 719px
     cell and Limerick's four in four, which squeezed a centre name into a 2px
     column 179px tall. Measured, and the viewport gate caught it. The full path
     wins on specificity and says what it is addressing. */
  .bk-counties > .sm-section > .sm-wrap > .sm-places { grid-template-columns: minmax(0, 1fr); }
  /* The page heading keeps the full display step; a county heading inside a
     half-width cell takes the step below it, still well clear of the pack's
     30px floor for an h2. */
  .bk-counties h2 { font-size: clamp(30px, 2.6vw, 40px); }
}

/* ==========================================================================
   20. Lessons across Ireland (/areas), finding 4
   ========================================================================== */

/* /areas ran 2326px of district accordions straight into 2163px of county
   cards: two different modules reading as one list rhythm, which is the fault
   the pack's rule 5 is about. The accordion above cannot change, it is the
   page's search target, so this section changes archetype instead: the 25
   cards stop being 25 bordered cards and become the pack's hairline matrix,
   with the ground breaking cell by cell between Road Black and Raised. That is
   a ground break inside the section as well as a different shape, so the two
   long runs no longer read the same.
   Five columns for 25 cards is exact, so the matrix has no short row. The green
   edge moves from every card to the leading cell of each row: on 25 cards at
   once it stopped being an accent. */
@media (min-width: 1100px) {
  #outside-dublin .sm-cards {
    gap: 2px;
    background: var(--rsa-line-10);
    border: 1px solid var(--rsa-line-10);
  }
  #outside-dublin .county-card {
    background: var(--color-bg);
    border: 0;
    border-radius: 0;
  }
  #outside-dublin .county-card:nth-child(even) { background: var(--color-panel-raised); }
  #outside-dublin .county-card:nth-child(5n + 1) { border-left: var(--rule-green); }
}

/* ==========================================================================
   21. The featured review wall, finding 6
   ========================================================================== */

/* On /automatic-driving-lessons the review wall and the ticket row below it
   were two rows of three and four equal boxes, one after the other: the same
   archetype twice, which the pack's rule 5 forbids and which the grounds
   alternating does not fix.
   The wall already marks its first review as the feature, and the pack's C2
   gives the featured review the tall cell with the others stacked beside it, so
   the composition the copy already describes is the one that gets drawn. The
   row below keeps its four tickets and the two sections no longer rhyme.
   Scoped to a wall of exactly three with the feature first, which is the shape
   this page has: at four or more the feature's second row would strand a cell. */
@media (min-width: 1100px) {
  .sm-reviews:has(> .sm-review--feature:first-child):has(> :nth-child(3):last-child) {
    grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr);
  }
  .sm-reviews:has(> .sm-review--feature:first-child):has(> :nth-child(3):last-child) > .sm-review--feature {
    grid-row: span 2;
  }
}

