/* Ideal Truck Accessories — stylesheet.
 *
 * PART 1 below is the supplied Custom Garage template stylesheet, kept as
 * delivered so the approved layout survives: the 27/73 hero split, the
 * clip-path angled red divider, the three-column "From the bay" row. Two
 * changes only — the fonts point at local woff2, and --red is #c80510,
 * sampled from the logo artwork rather than guessed.
 *
 * PART 2 is everything the template did not cover: forms, prices, FAQ
 * blocks, breadcrumbs, placeholder markers. Written to match.
 *
 * Do not replace PART 1 with a rewrite. That loses the design.
 */

/* ============================ PART 1 — template ========================== */

@font-face{font-family:Barlow;src:url('/fonts/barlow-bold.woff2') format('woff2');font-weight:700;font-display:swap}@font-face{font-family:Barlow;src:url('/fonts/barlow-heavy.woff2') format('woff2');font-weight:800;font-display:swap}
:root{--bg:#101113;--panel:#141619;--white:#f4f4ef;--muted:#a5a9ae;--red:#c80510;--line:#393c40;--navy:#002070;--display:Barlow,'Arial Narrow',Impact,sans-serif}*{box-sizing:border-box}html{scroll-behavior:smooth;scroll-padding-top:24px}body{margin:0;background:var(--bg);color:var(--white);font-family:Arial,sans-serif;line-height:1.55}a{color:inherit;text-decoration:none}button{font:inherit}a,button{-webkit-tap-highlight-color:transparent}a:focus-visible,button:focus-visible{outline:3px solid #fff;outline-offset:5px}img{display:block;max-width:100%;object-fit:cover}h1,h2,h3,p,figure{margin:0}h1,h2,h3,.button,nav,.accessory-index a{font-family:var(--display);font-weight:700}h1,h2{font-weight:800;line-height:.96}h2{font-size:clamp(42px,4.7vw,72px)}h3{font-size:28px;text-transform:uppercase}p{color:var(--muted)}.skip{position:absolute;top:-80px;left:20px;background:#fff;color:#000;padding:12px;z-index:20}.skip:focus{top:12px}.topline{display:flex;justify-content:space-between;padding:9px 3.2%;border-bottom:1px solid var(--line);font:10px Arial;letter-spacing:3px;color:var(--muted)}.header{display:flex;align-items:center;gap:4%;padding:16px 3.2% 14px}.brand{width:225px;flex-shrink:0}.brand img{width:100%;height:122px;object-fit:contain;mix-blend-mode:lighten}.header nav{display:flex;gap:30px;margin-left:auto}nav a{font-size:19px;text-transform:uppercase;letter-spacing:1px;white-space:nowrap}nav a:hover,.text-link:hover{color:#ff3543}.header-contact{margin-left:auto;text-align:right}.header-contact>div{display:flex;gap:12px}.button{display:inline-flex;justify-content:center;align-items:center;gap:20px;min-height:48px;padding:10px 24px;background:var(--red);border:1px solid #ed4650;color:#fff;font-size:20px;letter-spacing:1.4px;text-transform:uppercase;transition:background .15s}.button:hover{background:#f01626}.button.outline{background:transparent;border-color:#e2e3e3}.button.outline:hover{background:#282b30}.address{display:block;margin-top:10px;font:12px var(--display);letter-spacing:2px;text-transform:uppercase}.menu-toggle{display:none}.hero{display:grid;grid-template-columns:27% 73%;position:relative;min-height:615px;overflow:hidden}.hero-copy{padding:30px 10px 25px 12%;position:relative;z-index:2}.eyebrow{display:flex;align-items:center;gap:12px;font:12px var(--display);letter-spacing:3px;text-transform:uppercase;color:var(--white)}.eyebrow>span{width:22px;height:2px;background:var(--red)}h1{font-size:clamp(82px,7.8vw,126px);letter-spacing:-2px;margin:15px 0 12px}h1 em{font-style:normal;color:var(--red)}.hero-intro{font:700 20px/1.35 var(--display);letter-spacing:3px;text-transform:uppercase;color:#d8dade}.hero-actions{display:grid;gap:10px;max-width:235px;margin-top:20px}.hero-location{display:flex;gap:15px;align-items:center;margin-top:24px;font:12px/1.5 var(--display);letter-spacing:2px;text-transform:uppercase;color:var(--muted)}.hero-location>span:first-child{font-size:32px;color:#fff}.hero-photo{position:relative;margin-left:-72px;clip-path:polygon(11% 0,100% 0,100% 100%,0 100%);background:var(--red);padding-left:9px}.hero-photo img{width:100%;height:100%;object-position:center;clip-path:polygon(11% 0,100% 0,100% 100%,0 100%)}.bay{display:grid;grid-template-columns:38% 35% 27%;border-top:1px solid var(--line);padding-top:17px}.bay-photo{position:relative;min-height:310px}.bay-photo img{height:100%;width:100%}.bay-photo figcaption{position:absolute;bottom:20px;left:30px;background:#101113de;padding:8px 12px;font:14px/1.4 var(--display);text-transform:uppercase;letter-spacing:2px}.bay-copy{padding:2px 30px 25px}.section-label{display:flex;align-items:center;gap:14px;color:#ff3543;font:700 12px/1.5 Arial;letter-spacing:3px;text-transform:uppercase;margin-bottom:17px}.section-label span{height:1px;background:#85898e;flex:1}.bay-copy h2{font-size:clamp(40px,4.4vw,68px)}.bay-copy>p:not(.section-label){margin:20px 0;color:#c7c9cd;font-size:15px;letter-spacing:.6px}.text-link{display:inline-flex;gap:20px;align-items:center;font:700 16px var(--display);text-transform:uppercase;letter-spacing:2px;min-height:44px}.text-link span{color:#ff3543;font:28px Arial}.accessory-index{border-left:1px solid var(--line);padding:2px 28px 20px}.accessory-index a{display:flex;align-items:center;border-bottom:1px solid #60646a;gap:20px;min-height:44px;text-transform:uppercase;letter-spacing:1px;font-size:18px}.accessory-index a:hover{background:#25272b}.accessory-index a>span{font:12px Arial;color:#999}.accessory-index b{margin-left:auto;font-weight:400}.divider,footer{display:flex;justify-content:space-between;gap:20px;padding:19px 3%;border-top:1px solid var(--line);font:11px/1.6 var(--display);letter-spacing:3px;text-transform:uppercase;color:var(--muted)}.section{padding:80px max(5%,24px)}.section-heading{display:flex;justify-content:space-between;align-items:end;margin-bottom:36px;gap:30px}.section-heading>p{max-width:380px}.catalog{background:#181a1d}.product-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:40px 28px}.product{scroll-margin-top:25px;border-bottom:1px solid var(--line);padding-bottom:20px}.product img{width:100%;aspect-ratio:4/3;height:auto}.product>div{padding:18px 0 0}.number{float:right;color:#888;font:20px var(--display)}.product p{margin:8px 0;font-size:15px}.product .text-link{font-size:14px;letter-spacing:1px}.quote{display:grid;grid-template-columns:1fr 1fr;gap:12%;border-top:3px solid var(--red)}.quote p{max-width:500px;margin-top:20px}.quote-contact{align-self:center}.phone{display:block;font:700 clamp(36px,4vw,64px) var(--display);white-space:nowrap;margin:12px 0 24px}.quote-contact .button{width:100%}.quote-contact p{font-size:14px}.visit{background:#191b1e;display:grid;grid-template-columns:1.2fr 1fr 1fr;gap:40px;border-top:1px solid var(--line)}address{font-style:normal;color:#c8cbd0;margin:15px 0}.visit p{margin:14px 0}.visit a:not(.text-link){text-decoration:underline}footer{font-size:12px}
@media(min-width:1600px){body{max-width:1800px;margin:auto}.hero{min-height:700px}}@media(max-width:1150px){.header{gap:20px}.brand{width:175px}.header nav{gap:20px}.header-contact .outline{display:none}.hero{min-height:580px;grid-template-columns:30% 70%}.hero-copy{padding-left:10%}h1{font-size:96px}.hero-intro{font-size:17px;letter-spacing:2px}.hero-photo{margin-left:-35px}.bay{grid-template-columns:34% 37% 29%}.bay-copy,.accessory-index{padding-left:20px;padding-right:20px}.bay-copy h2{font-size:48px}.accessory-index a{font-size:16px;gap:12px}.section-label{letter-spacing:2px}}
@media(max-width:800px){.header{flex-wrap:wrap;padding:10px 5%;gap:10px}.brand{width:170px}.brand img{height:95px}.menu-toggle{display:flex;gap:14px;margin-left:auto;color:white;background:none;border:1px solid var(--line);padding:10px 16px;text-transform:uppercase;font-family:var(--display);min-height:44px}.header nav{display:none;order:3;width:100%;margin:0;padding:15px 0;gap:20px}/* .header nav.open removed: the template's script added that class, ours
   drives the menu from aria-expanded. A dead rule here is what made the
   broken menu look like it should have worked. */.header-contact{display:none}.hero{grid-template-columns:1fr;min-height:0}.hero-copy{padding:28px 6% 34px;display:grid;grid-template-columns:1fr 1fr;column-gap:20px}.hero-copy .eyebrow{grid-column:1/-1}.hero h1{grid-row:2/5;font-size:clamp(74px,14vw,112px);margin-bottom:0}.hero-intro{margin-top:22px;align-self:end}.hero-actions{align-self:start;width:100%}.hero-actions .button{padding:9px 8px;font-size:17px;gap:12px}.hero-location{grid-column:2;margin-top:14px}.hero-photo{margin-left:0;padding:5px 0 0;clip-path:none}.hero-photo img{clip-path:none;width:100%;height:auto;object-fit:contain}.bay{grid-template-columns:1fr 1fr;padding:20px 0 0}.bay-photo{min-height:280px}.bay-copy{padding:5px 24px 25px}.bay-copy h2{font-size:48px}.accessory-index{grid-column:1/-1;padding:25px 6%;border:0;display:grid;grid-template-columns:1fr 1fr;gap:0 30px}.accessory-index .section-label{grid-column:1/-1}.divider span:last-child{display:none}.section{padding:55px 6%}.product-grid{grid-template-columns:1fr 1fr}.section-heading{display:block}.section-heading>p{margin-top:20px}.quote{gap:30px}.phone{font-size:38px}.visit{grid-template-columns:1fr 1fr}.visit>div:first-child{grid-column:1/-1}}
@media(max-width:480px){.topline{font-size:8px;letter-spacing:1.8px}.hero h1{font-size:78px;letter-spacing:-1px}.hero-copy{padding:22px 5% 28px;gap:0 15px;grid-template-columns:1fr 1fr}.eyebrow{font-size:10px;letter-spacing:2px}.hero-intro{font-size:15px;letter-spacing:1.1px}.hero-actions{margin-top:16px}.hero-actions .button{font-size:15px;letter-spacing:.8px}.hero-location{font-size:9px;letter-spacing:1px;gap:8px}.hero-location>span:first-child{font-size:22px}.bay{grid-template-columns:1fr}.bay-photo{min-height:0;height:260px}.bay-copy{padding:26px 6%}.bay-copy h2{font-size:54px}.accessory-index{grid-template-columns:1fr}.accessory-index a{font-size:20px;min-height:50px}.product-grid{grid-template-columns:1fr}.quote,.visit{grid-template-columns:1fr}.visit>div:first-child{grid-column:auto}.phone{font-size:48px}.divider,footer{letter-spacing:1.5px;font-size:10px}footer{flex-direction:column;gap:8px}}@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}*{transition:none!important}}


/* ======================= PART 2 — additions ============================== */
/* Everything the template did not cover. Written to sit inside its system:
   same display face, same red, same uppercase letter-spaced labels. */

/* Accessory index: icons instead of the template's 01–06 numbers, matching
   the approved concept. */
.accessory-index a > svg {
  width: 30px; height: 22px; flex: 0 0 30px;
  stroke: #cfd2d6; stroke-width: 1.4; fill: none;
  stroke-linecap: round; stroke-linejoin: round;
}
.accessory-index a:hover > svg { stroke: #ff3543; }

/* Sticky tap-to-call. Phones only — the header carries it on desktop. */
.call-bar { display: none; }
@media (max-width: 800px) {
  .call-bar {
    position: sticky; top: 0; z-index: 30;
    display: flex; margin: 0; background: var(--red); border-bottom: 1px solid #7d0209;
  }
  .call-bar a {
    flex: 1; display: flex; align-items: center; justify-content: center;
    min-height: 48px; padding: 10px;
    font: 700 17px var(--display); letter-spacing: 1.4px; text-transform: uppercase; color: #fff;
  }
  .call-bar a + a { border-left: 1px solid #7d0209; }
}

.breadcrumbs { padding: 14px max(5%, 24px); background: var(--bg); font: 12px Arial; color: var(--muted); letter-spacing: 1px; }
.breadcrumbs ol { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin: 0; padding: 0; }
.breadcrumbs li::after { content: '/'; margin-left: 6px; color: var(--line); }
.breadcrumbs li:last-child::after { content: ''; }

/* Long-form service copy. */
.prose { max-width: 62ch; }
.prose p { margin: 0 0 18px; color: #c7c9cd; font-size: 16px; line-height: 1.7; }
.prose h2 { margin: 40px 0 14px; font-size: clamp(32px, 3.6vw, 48px); }
.prose h3 { margin: 28px 0 10px; }
.prose a { color: #fff; text-decoration: underline; text-decoration-color: #ff3543; text-underline-offset: 3px; }
.prose ul { margin: 0 0 18px; padding-left: 20px; color: #c7c9cd; }

/* Media in the article gets one spacing value, on both sides.
   A bare <Image> in .prose is a block with no margin of its own, so the gap
   above it came from whatever preceded it — 14px, the h2's margin-bottom —
   and the gap below was 0, because .prose p sets margin-bottom only. Every
   image on the site sat hard against the paragraph under it while carrying
   air above it. 26px is the figure margin the stylesheet already uses, so
   media now spaces the same whether it is wrapped in a figure or not.
   .clip is excluded: it floats, and carries its own margins. */
.prose > img,
.prose > picture,
.prose > figure:not(.clip) { margin-top: 26px; margin-bottom: 26px; }
.prose li { margin-bottom: 8px; }
.lede { font: 400 19px/1.65 Arial; color: #d8dade; max-width: 58ch; margin: 0 0 22px; }

figure { margin: 26px 0; }
figure img { width: 100%; }
figcaption { color: var(--muted); font-size: 14px; padding-top: 8px; }

/* Prices. Every figure carries the qualifier; the component enforces it. */
.prices { background: #17191d; border-left: 4px solid var(--red); padding: 24px; margin: 30px 0; max-width: 520px; }
.prices h2 { margin: 0 0 14px; font-size: 26px; }
.prices dl { margin: 0; }
.prices div { display: flex; justify-content: space-between; align-items: baseline; gap: 20px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.prices div:last-of-type { border-bottom: 0; }
.prices dt { color: #c7c9cd; font-size: 15px; }
.prices dd { margin: 0; font: 800 26px var(--display); color: #fff; white-space: nowrap; }
.price-note { margin: 14px 0 0; font-size: 13px; color: var(--muted); line-height: 1.5; }

.faq { max-width: none; border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  display: flex; align-items: center; gap: 20px;
  min-height: 56px; padding: 12px 4px; cursor: pointer;
}
.faq summary:hover h3 { color: #ff3543; }
.faq summary:focus-visible { outline: 3px solid #fff; outline-offset: -3px; }
.faq summary h3 { margin: 0; font-size: 18px; line-height: 1.35; font-weight: 700; }
/* The +/− sits at a fixed size on the right. `content` on ::after rather than a
   glyph in the markup, so the schema text and the visible question stay equal. */
.faq summary::after {
  content: '+'; margin-left: auto; flex: 0 0 auto;
  font: 400 26px/1 Arial; color: var(--muted);
}
.faq details[open] summary::after { content: '\2212'; color: #ff3543; }
.faq p { margin: 0; padding: 0 4px 22px; color: #c7c9cd; font-size: 15px; line-height: 1.7; max-width: 76ch; }

/* Placeholder marker — an unverified fact must be impossible to miss. */
.ph { background: #3a2f05; color: #ffd76a; border-bottom: 2px dotted #c9a227; padding: 0 .15em; }
.ph::after { content: ' ⚠ placeholder'; font: 700 .7em Arial; text-transform: uppercase; letter-spacing: 1px; color: #c9a227; white-space: nowrap; }
.ph-note { background: #3a2f05; border: 1px solid #c9a227; border-left-width: 4px; color: #ffe9ae; padding: 14px 16px; margin: 0 0 24px; font-size: 14px; max-width: 62ch; }
.ph-note p { margin: 0; }

/* Forms. White fields on the dark page: contrast for a phone in daylight. */
.form { max-width: 520px; }
.field { margin-bottom: 18px; }
.field > label { display: block; font: 700 15px var(--display); letter-spacing: 1.5px; text-transform: uppercase; margin-bottom: 6px; }
.hint { display: block; font: 400 13px/1.5 Arial; letter-spacing: 0; text-transform: none; color: var(--muted); margin-top: 2px; }

input[type="text"], input[type="email"], input[type="tel"], input[type="number"], select, textarea {
  width: 100%; min-height: 48px; padding: 11px;
  background: #fff; color: #101113; border: 2px solid transparent; border-radius: 0;
  font: 16px Arial;   /* 16px stops iOS Safari zooming on focus */
}
textarea { min-height: 120px; resize: vertical; }
input:focus, select:focus, textarea:focus { border-color: var(--red); outline: none; }

.field-group { border: 0; padding: 0; margin: 0 0 24px; min-width: 0; }
.field-group > legend { padding: 0; margin-bottom: 10px; font: 700 20px var(--display); letter-spacing: 2px; text-transform: uppercase; }
.field-row { display: grid; grid-template-columns: 90px 1fr 1fr; gap: 8px; }
.field-row-3 { grid-template-columns: repeat(3, 1fr); }
.field-row .field { margin-bottom: 0; }

.checks { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: 2px 16px; }
.checks li { display: flex; align-items: center; gap: 10px; min-height: 44px; }
.checks input { width: 22px; height: 22px; flex: 0 0 auto; accent-color: var(--red); min-height: 0; }
.checks label { font: 15px Arial; margin: 0; flex: 1; cursor: pointer; text-transform: none; letter-spacing: 0; }
.checks-inline { max-width: 320px; }

/* Honeypot: in the HTML for bots, never visible or focusable for people. */
.hp { position: absolute !important; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

.form-status { margin: 16px 0 0; padding: 14px 16px; border: 2px solid var(--line); background: #17191d; font: 700 15px var(--display); letter-spacing: 1.2px; }
.form-status:empty { display: none; }
.form-status[data-state="ok"] { background: #0c2e15; border-color: #2f9e4f; color: #b8f3c9; }
.form-status[data-state="error"] { background: #3a0d10; border-color: #ff3543; color: #ffc9cd; }

.required-key { font-size: 13px; color: var(--muted); }
.req { color: #ff3543; }

.skip { position: absolute; top: -80px; left: 20px; background: #fff; color: #000; padding: 12px; z-index: 40; }
.skip:focus { top: 12px; }

.hours { margin: 0; }
.hours div { display: flex; justify-content: space-between; gap: 20px; padding: 5px 0; border-bottom: 1px solid #23262a; font-size: 14px; }
.hours dt { color: #c7c9cd; }
.hours dd { margin: 0; color: var(--muted); }
.hours .closed dd { color: #ff3543; }

@media (max-width: 800px) {
  .field-row { grid-template-columns: 80px 1fr 1fr; }
  .prices { padding: 18px; }
}

/* Nav: the template shipped flat links. The brief's six categories have
   dropdowns, so these extend it without altering the header's proportions. */
.header nav { display: flex; gap: 30px; margin-left: auto; align-items: center; }
.nav-item { position: relative; }
.nav-item > a { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; }
.nav-item > a > span { font-size: 13px; color: #85898e; }
.nav-item > a[aria-current="page"] { box-shadow: inset 0 -3px 0 var(--red); }
.sub {
  position: absolute; top: 100%; left: -14px; z-index: 25;
  min-width: 250px; margin: 0; padding: 8px 14px; list-style: none;
  background: #17191d; border: 1px solid var(--line); border-left: 2px solid var(--red);
  opacity: 0; visibility: hidden;
}
.nav-item:hover > .sub, .nav-item:focus-within > .sub { opacity: 1; visibility: visible; }
.sub a {
  display: block; min-height: 40px; padding: 9px 0;
  font: 400 14px/1.3 Arial; letter-spacing: 0; text-transform: none; color: #c7c9cd;
}
.sub a:hover { color: #ff3543; }

.menu-toggle {
  display: none; margin-left: auto; align-items: center; gap: 10px;
  min-height: 44px; padding: 8px 14px;
  background: transparent; border: 1px solid #e2e3e3; color: #fff;
  font: 700 17px var(--display); letter-spacing: 1.4px; text-transform: uppercase; cursor: pointer;
}
.menu-toggle:hover { background: #282b30; }

.address { display: block; margin-top: 10px; font: 11px var(--display); letter-spacing: 2px; text-transform: uppercase; color: var(--muted); }
.address:hover { color: #fff; }

@media (max-width: 800px) {
  .menu-toggle { display: inline-flex; }
  .header nav { display: none; order: 3; width: 100%; margin: 0; padding: 10px 0; gap: 0; flex-direction: column; align-items: stretch; }
  .nav-item { border-bottom: 1px solid var(--line); }
  .nav-item > a { display: flex; padding: 12px 0; font-size: 20px; }
  .sub {
    position: static; opacity: 1; visibility: visible;
    min-width: 0; margin: 0 0 10px; padding: 0 0 0 14px;
    background: transparent; border: 0; border-left: 2px solid var(--red);
  }
}

.hero h1 em { font-style: normal; color: var(--red); }

/* The concept sets every heading in caps. The template relied on the markup
   shouting; doing it in CSS keeps the source readable. */
h1, h2, h3, .hero-intro, .button, .text-link { text-transform: uppercase; }
.hero h1 em { font-style: normal; color: var(--red); }
.faq h3, .prices dt, .checks label, .hint, .sub a { text-transform: none; }

/* Six categories plus the contact block fill the row. Tighten the nav so both
   fit, and keep About and Contact for the mobile menu and the footer — the
   concept's top bar carries the shop links, not the utility ones. */
@media (min-width: 801px) {
  .header nav { gap: 22px; }
  .header nav a { font-size: 16px; letter-spacing: .6px; }
  .nav-secondary { display: none; }
}
@media (min-width: 1200px) {
  .header nav { gap: 28px; }
  .header nav a { font-size: 17px; }
}

.nav-item-right .sub { left: auto; right: -14px; }

/* §3 puts About, Contact and Get a Quote outside the category nav. The topline
   is where they fit without squeezing the six categories out of the row. */
.topline-links { display: flex; gap: 18px; }
.topline-links a { color: var(--muted); }
.topline-links a:hover { color: #fff; }
.topline-links a:last-child { color: #ff3543; }

/* Six categories need more room than the template's three. Collapse to the
   menu button below 1200 rather than letting the contact block run off the
   edge; the sticky call bar carries the phone and quote links below that. */
@media (max-width: 1199px) {
  .menu-toggle { display: inline-flex; }
  .header nav { display: none; order: 3; width: 100%; margin: 0; padding: 10px 0; gap: 0; flex-direction: column; align-items: stretch; }
  /* Keyed on the button's own ARIA state — the script sets that and nothing
     else, so the menu cannot be open to a screen reader and shut on screen. */
  .menu-toggle[aria-expanded="true"] + nav { display: flex; }
  .header nav a { font-size: 20px; letter-spacing: 1px; }
  .nav-secondary { display: block; }
  .nav-item { border-bottom: 1px solid var(--line); }
  .nav-item > a { display: flex; padding: 12px 0; }
  .header-contact { display: none; }
  .sub, .nav-item-right .sub {
    position: static; opacity: 1; visibility: visible; left: auto; right: auto;
    min-width: 0; margin: 0 0 10px; padding: 0 0 0 14px;
    background: transparent; border: 0; border-left: 2px solid var(--red);
  }
  .call-bar {
    position: sticky; top: 0; z-index: 30;
    display: flex; margin: 0; background: var(--red); border-bottom: 1px solid #7d0209;
  }
  .call-bar a {
    flex: 1; display: flex; align-items: center; justify-content: center;
    min-height: 48px; padding: 10px;
    font: 700 17px var(--display); letter-spacing: 1.4px; text-transform: uppercase; color: #fff;
  }
  .call-bar a + a { border-left: 1px solid #7d0209; }
}

/* Between 1200 and 1400 the six categories and the full contact block do not
   both fit. Keep the nav — it is the useful half — and drop the address line
   and the phone button, which the sticky bar and the footer both carry. */
@media (min-width: 1200px) and (max-width: 1439px) {
  .header { gap: 20px; }
  .header nav { gap: 15px; }
  .header nav a { font-size: 15px; letter-spacing: .3px; }
  .header-contact .outline, .header-contact .address { display: none; }
  .brand { width: 180px; }
  .brand img { height: 100px; }
}
@media (min-width: 1440px) {
  .header nav { gap: 28px; }
  .header nav a { font-size: 17px; }
}

/* Header buttons must stay on one line — "(972) / 563-0113" over two lines
   reads as a layout fault, and the phone number is the main call to action. */
.header-contact .button { white-space: nowrap; font-size: 17px; padding: 10px 18px; gap: 10px; }
.header-contact > div { justify-content: flex-end; }

/* The template's mobile headline is sized for a 480px column; on a 360–430px
   phone "MAKE IT" breaks after "MAKE", which reads as a fault rather than a
   line break. Size it to the column it actually has. */
@media (max-width: 430px) {
  .hero h1 { font-size: clamp(42px, 12.5vw, 58px); }
}

/* Button rows and the service-page lead block. The template only had the hero's
   stacked .hero-actions; service pages need a horizontal row and a two-column
   intro that mirrors the hero's proportions. */
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; margin: 24px 0; }
.page-lead { display: grid; gap: 28px; align-items: start; }
.page-lead > div > :first-child { margin-top: 0; }
.page-lead img { width: 100%; }
@media (min-width: 900px) {
  .page-lead { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 40px; }
}

/* Every image carries width and height attributes so the browser reserves the
   right box (§5, no layout shift). Without height:auto the browser also uses
   that height literally and squashes the picture. The template's own
   .hero-photo / .bay-photo rules are more specific and keep their height:100%. */
img { height: auto; }

/* The template's global h1 size (min 82px) is really a hero size — it only
   ever had one h1, in the hero, reading "MAKE IT / YOUR / TRUCK." A service
   page headline is a sentence, and at 320px an 82px "SPRAY-IN" alone is wider
   than the screen. Scope a page scale to .section and leave .hero h1 alone. */
.section h1 {
  font-size: clamp(32px, 5vw, 64px);
  letter-spacing: -0.5px;
  margin: 12px 0 10px;
}

/* Must come after .section h1 — same specificity, so order decides.
   That 10px was set for a headline sitting above the lead, where the grid gap
   supplied the rest. Inside the column it is the whole gap, and 10px under a
   64px line with line-height .96 drops the lede onto its descenders. */
.page-lead h1 { margin-bottom: 20px; }
h1, h2, h3 { overflow-wrap: break-word; }

/* §10: every section sets its own background-color. Inheriting from body does
   not survive mobile dark-mode inversion, which has bitten this site before.
   The template's .section only set padding. */
main { background: var(--bg); }
.section { background: var(--bg); }
.section-alt { background: var(--panel); }

/* Seven categories no longer fit a 19px nav with 30px gaps beside a 225px logo
   and the contact block — the block ran 35px past the right edge at 1440, with
   the template's own breakpoint not starting until 1150. Tighten the type
   rather than cut a category or rename one. */
@media (min-width: 1151px) and (max-width: 1560px) {
  .header nav { gap: 20px; }
  .header nav > .nav-item > a { font-size: 17px; letter-spacing: 0.5px; }
}

/* A phone-shot clip in the article column. Portrait, so it is capped rather
   than run to the column width — 620px wide would be 1,100px tall. */
.clip { margin: 0 0 22px; }
.clip video { display: block; width: 100%; max-width: 360px; height: auto; background: #000; }
.clip figcaption { margin-top: 10px; max-width: 46ch;
  font: 700 12px/1.5 var(--display); letter-spacing: 2px; text-transform: uppercase; color: var(--muted); }

/* Footer columns. The template's 1.2fr first column is mostly empty on this
   site's content, which squeezed the hours table up against "Areas we serve"
   with 39px between them. Even the middle column, widen the gutter. */
@media (min-width: 50rem) {
  .visit { grid-template-columns: 1fr 1.15fr 0.95fr; gap: 72px; }
}
/* The template zeroes margins on h2 and gives it line-height .96, so without a
   top margin this line sits on the heading's descenders. */
.visit .serving { margin: 16px 0 20px; }
/* Nine towns in one paragraph wraps to a ragged two lines. A column list keeps
   them scannable and holds the block to the width of the heading above it. */
.areas { list-style: none; margin: 0; padding: 0; columns: 2; column-gap: 28px; }
.areas li { color: #c8cbd0; padding: 5px 0; break-inside: avoid; }
.hero, .bay, .catalog, .quote { background: var(--bg); }

/* Above the breakpoint the nav is always visible, whatever the button says. */
@media (min-width: 1200px) {
  .header nav, .menu-toggle[aria-expanded="true"] + nav { display: flex; }
}

/* Form controls, sized deterministically.
   Safari applies its own metrics to a control whose `appearance` has not been
   reset, which is why the Year input, the Make select and the Model input came
   out at three different heights on iOS while Chromium had all three at exactly
   48px. Three things make the height engine-independent:
     1. reset `appearance`, so no engine substitutes its own control metrics;
     2. set an explicit line-height — the `font` shorthand resets it to
        `normal`, and `normal` is not the same number in every engine;
     3. give the row controls an exact height rather than a minimum. */
input[type="text"], input[type="email"], input[type="tel"], input[type="number"],
select, textarea {
  appearance: none;
  -webkit-appearance: none;
  line-height: 1.25;
}

/* Resetting the appearance removes the native dropdown arrow, so draw one. */
select {
  padding-right: 36px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23101113' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px 8px;
}

/* Spinners differ between engines and are useless for a four-digit year. */
input[type="number"] { -moz-appearance: textfield; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* The three truck fields share a row, so they get an exact height, not a
   minimum — a minimum lets each control settle wherever its own metrics land. */
.field-row input, .field-row select { height: 48px; }

/* iOS WebKit — which is every browser on an iPhone, Chrome included, because
   iOS requires it. Two things it does that no desktop engine does. */

/* Without this, WebKit inflates body text when the phone is rotated to
   landscape ("text autosizing"), and a carefully set page reflows on its own. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* The sticky call bar is 49px tall below 1200px. The template's 24px
   scroll-padding lands an anchor target behind it, which breaks every dropdown
   link to a #section — brake controllers, rear bumpers, bed rails, headache
   racks, power steps, floor mats. Clear the bar, then some. */
html { scroll-padding-top: 64px; }
@media (min-width: 1200px) {
  /* Above the breakpoint the call bar is hidden, so only breathing room. */
  html { scroll-padding-top: 24px; }
}

/* Texas mark beside the shop address in the hero. */
.texas { flex: 0 0 auto; overflow: visible; }
@media (max-width: 480px) { .texas { width: 40px; height: auto; } }
.texas-outline { fill: none; stroke: #9aa0a6; stroke-width: 3; stroke-linejoin: round; }
.texas-star { fill: #fff; }
.hero-location:hover .texas-outline { stroke: #fff; }

/* Long-form page body.
   The template only ever had short sections, so a single readable column was
   never a problem for it. A service page is 600 words, and at 1440px a lone
   62ch column sitting against the left edge leaves two thirds of the screen
   empty. Split it: copy in a column that stays readable, the price block in a
   rail beside it. */
.body-split { display: grid; gap: 2rem; }
/* A body section with no rail. Not `.body-split` with one child — that reserves
   the rail track anyway and leaves the copy sitting off to one side. */
/* One-column body section. The same trap as .body-split: .prose carries its
   own 62ch cap, so a 552px column of text sat inside a 676px track and left a
   124px hole down the right of every paragraph while the figures beside it ran
   the full width. The track is the measure here, so the inner cap comes off. */
/* 52rem, the same track .body-split gives the article, so a one-column
   section and an article column are the same width. At 76ch this section sat
   676px wide directly under an 832px article on /about/, which reads as two
   different pages stitched together. */
.body-solo { max-width: 52rem; margin-inline: auto; }
.body-solo .prose { max-width: none; }

/* Headline and strapline run the full width above the split. The breadcrumbs
   sit directly above, so the section's own 80px of top padding would put the
   headline adrift from the trail that leads to it. */
.page-head { padding-top: 34px; padding-bottom: 0; }
/* These headlines carry "in Terrell, TX" for the local search that pays for
   this site, so they wrap on a desktop. `balance` splits them into even lines
   instead of leaving "TX" alone on the second one. */
.page-head h1 { margin: 0; font-size: clamp(34px, 5.2vw, 74px); text-wrap: balance; }
.page-tagline {
  margin: 16px 0 0; max-width: 80ch;
  font: 700 clamp(15px, 1.5vw, 19px)/1.45 var(--display);
  letter-spacing: 2.5px; text-transform: uppercase; color: #d8dade;
}
.page-body { padding-top: 38px; }

/* The hero, in the template's .bay-photo idiom: full bleed to its column with
   a caption chip bottom-left. */
.page-hero { position: relative; margin: 0 0 28px; }
.page-hero img { width: 100%; aspect-ratio: 5 / 3; object-fit: cover; }
/* Under the photo on a phone, over it on a desktop. Overlaid at 390px the
   caption wraps to two lines and takes a third of the picture with it. */
.page-hero figcaption {
  padding: 12px 0 0;
  font: 700 13px/1.35 var(--display); letter-spacing: 2px; text-transform: uppercase;
  color: var(--muted);
}
@media (min-width: 62rem) {
  .page-hero figcaption {
    position: absolute; bottom: 20px; left: 20px; max-width: calc(100% - 40px);
    padding: 10px 14px; background: #101113de; color: var(--white);
    border-left: 3px solid var(--red);
  }
}
.body-main > .lede { margin-bottom: 28px; max-width: 70ch; }

/* The rail answers what the page is for: tell us about the truck, then what it
   costs, how to reach the shop, and what else is in the category. */
/* Flat blocks separated by hairlines, not a stack of panels. Boxes inside a
   column that already has a rule down its side gives two vertical lines a few
   rem apart and a dead strip between them. */
.rail { display: grid; }
.rail-card, .body-aside .prices {
  background: transparent; border: 0; border-top: 1px solid var(--line);
  padding: 30px 0; margin: 0; max-width: none;
}
.rail > :first-child { border-top: 3px solid var(--red); }
.rail-card h2, .body-aside .prices h2 { margin: 0 0 12px; font-size: 26px; }
.rail-card > p { margin: 0 0 18px; font-size: 14px; line-height: 1.6; }
.rail-card .button { width: 100%; }
.rail-fitment .form { max-width: none; }
/* One field per row in a 22rem column — three across is three unusable boxes,
   and stacking them sidesteps the equal-height problem entirely. */
.rail-fitment .field-row { grid-template-columns: minmax(0, 1fr); gap: 0; }
.rail-fitment .field-row .field { margin-bottom: 18px; }
.rail-fitment .field-group > legend { font-size: 17px; }
.rail-fitment .required-key { margin: 14px 0 0; }
/* Even air above and below: the mark sits halfway between the call button and
   the hours link rather than tucked under the button. */
.rail-card > p.rail-where {
  display: flex; align-items: center; gap: 14px;
  /* Uneven on purpose: .text-link below is a 44px tap target with its text
     centred in it, so 14px of margin reads as about 26px of white space. */
  margin: 26px 0 14px; font-size: 14px; line-height: 1.5;
}
.rail-where a { color: #c7c9cd; text-decoration: underline; text-decoration-color: #ff3543; text-underline-offset: 3px; }
.rail-card .text-link { font-size: 14px; letter-spacing: 1px; margin-top: 0; }
.rail-links ul { list-style: none; margin: 0; padding: 0; }
.rail-links li { border-bottom: 1px solid var(--line); }
.rail-links li:last-child { border-bottom: 0; }
.rail-links a { display: flex; align-items: center; min-height: 44px;
  font: 700 16px var(--display); letter-spacing: 1px; text-transform: uppercase; }
.rail-links a:hover { color: #ff3543; }

/* The row you jumped to, greyed — and only that one, only once you have jumped.
   Marking every row that lives on this page greyed the whole list from load,
   which reads as disabled. :target knows which section the URL is pointing at,
   and `:has()` on .body-split is what reaches from that section across to the
   rail beside it. CSS cannot match a link's href against the fragment
   generically, so it is one selector per anchor; an acceptance test fails the
   build when NAV gains one that is not here.

   Where :has() is unsupported the whole rule drops and nothing greys, which is
   the same as it was before any of this. */
.body-split:has(#more-than-one:target) .rail-links a[href$="#more-than-one"],
.body-split:has(#patrol-vehicles:target) .rail-links a[href$="#patrol-vehicles"],
.body-split:has(#towing:target) .rail-links a[href$="#towing"],
.body-split:has(#what-we-do:target) .rail-links a[href$="#what-we-do"],
.body-split:has(#bed-mats:target) .rail-links a[href$="#bed-mats"],
.body-split:has(#bed-rails:target) .rail-links a[href$="#bed-rails"],
.body-split:has(#bed-steps:target) .rail-links a[href$="#bed-steps"],
.body-split:has(#brake-controllers:target) .rail-links a[href$="#brake-controllers"],
.body-split:has(#bug-shields:target) .rail-links a[href$="#bug-shields"],
.body-split:has(#color-match:target) .rail-links a[href$="#color-match"],
.body-split:has(#fender-flares:target) .rail-links a[href$="#fender-flares"],
.body-split:has(#fifth-wheel:target) .rail-links a[href$="#fifth-wheel"],
.body-split:has(#floor-mats:target) .rail-links a[href$="#floor-mats"],
.body-split:has(#front-bumpers:target) .rail-links a[href$="#front-bumpers"],
.body-split:has(#gooseneck:target) .rail-links a[href$="#gooseneck"],
.body-split:has(#headache-racks:target) .rail-links a[href$="#headache-racks"],
.body-split:has(#light-bars:target) .rail-links a[href$="#light-bars"],
.body-split:has(#power-steps:target) .rail-links a[href$="#power-steps"],
.body-split:has(#rear-bumpers:target) .rail-links a[href$="#rear-bumpers"],
.body-split:has(#vent-visors:target) .rail-links a[href$="#vent-visors"],
.body-split:has(#leveling-kits:target) .rail-links a[href$="#leveling-kits"],
.body-split:has(#winches:target) .rail-links a[href$="#winches"],
/* The nine rows that name a whole page target its heading block, which is a
   sibling of the article rather than a section inside it — so these reach
   across with `~` instead of `:has()`. That also means they work where
   `:has()` does not. */
#air-bags:target ~ .page-body .rail-links a[href$="#air-bags"],
#grill-guards:target ~ .page-body .rail-links a[href$="#grill-guards"],
#hitches-wiring:target ~ .page-body .rail-links a[href$="#hitches-wiring"],
#running-boards:target ~ .page-body .rail-links a[href$="#running-boards"],
#spray-in-liners:target ~ .page-body .rail-links a[href$="#spray-in-liners"],
#tonneau-covers:target ~ .page-body .rail-links a[href$="#tonneau-covers"],
#tool-boxes:target ~ .page-body .rail-links a[href$="#tool-boxes"],
#transfer-tanks:target ~ .page-body .rail-links a[href$="#transfer-tanks"] {
  color: var(--muted);
}
.rail-links a[href]:hover { color: #ff3543; }

@media (min-width: 62rem) {
  /* Tracks are sized to their content, not stretched to the section: a 62ch
     column of body text inside an 860px track leaves a 200px hole between the
     copy and the rail, which reads as a fault. `justify-content: center` puts
     the slack on the outside of both columns, where it is margin. */
  .body-split {
    grid-template-columns: minmax(0, 52rem) minmax(20rem, 23rem);
    justify-content: center;
    gap: 3.5rem;
    align-items: start;
  }
  .body-split .prose { max-width: none; }

  /* The hairline is the whole answer to a rail that runs out before the
     article does. It makes the empty tail read as a defined column rather
     than as something that failed to load — and it is the template's own
     .accessory-index treatment. */
  .body-aside {
    align-self: stretch;
    border-left: 1px solid var(--line);
    padding-left: 3.5rem;
    margin-left: -1.75rem;
  }

  .body-split figure { margin-top: 0; }

  /* The clips are portrait — 360x640 inside an 832px track left a 440px hole
     down the right of the video and pushed the copy below it. Floating the
     figure lets the copy run beside it and then close back to full width
     underneath.

     Only at this breakpoint. Below 62rem the prose is back to its 62ch cap
     (552px), and 552 - 360 leaves a 160px ribbon of text, which is worse than
     the hole. Here the measure is 832 - 360 - 28 = 444px, about 50ch.

     Width is explicit rather than left to shrink-to-fit: a floated figure is
     sized from its contents, and the video's intrinsic size is not what WebKit
     and Chromium agree on. */
  .body-split .clip {
    float: left;
    width: 360px;
    margin: 0 28px 22px 0;
  }

  /* The float is 748px tall with the caption. If the copy beside it is ever
     shortened, the next heading would ride up alongside the video instead of
     starting a new section. Clear it. */
  .body-split .prose h2 { clear: both; }
}

/* The FAQ opens and closes with no script at all. WebKit draws its own marker
   on <summary> unless both the standard and the -webkit- reset are set, and
   ignores `display` on the summary box itself unless `list-style` goes too. */
.faq-heading { margin: 48px 0 8px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::marker { content: ''; }
.faq summary { list-style: none; }

/* Form pages: copy on the left, form on the right. Same reasoning as
   .body-split — a form is 520px wide and a desktop is not. */
.form-split { display: grid; gap: 2.5rem; }
@media (min-width: 62rem) {
  .form-split {
    grid-template-columns: minmax(0, 1fr) minmax(0, 34rem);
    gap: 4rem;
    align-items: start;
  }
  .form-split .form { max-width: none; }
  .form-split h1 { margin-top: 0; }
}

/* Brand wall (/about/).
   The logos are 200x150 JPEGs on a WHITE background and the site is dark, so
   each gets its own white tile and the artwork's own white disappears into it.
   The tile is pure #fff, not var(--white) — that token is #f4f4ef, and an
   off-white tile leaves a visible white rectangle where the JPEG sits.

   Flex-wrap and centred, NOT a fixed column count. The number of logos
   changes whenever the owner confirms or withdraws a brand, and a grid tuned
   to divide evenly today strands one tile alone on the last row tomorrow —
   which reads as something failed to load. 25 in six columns did exactly
   that. Centred rows absorb any count.

   Heights are explicit rather than aspect-ratio: these tiles share a row, and
   an engine that measures the intrinsic image differently gives a ragged row
   on iOS while Chromium looks perfect. */
.brand-wall {
  list-style: none;
  margin: 28px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}
.brand-wall li {
  flex: 0 0 auto;
  width: 124px;
  height: 84px;
  background: #fff;
  border: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;
}
.brand-wall img {
  width: auto;
  height: 100%;
  max-width: 100%;
  object-fit: contain;
}

@media (max-width: 800px) {
  .brand-wall { gap: 8px; }
  .brand-wall li { width: 104px; height: 70px; padding: 8px; }
}
@media (max-width: 480px) {
  .brand-wall li { width: 96px; height: 64px; }
}


/* /contact/ — the message form is the only thing in this band now.
   Shop hours and Areas we serve came out of it because Base.astro publishes
   both in the footer of every page: the section was repeating, at full size,
   what sits a few hundred pixels below it.

   It no longer uses .visit. That is a three-column grid, and a single child in
   it parks in the first track with two empty ones alongside — the same trap
   .body-split documents. This keeps the band and lays out in one column. */
.contact-send { background: #191b1e; border-top: 1px solid var(--line); }
.contact-send .form { max-width: none; }
.contact-send > p { margin: 14px 0; }

/* A 520px form in a full-width band is a narrow stack of white boxes down one
   side. The three short answers share a row and the message runs under them,
   so the form uses the width it is given. Single column below 50rem, where
   three inputs side by side would be unusable. */
@media (min-width: 50rem) {
  /* align-items: end because the phone field carries a hint line under its
     label. Aligning the field boxes at the top left its input sitting 21px
     below the other two, which reads as a broken row. */
  .field-trio {
    display: grid; grid-template-columns: repeat(3, 1fr);
    gap: 0 24px; align-items: end;
  }
}

/* "Finding us" sits under the call and directions buttons now rather than in
   its own column. The template zeroes h2 margins, and at h2's clamp() size it
   would shout over the lead it belongs to, so it is sized as a sub-head. */
.lead-sub { font-size: 28px; margin: 34px 0 10px; }
.lead-sub + p { margin-bottom: 14px; }

@media (min-width: 900px) {
  /* "Finding us" drops to the foot of the column so the copy runs the height
     of the photo beside it rather than stopping short and leaving a band of
     background under it.

     An auto margin rather than a number, because the slack is not a constant:
     the photo scales with the track, so it is +181px at 1920 and -269px at
     940, where the copy is already the taller of the two. With no free space
     an auto margin resolves to zero and nothing moves. The 34px separation
     from the buttons becomes padding, which an auto margin cannot eat. */
  .page-lead { align-items: stretch; }
  /* justify-content centres a copy column that is shorter than the photo
     beside it (/about/). It has no effect on /contact/, where .lead-sub
     carries an auto margin — auto margins take all the free space first, so
     the two pages get the right answer from one rule. */
  .page-lead > div:first-child {
    display: flex; flex-direction: column; justify-content: center;
  }
  .lead-sub { margin-top: auto; padding-top: 34px; }
}
