/* chassis.css: mechanics only. Generated by the Studio renderer; do not hand-edit. */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body { margin: 0; font-family: var(--cx-font-body); font-size: var(--cx-body); color: var(--cx-fg); background: var(--cx-bg); -webkit-font-smoothing: antialiased; }
img, picture, video, canvas, svg { display: block; max-width: 100%; }
img { height: auto; }
picture { display: contents; }
picture > source { display: none; }
h1 { font-size: var(--cx-h1); line-height: 1.08; text-wrap: balance; margin: 0 0 .5em; }
h2 { font-size: var(--cx-h2); line-height: 1.15; text-wrap: balance; margin: 0 0 .5em; }
h3 { font-size: var(--cx-h3); line-height: 1.25; margin: 0 0 .4em; }
p, li { line-height: 1.6; }
p { max-width: var(--cx-measure); margin: 0 0 1em; }
h2 + p, h3 + p { margin-top: 0; }
p + h2, ul + h2, ol + h2, figure + h2 { margin-top: var(--cx-band); }
p + h3, ul + h3, ol + h3 { margin-top: calc(var(--cx-gap) * 1.5); }
.cx-wrap { width: min(100% - (var(--cx-gap) * 2), var(--cx-wrap)); margin-inline: auto; }
.cx-stack > * + * { margin-top: var(--cx-gap); }
:focus-visible { outline: 2px solid var(--cx-accent); outline-offset: 2px; }
/* Bypass blocks (WCAG 2.4.1): a keyboard visitor lands on the skip link before the nav, and nobody
   else ever sees it. The site shipped without one. */
/* Which fields are required is a thing the visitor should be able to see before pressing submit, not
   discover from a browser bubble afterwards. The form shipped with three required fields and nothing
   saying so, beside copy that asked for an address the form treated as optional. */
.cx-req { font-weight: 400; opacity: .75; }
.cx-hint { display: block; margin-top: 6px; opacity: .75; }
.cx-skip { position: absolute; left: -9999px; top: 0; z-index: 100; padding: 12px 16px; background: var(--r-bg); color: var(--r-fg); border: 2px solid var(--r-accent); text-decoration: none; }
.cx-skip:focus { left: 8px; top: 8px; }
/* hidden means hidden. The attribute's own UA rule is display:none at specificity 0-0-0, so ANY class
   that sets display outranks it: the review link ships hidden until the platform supplies a real one,
   it carries .r-btn, and .r-btn's display:inline-flex un-hid it. A dead "Leave a review" button with
   href="#" rendered on the reviews page of a gate-green build, and the controls gate could not see it
   because the markup says hidden. !important because the whole point is that nothing may override it. */
[hidden] { display: none !important; }
.cx-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.cx-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
/* :not(.r-btn) because the submit IS a site button and the field sizing here outranks it. At
   .cx-form button this rule is 0-1-1 and .r-btn is 0-1-0, so the one button on the page that is also
   a form control came out 51px tall with 14px of inner padding against the site's 46px and 26px: the
   odd button out on every page that carries a form, and the kind of thing nobody can name and
   everybody sees. A form that ships a bare <button> still gets field sizing, which is the point of
   the rule; a button wearing the site's own class keeps the site's shape. */
.cx-form input, .cx-form select, .cx-form textarea, .cx-form button:not(.r-btn) {
  font: inherit; font-size: max(16px, var(--cx-body)); width: 100%;
  padding: .65em .8em; border: 1px solid var(--cx-line); border-radius: var(--cx-radius);
  background: var(--cx-bg); color: var(--cx-fg);
}
.cx-form textarea { resize: vertical; }
/* The file picker's own button is painted by the browser, and on a dark form it is the one white
   control in the column: the eye reported "one field is light while every other field is dark" on the
   contact page and named the wrong control, because the only light thing in the form was this. It is
   part of the field, so it wears the field's palette - a quiet outline, not a second submit. The text
   beside it ("No file chosen") belongs to the browser and cannot be styled or renamed. */
.cx-form input[type="file"] { padding: .45em .55em; }
.cx-form input[type="file"]::file-selector-button {
  font: inherit; font-size: .92em; font-weight: 600; margin-right: .7em; padding: .4em .8em;
  background: transparent; color: var(--cx-fg); border: 1px solid var(--cx-line);
  border-radius: var(--cx-radius); cursor: pointer;
}
.cx-form input[type="file"]::file-selector-button:hover { border-color: var(--cx-fg); }
.cx-form button { width: auto; cursor: pointer; border-color: transparent; }
.cx-field { display: grid; gap: .35em; max-width: none; }
.cx-field label { font-weight: 600; }
a[href^="tel:"], .cx-form button, .cx-bar a, .cx-nav a { min-height: 44px; }
.cx-form button, .cx-bar a { display: inline-flex; align-items: center; justify-content: center; }
:target, [id] { scroll-margin-top: calc(var(--cx-head-h, 64px) + var(--cx-gap)); }
.cx-head { position: sticky; top: 0; z-index: 50; background: var(--cx-bg); }
.cx-navbtn { display: none; align-items: center; gap: .55rem; min-height: 44px; min-width: 44px; padding: 0 .25rem; background: none; border: 0; font: inherit; color: inherit; cursor: pointer; }
.cx-navbtn-bars { display: inline-block; width: 22px; }
.cx-navbtn-bars span { display: block; height: 2px; margin: 4px 0; background: currentColor; }
.cx-navbtn[aria-expanded="true"] .cx-navbtn-bars span:nth-child(2) { opacity: 0; }
.cx-nav ul { list-style: none; margin: 0; padding: 0; display: flex; gap: 1.25rem; }
.cx-nav a { text-decoration: none; }
.cx-navbtn[hidden], .cx-nav[hidden] { display: none; }
/* Which of the two shows is a CSS decision made before the first paint, keyed on the js class the
   head sets: no script means the list and no button, script means the button and a collapsed list.
   Nothing mutates after paint, so a phone page does not jump when the menu resolves. */
@media (max-width: 900px) {
  html.js .cx-navbtn { display: inline-flex; }
  html.js .cx-nav { display: none; }
  html.js .cx-nav.is-open { display: block; }
}
img:not(.cx-bleed):not([class*="logo"]):not([class*="icon"]), picture:not(.cx-bleed) > img { border-radius: var(--cx-radius-media, 8px); }
.cx-bleed, .cx-bleed > img { border-radius: 0; }
@media (max-width: 900px) {
  .cx-nav { flex-basis: 100%; width: 100%; }
  .cx-nav ul { flex-direction: column; gap: 0; }
  .cx-nav a { display: flex; align-items: center; min-height: 44px; }
  .cx-navbtn { margin-left: auto; order: 99; }
  .cx-head:not(.cx-util-head) a[href^="tel:"]:not(.cx-nav a) { display: none; }
  body { padding-bottom: var(--cx-bar-h, 0px); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}
.cx-util-head { display: flex; align-items: center; justify-content: space-between; gap: var(--cx-gap); padding: .75rem var(--cx-gap); }
.cx-util-head .cx-util-tel { white-space: nowrap; }
.cx-util { width: min(100% - (var(--cx-gap) * 2), var(--cx-measure)); margin-inline: auto; padding-block: var(--cx-band); }
.cx-foot { padding: var(--cx-band) var(--cx-gap); }
