/* ============================================================
   The Laundry Hub SF: Astra header + footer chrome
   Matches design/mockups/hero-opt4.html. Astra Pro is NOT installed,
   so the sticky header is done here rather than via the sticky-header module.
   ============================================================ */

/* ---------- STICKY PRIMARY HEADER ---------- */
/* position:sticky can only travel inside its OWN parent's box. The primary row's
   parent .ast-main-header-wrap is exactly as tall as the row itself (77px), so a
   sticky rule on .ast-primary-header-bar had zero distance to travel and scrolled
   away with the page. Verified in Chrome: barTop went to -1339 at scrollY 1400.
   Pinning #masthead instead gives it #page as the containing block, which is the
   full document height. The negative top is the height of the navy utility bar,
   so that bar scrolls up out of view and the white primary row lands flush at 0,
   which is the behaviour the old rule was reaching for. */
.ast-primary-header-bar {
	background: var(--white, #fff);
	border-bottom: 1px solid var(--line, #dbe4ee);
}
/* Tony, 2026-08-26: both rows pin, not just the primary one. This used to sit at
   top: var(--lh-hdr-offset), a negative value equal to the utility bar's measured
   height, which slid the navy bar off the top and landed the white row flush at 0.
   top: 0 keeps the whole masthead on screen, so the address, hours, social icons
   and phone number stay reachable at any scroll depth.
   The functions.php script still publishes --lh-hdr-offset; it is read by
   --lh-hdr-total below rather than by this rule. */
#masthead {
	position: sticky;
	top: 0;
	z-index: 99;
	transition: box-shadow .2s ease;
}
.admin-bar #masthead { top: 32px; }
@media (max-width: 782px) { .admin-bar #masthead { top: 46px; } }
body.lh-scrolled #masthead { box-shadow: 0 3px 18px rgba(18, 63, 105, .09); }

/* Anchor jumps have to clear BOTH pinned rows now, not just the primary one.
   Desktop: 40 utility + 76 primary. Narrow phones: the utility bar wraps to two
   lines (55) over a 64px primary row. A few px of slack on each so a heading
   never lands tight against the bar. */
html { scroll-padding-top: 124px; }
@media (max-width: 921px) { html { scroll-padding-top: 124px; } } /* 2026-08-30: mobile header is 116px now (59 utility + 57 primary), was 122. */

/* both rows pin together as one block */
.ast-above-header-bar { position: relative; z-index: 100; }

/* ---------- THE NAVY UTILITY BAR ---------- */
.ast-above-header-bar {
	background: var(--navy, #123f69);
	color: #b9d0e6;
	font-size: 13.5px;
	line-height: 1.5;
}
/* `body` prefix is load-bearing. Elementor's kit stylesheet emits
   `.elementor-kit-8 a { color: ... }` at (0,1,1) and loads AFTER this file, so a
   bare `.ast-above-header-bar a` at the same specificity loses and the phone
   number renders dark-on-navy at 1.51:1. (0,1,2) keeps it white. */
body .ast-above-header-bar a { color: #fff; font-weight: 600; text-decoration: none; }
.ast-above-header-bar a:hover { color: var(--bright, #499be6); }
.ast-above-header-bar .ast-builder-html-element { line-height: 1.5; }
.ast-above-header-bar .site-header-above-section-left,
.ast-above-header-bar .site-header-above-section-right { min-height: 40px; }

.lh-top { display: flex; align-items: center; gap: 26px; flex-wrap: wrap; }
.lh-top--right { justify-content: flex-end; }

/* Brian, 2026-08-25: Instagram and Facebook in the utility bar, so both are
   visible before any scroll. Same two SVGs as the footer brand column, sized
   down and unboxed -- the footer's 38px tinted tiles would not fit a 40px bar.
   Colour comes from currentColor, so they inherit the bar's link white from
   `body .ast-above-header-bar a` above and the same hover blue as the phone. */
/* Masked, not inline SVG. Astra pushes the header HTML field through
   wp_kses_post(), which drops <svg> and <path> on output -- the markup survives
   in the option and renders as two empty anchors. Masking the same two marks
   from /img keeps them tinted by currentColor, so they still inherit the bar's
   white and the same hover blue as the phone number. */
.lh-top__social { display: inline-flex; align-items: center; gap: 14px; }
.lh-ic {
	display: inline-block;
	width: 16px;
	height: 16px;
	background-color: currentColor;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
	transition: background-color .18s;
}
.lh-ic--ig {
	-webkit-mask-image: url('img/icon-instagram.svg');
	mask-image: url('img/icon-instagram.svg');
}
.lh-ic--fb {
	-webkit-mask-image: url('img/icon-facebook.svg');
	mask-image: url('img/icon-facebook.svg');
}
.lh-stars { color: #f0a500; letter-spacing: 2px; }

/* ---------- PRIMARY ROW ---------- */
.ast-primary-header-bar .site-primary-header-wrap { min-height: 76px; }
/* Brian, 2026-08-25: the logo was rendering 190x32, a 5.94 ratio against the
   file's natural 4.76 (900x189), so it read as horizontally stretched. Astra
   sets the width from ast-header-responsive-logo-width; forcing a height here
   as well overrode the aspect ratio. Height is auto now, so the width control
   is the only dimension we set and the ratio stays native. */
.site-logo-img img { height: auto; }

/* Poppins is a wider face than the Encode Sans this row was drawn with. At the
   old 14.5px / 14.5px padding the eight items measured 750px, and logo + nav +
   CTA + the grid gaps overran the 1200px row, so the header wrapped to two lines
   and stood 152px tall instead of 76px. 13.5px with 11px padding brings the nav
   back to roughly 660px and the row back onto one line. */
.ast-primary-header-bar .main-header-menu > .menu-item > .menu-link {
	font-family: 'Poppins', system-ui, sans-serif;
	font-size: 13.5px;
	font-weight: 600;
	padding-left: 11px;
	padding-right: 11px;
	color: var(--navy, #123f69);
	white-space: nowrap;
}
.ast-primary-header-bar .main-header-menu > .menu-item > .menu-link:hover,
.ast-primary-header-bar .main-header-menu > .menu-item.current-menu-item > .menu-link {
	color: var(--bright, #499be6);
}

/* header CTA, same shape as the in-page .btn */
.ast-primary-header-bar .ast-custom-button {
	font-family: 'Poppins', system-ui, sans-serif;
	font-size: 15px;
	font-weight: 600;
	padding: 13px 22px;
	border-radius: 6px;
	/* --brand, not --bright: white on #499be6 is 2.95:1 and fails WCAG AA.
	   #2c5894 is 7.6:1 with almost no visual change. */
	background: var(--brand, #2c5894);
	color: #fff;
	border: 2px solid transparent;
	white-space: nowrap;
	transition: .18s;
}
.ast-primary-header-bar .ast-custom-button:hover { background: var(--navy, #123f69); color: #fff; }

/* ---------- MOBILE ---------- */
@media (max-width: 921px) {
	.ast-above-header-bar { font-size: 12.5px; }
	.lh-top { gap: 14px; justify-content: center; }
	.lh-top--right { justify-content: center; }
	.ast-primary-header-bar .site-primary-header-wrap { min-height: 64px; }
	.site-logo-img img { height: auto; }
}

/* ---------- FOOTER ---------- */
/* Same specificity leak as the headings below: `body.elementor-page a` from
   atomic-overrides.css ties `.site-footer a` at 0,1,1 and wins on load order,
   repainting every footer link the bright accent instead of the muted blue.
   Repeating the body class settles it at 0,2,1. */
.site-footer { background: var(--navy, #123f69); color: #9dc5ea; }
.site-footer a,
body.elementor-page .site-footer a { color: #9dc5ea; text-decoration: none; }
.site-footer a:hover,
body.elementor-page .site-footer a:hover { color: #fff; }

.ast-primary-footer-wrap { padding-block: clamp(44px, 5vw, 72px); }

/* atomic-overrides.css mirrors the ENTIRE design system behind `body.elementor-page`,
   and that prefix matches the footer and header too, not only the Elementor content.
   So `body.elementor-page h4 { color: var(--navy) }` (specificity 0,1,2) outranks a
   plain `.site-footer h4` (0,1,1) and painted every footer heading navy-on-navy --
   invisible against the navy footer. The old "The Store" address column had the same
   bug and simply looked like it had no heading. Repeating the body class here wins at
   0,2,2. Any future footer rule that fights the design system needs the same prefix. */
.site-footer h2,
.site-footer h3,
.site-footer h4,
.site-footer .widget-title,
body.elementor-page .site-footer h2,
body.elementor-page .site-footer h3,
body.elementor-page .site-footer h4,
body.elementor-page .site-footer .widget-title {
	font-family: 'Poppins', system-ui, sans-serif;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: #fff;
	margin: 0 0 16px;
}

/* Helena's footer gives the brand column extra width; Astra's "4-equal" preset does
   not. Matches the mockup's 1.4fr 1fr 1fr 1fr.
   Astra wins this with `.ast-builder-grid-row-4-equal .ast-builder-grid-row` (0,2,0),
   so the override needs three classes. Note the wrapper is .site-primary-footer-wrap,
   NOT .ast-primary-footer-wrap -- the latter matches nothing on this build. */
@media (min-width: 922px) {
	.site-primary-footer-wrap .ast-builder-grid-row.ast-builder-footer-grid-columns {
		grid-template-columns: 1.5fr 1fr 1fr 1.25fr;
	}
}

.lh-fcol { font-size: 14.5px; line-height: 1.9; }
.lh-fcol a,
.lh-fcol span { display: block; }
.lh-fcol .lh-ph { color: #6f8fb3; }

.lh-nap {
	text-align: center;
	font-size: 14px;
	color: #9dc5ea;
	padding: 20px 0 0;
	border-top: 1px solid rgba(255, 255, 255, .13);
}
.lh-nap a { color: #fff; font-weight: 600; }

/* ---------- FOOTER BRAND COLUMN (col 1) ---------- */
/* Mirrors the Helena Aesthetics footer: wordmark, one-line description, rating,
   social buttons. The logo is the white recolour -- the navy original disappears
   on this background. */
.lh-brand__logo {
	height: 34px;
	width: auto;
	display: block;
	margin-bottom: 18px;
}
.lh-brand p { font-size: 14.5px; line-height: 1.75; margin: 0 0 12px; }
.lh-brand .lh-stars { color: #f0a500; letter-spacing: 2px; }

.lh-social { display: flex; gap: 10px; margin-top: 20px; }
.lh-social a {
	display: grid;
	place-items: center;
	width: 38px;
	height: 38px;
	border-radius: 9px;
	background: rgba(255, 255, 255, .10);
	color: #fff;
	transition: background .18s;
}
.lh-social a:hover { background: rgba(255, 255, 255, .22); }
.lh-social svg { width: 18px; height: 18px; }

/* ---------- BELOW BAR ---------- */
/* Tony asked for the legal links centred. Astra lays the below row out as flex
   columns, so a single centred column needs the wrap forced to centre too --
   otherwise below_1 hugs the left edge regardless of text-align. */
.ast-below-footer-wrap {
	background: #0d2135;
	font-size: 13px;
	color: #7f9dbd;
	text-align: center;
}
.ast-below-footer-wrap .ast-builder-grid-row {
	justify-content: center;
	grid-template-columns: 1fr;
}
.ast-below-footer-wrap .site-footer-section { justify-content: center; }
.ast-below-footer-wrap .ast-footer-copyright { text-align: center; width: 100%; }
.ast-below-footer-wrap .ast-footer-copyright p { margin: 0; }

.lh-legal { margin: 8px 0 0; text-align: center; }
.lh-legal a { color: #9dc5ea; }
.lh-legal a:hover { color: #fff; }

/* ---------- SECTION 3, SERVICE CARDS ---------- */
/* Reference: home-painting-04 "Our Services", supplied by Tony 2026-08-12.
   Three things it needs that the Elementor panel has no control for:

   1. the link sitting on a shared baseline across cards of unequal copy
      (margin-top:auto -- the margin control takes numbers, not "auto"),
   2. the stagger. Doing it with margin-top would make each staggered card
      SHORTER than its neighbour, which breaks Tony's "exactly the same
      height". A transform costs no layout, so heights stay identical,
   3. the badge riding on the photo instead of in the card flow, which is what
      keeps card 1's headline level with the other three.

   The photo breaking out above the card's top edge is NOT here: that is a
   negative top margin, which the panel does expose, so it stays editable.

   Everything is scoped to .svc-grid, a class set on the row in Elementor, so
   none of it can reach page 9. */
.svc-grid,
.svc-grid .svc-card { overflow: visible; }
.svc-grid .svc-card { position: relative; }
.svc-grid .svc-link { margin-top: auto; }

.svc-grid .svc-badge {
	position: absolute;
	top: -26px;
	left: 18px;
	z-index: 2;
	margin: 0;
	width: auto;
}

/* The zigzag stagger was removed 2026-08-12 at Tony's instruction: "make the
   service cards uniform instead of zigzagging". All four cards now sit on one
   top line and one bottom line. The equal-height and shared-link-baseline rules
   above are what make that read as deliberate rather than as four cards that
   happen to be the same length, so they stay. */

@media (max-width: 1024px) {
	.svc-grid .svc-badge { top: -22px; }
}

/* The icon-band variant of the service card, added 2026-08-30.

   The Commercial and Drop-Off pages clone this card but swap the photo for a
   navy band holding a white icon. The clone dropped the photo widget's
   margin-top:-38px, so the band sat flush against the card's top border and its
   10px corners collided with the card's 12px corners. Tony: "the icon is not
   overflowing, just like the homepage".

   The homepage keeps its -38px in the Elementor panel, per the note above. This
   one cannot: the band is a container whose element id drifts per page
   (dodoband0 / vband0 / m33dodoband0), and there are 72 of them across 18 pages.
   The card's .svc-card class is stable everywhere, and on the icon pages the
   band is the card's first child CONTAINER while the homepage's first child is a
   WIDGET, so this selector reaches all 72 bands and cannot touch the homepage.
   Verified at ten widths from 390 to 1440: 4 hits per icon page, 0 on home.

   The min-height matches the band to the homepage photo's 172px. Elementor
   already sets 172px from 768 up and 150px below it, so only mobile is
   overridden here. */
.svc-grid .svc-card > .e-con:first-child {
	margin-top: -38px;
}

@media (max-width: 767px) {
	.svc-grid .svc-card > .e-con:first-child { min-height: 172px; }
}

/* ---------- SECTION 10, SERVICE AREA ROWS ---------- */
/* Reference: the "Perth Services" three-up link grid Tony sent 2026-08-12. Its
   move is the label hard left and the chevron hard right, with a hairline under
   every row.

   The hairline is NOT here: Elementor's icon-list exposes a Divider control, so
   it stays in the panel. The only thing this adds is the one part no icon-list
   control can express, which is putting the icon AFTER the label and pushing
   the two apart. row-reverse plus space-between does it: in row-reverse the
   main axis starts on the right, so the icon (first in the DOM) lands right and
   the text lands left.

   Elementor wraps linked rows in an <a> and unlinked ones in a <span>, so both
   have to be targeted or a row without a link collapses back to inline. */
.area-rows .elementor-icon-list-item > a,
.area-rows .elementor-icon-list-item > span {
	display: flex;
	flex-direction: row-reverse;
	justify-content: space-between;
	align-items: center;
	width: 100%;
	padding: 15px 2px;
}
.area-rows .elementor-icon-list-icon { flex: 0 0 auto; }
.area-rows .elementor-icon-list-text { flex: 1 1 auto; }

/* Elementor's Divider draws on :not(:last-child), so the bottom row of each
   column came out unruled. The reference rules every row, and with columns of
   3/3/2 the missing lines read as an accident rather than a choice.
   NOTE: this colour has to track the widget's Divider colour in the panel.
   They are the same hairline (lhline #DBE4EE); change both together. */
.area-rows .elementor-icon-list-item:last-child::after {
	content: '';
	display: block;
	border-top: 1px solid #DBE4EE;
	width: 100%;
}

/* ---------- $20 OFF TAG, THE TILT ---------- */
/* Elementor 4.2.2 writes `--e-con-transform-rotateZ: -7deg` onto the container
   from the Advanced > Transform panel, but ships NO rule that consumes it for
   containers. A scan of every stylesheet on the page found zero rules
   referencing `e-con-transform`, so the tag rendered dead flat with
   `transform: none` however the panel was set. This is Elementor's gap, not a
   bad setting.

   The angle stays a panel control. This only supplies the plumbing, reading
   Elementor's own variable, so changing the rotation in the editor still works
   and nothing is hardcoded here. Scoped to page 328 so it cannot reach page 9.
   Re-test after any Elementor update: if they ship the rule, this becomes a
   harmless duplicate, but a differing default would fight it. */
.elementor-328 .elementor-element-b3246fc {
	transform: rotateZ(var(--e-con-transform-rotateZ, 0deg));
}

/* =========================================================
   FAQ GRID, page /faqs/ only
   Two-column card accordion. Native Elementor accordion controls
   cannot set an ACTIVE-state title background, which is the whole
   visual signature of this component, so the open-state fill lives
   here. Everything else (typography, colours, spacing) is set on the
   widget in Elementor. Scoped to .lh-faqcol so the deep-band
   accordions on 363 / 433 / 435 / 466 / 479 are untouched.
   ========================================================= */
.lh-faqcol .elementor-accordion { border: 0; }
.lh-faqcol .elementor-accordion .elementor-accordion-item {
  border: 1px solid #DBE4EE;
  border-radius: 12px;
  overflow: hidden;
  margin-bottom: 14px;
  background: #FFFFFF;
}
.lh-faqcol .elementor-accordion .elementor-accordion-item:last-child { margin-bottom: 0; }
.lh-faqcol .elementor-accordion .elementor-tab-title {
  padding: 17px 22px;
  border: 0;
  background: #FFFFFF;
  transition: background .18s ease;
}
.lh-faqcol .elementor-accordion .elementor-tab-title:hover { background: #F6FAFD; }
.lh-faqcol .elementor-accordion .elementor-tab-title.elementor-active,
.lh-faqcol .elementor-accordion .elementor-tab-title.elementor-active:hover { background: #123F69; }
.lh-faqcol .elementor-accordion .elementor-tab-title.elementor-active .elementor-accordion-title,
.lh-faqcol .elementor-accordion .elementor-tab-title.elementor-active a { color: #FFFFFF; }
.lh-faqcol .elementor-accordion .elementor-tab-title.elementor-active .elementor-accordion-icon,
.lh-faqcol .elementor-accordion .elementor-tab-title.elementor-active .elementor-accordion-icon i,
.lh-faqcol .elementor-accordion .elementor-tab-title.elementor-active .elementor-accordion-icon svg { color: #9DC5EA; fill: #9DC5EA; }
.lh-faqcol .elementor-accordion .elementor-tab-content {
  background: #123F69;
  color: #CFE0EE;
  border: 0;
  padding: 0 22px 22px;
}
.lh-faqcol .elementor-accordion .elementor-tab-content p { margin: 0; }
@media (max-width: 767px) {
  .lh-faqcol .elementor-accordion .elementor-tab-title { padding: 15px 18px; }
  .lh-faqcol .elementor-accordion .elementor-tab-content { padding: 0 18px 18px; }
}

/* =========================================================
   lh-navdrop: primary nav flyouts
   SERVICES opens a two-panel flyout. Left rail is the locations,
   hovering one opens that location's service list flush to the
   right, aligned to the TOP of the panel rather than to the
   hovered row. AREAS WE SERVE opens a three-column list.
   Astra Pro is NOT installed, so there is no native mega menu.
   Everything reverts to a plain stacked list below 921px.
   ========================================================= */
.ast-primary-header-bar .main-header-menu .sub-menu {
  padding: 8px 0;
  border: 1px solid #DBE4EE;
  border-top: 3px solid #2C5894;
  box-shadow: 0 18px 44px rgba(18, 63, 105, .14);
  background: #FFFFFF;
}
.ast-primary-header-bar .main-header-menu .sub-menu .menu-link {
  font-size: 15px;
  font-weight: 500;
  color: #123F69;
  padding: 10px 22px;
  line-height: 1.4;
}
.ast-primary-header-bar .main-header-menu .sub-menu .menu-item:hover > .menu-link {
  background: #EEF4FA;
  color: #2C5894;
}
@media (min-width: 922px) {
  /* SERVICES, two panels */
  .ast-primary-header-bar .main-header-menu .menu-item-12 > .sub-menu {
    width: 236px;
    background: #F4F7FB;
    border-radius: 0 0 0 10px;
  }
  .ast-primary-header-bar .main-header-menu .menu-item-12 > .sub-menu > .menu-item { position: static; }
  .ast-primary-header-bar .main-header-menu .menu-item-12 > .sub-menu > .menu-item > .menu-link {
    font-weight: 600;
  }
  .ast-primary-header-bar .main-header-menu .menu-item-12 > .sub-menu > .menu-item:hover > .menu-link {
    background: #FFFFFF;
    color: #2C5894;
  }
  /* lh-flyout-chevron: every location row shows the affordance, not
     only the hovered one. Astra's own toggle is hidden to avoid two. */
  .ast-primary-header-bar .main-header-menu .menu-item-12 > .sub-menu > .menu-item-has-children > .menu-link {
    display: flex;
    align-items: center;
  }
  .ast-primary-header-bar .main-header-menu .menu-item-12 > .sub-menu > .menu-item-has-children > .menu-link .dropdown-menu-toggle,
  .ast-primary-header-bar .main-header-menu .menu-item-12 > .sub-menu > .menu-item-has-children > .menu-link .ast-icon {
    display: none;
  }
  .ast-primary-header-bar .main-header-menu .menu-item-12 > .sub-menu > .menu-item-has-children > .ast-menu-toggle { display: none; }
  .ast-primary-header-bar .main-header-menu .menu-item-12 > .sub-menu > .menu-item-has-children > .menu-link::after {
    content: "\203A";
    margin-left: auto;
    padding-left: 12px;
    font-size: 19px;
    line-height: 1;
    color: #8FA6BC;
  }
  .ast-primary-header-bar .main-header-menu .menu-item-12 > .sub-menu > .menu-item-has-children:hover > .menu-link::after { color: #2C5894; }
  .ast-primary-header-bar .main-header-menu .menu-item-12 > .sub-menu > .menu-item > .sub-menu {
    position: absolute;
    left: 236px;
    top: -3px;
    width: 282px;
    min-height: calc(100% + 3px);
    margin: 0;
    border-left: 1px solid #DBE4EE;
    border-radius: 0 0 10px 0;
  }
  /* AREAS WE SERVE, three columns filled top to bottom */
  .ast-primary-header-bar .main-header-menu .menu-item-14 > .sub-menu {
    display: grid;
    grid-template-columns: repeat(3, minmax(184px, 1fr));
    grid-template-rows: repeat(7, auto);
    grid-auto-flow: column;
    width: auto;
    padding: 14px 6px 12px;
    border-radius: 0 0 10px 10px;
  }
  .ast-primary-header-bar .main-header-menu .menu-item-14 > .sub-menu > .menu-item { width: 100%; }
  .ast-primary-header-bar .main-header-menu .menu-item-14 > .sub-menu > .lh-seeall {
    grid-row: 8;
    grid-column: 1 / -1;
    margin-top: 8px;
    padding-top: 6px;
    border-top: 1px solid #DBE4EE;
  }
  .ast-primary-header-bar .main-header-menu .menu-item-14 > .sub-menu > .lh-seeall > .menu-link {
    color: #2C5894;
    font-weight: 600;
  }
}

/* =========================================================
   lh-linklist: three-column link list
   Label left, chevron right, hairline under each row. Used for the
   services block and the extra service-area columns on 435, and
   reusable on /services/ and every location page.
   Elementor's icon-list puts its icon on the left with no control
   to move it, so the row is flipped here.
   ========================================================= */
.lh-linklist .elementor-icon-list-items { width: 100%; }
.lh-linklist .elementor-icon-list-item { border-bottom: 1px solid #DBE4EE; }
.lh-linklist .elementor-icon-list-item > a,
.lh-linklist .elementor-icon-list-item > a:hover { text-decoration: none; }
.lh-linklist .elementor-icon-list-item > a {
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 15px 2px;
  transition: color .16s ease;
}
.lh-linklist .elementor-icon-list-icon { margin: 0 0 0 12px; }
.lh-linklist .elementor-icon-list-icon i { font-size: 13px; }
.lh-linklist .elementor-icon-list-text { padding-left: 0; }
.lh-linklist .elementor-icon-list-item:hover > a .elementor-icon-list-text,
.lh-linklist .elementor-icon-list-item:hover > a .elementor-icon-list-icon i { color: #2C5894; }
@media (max-width: 767px) {
  .lh-linklist .elementor-icon-list-item > a { padding: 13px 2px; }
}

/* Neighborhood cards on 435: the body fills the card so the link
   button sits on one baseline across a row whatever the blurb length.
   _css_classes does not apply to inner containers, so these are
   targeted by Elementor's own element ids. */
.e-con.elementor-element.elementor-element-hood0-b,
.e-con.elementor-element.elementor-element-hood1-b,
.e-con.elementor-element.elementor-element-hood2-b,
.e-con.elementor-element.elementor-element-hood3-b,
.e-con.elementor-element.elementor-element-hood4-b,
.e-con.elementor-element.elementor-element-hood5-b,
.e-con.elementor-element.elementor-element-hood6-b,
.e-con.elementor-element.elementor-element-hood7-b {
  --flex-grow: 1;
  flex-grow: 1 !important;
}


/* =========================================================
   lh-fab: floating action button, bottom right
   Two destinations behind one control: the Cents booking flow for
   consumers, the commercial quote form for businesses. Built in the
   child theme rather than as an Elementor global widget so it renders
   on every template including the blog, search and 404, and so the
   markup stays out of all 80-odd page document trees.

   Colour rules are written with TWO classes on purpose. Elementor's kit
   emits `.elementor-kit-8 a { color: ... }` at (0,1,1) and loads AFTER
   chrome.css, so a single-class `.lh-fab-opt` would tie and lose on
   load order, exactly the leak documented on the footer links above.
   ========================================================= */
.lh-fab {
	position: fixed;
	right: 24px;
	bottom: 24px;
	bottom: calc(24px + env(safe-area-inset-bottom));
	z-index: 120;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 12px;
}
.lh-fab .lh-fab-btn {
	width: 60px;
	height: 60px;
	border: 0;
	padding: 0;
	border-radius: 50%;
	background: var(--navy, #123f69);
	color: #fff;
	cursor: pointer;
	box-shadow: 0 10px 28px rgba(13, 33, 53, .32);
	display: grid;
	place-items: center;
	transition: background .2s ease;
}
.lh-fab .lh-fab-btn:hover { background: #0d2f50; }
.lh-fab .lh-fab-btn:focus-visible { outline: 3px solid #f2a03d; outline-offset: 3px; }
.lh-fab .lh-fab-btn svg { width: 24px; height: 24px; fill: currentColor; transition: transform .2s ease; }
.lh-fab.is-open .lh-fab-btn svg { transform: rotate(45deg); }

.lh-fab .lh-fab-menu { display: flex; flex-direction: column; gap: 10px; align-items: flex-end; }
.lh-fab .lh-fab-menu[hidden] { display: none; }
.lh-fab .lh-fab-opt {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	padding: 13px 20px;
	border-radius: 999px;
	background: #fff;
	color: var(--navy, #123f69);
	font-weight: 600;
	font-size: 15px;
	line-height: 1;
	text-decoration: none;
	white-space: nowrap;
	box-shadow: 0 8px 22px rgba(13, 33, 53, .22);
	animation: lh-fab-in .18s ease both;
	/* 44px is the minimum comfortable tap target. Padding plus a 1.0 line-height
	   landed at 41px on phones and 43px on tablets, so the height is set here
	   rather than left to fall out of the font size. */
	min-height: 46px;
}
.lh-fab .lh-fab-opt:hover,
.lh-fab .lh-fab-opt:focus { background: var(--navy, #123f69); color: #fff; }
.lh-fab .lh-fab-opt svg { width: 17px; height: 17px; fill: currentColor; flex: none; }
.lh-fab .lh-fab-opt + .lh-fab-opt { animation-delay: .05s; }
@keyframes lh-fab-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

@media (max-width: 480px) {
	.lh-fab { right: 16px; bottom: calc(16px + env(safe-area-inset-bottom)); }
	.lh-fab .lh-fab-opt { font-size: 14.5px; padding: 12px 18px; }
}
@media (prefers-reduced-motion: reduce) {
	.lh-fab .lh-fab-btn, .lh-fab .lh-fab-btn svg, .lh-fab .lh-fab-opt { transition: none; animation: none; }
}

/* Astra's Scroll to Top ships bottom-right, the corner the FAB now owns. */
#ast-scroll-top.ast-scroll-to-top-right { right: auto; left: 24px; }
@media (max-width: 480px) { #ast-scroll-top.ast-scroll-to-top-right { left: 16px; } }

/* ---------- FOOTER MAP (col 4) ---------- */
/* Hybrid satellite, so the imagery matches the reference Tony supplied while the
   street labels stay readable at 190px. output=embed needs no Maps API key.
   line-height:0 on the wrapper kills the inline-descender gap under the iframe,
   which otherwise shows as a 4px navy sliver below the rounded corner. */
.lh-fmap {
	margin-top: 18px;
	border-radius: 10px;
	overflow: hidden;
	line-height: 0;
	border: 1px solid rgba(255, 255, 255, .14);
}
.lh-fmap iframe { display: block; width: 100%; height: 190px; border: 0; }

/* ---------- BELOW BAR NAV ---------- */
/* About / FAQs / Contact / Business quote used to be tacked onto the bottom of
   the address column, which made column 4 read as two unrelated blocks. They are
   utility links, so they belong with the legal row. */
.lh-belowbar .lh-fnav {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 6px 22px;
	margin: 0 0 12px;
	font-size: 14.5px;
}
.lh-belowbar .lh-fnav a { color: #9dc5ea; }
.lh-belowbar .lh-fnav a:hover { color: #fff; }

/* ---------- FOOTER GUTTERS BELOW DESKTOP ---------- */
/* Astra only applies the container gutter to the footer at desktop width. Below
   921px every column ran flush to x=0, so the brand copy, the link lists and the
   map all touched the screen edge. Measured: brand text x=0 at 390, 768 and 900,
   against 120 at 1440. */
@media (max-width: 1240px) {
	.site-primary-footer-wrap .ast-builder-grid-row,
	.site-below-footer-wrap .ast-builder-grid-row {
		padding-left: 24px;
		padding-right: 24px;
	}
}
/* Tony, 2026-08-30: the drop-off note replaces the review count in the utility bar.
   At 1200px and below the bar has no room for the full sentence and the phone number
   wrapped to a second line, taking the pinned header from 40px to 71px. Below that
   width only the first clause shows; the full detail is on the drop-off page. */
@media (max-width: 1199px) { .lh-top__more { display: none; } }

/* Tony, 2026-08-30: mobile utility bar. Was address + hours + social wrapping into
   two ragged rows with zero vertical padding, so the address sat flush against the top
   of the screen, and no drop-off information anywhere on mobile. Now two deliberate
   rows: full NAP on one, the booking rule plus social on the next.
   Hours come off the MOBILE bar only. They stay above the fold in the hero, in the
   footer and on the contact page. Desktop keeps hours and carries its own drop-off
   note in header-html-2, which Astra places in the desktop zone only. */
.lh-top__drop { display: none; }
@media (max-width: 921px) {
	.lh-top { padding: 6px 0; row-gap: 6px; align-items: center; }
	.lh-top__hours { display: none; }
	.lh-top__drop { display: inline; }
	.ast-primary-header-bar .site-primary-header-wrap { min-height: 56px; }
}

/* The 56px min-height above cannot bind on its own: .site-branding carries
   padding 17px top and bottom around a 32px logo, so the bar measures 66px of
   content. Trim the padding to 12px and the bar lands on 56px. Tap target on the
   menu toggle stays 46px. */
@media (max-width: 921px) {
	.ast-primary-header-bar .site-branding.ast-site-identity { padding-top: 12px; padding-bottom: 12px; }
}
