/* ==========================================================================
   Balfe's Bikes — reusable store landing page
   Everything is scoped under .gtw-page so it cannot leak into site chrome.
   Brand fonts and colour tokens come from the live citr-misc.css
   (--font-*-family, --cg-color-1..4); the literals below are fallbacks.
   Flat colours only — no gradients anywhere.

   Colour contract: bronze fails 4.5:1 against both white and navy, so it is
   reserved for rules, markers and other non-text accents. Small text uses
   navy or blue on light, white or sand on navy.
   ========================================================================== */

.gtw-page {
  /* Four-colour brand palette */
  --gtw-navy: var(--cg-color-1, #00334c);
  --gtw-blue: var(--cg-color-2, #056991);
  --gtw-sand: var(--cg-color-3, #e2a854);
  --gtw-bronze: var(--cg-color-4, #c17c2a);

  /* Neutrals */
  --gtw-white: #ffffff;
  --gtw-tint: #edf1f3;
  /* The "Today" badge. A slate grey dark enough to carry white text at badge
     size, which a light grey cannot, and to separate from the tint band the
     marked row already sits on. */
  --gtw-today: #55636b;
  --gtw-line: #d6e0e5;
  --gtw-line-invert: rgba(255, 255, 255, 0.24);
  --gtw-body: rgba(0, 51, 76, 0.78);
  --gtw-body-invert: rgba(255, 255, 255, 0.84);

  --gtw-shell: 1240px;
  --gtw-gutter: 20px;
  --gtw-radius: 6px;

  font-family: var(--font-body-family);
  font-weight: var(--font-body-weight);
  color: var(--gtw-navy);
  background: var(--gtw-white);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

@media (min-width: 900px) {
  .gtw-page {
    --gtw-gutter: 40px;
  }
}

.gtw-page *,
.gtw-page *::before,
.gtw-page *::after {
  box-sizing: border-box;
}

.gtw-page img {
  display: block;
  max-width: 100%;
  height: auto;
}

/* citr-misc.css pins every heading to --cg-color-1, which goes invisible on the
   navy sections. Reclaim inheritance so section context drives heading colour. */
.gtw-page h1,
.gtw-page h2,
.gtw-page h3,
.gtw-page h4 {
  color: inherit;
}

.gtw-page a:focus-visible,
.gtw-page iframe:focus-visible {
  outline: 3px solid var(--gtw-sand);
  outline-offset: 3px;
}

/* --------------------------------------------------------------- Layout -- */

.gtw-page .gtw-shell {
  width: 100%;
  max-width: var(--gtw-shell);
  margin-inline: auto;
  padding-inline: var(--gtw-gutter);
}

.gtw-page .gtw-section {
  padding-block: clamp(56px, 8vw, 104px);
  background: var(--gtw-white);
}

/* No scroll-margin on the landing sections: citr-misc already sets
   scroll-padding-top: 100px on the root to clear the site's sticky header, and
   the two add up rather than overriding, which parks the section a header's
   height too low. The section's own padding-block gives the heading its
   breathing room from there. */

/* Eases the same-page jumps from the hero and panel CTAs rather than cutting to
   them. scroll-behavior only has an effect on the scrolling element, which is
   the document — it cannot be set from inside .gtw-page — so :has() keeps it
   off any page without this one in it. Opt-in via no-preference, so a reader
   who asked for less motion gets the instant jump instead of being scrolled
   through the length of the page. */
@media (prefers-reduced-motion: no-preference) {
  html:has(.gtw-page) {
    scroll-behavior: smooth;
  }
}

.gtw-page .gtw-section--tint {
  background: var(--gtw-tint);
}

/* The Visit section opens with the promo, so the usual section top padding
   leaves a large empty tint band between the hero and the advert. The bottom
   stays at the section default so the three panels keep their breathing room. */
.gtw-page .gtw-visit {
  padding-top: clamp(28px, 4vw, 48px);
}

.gtw-page .gtw-section--dark {
  background: var(--gtw-navy);
  color: var(--gtw-white);
}

/* -------------------------------------------------------- Section heads -- */

.gtw-page .gtw-head {
  margin-bottom: clamp(32px, 4vw, 48px);
}

/* The rule replaces the eyebrow: rhythm without labelling the heading. */
.gtw-page .gtw-head::before {
  content: "";
  display: block;
  width: 56px;
  height: 3px;
  margin-bottom: 22px;
  background: var(--gtw-bronze);
}

.gtw-page .gtw-section--dark .gtw-head::before {
  background: var(--gtw-sand);
}

.gtw-page .gtw-head__title {
  margin: 0;
  font-size: clamp(1.375rem, 2.7vw, 2rem);
  line-height: 1.08;
  letter-spacing: -0.025em;
  text-transform: uppercase;
  text-wrap: balance;
}

.gtw-page .gtw-head__lead {
  margin: 16px 0 0;
  max-width: 68ch;
  font-size: 1.0625rem;
  color: var(--gtw-body);
}

.gtw-page .gtw-section--dark .gtw-head__lead {
  color: var(--gtw-body-invert);
}

/* -------------------------------------------------------------- Buttons -- */

.gtw-page .gtw-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 12px 22px;
  font-family: var(--font-heading-family);
  /* Sized so the longest label — "Book a collection service" — stays on one line
     inside a panel button at desktop widths. It is 6px too wide at 15px/0.06em.
     The floor matters because citr-misc drops the root to 12.8px on phones, where
     0.875rem would render an 11.2px label; buttons are full-width there and have
     no reason to shrink with the desktop constraint that set this size. */
  font-size: max(0.875rem, 12px);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  border: 2px solid transparent;
  border-radius: var(--gtw-radius);
  background: var(--gtw-navy);
  color: var(--gtw-white);
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

.gtw-page .gtw-btn--primary:hover,
.gtw-page .gtw-btn--primary:focus-visible {
  background: var(--gtw-blue);
  color: var(--gtw-white);
}

.gtw-page .gtw-btn--outline {
  background: transparent;
  color: var(--gtw-navy);
  border-color: var(--gtw-navy);
}

.gtw-page .gtw-btn--outline:hover,
.gtw-page .gtw-btn--outline:focus-visible {
  background: var(--gtw-navy);
  color: var(--gtw-white);
}

.gtw-page .gtw-btn--dark {
  background: var(--gtw-navy);
  color: var(--gtw-white);
}

.gtw-page .gtw-btn--dark:hover,
.gtw-page .gtw-btn--dark:focus-visible {
  background: var(--gtw-blue);
}

.gtw-page .gtw-btn--block {
  width: 100%;
}

/* On navy the primary action flips to sand. Hover goes to white, not bronze:
   bronze only reaches 3.4:1 behind this size of bold text. */
.gtw-page .gtw-hero .gtw-btn--primary,
.gtw-page .gtw-section--dark .gtw-btn--primary,
.gtw-page .gtw-cta .gtw-btn--primary {
  background: var(--gtw-sand);
  color: var(--gtw-navy);
}

.gtw-page .gtw-hero .gtw-btn--primary:hover,
.gtw-page .gtw-hero .gtw-btn--primary:focus-visible,
.gtw-page .gtw-section--dark .gtw-btn--primary:hover,
.gtw-page .gtw-section--dark .gtw-btn--primary:focus-visible,
.gtw-page .gtw-cta .gtw-btn--primary:hover,
.gtw-page .gtw-cta .gtw-btn--primary:focus-visible {
  background: var(--gtw-white);
  color: var(--gtw-navy);
}

.gtw-page .gtw-btn--ghost {
  background: transparent;
  color: var(--gtw-white);
  border-color: rgba(255, 255, 255, 0.5);
}

.gtw-page .gtw-btn--ghost:hover,
.gtw-page .gtw-btn--ghost:focus-visible {
  background: rgba(255, 255, 255, 0.14);
  border-color: var(--gtw-white);
  color: var(--gtw-white);
}

/* ---------------------------------------------------------------- Links -- */

.gtw-page .gtw-link {
  color: var(--gtw-blue);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 2px solid var(--gtw-sand);
}

.gtw-page .gtw-link:hover,
.gtw-page .gtw-link:focus-visible {
  color: var(--gtw-navy);
  border-bottom-color: var(--gtw-bronze);
}

.gtw-page .gtw-link--arrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* Standalone links sit on a ~20px line box. Grow the hit area with a
   pseudo-element so the target clears 24px without pushing the underline
   away from the text. */
.gtw-page .gtw-link--arrow,
.gtw-page .gtw-contact__body .gtw-link {
  position: relative;
}

.gtw-page .gtw-link--arrow::after,
.gtw-page .gtw-contact__body .gtw-link::after {
  content: "";
  position: absolute;
  inset: -7px 0;
}

.gtw-page .gtw-link__arrow {
  width: 17px;
  height: 17px;
  flex: 0 0 auto;
  transition: transform 0.18s ease;
}

.gtw-page .gtw-link--arrow:hover .gtw-link__arrow,
.gtw-page .gtw-link--arrow:focus-visible .gtw-link__arrow {
  transform: translateX(3px);
}

.gtw-page .gtw-section--dark .gtw-link,
.gtw-page .gtw-link--invert {
  color: var(--gtw-white);
}

.gtw-page .gtw-section--dark .gtw-link:hover,
.gtw-page .gtw-link--invert:hover,
.gtw-page .gtw-link--invert:focus-visible {
  color: var(--gtw-sand);
  border-bottom-color: var(--gtw-sand);
}

/* ----------------------------------------------------------------- Hero -- */

.gtw-page .gtw-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  align-items: center;
  min-height: clamp(440px, 60vh, 620px);
  background: var(--gtw-navy);
  color: var(--gtw-white);
  padding-block: clamp(56px, 7vw, 96px);
}

/* Faded backdrop, filling the hero and centred on its middle. The fade is
   opacity on the image itself over flat navy rather than a scrim, because the
   palette rules out gradients. At 0.22 even a pure white pixel composites to
   6.8:1 behind the white headline, so the fade holds for any photo Google
   returns.

   The slot is data-gtw-photo="0" — whatever Google has as the store's main
   image — so the crop has to suit a photo this file has never seen. Centring
   is the only anchor that behaves for all of them: it keeps the middle of the
   frame, which is where a shopfront's door and window display sit, and trims
   evenly from the edges at every viewport. */
.gtw-page .gtw-hero__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: 50% 50%;
  opacity: 0.22;
}

.gtw-page .gtw-hero__inner {
  width: 100%;
  max-width: var(--gtw-shell);
  margin-inline: auto;
  padding-inline: var(--gtw-gutter);
}

.gtw-page .gtw-hero__content {
  max-width: 46rem;
}

.gtw-page .gtw-hero__title {
  margin: 0 0 20px;
  font-size: clamp(2.25rem, 4.9vw, 3.75rem);
  line-height: 1;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  text-wrap: balance;
}

.gtw-page .gtw-hero__lead {
  margin: 0 0 28px;
  max-width: 66ch;
  font-size: 1.125rem;
  color: var(--gtw-body-invert);
}

.gtw-page .gtw-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}


/* --------------------------------------------------------- Hours strip -- */

.gtw-page .gtw-facts {
  background: var(--gtw-blue);
  color: var(--gtw-white);
}

.gtw-page .gtw-facts__message {
  width: 100%;
  max-width: var(--gtw-shell);
  /* Block margin must be zeroed, not just centred: the default paragraph
     margin escapes the section and opens a white band below the strip. */
  margin: 0 auto;
  padding: 20px var(--gtw-gutter);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  text-align: center;
  font-family: var(--font-heading-family);
  font-size: clamp(0.9375rem, 1.5vw, 1.125rem);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.3;
}

.gtw-page .gtw-facts__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--gtw-sand);
}

.gtw-page .gtw-facts__icon svg {
  width: 26px;
  height: 26px;
}

/* --------------------------------------------------------------- Panels -- */

.gtw-page .gtw-panel {
  --gtw-panel-pad: clamp(24px, 3vw, 34px);
  padding: var(--gtw-panel-pad);
  background: var(--gtw-white);
  border: 1px solid var(--gtw-line);
  border-radius: var(--gtw-radius);
}

/* Bleeds to the panel edge by cancelling the padding, so the image sits flush
   in the top corners instead of floating inside a white margin. */
.gtw-page .gtw-panel__media {
  width: calc(100% + (2 * var(--gtw-panel-pad)));
  max-width: none;
  margin: calc(-1 * var(--gtw-panel-pad)) calc(-1 * var(--gtw-panel-pad)) 26px;
  border-radius: calc(var(--gtw-radius) - 1px) calc(var(--gtw-radius) - 1px) 0 0;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.gtw-page .gtw-panel__map {
  position: relative;
  overflow: hidden;
  background: var(--gtw-tint);
}

.gtw-page .gtw-panel__map iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.gtw-page .gtw-panel--aside {
  background: var(--gtw-tint);
}

.gtw-page .gtw-panel__title {
  margin: 0 0 20px;
  font-size: 1.1875rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--gtw-navy);
}

.gtw-page .gtw-panel__text {
  margin: 0 0 22px;
  color: var(--gtw-body);
}

.gtw-page .gtw-panel__actions {
  margin-top: 26px;
}

/* ---------------------------------------------------------------- Visit -- */

.gtw-page .gtw-visit__grid {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  align-items: stretch;
}

.gtw-page .gtw-contact {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 18px;
}

.gtw-page .gtw-contact__item {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}

.gtw-page .gtw-contact__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  color: var(--gtw-blue);
}

.gtw-page .gtw-contact__icon svg {
  width: 21px;
  height: 21px;
}

.gtw-page .gtw-contact__body {
  display: block;
}

.gtw-page .gtw-contact__label {
  display: block;
  font-family: var(--font-heading-family);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gtw-body);
}

.gtw-page .gtw-contact__value {
  display: block;
  color: var(--gtw-navy);
}

/* Opening hours.
   citr-misc.css ships global zebra striping and cell borders for tables. */
.gtw-page .gtw-hours,
.gtw-page .gtw-hours tbody,
.gtw-page .gtw-hours tr,
.gtw-page .gtw-hours th,
.gtw-page .gtw-hours td {
  background: transparent;
  border: 0;
  box-shadow: none;
}

.gtw-page .gtw-hours {
  /* Outdented by the same amount the cells take back as padding, so the band
     behind today's row extends past the text instead of stopping flush against
     it, while day names stay aligned with the rest of the panel. Separate
     borders because collapsed ones ignore the radius on that band. */
  --gtw-hours-bleed: 10px;
  width: calc(100% + (2 * var(--gtw-hours-bleed)));
  margin-inline: calc(-1 * var(--gtw-hours-bleed));
  border-collapse: separate;
  border-spacing: 0;
}

.gtw-page .gtw-hours th,
.gtw-page .gtw-hours td {
  padding: 9px var(--gtw-hours-bleed);
  border-bottom: 1px solid var(--gtw-line);
  text-align: left;
  vertical-align: middle;
  font-size: 0.9375rem;
  font-weight: 400;
}

.gtw-page .gtw-hours th {
  font-family: var(--font-heading-family);
  font-weight: 700;
  color: var(--gtw-navy);
}

.gtw-page .gtw-hours td {
  text-align: right;
  color: var(--gtw-navy);
  font-variant-numeric: tabular-nums;
}

.gtw-page .gtw-hours tr:last-child th,
.gtw-page .gtw-hours tr:last-child td {
  border-bottom: 0;
}

/* Labels the dated exceptions above the ordinary week. Borrowed wholesale from
   the Contact panel's field labels, so a reader meets one kind of small label
   across the Visit panels rather than two. Its own row rather than a caption:
   it belongs to the rows under it, not to the table.

   No top padding: this is the first row in the table, so it sets the gap under
   the panel title, and the 18px that used to separate it from Sunday's divider
   would now read as the label having drifted away from the heading.

   Never rendered on its own: gtw-places.js emits it with its rows and removes
   it with them, so there is no state where it heads an empty group. */
.gtw-page .gtw-hours__group th {
  padding-top: 0;
  padding-bottom: 2px;
  border-bottom: 0;
  color: var(--gtw-body);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* The seam where the exceptions end and the ordinary week begins. The last
   special row keeps its divider; this adds space beneath it so the two groups
   read as separate rather than as one nine-row list. Keyed off the adjacency
   rather than a class, so it appears and disappears with the group itself.

   The space hangs off the special row rather than the weekday row below it
   because that row can be today, and padding there would leave the tinted
   "Today" band taller than every other row in the table. */
.gtw-page .gtw-hours tr[data-gtw-special]:has(+ tr[data-gtw-day]) th,
.gtw-page .gtw-hours tr[data-gtw-special]:has(+ tr[data-gtw-day]) td {
  padding-bottom: 20px;
}

/* Today. The row is marked with aria-current="date" rather than a class, so the
   state is announced as well as drawn — and because only one row can hold it,
   there is nothing to keep in sync. Set at runtime, since a build cannot know
   which day the page is read on; unmarked is a perfectly good resting state. */
.gtw-page .gtw-hours tr[aria-current='date'] th,
.gtw-page .gtw-hours tr[aria-current='date'] td {
  background: var(--gtw-tint);
}

.gtw-page .gtw-hours tr[aria-current='date'] th {
  border-radius: var(--gtw-radius) 0 0 var(--gtw-radius);
}

.gtw-page .gtw-hours tr[aria-current='date'] td {
  border-radius: 0 var(--gtw-radius) var(--gtw-radius) 0;
  font-weight: 700;
}

.gtw-page .gtw-hours tr[aria-current='date'] th::after {
  content: 'Today';
  display: inline-block;
  margin-left: 8px;
  padding: 1px 6px;
  border-radius: 3px;
  background: var(--gtw-today);
  color: var(--gtw-white);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.5;
  text-transform: uppercase;
  vertical-align: 1px;
}

.gtw-page .gtw-stack {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 10px;
}

/* --------------------------------------------------------- Stock banner -- */

.gtw-page .gtw-banner {
  background: var(--gtw-sand);
  color: var(--gtw-navy);
  padding-block: 26px;
}

.gtw-page .gtw-banner__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 20px;
}

.gtw-page .gtw-banner__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  color: var(--gtw-navy);
}

.gtw-page .gtw-banner__icon svg {
  width: 30px;
  height: 30px;
}

.gtw-page .gtw-banner__text {
  flex: 1 1 320px;
  max-width: 68ch;
  margin: 0;
  font-family: var(--font-heading-family);
  font-size: clamp(1rem, 1.6vw, 1.1875rem);
  font-weight: 700;
  line-height: 1.35;
}

/* ------------------------------------------------------------- Services -- */

.gtw-page .gtw-services__grid {
  display: grid;
  gap: clamp(28px, 4vw, 48px);
}

@media (min-width: 900px) {
  .gtw-page .gtw-services__grid {
    grid-template-columns: 1.7fr 1fr;
    align-items: stretch;
  }
}

.gtw-page .gtw-checks {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0 32px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  /* Equal rows let the list fill the height set by the taller parking panel,
     so the separators stay evenly spaced instead of bunching at the top.
     Collapses to auto in the single-column stack, where height is indefinite. */
  grid-auto-rows: 1fr;
}

.gtw-page .gtw-check {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 15px 0;
  border-top: 1px solid var(--gtw-line);
  font-family: var(--font-heading-family);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.3;
}

.gtw-page .gtw-check__icon {
  flex: 0 0 auto;
  display: inline-flex;
  color: var(--gtw-blue);
}

.gtw-page .gtw-check__icon svg {
  width: 22px;
  height: 22px;
}

.gtw-page .gtw-bullets {
  margin: 0 0 22px;
  padding-left: 20px;
  color: var(--gtw-body);
  list-style: disc outside;
  display: grid;
  gap: 10px;
}

.gtw-page .gtw-bullets li::marker {
  color: var(--gtw-bronze);
}

/* ------------------------------------------------------------- Bike fit -- */

.gtw-page .gtw-bikefit__grid {
  display: grid;
  gap: clamp(32px, 4vw, 56px);
  align-items: center;
}

@media (min-width: 900px) {
  .gtw-page .gtw-bikefit__grid {
    grid-template-columns: 1fr 1fr;
  }
}

.gtw-page .gtw-bikefit__media img {
  width: 100%;
  border-radius: var(--gtw-radius);
  object-fit: cover;
  aspect-ratio: 3 / 2;
}

.gtw-page .gtw-levels {
  margin: 0 0 30px;
  padding: 0;
}

.gtw-page .gtw-level {
  padding: 16px 0;
  border-top: 1px solid var(--gtw-line-invert);
}

.gtw-page .gtw-level__name {
  margin: 0 0 4px;
  font-family: var(--font-heading-family);
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--gtw-sand);
}

.gtw-page .gtw-level__desc {
  margin: 0;
  color: var(--gtw-body-invert);
}

/* ----------------------------------------------------- Brompton test rides -- */

.gtw-page .gtw-test-rides__grid {
  display: grid;
  gap: clamp(24px, 3vw, 36px);
}

@media (min-width: 900px) {
  .gtw-page .gtw-test-rides__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.gtw-page .gtw-test-ride {
  display: grid;
  overflow: hidden;
  border: 1px solid var(--gtw-line-invert);
  border-radius: var(--gtw-radius);
  background: color-mix(in srgb, var(--gtw-navy) 88%, white);
}

.gtw-page .gtw-test-ride__image {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  background: #fff;
}

.gtw-page .gtw-test-ride__content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: clamp(24px, 3vw, 34px);
}

.gtw-page .gtw-test-ride__title {
  margin: 0 0 6px;
  color: #fff;
  font-family: var(--font-heading-family);
  font-size: clamp(1.2rem, 2vw, 1.55rem);
  font-weight: var(--font-heading-weight);
  line-height: 1.15;
  text-transform: uppercase;
}

.gtw-page .gtw-test-ride__meta {
  margin: 0 0 20px;
  color: var(--gtw-sand);
  font-weight: 700;
}

.gtw-page .gtw-test-ride .gtw-bullets {
  flex: 1;
  margin-bottom: 26px;
  color: var(--gtw-body-invert);
}

/* --------------------------------------------------------------- Brands -- */

.gtw-page .gtw-brands__grid {
  margin: 0 0 32px;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

.gtw-page .gtw-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 112px;
  height: 100%;
  padding: 18px;
  background: var(--gtw-white);
  border: 1px solid var(--gtw-line);
  border-radius: var(--gtw-radius);
  transition: border-color 0.18s ease;
}

.gtw-page .gtw-brand:hover,
.gtw-page .gtw-brand:focus-visible {
  border-color: var(--gtw-blue);
}

.gtw-page .gtw-brand img {
  width: 100%;
  max-width: 180px;
  max-height: 72px;
  height: auto;
  object-fit: contain;
}

.gtw-page .gtw-brands__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 28px;
}

/* -------------------------------------------------------------- Gallery -- */

.gtw-page .gtw-gallery__grid {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}

.gtw-page .gtw-gallery__grid img {
  width: 100%;
  border-radius: var(--gtw-radius);
  object-fit: cover;
  aspect-ratio: 3 / 2;
}

/* --------------------------------------------------------- Video and map -- */

.gtw-page .gtw-video__frame,
.gtw-page .gtw-map__frame,
.gtw-page .gtw-book__frame {
  position: relative;
  overflow: hidden;
  border-radius: var(--gtw-radius);
  aspect-ratio: 16 / 9;
}

/* Booking is a multi-step SPA (workshop list + map), not a 16:9 media clip.
   Fixed height rather than aspect-ratio so the form has room to work without
   becoming a postage stamp on desktop or an endless scroll on phones. */
.gtw-page .gtw-book__frame {
  aspect-ratio: auto;
  height: clamp(560px, 78vh, 900px);
  background: var(--gtw-white);
  border: 1px solid var(--gtw-line);
}

.gtw-page .gtw-book__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.gtw-page .gtw-book__fallback {
  margin: 18px 0 0;
}

/* Reserved space is navy so it reads against the tint section while the
   embed loads, and matches the video's own letterboxing once it does. */
.gtw-page .gtw-video__frame {
  background: var(--gtw-navy);
}

.gtw-page .gtw-map__frame {
  background: var(--gtw-tint);
  aspect-ratio: 21 / 9;
}

.gtw-page .gtw-video__frame iframe,
.gtw-page .gtw-map__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.gtw-page .gtw-map__note {
  margin: 22px 0 0;
}

/* ----------------------------------------------------------- Reviews -- */

.gtw-page .gtw-reviews__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(16px, 2vw, 24px);
  margin: clamp(24px, 3vw, 34px) 0 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 1000px) {
  .gtw-page .gtw-reviews__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.gtw-page .gtw-review {
  display: flex;
  flex-direction: column;
  padding: clamp(22px, 2.4vw, 30px);
  background: var(--gtw-white);
  border: 1px solid var(--gtw-line);
  border-radius: var(--gtw-radius);
}

/* citr-misc.css indents and italicises blockquotes; this is a quote card. */
.gtw-page .gtw-review__body {
  flex: 1 1 auto;
  margin: 16px 0 0;
  padding: 0;
  border: 0;
  quotes: none;
  font-style: normal;
}

.gtw-page .gtw-review__body p {
  margin: 0 0 12px;
  color: var(--gtw-body);
}

.gtw-page .gtw-review__body p:last-child {
  margin-bottom: 0;
}

.gtw-page .gtw-review__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 12px;
  margin: 20px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--gtw-line);
}

.gtw-page .gtw-review__author {
  font-family: var(--font-heading-family);
  font-weight: 700;
  font-style: normal;
  color: var(--gtw-navy);
}

.gtw-page .gtw-review__date {
  font-size: 0.875rem;
  color: var(--gtw-body);
}

.gtw-page .gtw-reviews__note {
  margin: clamp(24px, 3vw, 34px) 0 0;
}

/* Google Places rating, written in by scripts/fetch-place.mjs */
.gtw-page .gtw-rating {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 16px;
  margin: 24px 0 0;
}

.gtw-page .gtw-rating__score {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-heading-family);
  font-size: 1.25rem;
  font-weight: 800;
  color: var(--gtw-navy);
}

/* Two stacked rows: empty underneath, filled on top clipped to the score. */
.gtw-page .gtw-rating__stars {
  position: relative;
  display: inline-flex;
  /* The fill overlay is absolute, so its percentage width resolves against this
     element. As a column flex item it would otherwise stretch to the full card
     and every rating would render as five stars, so pin it to the star row. */
  width: max-content;
}

.gtw-page .gtw-rating__stars-empty,
.gtw-page .gtw-rating__stars-fill {
  display: inline-flex;
  gap: 2px;
}

.gtw-page .gtw-rating__stars-empty {
  color: var(--gtw-line);
}

.gtw-page .gtw-rating__stars-fill {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: var(--gtw-rating-fill, 100%);
  overflow: hidden;
  /* Bronze, not sand: a meaningful graphic needs 3:1 and sand is 1.9:1 on white. */
  color: var(--gtw-bronze);
}

.gtw-page .gtw-rating__star {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
}

@media (max-width: 640px) {
  .gtw-page .gtw-map__frame {
    aspect-ratio: 4 / 3;
  }
}

/* ----------------------------------------------------------- Closing CTA -- */

.gtw-page .gtw-cta {
  background: var(--gtw-navy);
  color: var(--gtw-white);
  padding-block: clamp(56px, 8vw, 104px);
}

.gtw-page .gtw-cta__title {
  margin: 0 0 16px;
  max-width: 20ch;
  font-size: clamp(1.625rem, 3.5vw, 2.625rem);
  line-height: 1.06;
  letter-spacing: -0.025em;
  text-transform: uppercase;
  text-wrap: balance;
}

.gtw-page .gtw-cta__lead {
  margin: 0 0 30px;
  max-width: 62ch;
  color: var(--gtw-body-invert);
}

.gtw-page .gtw-cta__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

@media (prefers-reduced-motion: reduce) {
  .gtw-page * {
    transition-duration: 0.01ms !important;
  }
}
