/* CARRIED-OVER COMMENTS, 2026-09-28. This file came with the migration toolkit, and some
 * of its comments were written against EARLIER clients' sites in that lineage. Every other
 * client's page path, name and domain was removed from them on 2026-09-28 (shown as
 * "another client's page" and similar). Censuses, counts and widget ids in the comments
 * below were NOT re-measured on this site: do not cite one as a fact about this site
 * without measuring it here. The code is unchanged by that clean-up. */
/* Hand-written overrides for this migration.
 *
 * NO PREVIOUS CLIENT IS NAMED IN THIS FILE, DELIBERATELY: it is copied verbatim into
 * dist, so a prior client's name here would be PUBLISHED on this client's domain and
 * would make a residue sweep report a correct file dirty. Provenance lives in
 * MIGRATION-NOTES, which does not ship.
 *
 * DELIBERATELY OUTSIDE site/public/styles/ (gotcha 49): tools/port-css.mjs owns that
 * directory and clears its own hashed outputs on every run, so a hand-written sheet
 * placed there is deleted by the next port with no error anywhere.
 *
 * EVERY NUMBER BELOW WAS CENSUSED ON THIS SITE ON 2026-09-08. This file arrived carrying
 * the populations of TWO earlier repos (53 pages/31 posts and 59 pages/15 posts) in prose
 * that read as measurement — gotcha 64. The RULES were sound and are kept; every
 * measurement around them is re-taken. Population, DERIVED and not typed: pages.txt holds
 * 32 paths — 18 static pages (the export's 18 page directories, all still 200 on live)
 * plus the 13 blog posts generated/blog.rss declares as <item>s (one of which the sitemap
 * omits) plus /blog-search (declared only in a widget attribute) — so 96 captures
 * (32 x 3 bands) plus 96 served documents (32 x 3 device UAs).
 *
 * Keep this file minimal. Anything that can come from the ported cascade should.
 */

/* The honeypot. Positioned off-screen rather than display:none — bots skip obviously
 * hidden fields, and taking it out of flow means it costs no layout, which the pixel
 * gate would otherwise measure. Live has NO honeypot on this site's one form
 * (/contact — generated/form-pages.json, 1 of 32 pages) and no reCAPTCHA in its served
 * markup either; reCAPTCHA is mounted at runtime and is removed here (gotcha 17: its keys
 * are Duda's own and domain-restricted). So this is ours, must cost nothing, and is the
 * ONLY spam protection. /migration phase 8 specifies exactly this. */
.mg-hp {
  position: absolute !important;
  left: -9999px !important;
  top: auto !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
}

/* SPECIFICITY NOTE — read before editing any rule below.
 *
 * Duda emits a per-widget rule for EVERY widget on the site, shaped
 *     #dm .dmBody div.u_1213107879 { display: block !important }
 * That is (1,2,1) and it is `!important`. A hide written as a plain
 * `.mg-only-t { display:none !important }` is (0,1,0), so with `!important` on both
 * sides SPECIFICITY decides and Duda's rule wins — the element stays visible and
 * nothing in the console says so. So every gate below repeats its class three times
 * behind `#dm`, giving (1,3,0), which outranks (1,2,1) on class count without relying
 * on source order. Do not "tidy" the repetition away (gotcha 70).
 */

/* ---------------------------------------------------------------------------
 * BLOG PAGINATION — ONE REAL CONTROL, ON ONE PAGE, AND IT IS THE SHOW-MORE SHAPE.
 *
 * Censused on the raw served html of all 32 pages and confirmed by driving live's own
 * control (generated/blog-widgets.json, 6 of 6 records, tools/capture-blog-widgets.mjs):
 *
 *   /(another client's page)     visible-items="9", data-paginate-total-elements="13",
 *                  more-posts-text-container x1  ("Show More" APPENDS): driven 9 -> 13
 *                  on d, t and m.  pagination-nav x0.
 *   /blog-search   visible-items="20", total 13, NO control — all 13 render at once.
 *   13 blog posts  NO blog-list widget of any kind (internal_blog_list is on exactly the
 *                  two pages above), so nothing here has a subject on any post.
 *
 * generated/blog.rss independently declares 13 items — counted from the file, never
 * typed — and /(another client's page)'s own total agrees at 13, which is the cross-check that makes a
 * truncated index fail rather than ship quietly (gotcha 83).
 *
 * A static build has no Duda backend, so every card ships and the 4 past the first batch
 * are stamped mg-blog-hidden with data-mg-blog-page; runtime.js reveals them in live's own
 * batch when "Show More" is clicked. This rule is what hides them initially — 13 declared
 * minus the 9 the first render shows = 4 cards, on the one page that has a control.
 * ------------------------------------------------------------------------- */
#dm .mg-blog-hidden.mg-blog-hidden.mg-blog-hidden {
  display: none !important;
}

/* display:none DOES NOT CHANGE CHILD INDICES, so shipping the withheld cards silently
 * moves which card is :last-child — gotcha 69. Duda's own rule is
 * `.postArticle:not(:last-child){padding-bottom:Npx}`; on live the last VISIBLE card is
 * genuinely :last-child and takes none of it, while in our build it is followed by hidden
 * siblings, so it stops matching and GAINS that padding. Keyed on `:has(+ .mg-blog-hidden)`
 * rather than on a stamped class, because that tracks the SEQUENCE as batches are revealed
 * instead of pinning the initial state. `!important` because Duda's rule here can outrank
 * this one on attribute count and carries none of its own.
 *
 * SUBJECT ON THIS SITE: the 9th card on /(another client's page) and nothing else. Whether Duda's rule
 * is ARMED on this site's cascade is decided by the gate, not asserted here: gate 1 scored
 * /(another client's page) 0.000% at 375, 768 and 1440 with this rule in place. */
#dm .postArticle:not(.mg-blog-hidden):has(+ .postArticle.mg-blog-hidden) {
  padding-bottom: 0 !important;
}

/* ---------------------------------------------------------------------------
 * PER-DEVICE CONTENT FORKS.
 *
 * THIS SITE IS DUDA **FLEX**, AND ON FLEX THE CHROME DOES NOT FORK — GOTCHA 5 IS
 * INVERTED. Measured over generated/served-by-device (96 documents, 32 paths x 3
 * device UAs, all 200):
 *
 *   dmtemplateid    FlexHeader on ALL THREE BANDS, all 32 pages
 *   <body> class    `dmRoot fix-mobile-scrolling flex-site dmResellerSite`,
 *                   BYTE-IDENTICAL on all three bands, all 32 pages
 *   data-flex-site  present on all three bands, all 32 pages
 *
 * `fix-mobile-scrolling` in that class list is LOAD-BEARING (gotcha 35): Duda's
 * body{overflow:hidden} is undone only by it.
 *
 * THE CONTENT FORK IS THREE-WAY, measured on the served BYTES (tools/measure-served-fork.mjs,
 * generated/served-fork.json): desktop == tablet on 0 of 32, desktop == mobile on 0 of 32,
 * each disagreement re-sampled. So each band's body is emitted whole and the two inactive
 * copies are PRUNED pre-paint by the boot script (band_prune). The mg-only-* gates below
 * are the CSS backstop for the interval between parse and prune, and for any element the
 * builder stamps per band rather than per body.
 *
 * THE THREE BANDS DECLARE THREE DIFFERENT VIEWPORTS (32/32 on each band):
 *   desktop  initial-scale=1, minimum-scale=1, maximum-scale=5, viewport-fit=cover
 *   tablet   width=960px                 <- gotcha 3's 960 canvas DOES apply, measured
 *   mobile   width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=5,
 *            viewport-fit=cover
 *
 * THE BAND BOUNDARIES ARE DUDA'S OWN: the ported cascade's media queries are
 * max-width:767px / min-width:768px / max-width:1024px / min-width:1025px, so 1025 is the
 * desktop edge on Duda's own declarations. Only the INACTIVE bands are hidden, inside the
 * media queries; the active band keeps whatever `display` the ported cascade gives it.
 * ------------------------------------------------------------------------- */
@media (max-width: 767px) {
  #dm .mg-only-d.mg-only-d.mg-only-d,
  #dm .mg-only-t.mg-only-t.mg-only-t {
    display: none !important;
  }
}
@media (min-width: 768px) and (max-width: 1024px) {
  #dm .mg-only-d.mg-only-d.mg-only-d,
  #dm .mg-only-m.mg-only-m.mg-only-m {
    display: none !important;
  }
}
@media (min-width: 1025px) {
  #dm .mg-only-t.mg-only-t.mg-only-t,
  #dm .mg-only-m.mg-only-m.mg-only-m {
    display: none !important;
  }
}

/* ---------------------------------------------------------------------------
 * SLIDERS: NONE ON THIS SITE. ssrimageslider 0 of 96 served documents, .flexslider 0
 * (served AND post-JS), data-gallery-bg 0, .bgGallerySlide 0, <video> 0. No rule, no
 * gate exclusion on rotation grounds, and that is a measurement rather than an omission
 * (positive control on the same corpus: ssraccordion 22/32, mapextension 6/32).
 * ------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
 * ACCORDION OPEN STATE — recovering a rule the live CSS read cannot see.
 *
 * THIS SITE, from generated/accordion-config.json (derived from live's own
 * initiateWidget({"type":"SSR_ACCORDION"}) payloads) and corroborated against an
 * `ssraccordion` census of the raw served html:
 *
 *     22 of 32 served documents carry an accordion — ONE widget per page, 22 distinct ids
 *     5 items each, except /faq with 10
 *     EVERY widget: firstExpanded FALSE, closeOthers TRUE, LAYOUT_1
 *     live reveal MEASURED per widget (tools/measure-accordion-reveal.mjs): 0 of 22 auto-open
 *
 * So every accordion ships CLOSED, exactly as live serves it, and there is no
 * expandFirstItem height to reproduce. The per-widget stamp is still used, because a
 * site-wide rule that is right today is the shape that ships unnoticed the day one widget
 * differs.
 *
 * THE CLOSED RULE IS IN THE PORT AND THE OPEN RULE IS NOT, AND THAT IS NOT A PORTING
 * MISTAKE. styled-components insert through the CSSOM, so a class exists in a document's
 * sheet only if that component actually RENDERED with it; the CLOSED rule (max-height:0)
 * is served once per instance and NO open-state rule is served anywhere, because Duda
 * mints one per distinct pixel height at runtime. runtime.js sets an inline max-height from
 * each panel's own scrollHeight; this rule is the ceiling that lets the transition run.
 * ------------------------------------------------------------------------- */
#dm .mg-acc-open.mg-acc-open.mg-acc-open {
  max-height: 2000px;
}

/* NO POPUP HOST RULES. The FLEX click-popup hosts (#flex-popup-overlay,
 * #flex-runtime-popup-container) that a sibling repo had to hand-write have no subject
 * here: link_type="popup" 0, popup_target 0, flex-runtime-popup 0, #dmPopup 0 on all 96
 * served documents. runtime.js's flexPopup() returns on zero triggers, so the rules are
 * omitted rather than shipped inert. */

/* ---- Pre-launch review 2026-10-07 ------------------------------------------ */

/* Tablet/phone drawer sub-menus ("Services", "Irrigation Repair", "Why Us", "Service
 * Areas"). runtime.js drawer() opens and closes each from its caret (and from the label
 * where the label is href="#"); closed is the class gy-sub-closed. The closed state
 * collapses height, padding, border and opacity together (max-height alone clips only
 * the content box), takes the panel out of the tab order, and is !important at doubled
 * id specificity so it outranks the ported cascade's own :hover opener, which a tap
 * leaves stuck on a touch screen and which would otherwise keep a closed group open. */
#hamburger-drawer#hamburger-drawer li.gy-sub > .unifiednav__container_sub-nav {
  overflow: hidden;
  transition: max-height .3s ease, opacity .2s ease;
}
#hamburger-drawer#hamburger-drawer li.gy-sub.gy-sub-closed > .unifiednav__container_sub-nav {
  max-height: 0 !important;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
  margin-top: 0 !important;
  margin-bottom: 0 !important;
  border-width: 0 !important;
  opacity: 0 !important;
  pointer-events: none !important;
  visibility: hidden;
}
/* Closed, the caret points down whatever :hover says. */
#hamburger-drawer#hamburger-drawer li.gy-sub.gy-sub-closed > a .icon::before {
  transform: none !important;
}
#hamburger-drawer .hamburgerButton {
  position: relative;
  z-index: 5;
}
/* The close (X) follows the panel's scroll (runtime.js drawer()). Its row and the
 * menu's row are each transformed, so each is its own stacking context and the later
 * one — the menu — would paint over the X once an open group scrolled up under it. */
#hamburger-drawer div:has(.hamburgerButton) {
  z-index: 5;
}

/* Desktop menu on one row, 1190-1699px (review 2026-10-07). The five labels need 613px
 * at the menu's own 16px / 30px-gap and the menu column is 359px at 1025, 456 at 1280,
 * 517 at 1440 and 578 at 1600, so "CONTACT" (and at 1025 "PRICING" too) dropped onto a
 * second and third row all the way up to 1699px, on live too. Inside that range the
 * labels step down in size and gap so the row fits its column; 1700 and wider are
 * untouched, and from 1190 the row is also forbidden to wrap (there are 49px or more
 * between "CONTACT" and the logo at every width in the range). Below 1190 the column
 * cannot hold five labels at a readable size, so the row breaks once (two rows instead
 * of live's three). */
@media (min-width: 1025px) and (max-width: 1309px) {
  #dm#dm#dm .dmInner nav[id="1198691314"].main-navigation.unifiednav .unifiednav__container:not([data-depth]) > .unifiednav__item-wrap > .unifiednav__item {
    padding-right: 8px !important;
  }
  #dm#dm#dm .dmInner nav[id="1198691314"].main-navigation.unifiednav .unifiednav__container:not([data-depth]) > .unifiednav__item-wrap > .unifiednav__item .nav-item-text {
    font-size: 13px !important;
  }
}
@media (min-width: 1310px) and (max-width: 1474px) {
  #dm#dm#dm .dmInner nav[id="1198691314"].main-navigation.unifiednav .unifiednav__container:not([data-depth]) > .unifiednav__item-wrap > .unifiednav__item {
    padding-right: 12px !important;
  }
  #dm#dm#dm .dmInner nav[id="1198691314"].main-navigation.unifiednav .unifiednav__container:not([data-depth]) > .unifiednav__item-wrap > .unifiednav__item .nav-item-text {
    font-size: 14px !important;
  }
}
@media (min-width: 1475px) and (max-width: 1629px) {
  #dm#dm#dm .dmInner nav[id="1198691314"].main-navigation.unifiednav .unifiednav__container:not([data-depth]) > .unifiednav__item-wrap > .unifiednav__item {
    padding-right: 20px !important;
  }
  #dm#dm#dm .dmInner nav[id="1198691314"].main-navigation.unifiednav .unifiednav__container:not([data-depth]) > .unifiednav__item-wrap > .unifiednav__item .nav-item-text {
    font-size: 15px !important;
  }
}
@media (min-width: 1630px) and (max-width: 1699px) {
  #dm#dm#dm .dmInner nav[id="1198691314"].main-navigation.unifiednav .unifiednav__container:not([data-depth]) > .unifiednav__item-wrap > .unifiednav__item {
    padding-right: 22px !important;
  }
}
@media (min-width: 1025px) and (max-width: 1699px) {
  #dm#dm#dm .dmInner nav[id="1198691314"].main-navigation.unifiednav .unifiednav__container:not([data-depth]) > .unifiednav__item-wrap:last-child > .unifiednav__item {
    padding-right: 0 !important;
  }
}
@media (min-width: 1190px) and (max-width: 1699px) {
  #dm#dm#dm .dmInner nav[id="1198691314"].main-navigation.unifiednav > .unifiednav__container:not([data-depth]) {
    flex-wrap: nowrap !important;
  }
}

/* /blog-search and the 404 page have no hero, so the header (white logo, white menu,
 * white phone numbers, white hamburger) sat on the page's white ground and only the
 * mint "BOOK ONLINE" button could be seen — on live too (review 2026-10-07). On those
 * two pages the header row takes the site's own dark teal (the drawer's ground,
 * rgb(0,91,90)), where every one of those is legible. */
body[data-page-alias="blog-search"] #flex-header,
body[data-page-alias="dmPageNotFound"] #flex-header {
  background-color: rgb(0, 91, 90) !important;
}

/* Phone header: click-to-call beside the menu button (tools/review-fixes.py). The
 * icon is the menu button's size and ink (rgb(159,226,191)). */
#dm#dm [id="764397de"]:has(> .gy-call) {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: flex-end;
  gap: 18px;
}
#dm#dm [id="764397de"]:has(> .gy-call) > [id="00ca91b4"] {
  flex: 0 0 30px;
  width: 30px;
}
#dm#dm a.gy-call {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  color: rgb(159, 226, 191);
  position: relative;
}
#dm#dm a.gy-call svg {
  width: 24px;
  height: 24px;
  display: block;
}
#dm#dm a.gy-call::after {
  content: "";
  position: absolute;
  inset: -7px;
}

/* /blog's "BOOK NOW" button (tools/review-fixes.py): the site's default button,
 * restated from its measured style (280x50 mint pill, teal 16px/700 Plus Jakarta Sans,
 * colours swapping on hover), centred under the post list. FLEX groups place children
 * by `order`, so it is sent to the end explicitly. */
#dm#dm .gy-cta-wrap {
  order: 999;
  width: 100%;
  height: auto;
  min-height: 0;
  display: flex;
  justify-content: center;
  margin: 40px 0 0;
  padding: 0;
}
#dm#dm a.gy-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 280px;
  max-width: 100%;
  height: 50px;
  margin: 0;
  padding: 10px 0;
  box-sizing: border-box;
  border: 0;
  border-radius: 50px;
  background: rgb(159, 226, 191);
  transition: background-color .2s, border-color .2s;
  text-decoration: none;
}
#dm#dm a.gy-cta .text {
  color: rgb(0, 91, 90);
  font-family: 'Plus Jakarta Sans', 'Plus Jakarta Sans Fallback', sans-serif;
  font-size: 16px;
  font-weight: 700;
  white-space: nowrap;
}
#dm#dm a.gy-cta .iconBg {
  display: none;
}
#dm#dm a.gy-cta:hover {
  background: rgb(0, 91, 90);
}
#dm#dm a.gy-cta:hover .text {
  color: rgb(159, 226, 191);
}

/* Legal pages (tools/build-legal-pages.mjs). Duda's reset zeroes margin on p, ul
 * and h2, so the template text would otherwise render as one slab with every
 * heading pressed against the paragraph above it. The row paints its own white so
 * it never inherits whatever the page ground is. */
#dm .gy-legal-row {
  max-width: 1200px;
  margin: 0 auto;
  padding: 60px 40px 80px;
  box-sizing: border-box;
  background-color: rgb(255, 255, 255);
  color: rgb(12, 16, 21);
}
#dm .gy-legal-row h2 {
  margin: 36px 0 12px;
}
#dm .gy-legal-row p,
#dm .gy-legal-row li {
  line-height: 1.6;
}
#dm .gy-legal-row p {
  margin: 0 0 14px;
}
#dm .gy-legal-row ul {
  margin: 0 0 14px;
  padding-left: 1.4em;
  list-style: disc;
}
#dm .gy-legal-row li {
  margin: 0 0 4px;
}
#dm .gy-legal-row a {
  text-decoration: underline;
}
@media (max-width: 767px) {
  #dm .gy-legal-row {
    padding: 32px 15px 60px;
  }
}

/* "Privacy Policy | Terms & Conditions" under the footer copyright and under each
 * form's Submit button (tools/build-legal-pages.mjs): the links keep the ink of the
 * line they sit on, whatever the page's own link colour is. The footer line takes the
 * copyright's own type: Roboto 16px at desktop, 13px on tablet and phone. */
#dm#dm .gy-legal-links a {
  color: inherit !important;
  text-decoration: underline !important;
  font-weight: inherit !important;
}
#dm#dm .gy-legal-links--footer {
  width: 100%;
  padding-top: 6px;
  font-family: Roboto, 'Roboto Fallback', sans-serif;
  font-size: 16px;
  line-height: 1.6;
}
@media (max-width: 1024px) {
  #dm#dm .gy-legal-links--footer {
    font-size: 13px;
  }
}

/* The 404 page (review 2026-10-07). Duda styles its "4 04" block from a platform
 * sheet that is not part of the port, so the page shipped as four lines of unstyled
 * text pressed against the left edge with a default blue link. Live's measured look
 * (1440): 120px above, centred on white, a 130px "4 04" in Oswald (falling back to
 * sans-serif, as on live) in rgb(73,75,79) with the first 4 rotated 15deg, a 22px line
 * with 45px above and below, and a 184x37 button, white on rgb(137,137,137), 2px
 * radius, 20px below. */
#dm #error-container {
  padding: 120px 0 0;
  text-align: center;
  background-color: rgb(255, 255, 255);
}
#dm #error-container .four-o-four {
  font-family: Oswald, sans-serif;
  font-size: 130px;
  line-height: normal;
  color: rgb(73, 75, 79);
}
#dm #error-container .four-o-four .lean {
  display: inline-block;
  transform: rotate(15deg);
}
#dm #error-container .description {
  margin: 45px 0;
  font-size: 22px;
  line-height: normal;
  color: rgb(73, 75, 79);
}
#dm #error-container a.back-button {
  display: inline-block;
  box-sizing: border-box;
  min-width: 184px;
  height: 37px;
  margin: 0 0 20px;
  padding: 0 12px;
  border-radius: 2px;
  background-color: rgb(137, 137, 137);
  color: rgb(255, 255, 255) !important;
  font-size: 16px;
  line-height: 37px;
  text-decoration: none !important;
}

/* One <h1> on /blog-search (tools/review-fixes.py): "Search Results" was an <h2>, and
 * the theme prints an <h1> in capitals and, on the tablet band (which sizes by tag),
 * at 48px. It is held at the type it had — measured on live at 1440, 768 and 390:
 * mixed case, 32 / 36 / 26px, 1.2 line-height on tablet. */
#dm#dm .dmNewParagraph[id="1523391464"] h1.gy-h1,
#dm#dm .dmNewParagraph[id="1523391464"] h1.gy-h1 span {
  text-transform: none !important;
}
@media (min-width: 768px) and (max-width: 1024px) {
  #dm#dm .dmNewParagraph[id="1523391464"] h1.gy-h1,
  #dm#dm .dmNewParagraph[id="1523391464"] h1.gy-h1 span {
    font-size: 36px !important;
    line-height: 43.2px !important;
  }
}

/* Buttons whose label wrapped (review 2026-10-07; on live too). The "Other Services We
 * Offer" list on the nine service pages (and the same buttons on /services) is a column
 * of 115px pills on phones, so every label broke onto two or three lines and
 * "BACKFLOW RESTORATION" ran outside its outline; on tablets "PERMANENT OUTDOOR
 * LIGHTING" alone wrapped in its 282px pill. Each label now sits on one line: on
 * phones the pill takes the column's width (up to 320px) at its one-line height, and
 * the type steps down only as far as the longest label needs. */
#dm#dm a.dmButtonLink.flexButtonIcon[href$="-austin-tx"] .text {
  white-space: nowrap !important;
}
@media (min-width: 768px) and (max-width: 1024px) {
  /* 14px on a tablet (a 960px canvas, 282px pills); a narrowed desktop window in this
   * band has narrower pills, so the size follows the width below that. */
  #dm#dm a.dmButtonLink.flexButtonIcon[href$="-austin-tx"] .text {
    font-size: clamp(11px, 1.458vw, 14px) !important;
  }
}
/* /services: the eight jump buttons under the hero are the same pills (280px; 222px at
 * 1025 and 240px at 1100), and "PERMANENT OUTDOOR LIGHTING" wrapped at every width,
 * which also made its whole row of four 66px tall instead of 50. One line each; the
 * type is 13.5px where the pill is 280px and follows the pill down to 1025. */
#dm#dm a.dmButtonLink.flexButtonIcon[href^="/services#"] .text {
  white-space: nowrap !important;
  font-size: 13.5px !important;
}
@media (min-width: 1025px) {
  #dm#dm a.dmButtonLink.flexButtonIcon[href^="/services#"] .text {
    font-size: clamp(10.8px, calc(0.65vw + 4.1px), 13.5px) !important;
  }
}
@media (max-width: 767px) {
  #dm#dm .flex-element.widget-wrapper:has(> a.dmButtonLink.flexButtonIcon[href$="-austin-tx"]) {
    width: 100% !important;
    max-width: 320px !important;
    min-width: 0 !important;
    height: auto !important;
    min-height: 0 !important;
    align-self: center !important;
  }
  #dm#dm a.dmButtonLink.flexButtonIcon[href$="-austin-tx"] {
    width: 100% !important;
    height: 50px !important;
  }
  #dm#dm a.dmButtonLink.flexButtonIcon[href$="-austin-tx"] .text {
    font-size: clamp(13px, 4vw, 16px) !important;
  }
  /* Home page, landscape lighting band: "BOOK A LANDSCAPE LIGHTING INSTALLATION". */
  #dm#dm a.dmButtonLink.u_1334780529 .text {
    white-space: nowrap !important;
    font-size: clamp(11.5px, 3.6vw, 16px) !important;
  }
}

/* Header phone numbers, 1025-1199px (review 2026-10-07; on live too): the two
 * click-to-call lines sit in a 215-255px column there, and "Cypress: (832) 514-1032"
 * broke after "514-" (both lines broke at 1025). One line each, a size down. */
@media (min-width: 1025px) and (max-width: 1199px) {
  #dm#dm #flex-header a.dmButtonLink[href^="tel:"] .text {
    white-space: nowrap !important;
    font-size: 15px !important;
  }
}

/* Footer menu sub-menus on touch screens (runtime.js footerSubnav()): the same closed
 * state as the drawer's groups, and for the same reason — it has to outrank the
 * cascade's :hover opener, which a tap leaves stuck. An open group shows, whatever
 * :hover currently says. */
#flex-footer#flex-footer li.gy-fsub > .unifiednav__container_sub-nav {
  overflow: hidden;
  transition: max-height .3s ease, opacity .2s ease;
}
#flex-footer#flex-footer li.gy-fsub.gy-sub-closed > .unifiednav__container_sub-nav {
  max-height: 0 !important;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
  margin-top: 0 !important;
  margin-bottom: 0 !important;
  border-width: 0 !important;
  opacity: 0 !important;
  pointer-events: none !important;
  visibility: hidden;
}
#flex-footer#flex-footer li.gy-fsub:not(.gy-sub-closed) > .unifiednav__container_sub-nav {
  max-height: 200em;
  opacity: 1 !important;
  pointer-events: auto !important;
}
#flex-footer#flex-footer li.gy-fsub.gy-sub-closed > a .icon::before {
  transform: none !important;
}

/* Legal pages: the hero is /thank-you's, which is a full-screen band (250px above and
 * below its content at desktop, 801px tall) built for a two-line message and a button.
 * With only the page title in it that left far too much room above and below the
 * <h1> (review 2026-10-07). On the two legal pages the band hugs the title: the space
 * above clears the header (156 / 147 / 123px) with ~60px to spare, and ~60px below. */
body[data-page-alias="privacy-policy"] #dm [id="b9d9a3f5"],
body[data-page-alias="terms-and-conditions"] #dm [id="b9d9a3f5"] {
  min-height: 0 !important;
  padding-top: 216px !important;
  padding-bottom: 64px !important;
}
body[data-page-alias="privacy-policy"] #dm [id="1d70b90f"],
body[data-page-alias="terms-and-conditions"] #dm [id="1d70b90f"] {
  min-height: 0 !important;
  height: auto !important;
}
@media (min-width: 768px) and (max-width: 1024px) {
  body[data-page-alias="privacy-policy"] #dm [id="b9d9a3f5"],
  body[data-page-alias="terms-and-conditions"] #dm [id="b9d9a3f5"] {
    padding-top: 200px !important;
    padding-bottom: 56px !important;
  }
}
@media (max-width: 767px) {
  body[data-page-alias="privacy-policy"] #dm [id="b9d9a3f5"],
  body[data-page-alias="terms-and-conditions"] #dm [id="b9d9a3f5"] {
    padding-top: 160px !important;
    padding-bottom: 44px !important;
  }
}
