/* Teddy Auto Services
   Transcribed from the Claude Design export "Teddy Auto Services.dc.html".
   Every value here is taken verbatim from that file's inline styles. The design
   tool's runtime constructs are translated as follows, with no change to output:
     style-hover="..."          -> a :hover rule
     <sc-if value="{{ wide }}">  -> @media (min-width: 1180px)
     {{ tileCols }}              -> @media (min-width: 760px) on .tiles
   Those two breakpoints match the export's `narrow` (<1180) and `mobile` (<760). */

/* ---------------------------------------------------------------- base ---- */

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: #FFFFFF;
  color: #14161A;
  font-family: 'Barlow', system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;
  font-size: 17px;
  line-height: 1.62;
  text-wrap: pretty;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
h1, h2, h3, h4 { margin: 0; font-family: 'Oswald', 'Barlow', Arial, sans-serif; font-weight: 600; line-height: 1.1; }
p { margin: 0; }
a { color: #C8202F; text-decoration: none; transition: color .2s ease; }
a:hover { color: #14161A; }
img { max-width: 100%; display: block; }
iframe { border: 0; display: block; }
input, textarea { font-family: inherit; font-size: 16px; }
summary { cursor: pointer; list-style: none; }
summary::-webkit-details-marker { display: none; }
details[open] summary [data-plus] { transform: rotate(45deg); }

@keyframes tas-rise { from { opacity: 0; transform: translate3d(0, 26px, 0); } to { opacity: 1; transform: none; } }
@keyframes tas-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes tas-dot { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .4; transform: scale(.7); } }

#top { background: #FFFFFF; }

/* ------------------------------------------------------------ scaffold ---- */

.wrap { max-width: 1240px; margin: 0 auto; padding: 0 clamp(16px, 4.5vw, 40px); }
.wrap--narrow { max-width: 960px; }

.section { padding: clamp(36px, 4.5vw, 64px) 0; scroll-margin-top: 120px; }
.section--tint { background: #F7F5F1; }
.section--dark { background: #14161A; color: #E7E3DB; }
.section--ruled { border-top: 1px solid #E4DFD6; }

.eyebrow {
  font-family: 'Oswald', Arial, sans-serif;
  font-size: 12.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #A8801F;
}
.section-title { margin-top: 10px; font-size: clamp(31px, 4vw, 46px); font-weight: 700; text-transform: uppercase; }

.btn {
  font-family: 'Oswald', Arial, sans-serif;
  font-weight: 500;
  text-transform: uppercase;
}

/* -------------------------------------------------------------- header ---- */

/* Exactly the export's. `transform` used to join the transition for the
   hide-on-scroll behaviour; the header condenses instead now (deviation 11) and
   nothing transforms it, so the addition has gone back out. What animates is on
   .topbar, .header__inner and the logo, at the foot of this file. */
.header { position: sticky; top: 0; z-index: 60; background: #FFFFFF; transition: box-shadow .3s ease; }

.topbar { background: #14161A; }
.topbar__inner {
  max-width: 1240px;
  margin: 0 auto;
  padding: 9px clamp(16px, 4.5vw, 40px);
  display: flex;
  flex-wrap: wrap;
  gap: 6px 24px;
  align-items: center;
  justify-content: space-between;
  font-family: 'Oswald', Arial, sans-serif;
  font-size: 13px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #C9C4B9;
}
.topbar__status { display: inline-flex; align-items: center; gap: 9px; }
.status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #46B872;
  animation: tas-dot 2.6s ease-in-out infinite;
}
.topbar__status-text { color: #F2EFE9; }
.topbar__meta { display: inline-flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.topbar__email { color: #D9A521; }
.topbar__email:hover { color: #FFFFFF; }

.header__inner {
  max-width: 1240px;
  margin: 0 auto;
  padding: 7px clamp(16px, 4.5vw, 40px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 18px;
}
.header__logo { flex: 0 0 auto; display: block; }
/* The export drew this at clamp(46px, 6vw, 62px), which put the logo at 93px
   wide against a 147px quote button — smaller than the button next to it, and
   the smallest thing in the header. Sized so its width matches that button at
   the desktop end (98px tall on a 3:2 mark is 147px wide). */
.header__logo img { height: clamp(56px, 7vw, 98px); width: auto; }
/* Shrinkable + wrapping so the quote button drops under the phone number at
   320px instead of being cut off. `flex: 0 0 auto` sized this to max-content, so
   it could never wrap and simply overflowed. Right-aligned content keeps the
   desktop position identical to the space-between layout it replaces. */
.header__actions {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 1 1 auto;
  min-width: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.header__phone {
  font-family: 'Oswald', Arial, sans-serif;
  font-weight: 600;
  font-size: clamp(19px, 2.2vw, 25px);
  color: #14161A;
}
.header__phone:hover { color: #C8202F; }

.btn--header-quote {
  padding: 11px 20px;
  background: #C8202F;
  color: #FFFFFF;
  font-size: 14.5px;
  letter-spacing: .09em;
  white-space: nowrap;
}
.btn--header-quote:hover { background: #14161A; color: #FFFFFF; }

/* ---------------------------------------------------------------- hero ---- */

.hero {
  position: relative;
  aspect-ratio: 1448 / 1086;
  /* Without an explicit width, `min-height` wins on short/narrow viewports and
     aspect-ratio then derives the WIDTH from it — 864px on a 375px phone, which
     pushed the headline and buttons off screen. Pinning the width keeps the
     ratio as a height hint only. Desktop is unaffected: there the ratio already
     produces the taller box. */
  width: 100%;
  min-height: clamp(460px, 72vh, 900px);
  display: grid;
  align-items: end;
  background-color: #0C0D10;
  background-image:
    linear-gradient(180deg, rgba(12,13,16,.42) 0%, rgba(12,13,16,.14) 30%, rgba(12,13,16,.6) 70%, rgba(12,13,16,.93) 100%),
    url('../../uploads/hero.png');
  background-size: auto, cover;
  background-position: center, center center;
  background-repeat: no-repeat, no-repeat;
}
.hero__inner {
  max-width: 1240px;
  width: 100%;
  margin: 0 auto;
  padding: clamp(56px, 8vw, 104px) clamp(16px, 4.5vw, 40px);
}
.hero__copy { max-width: 760px; animation: tas-rise .9s cubic-bezier(.2,.7,.2,1) both; }
.hero__eyebrow {
  display: inline-block;
  padding: 7px 14px;
  border-left: 3px solid #D9A521;
  font-family: 'Oswald', Arial, sans-serif;
  font-size: 12.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #F0D48A;
  background-color: #E6DECA29;
}
.hero__title {
  margin-top: 20px;
  color: #FFFFFF;
  font-size: clamp(27px, 6.6vw, 70px);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1.04;
  overflow-wrap: break-word;
  hyphens: auto;
  text-shadow: 0 2px 30px rgba(0,0,0,.45);
}
/* The first line reads as the promise; the rest completes it. Red is the site's
   accent, and the title's own text-shadow keeps it legible over the photo. */
.hero__accent { color: #C8202F; }
.hero__sub {
  margin-top: 18px;
  font-family: 'Barlow', Arial, sans-serif;
  font-weight: 500;
  font-size: clamp(17px, 1.7vw, 22px);
  line-height: 1.5;
  color: #D8D4CC;
  max-width: 54ch;
}
.hero__cta { margin-top: 30px; display: flex; flex-wrap: wrap; gap: 12px; }
.btn--hero-primary {
  padding: 17px 32px;
  background: #C8202F;
  color: #FFFFFF;
  font-size: 17px;
  letter-spacing: .09em;
}
.btn--hero-primary:hover { background: #FFFFFF; color: #14161A; }
.btn--hero-ghost {
  padding: 17px 30px;
  border: 1px solid rgba(255,255,255,.6);
  color: #FFFFFF;
  font-size: 17px;
  letter-spacing: .09em;
}
.btn--hero-ghost:hover { background: #FFFFFF; color: #14161A; }

/* ------------------------------------------------------------ services ---- */

.services__head-wrap {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 clamp(16px, 4.5vw, 40px);
}
.section-head { text-align: center; max-width: 62ch; margin: 0 auto; }
.services__lede { margin-top: 14px; font-size: 17.5px; color: #545A63; }

.tiles {
  margin-top: clamp(22px, 3vw, 34px);
  display: grid;
  grid-template-columns: 1fr;
  gap: 2px;
  background: #14161A;
}
@media (min-width: 760px) {
  .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.tile {
  position: relative;
  z-index: 1;
  display: block;
  min-height: clamp(300px, 34vw, 460px);
  overflow: hidden;
  background: #14161A;
  color: #FFFFFF;
  transition: transform .35s cubic-bezier(.2,.7,.2,1), box-shadow .35s ease;
  will-change: transform;
}
.tile:hover {
  color: #FFFFFF;
  transform: scale(1.035);
  box-shadow: 0 32px 60px -18px rgba(0,0,0,.65);
  z-index: 3;
}
.tile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .6s cubic-bezier(.2,.7,.2,1);
}
.tile:hover img { transform: scale(1.06); }
.tile__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(12,13,16,.15) 0%, rgba(12,13,16,.55) 55%, rgba(12,13,16,.92) 100%);
}
.tile__body {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 22px 22px 24px;
  display: grid;
  gap: 8px;
  border-bottom: 4px solid #C8202F;
}
.tile__title {
  font-family: 'Oswald', Arial, sans-serif;
  font-weight: 600;
  font-size: clamp(21px, 2.2vw, 26px);
  line-height: 1.1;
  text-transform: uppercase;
  color: #FFFFFF;
}
.tile__text { font-size: 16px; line-height: 1.5; color: #D6D2CA; }
.tile__cta {
  font-family: 'Oswald', Arial, sans-serif;
  font-weight: 500;
  font-size: 13.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #E9B838;
}

/* --------------------------------------------------------------- about ---- */

.about__title {
  text-align: center;
  font-size: clamp(29px, 3.8vw, 44px);
  font-weight: 700;
  text-transform: uppercase;
  max-width: 24ch;
  margin: 0 auto;
}

.about__eyebrow {
  display: block;
  text-align: center;
  font-family: 'Oswald', Arial, sans-serif;
  font-size: 12.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #A8801F;
}

.about__pledges {
  margin-top: clamp(22px, 3vw, 36px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(26px, 4vw, 52px);
}
.pledge h3 { font-size: 26px; text-transform: uppercase; color: #C8202F; }
.pledge p { margin-top: 12px; font-size: 17.5px; color: #454B54; }

.about__split {
  margin-top: clamp(24px, 3vw, 38px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(26px, 4vw, 52px);
  align-items: center;
}
.about__figure { margin: 0; position: relative; }
.about__figure img {
  width: 100%;
  height: clamp(280px, 38vw, 420px);
  object-fit: cover;
  object-position: 50% 45%;
}
.about__heading { margin-top: 10px; font-size: clamp(26px, 3vw, 34px); text-transform: uppercase; }

.bullets { margin-top: 20px; display: grid; gap: 13px; }
.bullet { display: flex; gap: 13px; align-items: flex-start; }
.bullet__mark { margin-top: 8px; width: 9px; height: 9px; flex: 0 0 auto; background: #C8202F; }
.bullet__text { font-size: 16.5px; color: #2E333A; }
.bullet__text strong { font-weight: 600; }

.rate { margin-top: 22px; padding: 18px 20px; background: #FAF6EC; border-left: 3px solid #D9A521; }
.rate[hidden] { display: none; }
.rate__amount { font-family: 'Oswald', Arial, sans-serif; font-weight: 600; font-size: 24px; text-transform: uppercase; }
.rate__note { margin-top: 6px; color: #6B5A2E; font-size: 16.5px; }

/* ----------------------------------------------------------- insurance ---- */

.insurance__title {
  text-align: center;
  color: #FFFFFF;
  font-size: clamp(29px, 3.8vw, 44px);
  font-weight: 700;
  text-transform: uppercase;
  max-width: 24ch;
  margin: 0 auto;
}
.insurance__lede {
  margin: 16px auto 0;
  text-align: center;
  max-width: 62ch;
  font-size: 17.5px;
  color: #B9B5AC;
}
.steps {
  margin-top: clamp(24px, 3vw, 38px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 270px), 1fr));
  gap: 24px;
}
.step { border-top: 3px solid #C8202F; padding-top: 20px; }
.step__num { font-family: 'Oswald', Arial, sans-serif; font-weight: 700; font-size: 38px; line-height: 1; color: #3A3E45; }
.step h3 { margin-top: 10px; font-size: 22px; text-transform: uppercase; color: #FFFFFF; }
.step p { margin-top: 10px; color: #B9B5AC; font-size: 16.5px; }

.equipment {
  margin-top: clamp(22px, 3vw, 34px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: 1px;
  background: #2B2F36;
  border: 1px solid #2B2F36;
}
.equipment__cell { background: #14161A; padding: 22px 20px; }
.equipment__cell h4 { font-size: 19px; text-transform: uppercase; color: #FFFFFF; }
.equipment__cell p { margin-top: 8px; color: #B9B5AC; font-size: 16px; }

/* ------------------------------------------------- estimates + booking ---- */

.estimate {
  scroll-margin-top: 120px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: clamp(24px, 3vw, 48px);
  align-items: start;
}
.estimate__title { font-size: clamp(34px, 4.6vw, 54px); font-weight: 700; text-transform: uppercase; color: #C8202F; }
.estimate__subtitle { margin-top: 4px; font-size: clamp(24px, 3vw, 34px); text-transform: uppercase; }
.estimate__lede { margin-top: 16px; font-size: 17.5px; color: #454B54; max-width: 46ch; }
.estimate__contact { margin-top: 22px; display: grid; gap: 10px; }
.estimate__phone {
  font-family: 'Oswald', Arial, sans-serif;
  font-weight: 600;
  font-size: clamp(28px, 3.4vw, 38px);
  color: #14161A;
}
.estimate__phone:hover { color: #C8202F; }
.estimate__email { font-size: 16.5px; word-break: break-word; }
.estimate__address { font-size: 16.5px; color: #545A63; }

.hours {
  margin-top: 20px;
  border-top: 1px solid #E1DBD1;
  padding-top: 18px;
  display: grid;
  gap: 7px;
  max-width: 380px;
}
.hours__row { display: flex; justify-content: space-between; gap: 14px; }
.hours__label { color: #545A63; }
.hours__value { font-weight: 500; }
.hours__value--closed { color: #9CA1A8; }

.estimate__fallback { margin-top: 18px; font-size: 15.5px; color: #767B83; }

/* #book is on this panel, not on the .estimate grid around it. On desktop the
   two are the same scroll position — the grid puts the copy and the booking
   panel side by side, both starting at the same top — but on a phone they
   stack, and landing on the grid put the whole estimate column between the tap
   and the calendar. Book online now arrives at the calendar. .estimate keeps
   its own scroll-margin (it is the export's) and this one matches it, so the
   sticky header does not cover the panel's dark bar either way. */
.booking { scroll-margin-top: 120px; background: #FFFFFF; border: 1px solid #E4DFD6; box-shadow: 0 26px 60px -34px rgba(20,22,26,.5); }
.booking__bar { display: flex; align-items: center; gap: 10px; padding: 12px 18px; background: #14161A; }
.booking__dot { width: 8px; height: 8px; border-radius: 50%; background: #46B872; }
.booking__label {
  font-family: 'Oswald', Arial, sans-serif;
  font-size: 12.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #EFEBE3;
}
.booking iframe { width: 100%; height: clamp(560px, 74vh, 800px); }

/* --------------------------------------------------------------- visit ---- */

.visit__head { max-width: 60ch; }
.visit__lede { margin-top: 14px; font-size: 17.5px; color: #545A63; }
.visit__grid {
  margin-top: clamp(22px, 3vw, 34px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: 16px;
}
.map-card { border: 1px solid #E4DFD6; background: #FFFFFF; min-height: 340px; }
.map-card iframe { width: 100%; height: 100%; min-height: 340px; }

.visit-card {
  border: 1px solid #E4DFD6;
  background: #FFFFFF;
  padding: 26px 24px;
  display: grid;
  align-content: start;
  gap: 16px;
}
.visit-card__title { font-size: 23px; text-transform: uppercase; }
.visit-card__address { margin-top: 10px; color: #545A63; font-size: 16.5px; }
.visit-card__actions { display: flex; flex-wrap: wrap; gap: 10px; }
/* The border matches the fill, so this looks exactly like the flat red button
   in the design, but the box is already reserved: on hover the button turns
   white on a white card and would otherwise vanish. Padding is 1px shy of the
   design's 13px/22px so the border lands inside the original footprint. */
.btn--directions {
  padding: 12px 21px;
  border: 1px solid #C8202F;
  background: #C8202F;
  color: #FFFFFF;
  font-size: 15px;
  letter-spacing: .09em;
}
.btn--directions:hover { background: #FFFFFF; border-color: #14161A; color: #14161A; }
.btn--outline-dark {
  padding: 13px 22px;
  border: 1px solid #14161A;
  color: #14161A;
  font-size: 15px;
  letter-spacing: .09em;
}
.btn--outline-dark:hover { background: #FFFFFF; color: #14161A; }
.visit-card__areas { border-top: 1px solid #F0EDE7; padding-top: 14px; font-size: 16px; color: #545A63; }
.visit-card__areas strong { font-weight: 600; color: #14161A; }

/* ----------------------------------------------------------------- faq ---- */

.faq__head { text-align: center; }
.faq__title { margin-top: 10px; font-size: clamp(31px, 4vw, 44px); font-weight: 700; text-transform: uppercase; }
.faq__list { margin-top: 26px; display: grid; gap: 10px; }
.faq__list details { background: #F7F5F1; border: 1px solid #E4DFD6; padding: 2px 20px; }
.faq__list summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 17px 0;
  font-family: 'Oswald', Arial, sans-serif;
  font-weight: 500;
  font-size: 20px;
  text-transform: uppercase;
}
.faq__plus { font-size: 21px; color: #C8202F; transition: transform .25s ease; display: inline-block; }
.faq__list details p { padding: 0 0 18px; color: #545A63; font-size: 16.5px; }

/* -------------------------------------------------------------- footer ---- */

.footer { background: #14161A; color: #A5A9B0; padding: clamp(44px, 5vw, 70px) 0 0; }
.footer__grid {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 clamp(16px, 4.5vw, 40px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 215px), 1fr));
  gap: 32px;
}
.footer__logo { height: 178px; width: 268px; max-width: 100%; position: static; }
.footer__heading {
  font-family: 'Oswald', Arial, sans-serif;
  font-size: 12px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #D9A521;
}
.footer__links { margin-top: 12px; display: grid; gap: 7px; font-size: 16px; }
.footer__links a { color: #A5A9B0; }
.footer__links a:hover { color: #FFFFFF; }
.footer__text { margin-top: 12px; font-size: 16px; }
.footer__contact { margin-top: 12px; display: grid; gap: 8px; font-size: 16px; }
.footer__phone { color: #FFFFFF; font-family: 'Oswald', Arial, sans-serif; font-weight: 600; font-size: 26px; }
.footer__phone:hover { color: #E5303F; }
.footer__email { color: #A5A9B0; word-break: break-word; }
.footer__email:hover { color: #FFFFFF; }
.footer__link { color: #A5A9B0; }
.footer__link:hover { color: #FFFFFF; }
.footer__badges { margin-top: 18px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.footer__badge { width: auto; background: #FFFFFF; padding: 5px 7px; }
.footer__badge--caa { height: 62px; }
.footer__badge--amvic { height: 46px; }

.footer__bottom { margin-top: 38px; border-top: 1px solid #292D33; }
.footer__bottom-inner {
  max-width: 1240px;
  margin: 0 auto;
  padding: 16px clamp(16px, 4.5vw, 40px) 22px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  justify-content: space-between;
  font-size: 14.5px;
  color: #7B8087;
}

/* ----------------------------------------------------------- action bar --- */

.actionbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 70;
  background: rgba(20,22,26,.96);
  -webkit-backdrop-filter: blur(10px); /* iOS Safari still wants the prefix */
  backdrop-filter: blur(10px);
  border-top: 2px solid #D9A521;
  transform: translate3d(0, 110%, 0);
  transition: transform .45s cubic-bezier(.2,.7,.2,1);
}
.actionbar__inner {
  max-width: 1240px;
  margin: 0 auto;
  padding: 10px clamp(12px, 4.5vw, 40px) calc(10px + env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  gap: 12px;
  justify-content: space-between;
}
/* The export renders this block only when `wide` (window >= 1180px). */
.actionbar__id { display: none; gap: 2px; }
@media (min-width: 1180px) {
  .actionbar__id { display: grid; }
}
.actionbar__name {
  font-family: 'Oswald', Arial, sans-serif;
  font-weight: 600;
  font-size: 17px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #FFFFFF;
}
.actionbar__status {
  font-family: 'Oswald', Arial, sans-serif;
  font-size: 12.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #D9A521;
}
.actionbar__actions { display: flex; align-items: center; gap: 10px; flex: 1 1 auto; justify-content: flex-end; }
.btn--bar-call {
  flex: 1 1 auto;
  max-width: 260px;
  text-align: center;
  padding: 15px 22px;
  border: 1px solid #6B7078;
  color: #FFFFFF;
  font-size: 16px;
  letter-spacing: .08em;
}
.btn--bar-call:hover { background: #FFFFFF; border-color: #FFFFFF; color: #14161A; }
.btn--bar-book {
  flex: 1 1 auto;
  max-width: 260px;
  text-align: center;
  padding: 15px 22px;
  background: #C8202F;
  color: #FFFFFF;
  font-size: 16px;
  letter-spacing: .08em;
}
.btn--bar-book:hover { background: #FFFFFF; color: #14161A; }

/* Reserves the room the fixed bar covers. The 82px literal was two pixels more
   than the bar actually measures, and those two pixels sat between the end of
   the footer and the top of the bar showing the white body through — a hairline
   gap at the very bottom of every page. Two fixes, because either alone is
   fragile: site.js measures the real bar into --actionbar-h (its height moves
   with the viewport, the safe-area inset and whether the shop name is shown),
   and the spacer is painted the footer's colour so any remaining rounding is
   invisible instead of white. The literal stays as the no-JS fallback. */
.actionbar__spacer { height: var(--actionbar-h, 82px); background: #14161A; }

/* ==========================================================================
   Multi-page build — everything below this line is NEW, not transcribed from
   the export. The export is a single page with no menu, so the navigation,
   the interior page furniture and the large-monitor sizing all live here.
   Nothing above this line was changed except .hero (max-height), which is
   additive — the original declarations stand. .header briefly carried a
   transform transition for the old hide-on-scroll; that has been reverted and
   its rule is the export's again.
   ========================================================================== */

/* ------------------------------------------------------------ seams ------- */

/* Booking sits directly under the hero (deviation 18) and services follows it.
   Both are .section--tint, so the hairline that used to separate them was the
   only thing marking a seam that needs no marking — the pair is one "contact
   us then here's what we do" run. The rule is gone and the two sections close
   up: contact gives up its bottom pad and services keeps one shared pad
   instead of the two full ones that stacked there. .section--ruled itself
   stays — #visit on contact.html still follows a differently-tinted section
   and does need the line. */
.section--joined-below { padding-bottom: clamp(20px, 2.4vw, 32px); }
.section--joined-above { padding-top: clamp(20px, 2.4vw, 32px); }

/* ------------------------------------------------------------- reviews ---- */

/* A wall of the shop's Google reviews at the foot of the contact section, with
   the write-a-review link as its primary action. Both buttons address the
   place by the same id the LocalBusiness JSON-LD carries in `sameAs`, so there
   is one place id on the page and Google resolves the shop rather than a
   name-and-address search. The quotes are verbatim. */
.reviews { margin-top: clamp(36px, 4.5vw, 64px); }
.reviews__head { text-align: center; }
.reviews__title {
  margin-top: 10px;
  font-size: clamp(26px, 3.2vw, 38px);
  font-weight: 700;
  text-transform: uppercase;
}

.reviews__grid {
  margin-top: clamp(20px, 2.6vw, 32px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(16px, 1.8vw, 24px);
}

.review {
  margin: 0;
  display: flex;
  flex-direction: column;
  background: #FFFFFF;
  border: 1px solid #E4DFD6;
  padding: clamp(20px, 2.2vw, 28px);
}

/* The six run to very different lengths — the longest is four times the
   shortest — and grid stretches every card in a row to the tallest, so without
   a cap one review sets a card height its neighbours fill with white. Clamped
   at 9 lines: most are untouched at every width, only the two longest
   truncate, and the full text is one tap away on the Google page both buttons
   below point at. */
.review__text {
  margin: 0;
  font-size: 16.5px;
  line-height: 1.62;
  color: #454B54;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 9;
  line-clamp: 9;
  overflow: hidden;
}
.review__by {
  margin-top: auto;
  padding-top: 16px;
  display: grid;
  gap: 3px;
  justify-items: start;
}
.review__name {
  font-family: 'Oswald', Arial, sans-serif;
  font-weight: 600;
  font-size: 17px;
  text-transform: uppercase;
}
.review__meta { font-size: 14px; color: #767B83; }

.reviews__actions {
  margin-top: clamp(20px, 2.6vw, 30px);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
}

/* Same border-inside-the-footprint trick as .btn--directions (deviation 4), for
   the same reason: these sit on the cream tint, and a fill that swaps on hover
   needs the border to keep the button the same size either way. */
.btn--review-primary {
  padding: 12px 21px;
  border: 1px solid #C8202F;
  background: #C8202F;
  color: #FFFFFF;
  font-size: 15px;
  letter-spacing: .09em;
}
.btn--review-primary:hover { background: #14161A; border-color: #14161A; }
.btn--review-ghost {
  padding: 12px 21px;
  border: 1px solid #14161A;
  color: #14161A;
  font-size: 15px;
  letter-spacing: .09em;
}
.btn--review-ghost:hover { background: #14161A; color: #FFFFFF; }

/* One column below 760px, so six cards put ~2300px between the booking panel
   and the services heading — the opposite of what closing the seam above was
   for. The wall drops to four there and the last two are the two longest, so
   what a phone loses is the pair it was most likely to skip; "read all reviews
   on Google" is directly under them either way. The cut is at the same width
   the grid stops being able to place two cards side by side. */
@media (max-width: 759px) {
  .review:nth-child(n+5) { display: none; }
}

/* Stacked, the two buttons are very different widths and the pair reads as
   ragged rather than as one action block. */
@media (max-width: 560px) {
  .reviews__actions { flex-direction: column; align-items: stretch; }
  .btn--review-primary,
  .btn--review-ghost { text-align: center; }
}

/* ------------------------------------------------------ header, revisited -- */

/* Measured by site.js into --header-h so the hero can subtract it. The literal
   is the value at desktop sizes and is only used before/without JS. */
:root { --header-h: 116px; }

/* The header used to slide out of the way on the way down the page. It now
   condenses instead — see the mini-header block at the foot of this file — so
   nothing here transforms it any more.

   .header--measuring is on for the single frame in which site.js takes the
   header's full height while it happens to be condensed. Suppressing the
   transitions stops that round trip from animating. */
.header--measuring,
.header--measuring .topbar,
.header--measuring .header__inner,
.header--measuring .header__logo img { transition: none !important; }
/* Lifted so site.js measures the strip's own height and not the cap it is
   about to write. Measuring through the cap re-wrote it a pixel smaller each
   time, and the header never came back to full size. */
.header--measuring .topbar { max-height: none !important; }

/* --------------------------------------------------------------- nav ------ */

.nav__toggle {
  order: 2;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-left: auto;
  padding: 10px 12px;
  border: 1px solid #DED8CE;
  background: #FFFFFF;
  color: #14161A;
  font-family: 'Oswald', Arial, sans-serif;
  font-size: 13px;
  letter-spacing: .12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color .2s ease, color .2s ease;
}
.nav__toggle:hover { border-color: #14161A; color: #C8202F; }
.nav__bars { position: relative; display: block; width: 18px; height: 2px; background: currentColor; }
.nav__bars::before, .nav__bars::after {
  content: '';
  position: absolute;
  left: 0;
  width: 18px;
  height: 2px;
  background: currentColor;
  transition: transform .25s ease, opacity .2s ease;
}
.nav__bars::before { top: -6px; }
.nav__bars::after { top: 6px; }
.header--nav-open .nav__bars { background: transparent; }
.header--nav-open .nav__bars::before { transform: translateY(6px) rotate(45deg); }
.header--nav-open .nav__bars::after { transform: translateY(-6px) rotate(-45deg); }

.nav { order: 4; }
.nav__list, .nav__sub { list-style: none; margin: 0; padding: 0; }
.nav__link {
  display: block;
  font-family: 'Oswald', Arial, sans-serif;
  font-weight: 500;
  font-size: 14px;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: #14161A;
}
.nav__link:hover { color: #C8202F; }
.nav__link[aria-current="page"] { color: #C8202F; }
.nav__caret { display: inline-block; margin-left: 6px; font-size: 10px; color: #A8801F; }
.nav__sub-link { font-size: 13.5px; letter-spacing: .08em; text-transform: none; }

/* Phone and small tablet: the list drops out of a panel under the header.
   Two explicit rows — logo and hamburger, then the phone number and the quote
   button beneath them. Without the ordering, the actions land between the logo
   and the hamburger and the hamburger is what wraps, which reads as an
   afterthought hanging under the row. */
@media (max-width: 1099px) {
  .header__logo { order: 1; }
  .nav__toggle { order: 2; }
  /* The phone number and the quote button are hidden on phones and tablets.
     They used to wrap to a second row of their own, which cost about 60px above
     the hero for two actions the fixed bottom bar already carries — Call now and
     Book online are within thumb reach on every page, and the hero repeats both
     on the first screen. The header is logo + Menu here. They come back at
     1100px, where they fit on the one row beside the menu. */
  .header__actions { display: none; }
  .nav {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    z-index: 5;
    display: none;
    max-height: 78vh;
    overflow-y: auto;
    background: #FFFFFF;
    border-top: 1px solid #E4DFD6;
    box-shadow: 0 26px 44px -30px rgba(20,22,26,.65);
  }
  .header--nav-open .nav { display: block; }
  .nav__list { padding: 6px clamp(16px, 4.5vw, 40px) 18px; }
  .nav__item { border-bottom: 1px solid #F0EDE7; }
  .nav__item:last-child { border-bottom: 0; }
  .nav__link { padding: 14px 0; font-size: 16px; }
  .nav__caret { display: none; }
  .nav__sub { padding: 0 0 10px 16px; border-left: 2px solid #EFE7D4; }
  .nav__sub .nav__link { padding: 9px 0; color: #545A63; }
  .nav__sub .nav__link:hover, .nav__sub .nav__link[aria-current="page"] { color: #C8202F; }
}

/* The other half of the rule above. On desktop the header carries the phone
   number, so Call now in the bottom bar was the same action twice on the same
   screen — and a tel: link is worth much less on a machine that cannot dial.
   Below 1100px it is the reverse: the bar is the only place either action
   appears. Book online stays at every width; the header has no booking link. */
@media (min-width: 1100px) {
  .btn--bar-call { display: none; }
}

/* On a phone the top bar wrapped to three lines and the header pushed 270px of
   furniture above the hero. The email address is the least useful of the three
   on a device that can dial, and it is still in the footer of every page. */
@media (max-width: 560px) {
  .topbar__email { display: none; }
}

/* Desktop: inline, with the services list on hover or keyboard focus. */
@media (min-width: 1100px) {
  .nav__toggle { display: none; }
  /* `margin-left: auto` shoved the menu up against the phone number, so it read
     as part of the actions rather than as the site's navigation. Letting it take
     the space between the logo and the actions and centring inside that puts it
     in the middle of the header, with equal air on both sides at every width.
     This is the centring at all widths now — see the note further down for why
     the true-centre override at 1240px was removed rather than kept. */
  .nav { order: 2; flex: 1 1 auto; display: flex; justify-content: center; }
  .nav__list { display: flex; align-items: center; gap: clamp(16px, 1.7vw, 26px); }
  .nav__item { position: relative; }
  .nav__link { padding: 12px 0; border-bottom: 2px solid transparent; }
  .nav__link[aria-current="page"] { border-bottom-color: #C8202F; }
  .nav__sub {
    position: absolute;
    top: 100%;
    left: -18px;
    min-width: 264px;
    padding: 8px 0;
    background: #FFFFFF;
    border: 1px solid #E4DFD6;
    box-shadow: 0 26px 50px -28px rgba(20,22,26,.6);
    opacity: 0;
    visibility: hidden;
    transform: translateY(6px);
    transition: opacity .2s ease, transform .2s ease, visibility .2s;
  }
  .nav__item:hover > .nav__sub, .nav__item:focus-within > .nav__sub {
    opacity: 1;
    visibility: visible;
    transform: none;
  }
  .nav__sub .nav__link { padding: 9px 18px; border-bottom: 0; color: #2E333A; }
  .nav__sub .nav__link:hover,
  .nav__sub .nav__link[aria-current="page"] { color: #C8202F; background: #F7F5F1; }
  .nav__item--has-sub:hover > .nav__link,
  .nav__item--has-sub:focus-within > .nav__link { color: #C8202F; }
  .header__actions { flex: 0 0 auto; order: 3; }
}

/* -------------------------------------------------------- page furniture -- */

.pagehero {
  position: relative;
  background-color: #14161A;
  /* The gradient is the same on every page and only the photo changes, so the
     photo is a custom property. Pages that carry one of the client's service
     photos set --pagehero-img at the end of this file; the rest keep the shop
     front. Writing it this way means the gradient and the WebP ladder are each
     stated once instead of once per page. */
  --pagehero-img: url('../../uploads/hero.png');
  background-image:
    linear-gradient(180deg, rgba(12,13,16,.72) 0%, rgba(12,13,16,.86) 100%),
    var(--pagehero-img);
  background-size: cover;
  background-position: center 38%;
  color: #FFFFFF;
}
.pagehero__inner {
  max-width: 1240px;
  margin: 0 auto;
  padding: clamp(34px, 5vw, 66px) clamp(16px, 4.5vw, 40px) clamp(30px, 4.4vw, 56px);
}
.pagehero__title {
  margin-top: 14px;
  font-size: clamp(30px, 4.6vw, 54px);
  font-weight: 700;
  text-transform: uppercase;
  max-width: 20ch;
}
.pagehero__lede { margin-top: 16px; max-width: 62ch; font-size: clamp(17px, 1.5vw, 19.5px); color: #D3CFC7; }
.pagehero__cta { margin-top: 26px; display: flex; flex-wrap: wrap; gap: 12px; }

.crumbs {
  font-family: 'Oswald', Arial, sans-serif;
  font-size: 12.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #9E9C96;
}
.crumbs a { color: #D9A521; }
.crumbs a:hover { color: #FFFFFF; }
.crumbs__sep { padding: 0 8px; color: #6B7078; }

.lede { margin-top: 14px; max-width: 68ch; font-size: 17.5px; color: #545A63; }
.lede--center { margin-left: auto; margin-right: auto; }
.section--dark .lede { color: #B9B5AC; }

.copy { margin-top: clamp(18px, 2.4vw, 28px); max-width: 72ch; display: grid; gap: 14px; }
.copy h3 { margin-top: 10px; font-size: clamp(21px, 2.2vw, 26px); text-transform: uppercase; }
.copy p { font-size: 17px; color: #454B54; }
.section--dark .copy p { color: #B9B5AC; }
.section--dark .copy h3 { color: #FFFFFF; }

.cards {
  margin-top: clamp(22px, 3vw, 34px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 270px), 1fr));
  gap: 16px;
}
.card { background: #FFFFFF; border: 1px solid #E4DFD6; padding: 24px 22px; display: grid; align-content: start; gap: 10px; }
.card h3 { font-size: 21px; text-transform: uppercase; }
.card p { font-size: 16.5px; color: #545A63; }
.card__cta {
  margin-top: 4px;
  font-family: 'Oswald', Arial, sans-serif;
  font-weight: 500;
  font-size: 13.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #C8202F;
}
a.card { transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease; }
a.card:hover { border-color: #C8202F; box-shadow: 0 24px 44px -30px rgba(20,22,26,.55); transform: translateY(-2px); }
a.card:hover h3 { color: #C8202F; }

.checklist { margin-top: 20px; display: grid; gap: 12px; }
.checklist > div { display: flex; gap: 13px; align-items: flex-start; }
.checklist .bullet__mark { margin-top: 8px; }
.checklist span:last-child { font-size: 16.5px; color: #2E333A; }
.section--dark .checklist span:last-child { color: #C9C4B9; }

.cols2 {
  margin-top: clamp(22px, 3vw, 34px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(24px, 4vw, 48px);
  align-items: start;
}

.cta-band {
  margin-top: clamp(26px, 3.4vw, 42px);
  padding: clamp(24px, 3vw, 36px) clamp(22px, 3vw, 34px);
  background: #14161A;
  color: #E7E3DB;
  display: flex;
  flex-wrap: wrap;
  gap: 18px 26px;
  align-items: center;
  justify-content: space-between;
  border-left: 4px solid #D9A521;
}
.cta-band h3 { font-size: clamp(22px, 2.6vw, 30px); text-transform: uppercase; color: #FFFFFF; }
.cta-band p { margin-top: 8px; font-size: 16.5px; color: #B9B5AC; max-width: 52ch; }
.cta-band__actions { display: flex; flex-wrap: wrap; gap: 10px; }
.btn--band-call {
  padding: 15px 26px;
  border: 1px solid #6B7078;
  color: #FFFFFF;
  font-size: 15.5px;
  letter-spacing: .09em;
}
.btn--band-call:hover { background: #FFFFFF; border-color: #FFFFFF; color: #14161A; }
.btn--band-book {
  padding: 15px 26px;
  background: #C8202F;
  border: 1px solid #C8202F;
  color: #FFFFFF;
  font-size: 15.5px;
  letter-spacing: .09em;
}
.btn--band-book:hover { background: #FFFFFF; border-color: #FFFFFF; color: #14161A; }

.related { margin-top: clamp(26px, 3.4vw, 42px); border-top: 1px solid #E4DFD6; padding-top: 22px; }
.related__heading {
  font-family: 'Oswald', Arial, sans-serif;
  font-size: 12.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #A8801F;
}
.related__links { margin-top: 12px; display: flex; flex-wrap: wrap; gap: 10px 22px; font-size: 16.5px; }

/* --------------------------------------------------------- click zones --- */

/* These links sit in grid containers, so each one stretched the full column
   width: the pointer became a hand well past the end of the text and a click
   on the empty space beside a phone number still dialled it. Shrinking each
   link to its own text puts the hit area where the words are. */
.estimate__contact,
.footer__contact,
.footer__links { justify-items: start; }

.topbar__address { color: #C9C4B9; }
.topbar__address:hover { color: #FFFFFF; }

/* The footer address is a link to the map. inline-block so the two lines make
   one box the width of the longer line -- as an inline run the hit area would
   stretch to the end of the column on the wrapped line, the same trap the
   justify-items rule above fixes for the link grids. */
.footer__address { display: inline-block; color: inherit; }
.footer__address:hover { color: #FFFFFF; }

/* The footer gained a fifth column (Company) and the logo was occupying one of
   the other four. auto-fit could not fit five in the 1240 wrap, so Contact fell
   to a second row on its own with three empty columns beside it; squeezing five
   in instead wrapped the hours line and broke the email mid-word. The logo takes
   the full width above the four text columns now, which leaves each of them the
   266px they had before the Company column existed. 1100px is where four columns
   are wide enough for "Monday to Friday 9:30am to 7pm" on one line; below that,
   auto-fit reflows as it always did. The first child is the logo. */
@media (min-width: 1100px) {
  .footer__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .footer__grid > div:first-child { grid-column: 1 / -1; }
}

/* --------------------------------------------------------- tires + offers --- */

/* The brand strip scrolls one full row and starts over. Both rows carry the
   same brands, so translating the track by half its width lands exactly on the
   seam. Keep the two <div class="marquee__row"> lists identical when editing. */
.marquee {
  margin-top: clamp(22px, 3vw, 32px);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}
.marquee__track { display: flex; width: max-content; animation: tas-marquee 58s linear infinite; }
.marquee:hover .marquee__track, .marquee:focus-within .marquee__track { animation-play-state: paused; }
.marquee__row { display: flex; align-items: center; gap: 10px; padding-right: 10px; }
.marquee__row span {
  padding: 12px 20px;
  background: #FFFFFF;
  border: 1px solid #E4DFD6;
  font-family: 'Oswald', Arial, sans-serif;
  font-weight: 500;
  font-size: 15px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #2E333A;
  white-space: nowrap;
}
.marquee__note { margin-top: 14px; text-align: center; font-size: 15.5px; color: #767B83; }

/* The fifth tile: the same language as the four above it, spanning the whole
   grid so the quadrant and the tire band read as one block. The caption is
   padded back in to the column gutter since the photo runs edge to edge. */
.tile--wide {
  grid-column: 1 / -1;
  min-height: clamp(260px, 30vw, 420px);
  scroll-margin-top: 120px;
}
/* The shop-front photo used to sit here and was cropped to the banner across
   the top of the building, away from the cars parked in front. The client's
   tire-bay photo replaced it and is a centred close-up of a wheel being
   fitted, so it wants the middle of the frame; anchoring high cut the hands
   off. Kept as an explicit rule rather than deleted, because this box is far
   wider than the photo and the crop is the thing worth stating. */
.tile--wide img { object-position: 50% 50%; }
.tile--wide .tile__body { padding: 24px clamp(16px, 4.5vw, 40px) 26px; }
.tile--wide .tile__text { max-width: 62ch; }
@keyframes tas-marquee { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } }
@media (prefers-reduced-motion: reduce) {
  .marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .marquee__track { animation: none; }
  .marquee__row[aria-hidden="true"] { display: none; }
}

.offer {
  margin-top: clamp(26px, 3.4vw, 40px);
  padding: clamp(22px, 3vw, 32px);
  background: #FFFFFF;
  border: 1px solid #E4DFD6;
  border-left: 4px solid #C8202F;
  display: flex;
  flex-wrap: wrap;
  gap: 18px 28px;
  align-items: center;
  justify-content: space-between;
}
.offer__body { max-width: 62ch; }
.offer__kicker {
  display: block;
  font-family: 'Oswald', Arial, sans-serif;
  font-size: 12.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #A8801F;
}
.offer__price {
  margin-top: 8px;
  font-family: 'Oswald', Arial, sans-serif;
  font-weight: 600;
  font-size: clamp(23px, 2.8vw, 32px);
  line-height: 1.1;
  text-transform: uppercase;
}
.offer__note { margin-top: 10px; font-size: 16.5px; color: #545A63; }
.offer__actions { display: flex; flex-wrap: wrap; gap: 10px; }
/* Same reasoning as .btn--directions: this button sits on a white card, and the
   band hover turns it white on white. The border stays dark instead. */
.offer .btn--band-book:hover { border-color: #14161A; }

.figure-band { margin: clamp(22px, 3vw, 34px) 0 0; }
.figure-band img { width: 100%; height: clamp(240px, 32vw, 380px); object-fit: cover; object-position: 50% 45%; }
.figure-band figcaption { margin-top: 10px; font-size: 15.5px; color: #767B83; }

/* ------------------------------------------------------- large monitors --- */

/* The export's hero is a fixed 1448:1086 box. On a 2560px-wide monitor that
   works out to a 1920px-tall hero, so the page loads showing the top of the
   photo and nothing else — the headline and both buttons sit below the fold.
   Capping the height at one viewport minus the header keeps the whole hero on
   screen at any width; the ratio still drives the height below that cap. */
.hero {
  max-height: calc(100vh - var(--header-h));
  max-height: calc(100svh - var(--header-h));
}
/* Landscape phones are shorter than the hero's min-height, and min beats max in
   CSS. Below 560px of viewport height, let the hero simply fit the screen. */
@media (max-height: 560px) {
  .hero { min-height: 0; }
}

/* Full bleed at every width: the photo always fills the hero, never letterboxed
   and never framed. A 4:3 photo in a box near 2:1 has to lose height somewhere,
   so the crop is anchored high rather than centred — centring cut the top off
   the shop sign, which is the thing worth seeing. What goes instead is the
   bottom of the forecourt. A wider source photo is still the real fix: at
   1449px the image is upscaled on anything past about 1600px wide. */
.hero { background-position: center, center 28%; }

/* The wider the viewport, the more height `cover` has to throw away: a 4:3
   photo in a box near 2:1 overflows by roughly half its own height, and a fixed
   percentage then hides progressively more of the top as the screen grows. So
   the anchor steps toward the top as the box gets wider, which keeps about the
   same amount of sky above the sign at every size instead of slowly eating it.
   Phones keep 28% — their hero is close enough to 4:3 that there is little
   overflow to place.

   Judged against the sign: 15% at 1885px is the point where the whole banner
   clears the header with sky above it, and the headline still lands on the
   wall below rather than across the middle of the sign. Going further (10%)
   put the copy over the brightest part of the sign and cost more than the
   extra sky was worth. */
@media (min-width: 1240px) { .hero { background-position: center, center 18%; } }
@media (min-width: 1800px) { .hero { background-position: center, center 15%; } }

/* The headline wrapped in the middle of the width range and nowhere else: it was
   two lines on a laptop, three on a desktop, two again on a large monitor. The
   font grows with the viewport up to a 70px cap it reaches at ~1061px, but the
   column it sits in was fixed at 760px until 1800px, where it stepped to 880.
   "to get you the extra miles" measures 833px at 70px, so anything between the
   point the type outgrows 760px and the point the column catches up had to wrap.
   The column now widens with the type instead of long after it. 960px is where
   880 first fits inside the padding, and the copy is capped by the available
   width below that anyway, so nothing overflows. */
@media (min-width: 960px) { .hero__copy { max-width: 880px; } }

/* Past ~1800px the 1240px column starts to look like a stripe down the middle
   of the screen. Everything steps up together so the proportions hold. */
@media (min-width: 1800px) {
  .wrap,
  .topbar__inner,
  .header__inner,
  .hero__inner,
  .pagehero__inner,
  .services__head-wrap,
  .footer__grid,
  .footer__bottom-inner,
  .actionbar__inner { max-width: 1440px; }
  .wrap--narrow { max-width: 1040px; }
  .hero__copy { max-width: 880px; }
  body { font-size: 18px; }
}
@media (min-width: 2300px) {
  .wrap,
  .topbar__inner,
  .header__inner,
  .hero__inner,
  .pagehero__inner,
  .services__head-wrap,
  .footer__grid,
  .footer__bottom-inner,
  .actionbar__inner { max-width: 1600px; }
  .tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ==========================================================================
   Responsive images and the mini header. Both are additive: every rule below
   overrides a property set earlier without removing the earlier declaration,
   so the export-parity check still sees the originals it expects.
   ========================================================================== */

/* --------------------------------------------------- <picture> wrappers -- */

/* Wrapping an <img> in <picture> puts an inline box between it and its parent.
   .about__figure img is width:100%, which against an inline parent is circular,
   and the inline box adds a baseline gap under the two logos. Blocking the
   wrapper restores exactly the box tree the layout was written against. */
.header__logo picture,
.about__figure picture,
.tile picture,
.footer picture { display: block; }

/* ------------------------------------------------- WebP hero backgrounds -- */

/* The shop-front photo is a 1.9MB PNG and is the mobile LCP element. The <img>
   copies of it are handled by <picture> in the markup; these are the four
   places it is a CSS background, where the same ladder has to come from
   image-set(). Gated on @supports so a browser that cannot pick by type() is
   never handed a WebP it cannot decode -- it keeps the PNG and the page it
   always had. That means Safari 16 and older still pay for the PNG.
   uploads/hero.png is 1448px wide, so 1448 is the top of the ladder. */
@supports (background-image: image-set(url('../../uploads/hero-1448.webp') type('image/webp'))) {

  /* Home hero. Full bleed, but its width is NOT what decides the resolution it
     needs: the box is tall and narrow on a phone (min-height clamp(460px,
     72vh, 900px) against a 4:3 photo), so `cover` scales the photo by HEIGHT
     and the rendered image is much wider than the viewport. At 514x504 that is
     672px of source for a 514px box; at 390x607 it is 809px. image-set only
     sees device pixel ratio, never the box, so the 480 step it used to start
     from was under-resolved at every DPR and the hero looked soft. Starting at
     1024 costs 57KB more on a 1x phone and is the difference between sharp and
     blurry. 1448 is the top of the ladder because the source is 1448 wide --
     a 2x phone wants 1618 and cannot have it. See deviation 8b. */
  .hero {
    background-image:
      linear-gradient(180deg, rgba(12,13,16,.42) 0%, rgba(12,13,16,.14) 30%, rgba(12,13,16,.6) 70%, rgba(12,13,16,.93) 100%),
      image-set(url('../../uploads/hero-1024.webp') type('image/webp') 1x,
                url('../../uploads/hero-1448.webp') type('image/webp') 2x);
  }

  /* Interior page banner, same photo under a heavier gradient. */
  .pagehero {
    --pagehero-img:
      image-set(url('../../uploads/hero-480.webp') type('image/webp') 1x,
                url('../../uploads/hero-1024.webp') type('image/webp') 2x,
                url('../../uploads/hero-1448.webp') type('image/webp') 3x);
  }

  @media (min-width: 761px) {
    .hero {
      background-image:
        linear-gradient(180deg, rgba(12,13,16,.42) 0%, rgba(12,13,16,.14) 30%, rgba(12,13,16,.6) 70%, rgba(12,13,16,.93) 100%),
        image-set(url('../../uploads/hero-1448.webp') type('image/webp') 1x);
    }
    .pagehero {
      --pagehero-img: image-set(url('../../uploads/hero-1448.webp') type('image/webp') 1x);
    }
  }
}

/* ------------------------------------------------------------ mini header -- */

/* Past the top bar the utility strip rolls up and the logo drops to about two
   thirds, so the header keeps roughly half its height for the rest of the page.
   This replaces the earlier hide-on-scroll: the phone number and the quote
   button are the two things a driver actually wants, and sliding them off the
   screen on every downward scroll put them a gesture away instead of a tap.
   site.js measures the strip into --topbar-h so the collapse animates against
   its real height at whatever width it is; the 3.5rem literal covers the moment
   before that runs. */
.topbar {
  overflow: hidden;
  /* Only a cap, so an over-generous fallback costs nothing while the header is
     open; it just has to clear the strip at every width, including the ones
     where it wraps to two rows. site.js replaces it with the measured height on
     load, which is what makes the collapse animate against the real value. */
  max-height: var(--topbar-h, 12rem);
  transition: max-height .3s cubic-bezier(.2,.7,.2,1);
}
.header--condensed .topbar { max-height: 0; }

.header__logo img { transition: height .3s cubic-bezier(.2,.7,.2,1); }
/* Scaled with the bigger resting logo above, but deliberately not by the same
   factor: the point of condensing is to give the page back its height, so this
   still drops to a little over half. */
.header--condensed .header__logo img { height: clamp(38px, 4.6vw, 58px); }

.header__inner { transition: padding .3s cubic-bezier(.2,.7,.2,1); }
.header--condensed .header__inner { padding-top: 3px; padding-bottom: 3px; }

/* Nothing here reacts to the menu opening. site.js already leaves the condensed
   state alone while the panel is up, and rolling the strip back out underneath
   an open menu would shove the whole panel down a row mid-tap. */

@media (prefers-reduced-motion: reduce) {
  .topbar,
  .header__logo img,
  .header__inner { transition: none; }
}

/* ------------------------------------------------ services page, revisited -- */

/* Five services, and auto-fit fits four across at this wrap — which left the
   fifth stranded on a row of its own looking like an afterthought. Pinning
   three columns reads as a deliberate 3-and-2 block instead. Scoped to a
   modifier because every other page has three or four cards, where auto-fit
   already fills the row. Below 1024 the auto-fit rule still gives two, then
   one, so nothing else is needed. */
@media (min-width: 1024px) {
  .cards--3up { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* .steps was drawn for the dark band it sits in on the home and insurance
   pages: white headings, pale grey body. services.html puts the same block on
   white, where the headings were white-on-white and invisible and the body text
   was barely there. Repaint it for a light section and leave the dark one
   exactly as the export drew it. .step__num is #3A3E45 either way and reads on
   both. */
.section:not(.section--dark) .step h3 { color: #14161A; }
.section:not(.section--dark) .step p { color: #545A63; }

/* ------------------------------------------- service photos, per page -- */

/* The client's own photos, one per service. Each page's banner carries the
   photo for that service instead of the shop front, and each tile on the home
   page carries the matching wider shot; the -main / -html pair in uploads/ is
   that split. These sit at the end of the file on purpose: a modifier class has
   the same specificity as .pagehero itself, so source order is what makes it
   win, including over the @supports and 761px rules above.

   Two photos arrived under 1600px (wheel-alignment-html is 1111 wide,
   insurance-html 1079), so their ladders stop at 1024 and the 2x/3x steps
   point at the largest variant that exists rather than one that does not. */
.pagehero--mechanical { --pagehero-img: url('../../uploads/mechanic-html.jpg'); }
.pagehero--autobody   { --pagehero-img: url('../../uploads/autobody-html.jpg'); }
.pagehero--paint      { --pagehero-img: url('../../uploads/paint-html.jpg'); }
.pagehero--tires      { --pagehero-img: url('../../uploads/tire-html.jpg'); }
.pagehero--alignment  { --pagehero-img: url('../../uploads/wheel-alignment-html.jpg'); }
.pagehero--insurance  { --pagehero-img: url('../../uploads/insurance-html.jpg'); }

@supports (background-image: image-set(url('../../uploads/hero-1448.webp') type('image/webp'))) {
  .pagehero--mechanical {
    --pagehero-img:
      image-set(url('../../uploads/mechanic-html-480.webp') type('image/webp') 1x,
                url('../../uploads/mechanic-html-1024.webp') type('image/webp') 2x,
                url('../../uploads/mechanic-html-2048.webp') type('image/webp') 3x);
  }
  .pagehero--autobody {
    --pagehero-img:
      image-set(url('../../uploads/autobody-html-480.webp') type('image/webp') 1x,
                url('../../uploads/autobody-html-1024.webp') type('image/webp') 2x,
                url('../../uploads/autobody-html-2048.webp') type('image/webp') 3x);
  }
  .pagehero--paint {
    --pagehero-img:
      image-set(url('../../uploads/paint-html-480.webp') type('image/webp') 1x,
                url('../../uploads/paint-html-1024.webp') type('image/webp') 2x,
                url('../../uploads/paint-html-2048.webp') type('image/webp') 3x);
  }
  .pagehero--tires {
    --pagehero-img:
      image-set(url('../../uploads/tire-html-480.webp') type('image/webp') 1x,
                url('../../uploads/tire-html-1024.webp') type('image/webp') 2x,
                url('../../uploads/tire-html-2048.webp') type('image/webp') 3x);
  }
  .pagehero--alignment {
    --pagehero-img:
      image-set(url('../../uploads/wheel-alignment-html-480.webp') type('image/webp') 1x,
                url('../../uploads/wheel-alignment-html-768.webp') type('image/webp') 2x,
                url('../../uploads/wheel-alignment-html-1111.webp') type('image/webp') 3x);
  }
  .pagehero--insurance {
    --pagehero-img:
      image-set(url('../../uploads/insurance-html-480.webp') type('image/webp') 1x,
                url('../../uploads/insurance-html-768.webp') type('image/webp') 2x,
                url('../../uploads/insurance-html-1079.webp') type('image/webp') 3x);
  }

  /* Past the phone the banner is wider than any 1x step, so serve the top of
     each ladder outright rather than letting a 1x pick a 480px file. */
  @media (min-width: 761px) {
    .pagehero--mechanical { --pagehero-img: image-set(url('../../uploads/mechanic-html-2048.webp') type('image/webp') 1x); }
    .pagehero--autobody   { --pagehero-img: image-set(url('../../uploads/autobody-html-2048.webp') type('image/webp') 1x); }
    .pagehero--paint      { --pagehero-img: image-set(url('../../uploads/paint-html-2048.webp') type('image/webp') 1x); }
    .pagehero--tires      { --pagehero-img: image-set(url('../../uploads/tire-html-2048.webp') type('image/webp') 1x); }
    .pagehero--alignment  { --pagehero-img: image-set(url('../../uploads/wheel-alignment-html-1111.webp') type('image/webp') 1x); }
    .pagehero--insurance  { --pagehero-img: image-set(url('../../uploads/insurance-html-1079.webp') type('image/webp') 1x); }
  }
}

/* ----------------------------------------------------- menu, where it reads -- */

/* This is where the menu used to be pinned to the header's true centre line at
   1240px and up: position: absolute, left: 50%, translate(-50%, -50%).
   Measured, it was exactly centred and looked anything but. The actions are
   316px wide against the logo's 147px, so an axis-centred menu sits 14px from
   the phone number at 1440 with 183px of empty cream on its other side — it
   read as shoved against the actions, which is the same complaint the
   margin-left: auto version drew. Balanced air beats a balanced axis here: the
   flex centring in the 1100px block gives the menu equal gaps at every width
   (98px either side at 1440), which is what the eye actually reads as centred,
   at the cost of sitting ~85px left of the page's middle. Nothing to add — the
   rule that does it is `.nav { flex: 1 1 auto; justify-content: center }`
   above, and this note is here so the axis version does not get reinvented. */
