@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');

/* ============================================================================
 * Urban Clean - child template custom.css
 *
 * Emptied 2026-08-13: previous contents were the AXM Law design system this
 * build was cloned from. Archived server-side as axm-custom-css-20260813-031851.css.
 *
 * The @import MUST stay the first rule - CSS ignores @import if anything
 * precedes it.
 *
 * SCOPE RULE: this file carries DECORATION only, never tokens. Colours, fonts,
 * type sizes and spacing live in the YOOtheme Customizer so the client's team
 * can change them without touching CSS.
 *
 * The one standing exception is anything that has to override an ALREADY
 * COMPILED value in theme.12.css. YOOtheme compiles LESS in the browser only,
 * so a Customizer variable cannot be changed over SSH; until someone opens the
 * Customizer and saves, an override has to live here to take effect. Those
 * rules are marked "compiled-LESS override" and should be folded back into the
 * Customizer (and deleted here) at the next browser session.
 *
 * Cache: YOOtheme versions this file by TEMPLATE version (?5.0.23), not mtime,
 * and the server sent max-age=604800, which hid every edit for a week. An
 * .htaccess block now forces revalidation - see .htaccess on the server.
 * ========================================================================= */

:root {
    --uc-navy: #003776;
    --uc-deep: #00234E;
    --uc-blue: #0B62B0;
    --uc-teal: #64BFA2;
    --uc-wash: #EEF4FA;
    --uc-card: #F8FAFD;
    --uc-line: #E4EAF2;
    --uc-body: #33445B;
    --uc-muted: #5A6B82;
    /* Mockup value was #7A8AA0, which measures 3.52:1 on white and fails AA
       for the small labels it is used on (eyebrow text, testimonial roles).
       Darkened to the nearest tone that clears 4.5:1; visually near-identical. */
    --uc-quiet: #66768D;
}

/* --- shared geometry ----------------------------------------------------- */
/* Mockup: pill 99px on every button/badge, 14px cards, 20px panels, 16px imagery. */
.uk-button:not(.uk-button-text) { border-radius: 99px; font-weight: 600; }
.uk-card { border-radius: 14px; }
.uc-hero-image img { border-radius: 16px; }

/* ==========================================================================
 * HEADER
 * ====================================================================== */

/* compiled-LESS override.
 * theme.12.css treats the navbar as an INVERSE (dark-ground) container, a
 * leftover from the AXM Law header this build was cloned from. Its rule
 *   .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li > a
 * paints every link rgba(255,255,255,.4), so on Urban Clean's white navbar the
 * entire menu was invisible. The staged @navbar-nav-item-color is correct but
 * loses on specificity, hence the override rather than a Customizer change.
 * Fold back in by setting the navbar colour mode to default in the Customizer.
 */
.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li > a {
    color: var(--uc-navy);
}
.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li > a:hover,
.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li > a:focus,
.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li.uk-active > a {
    color: var(--uc-blue);
}
/* Same inverse leak on the dropdown panels and the logo link. */
.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-dropdown-nav > li > a {
    color: var(--uc-navy);
}
.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-dropdown-nav > li > a:hover,
.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-dropdown-nav > li > a:focus,
.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-dropdown-nav > li.uk-active > a {
    color: var(--uc-blue);
}

/* THE HAMBURGER. Same inverse leak again, and the reason it read as "missing"
   on tablet and mobile: the toggle was painted rgba(255,255,255,.4) on a white
   navbar. It was always there and always 44x44 - a DOM check finds it and can
   even click it, which is why the earlier sweeps passed. Only looking at the
   rendered header shows it. */
.uk-navbar-toggle,
.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-toggle {
    color: var(--uc-navy);
}
.uk-navbar-toggle:hover,
.uk-navbar-toggle:focus,
.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-toggle:hover {
    color: var(--uc-blue);
}

/* The dropdown panel had no separation from the page behind it. */
.uk-navbar-dropdown {
    box-shadow: 0 18px 44px rgba(0, 35, 78, .13);
    border: 1px solid var(--uc-line);
    border-radius: 12px;
}

.tm-header .uk-navbar-container { background: #fff; border-bottom: 1px solid var(--uc-line); }
.tm-header .uk-navbar-nav > li > a { font-weight: 500; }

/* Logo. The mockup draws it at 64px; asked to run larger than that on the real
   site. Set here rather than in the Customizer because logo.image_height has
   already been cleared once by a Customizer save. */
.tm-header .uk-logo img,
.tm-header .uk-navbar-item img { height: 78px; width: auto; }
/* Tablet and phone. The mobile navbar is 64px by default, so the bar has to
   grow with the logo or it clips. */
.tm-header-mobile .uk-logo img { height: 64px; width: auto; }
.tm-header-mobile .uk-navbar-container,
.tm-header-mobile .uk-navbar-left,
.tm-header-mobile .uk-navbar-right { min-height: 80px; }

/* The mockup runs the nav hard against the right edge, level with the logo on
   the left. uk-container-expand keeps a wide gutter at xlarge, which left a
   ~130px hole after the CTA, so the header container is pulled back to the
   mockup's 48px inset. */
.tm-header .uk-navbar-container > .uk-container,
.tm-toolbar > .uk-container {
    padding-left: 48px;
    padding-right: 48px;
}
.tm-header .uk-navbar-right { margin-left: auto; }

/* Parent items get a caret, as in the mockup. Pure CSS so it follows whatever
   the client nests under a menu item later. */
.tm-header .uk-navbar-nav > li.uk-parent > a::after {
    content: '';
    width: 0;
    height: 0;
    margin-left: 7px;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid currentColor;
    opacity: .75;
}

/* The mockup's nav has no Home item; the logo is the home link. Home stays in
   mainmenu because it is Joomla's default menu item and moving it re-routes
   every SEF URL. Delete this rule to put Home back in the bar. */
.tm-header .uk-navbar-nav > li.item-101 { display: none; }

/* Franchise Opportunities is a pill button, not a nav link. The class comes
   from the menu item's own "Link CSS Style" field, so the client can move or
   rename the item without touching CSS.

   The pill has to be centred against the other nav items by its PARENT <li>,
   not by align-self on the anchor. The <li> is the flex item of .uk-navbar-nav
   and stretches to the 64px row, but it is display:list-item, so an anchor
   inside it has no flex context and align-self is inert: the pill sat flush to
   the top of the row, 13px above the menu's centre line. */
.uk-navbar-nav > li:has(> a.uc-nav-cta) {
    display: flex;
    align-items: center;
}
.uk-navbar-nav > li > a.uc-nav-cta,
.uk-nav > li > a.uc-nav-cta {
    border: 1.5px solid var(--uc-teal);
    background: #EDF8F4;
    color: var(--uc-navy);
    border-radius: 99px;
    padding: 8px 16px;
    font-weight: 600;
    min-height: 0;
    height: auto;
    line-height: 1.4;
    align-self: center;
    margin-left: 10px;
}
.uk-navbar-nav > li > a.uc-nav-cta:hover { background: #DFF2EA; color: var(--uc-navy); }

/* --- utility bar --------------------------------------------------------- */
/* Navy strip above the header: phone, client portal, quote CTA. */
.tm-toolbar {
    background: var(--uc-navy);
    color: #fff;
    font-size: 12.5px;
    min-height: 0;
    padding: 7px 0;
}
.tm-toolbar a { color: #fff; text-decoration: none; }
.tm-toolbar .uc-util { display: flex; align-items: center; gap: 26px; }
.tm-toolbar .uc-util-phone { font-weight: 600; display: inline-flex; align-items: center; gap: 7px; }
.tm-toolbar .uc-util-portal { color: #CFE0F4; }
.tm-toolbar .uc-util-portal:hover { color: #fff; }
.tm-toolbar .uc-util-quote {
    background: var(--uc-blue);
    padding: 4px 14px;
    border-radius: 99px;
    font-weight: 600;
}
.tm-toolbar .uc-util-quote:hover { background: #0A559B; }

/* ==========================================================================
 * MOCKUP GEOMETRY
 * Measured off website-build/mockup/index.html at 1360px with
 * build/scripts/measure.mjs. The theme's own defaults are close but not equal,
 * and the drift compounds down the page, so the mockup's actual numbers are
 * set here rather than approximated.
 * ====================================================================== */

/* The theme's base body weight is 300. The mockup is 400 throughout, which is
 * why every paragraph on the build read lighter and thinner than the design.
 * This was the single biggest source of "close but not right".
 */
body,
p, li, .uk-card-body, .uk-panel {
    font-weight: 400;
}

/* Page gutter. Every band sat 8px wider than the mockup on both sides, because
 * uk-container pads 40px at this breakpoint where the mockup uses 48px. This
 * is the one value that shifts the alignment of the entire page, so it is set
 * once here rather than per section. Content column becomes 48..1312 at
 * 1360px, matching the mockup's 1264px inner width exactly.
 */
/* Desktop only. The mockup is a desktop-width document, and applying its 48px
 * gutter at every breakpoint squeezed a 375px phone to 279px of content.
 * UIkit's own smaller mobile padding is correct below this. */
@media (min-width: 960px) {
    .uk-container { padding-left: 48px; padding-right: 48px; }
}

/* Section padding. The mockup varies it per section; the build had a flat 70px
 * from uk-section-default, which is why band heights drifted. */
.uc-hero { padding-top: 64px; padding-bottom: 56px; }
.uc-trust { padding-top: 22px; padding-bottom: 22px; }
.uc-problem { padding-top: 72px; padding-bottom: 72px; }
.uc-janiflow { padding-top: 76px; }
.uc-services { padding-top: 56px; padding-bottom: 72px; }
.uc-steps { padding-top: 72px; padding-bottom: 72px; }
.uc-testimonials { padding-top: 72px; padding-bottom: 72px; }
.uc-locations { padding-top: 64px; padding-bottom: 64px; }
.uc-franchise-band { padding-top: 64px; padding-bottom: 72px; }
.uc-news { padding-top: 64px; padding-bottom: 64px; }
.uc-close { padding-top: 64px; }

/* Grid gutters. UIkit's default gutter is 40px at this breakpoint; the mockup
 * uses a tighter, per-section value. UIkit builds a gutter from a negative
 * margin on the row, matching left padding on each cell, and a top margin on
 * wrapped rows, so all three are set together. Overriding display to `grid`
 * instead does NOT work: the cells carry uk-width-1-4@m percentages, which
 * collapse to ~150px auto-sized tracks and double the section height.
 */
.uc-problem .uk-grid  { margin-left: -28px; }
.uc-problem .uk-grid > *  { padding-left: 28px; }
.uc-problem .uk-grid > .uk-grid-margin  { margin-top: 28px; }

.uc-services .uk-grid { margin-left: -20px; }
.uc-services .uk-grid > * { padding-left: 20px; }
.uc-services .uk-grid > .uk-grid-margin { margin-top: 20px; }

.uc-news .uk-grid { margin-left: -24px; }
.uc-news .uk-grid > * { padding-left: 24px; }
.uc-news .uk-grid > .uk-grid-margin { margin-top: 24px; }

.uc-close .uk-grid { margin-left: -26px; }
.uc-close .uk-grid > * { padding-left: 26px; }
.uc-close .uk-grid > .uk-grid-margin { margin-top: 26px; }

/* Locations is a two-up with no gutter in the mockup: the pill box takes the
   full right half (640px). UIkit's 40px gutter left it 604px, which fits five
   pills per row instead of six. */
.uc-locations .uk-grid { margin-left: 0; }
.uc-locations .uk-grid > * { padding-left: 0; }

.uc-testimonials .uk-slider-items { margin-left: -24px; }
.uc-testimonials .uk-slider-items > * { padding-left: 24px; }

/* Text buttons are links, not buttons. The shared .uk-button rule above gives
 * every button 13px of vertical padding for the solid CTAs, which was also
 * inflating every "Learn more" and "All articles" link to a 44px block. */
.uk-button-text {
    padding: 0;
    min-height: 0;
    line-height: 1.4;
}

/* YOOtheme separates every element inside a panel with a uniform 20px
 * uk-margin-top. The mockup uses a tighter, deliberate rhythm inside the
 * cards: 12px under the icon, 6px under the title, 10px above the link.
 *
 * !important is required, not sloppiness: UIkit's spacing utilities are
 * themselves declared !important, so no amount of specificity beats them.
 */
.uc-service-card .el-title { margin-top: 0 !important; }
.uc-service-card .el-content { margin-top: 6px !important; }
.uc-service-card > .uk-margin-top:last-child { margin-top: 10px !important; }
.uc-problem-card .el-content { margin-top: 10px !important; }
.uc-trust-slider .el-title { margin-top: 0 !important; }

/* Heading scale. The mockup does not use one h2 size throughout: the three
 * lead sections run 38px, locations and news drop to 30px, and the franchise
 * band sits at 34px. The build had them all on the theme's h2/h3 defaults.
 */
.uc-locations h2 { font-size: 30px; }
.uc-news h2 { font-size: 30px; }
.uc-franchise-band h2 { font-size: 34px; }
.uc-close .uc-door h2 { font-size: 27px; }

/* Body copy sizes, per the mockup, rather than the theme's uniform 16px. */
.uc-problem-card p { font-size: 15px; line-height: 1.6; }
.uc-problem-card p.uc-proof { font-size: 12.5px; }
.uc-testimonials .uc-section-lead { font-size: 15px; }
.uc-locations .uc-section-lead { font-size: 14.5px; }
.uc-franchise-band p { font-size: 15.5px; line-height: 1.6; color: var(--uc-muted); }

/* Eyebrow labels are 700 in the mockup, not the theme's 600. */
.uc-franchise-band .uc-eyebrow,
.uc-close .uc-eyebrow { font-weight: 700; }

.uc-franchise-band .uk-button-secondary,
.uc-close .uk-button-secondary,
.uc-close .uk-button-primary { font-weight: 700; }
.uc-franchise-band .uk-button-default,
.uc-close .uk-button-default { font-weight: 600; }

/* Janiflow's four-channel list replaced the mockup's 13px/500 chips. Keeping
 * it close to that scale stops it shouting over the heading. */
.uc-channels li { font-size: 14px; }
.uc-channels strong { font-weight: 600; }

/* Mockup hero CTA is 16.5px; the theme collapses every button to 15px. The
 * theme's 13px/30px padding also made the pill 6px shorter and 4px wider than
 * the mockup's, which was enough to push the secondary CTA onto a second line. */
.uc-hero-buttons .uk-button-primary {
    font-size: 16.5px;
    padding: 16px 28px;
    line-height: 1.2;
}

/* Mockup spacing between a section heading and the content under it. */
.uc-steps h2 { margin-bottom: 44px; }
.uc-lead-narrow { max-width: 560px; margin-left: auto; margin-right: auto; margin-bottom: 44px; }

/* ==========================================================================
 * SECTIONS
 * ====================================================================== */

.uc-section-lead { font-size: 16px; color: var(--uc-muted); }
.uk-section .uc-section-lead { margin-top: 6px; }

.uc-eyebrow {
    font-size: 12px;
    letter-spacing: .14em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--uc-blue);
    display: block;
}

/* Heading paired with a right-aligned "see all" link. */
.uc-head-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 24px;
    flex-wrap: wrap;
}
.uc-head-row h2 { margin: 0; }
.uc-head-link { font-size: 14px; font-weight: 600; color: var(--uc-navy); white-space: nowrap; }

/* --- hero ---------------------------------------------------------------- */
.uc-hero-image { display: block; }
.uc-hero-lead p, .uc-hero-lead { font-size: 19px; line-height: 1.55; }
.uc-hero-lead p { max-width: 520px; margin-bottom: 30px; }
.uc-hero h1 { margin-bottom: 18px; }
.uc-hero-lead strong { color: var(--uc-navy); }

/* Mockup pairs a solid primary CTA with a quiet teal-outlined secondary. */
.uc-hero-buttons .uk-button-default,
.uc-franchise-buttons .uk-button-default {
    background: #EDF8F4;
    border: 1px solid var(--uc-teal);
    color: var(--uc-navy);
}
.uc-hero-buttons .uk-button-default:hover,
.uc-franchise-buttons .uk-button-default:hover { background: #DFF2EA; color: var(--uc-navy); }

/* --- trust bar ----------------------------------------------------------- */
/* Brief calls this the single highest-value change to the current page, so it
   stays legible and quiet rather than competing with the hero. */
.uc-trust { border-bottom: 1px solid var(--uc-line); }

/* The mockup runs this band as ONE row: label, logos, ISO pills, spread with
   space-between. It had been three stacked blocks, which is what made it read
   as a different design. The logo slider takes the remaining middle space. */
.uc-trust-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
}
.uc-trust-label {
    font-size: 12px;
    letter-spacing: .1em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--uc-quiet);
    white-space: nowrap;
    flex: none;
}
/* The slider needs an explicit basis or it collapses to its content width and
   the ISO pills jump left against it.
   It also has to be a flex container in its own right: as a block, the 24px
   slider sat at the TOP of this 44px cell while the label and ISO pills centred
   against the row, which is what put the wordmarks 10px high. */
.uc-trust-logos {
    flex: 1 1 340px;
    min-width: 0;
    display: flex;
    align-items: center;
}
/* Centre the whole chain, not just the outer cell. Widgetkit nests
   slider > slider-container > ul, and each level stretched to the row height
   while the ul stayed 24px at the top - so fixing only one level moved the
   problem down a layer instead of solving it. */
.uc-trust-logos > *,
.uc-trust-slider,
.uc-trust-slider .uk-slider-container {
    display: flex;
    align-items: center;
    width: 100%;
}
/* Widgetkit wraps the list in a div carrying `uk-margin`, i.e. a 20px top
   margin. THAT was the whole 44-vs-24 discrepancy that kept the wordmarks
   sitting high - not the flex alignment, which is why centring each level in
   turn only moved the problem down a layer. UIkit's margin utilities are
   !important, so this has to be too. */
.uc-trust-slider > * {
    width: 100%;
    margin-top: 0 !important;
    margin-bottom: 0 !important;
}

/* Wordmarks now, client logos later. Both are greyscaled and dimmed so the
   strip reads as reassurance rather than competing with the hero; hovering a
   slide brings it back to full colour. Once real logo files are supplied the
   img rules below do the work and the title rule stops matching anything. */
.uc-trust-slider .uk-panel { text-align: center; }
/* Two different title elements to cover, because this moved from a YOOtheme
   panel-slider to a Widgetkit slideset: YOOtheme emits div.el-title, Widgetkit
   emits div.uk-h5. Targeting only the first is why the wordmarks came back
   navy and oversized after the switch. */
.uc-trust-slider .el-title,
.uc-trust-slider .uk-h5 {
    font-size: 20px;
    font-weight: 700;
    /* Mockup grey was #8B99AB (2.9:1). These are bold 20px, so WCAG large-text
       applies and the bar is 3:1, which that missed. */
    color: #7E8DA1;
    margin: 0;
    white-space: nowrap;
    line-height: 1.2;
}
/* Vertically centre the slides against the label and the ISO pills. Widgetkit
   wraps the slider in its own margin-bearing divs, which sat the wordmarks 10px
   above the centre line of the row. */
.uc-trust-slider .uk-slider-items > li { display: flex; align-items: center; justify-content: center; }
.uc-trust-slider .uk-panel { width: 100%; }
.uc-trust-logos > *,
.uc-trust-slider,
.uc-trust-slider .uk-slider-container,
.uc-trust-slider .uk-slider-items { margin-top: 0; margin-bottom: 0; }
.uc-trust-slider img {
    max-height: 40px;
    width: auto;
    margin: 0 auto;
    filter: grayscale(100%);
    opacity: .6;
    transition: filter .2s ease, opacity .2s ease;
}
.uc-trust-slider li:hover img { filter: grayscale(0); opacity: 1; }
.uc-trust-slider .uk-slider-items { align-items: center; }

.uc-trust-badges {
    display: flex;
    gap: 10px;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    flex: none;
}
.uc-badge {
    border: 1px solid #D6DEE9;
    border-radius: 99px;
    padding: 5px 12px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--uc-body);
}
.uc-badge-fill { background: var(--uc-wash); border-color: transparent; color: var(--uc-navy); }

/* --- problem trio -------------------------------------------------------- */
.uc-problem-card.uk-card {
    background: var(--uc-card);
    border: 1px solid var(--uc-line);
}
/* Mockup service and news cards sit on the wash ground, so they are white with
   a slightly cooler border, not the wash fill the problem cards use. */
.uc-service-card.uk-card-default,
.uc-news-card {
    background: #fff;
    border: 1px solid #E0E8F2;
}
.uc-problem-card .uk-card-title { font-size: 21px; color: var(--uc-navy); }
.uc-proof {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--uc-blue);
    margin-bottom: 0;
}
.uc-tick { flex: none; }

/* --- Janiflow ------------------------------------------------------------ */
/* .uc-section-lead is a mid grey tuned for white grounds. On the navy Janiflow
   section it rendered at roughly 2:1 against the background, so it is
   overridden to the same light ink the rest of the section uses. */
.uc-janiflow .uc-section-lead { color: #D7E4F2; }
.uc-janiflow .uc-eyebrow { color: #7FB5E8; }

.uc-channels { list-style: none; padding: 0; margin: 18px 0 0; }
.uc-channels li { margin-bottom: 10px; line-height: 1.5; }
.uc-channels strong { color: #fff; }
.uc-channels span { color: #D7E4F2; }

.uc-janiflow-foot { display: flex; gap: 28px; align-items: center; flex-wrap: wrap; margin-top: 30px; }
/* uk-section-secondary restyles .uk-button-default as a ghost button, which
   swallowed the mockup's solid white CTA. Scoped override wins it back. */
.uc-janiflow .uk-button.uc-btn-light,
.uk-section-secondary .uk-button.uc-btn-light {
    background: #fff;
    color: var(--uc-navy);
    border-color: #fff;
}
.uc-janiflow .uk-button.uc-btn-light:hover,
.uk-section-secondary .uk-button.uc-btn-light:hover {
    background: #E8F0FA;
    color: var(--uc-navy);
}
.uc-stat { display: flex; flex-direction: column; }
.uc-stat-figure { font-size: 30px; font-weight: 700; color: #7FB5E8; line-height: 1; }
.uc-stat-label { font-size: 11.5px; color: #7FA3CE; }
.uc-janiflow .uk-text-meta { color: #7FA3CE; }

/* Indicative Janiflow UI, ported from the approved mockup. Swap for real
   screenshots once Shane supplies them; the classes stay the same. */
.uc-devices { color: var(--uc-body); }
.uc-device-stack { display: flex; gap: 22px; align-items: flex-start; }
.uc-phone {
    width: 240px;
    flex: none;
    background: #0A1B33;
    border-radius: 32px;
    padding: 10px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
    transform: rotate(-2deg);
}
.uc-phone-screen {
    background: linear-gradient(180deg, #16345C, #0C2244);
    border-radius: 24px;
    padding: 20px 12px 24px;
    min-height: 380px;
}
.uc-phone-time { text-align: center; color: #B8CCE6; font-size: 12px; }
.uc-phone-clock { text-align: center; font-weight: 600; font-size: 38px; color: #fff; margin: 2px 0 18px; }
.uc-notif { background: rgba(255, 255, 255, .96); border-radius: 13px; padding: 10px 11px; color: #1B2B3F; }
.uc-notif-head { display: flex; gap: 8px; align-items: center; margin-bottom: 4px; }
.uc-notif-app {
    width: 18px; height: 18px; border-radius: 5px;
    background: var(--uc-navy); color: #fff;
    font: 700 8px/1 'Poppins', sans-serif;
    display: inline-flex; align-items: center; justify-content: center;
}
.uc-notif-name { font-size: 10.5px; font-weight: 600; }
.uc-notif-when { margin-left: auto; font-size: 9.5px; color: #8A97A8; }
.uc-notif-title { font-size: 11.5px; font-weight: 600; margin-bottom: 2px; }
.uc-notif-body { font-size: 11px; line-height: 1.45; color: #4A5A6E; }
.uc-notif-ghost {
    background: rgba(255, 255, 255, .14);
    color: #DCE7F4;
    margin-top: 7px;
    font-size: 10.5px;
    font-weight: 600;
}

.uc-report {
    flex: 1;
    background: #fff;
    border-radius: 14px;
    padding: 17px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, .4);
    margin-top: 52px;
    transform: rotate(1.5deg);
}
.uc-report-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.uc-report-title { font-weight: 700; font-size: 13.5px; color: #1B2B3F; }
.uc-report-head .uc-verified { margin-left: auto; }
.uc-report-meta { font-size: 11px; color: #69788C; margin-bottom: 10px; }
.uc-report-list { list-style: none; padding: 0; margin: 0; font-size: 12px; color: #1B2B3F; }
.uc-report-list li { display: flex; gap: 7px; align-items: center; margin-bottom: 6px; color: var(--uc-blue); }
.uc-report-list li { color: #1B2B3F; }
.uc-report-list .uc-tick { color: var(--uc-blue); }
.uc-report-shots { display: flex; gap: 7px; margin: 11px 0; }
.uc-report-shots span { flex: 1; height: 46px; border-radius: 7px; background: center/cover no-repeat; }
.uc-report-link { font-size: 11px; font-weight: 600; color: var(--uc-navy); }

.uc-verified {
    background: #E4EFFA;
    color: #0B4F8F;
    font-size: 11px;
    font-weight: 700;
    padding: 3px 8px;
    border-radius: 99px;
    white-space: nowrap;
}

/* --- services ------------------------------------------------------------ */
.uc-service-card .uk-card-title { font-size: 18px; color: var(--uc-navy); }
.uc-service-card > .uk-card-body, .uc-service-card.uk-card-body { padding: 24px; }
.uc-service-card p { font-size: 13.5px; line-height: 1.55; color: var(--uc-muted); }
.uc-service-card .uk-button-text,
.uc-service-card a.el-link { font-size: 12.5px; font-weight: 600; color: var(--uc-blue); }

/* Hover: lift, deepen the border and warm the shadow. Kept to transform and
   shadow (both compositor-only) so the 8-card grid stays smooth, and disabled
   under prefers-reduced-motion. */
.uc-service-card {
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.uc-service-card:hover {
    transform: translateY(-4px);
    border-color: #C9D8EA;
    box-shadow: 0 14px 30px rgba(0, 55, 118, .12);
}
.uc-service-card.uk-card-primary:hover {
    border-color: transparent;
    box-shadow: 0 14px 30px rgba(0, 35, 78, .35);
}
.uc-service-card:hover .uk-card-title { color: var(--uc-blue); }
.uc-service-card.uk-card-primary:hover .uk-card-title { color: #fff; }
/* "Learn more" was the one interactive element on the page with no hover state
   of its own - hovering the link directly changed nothing. */
.uc-service-card .el-link { transition: color .15s ease; }
.uc-service-card .el-link:hover,
.uc-service-card:hover .el-link { color: var(--uc-navy); text-decoration: underline; }
.uc-service-card.uk-card-primary .el-link:hover,
.uc-service-card.uk-card-primary:hover .el-link { color: #fff; }

@media (prefers-reduced-motion: reduce) {
    .uc-service-card, .uc-news-card { transition: none; }
    .uc-service-card:hover { transform: none; }
}
/* YOOtheme renders the panel image as a plain <img> with only a width, and an
   inline SVG with no intrinsic ratio then stretches to fill the flex column
   (measured 25x375). Pin both axes so the icon keeps its 26px square. */
.uc-service-card img {
    display: block;
    width: 26px;
    height: 26px;
    margin-bottom: 12px;
}
/* Last card is the navy Multi-Site tile; image_svg_color makes the icon follow. */
.uc-service-card.uk-card-primary { background: var(--uc-navy); }
.uc-service-card.uk-card-primary .uk-card-title { color: #fff; }
.uc-service-card.uk-card-primary p { color: #B9CDE4; }
.uc-service-card.uk-card-primary .uk-button-text,
.uc-service-card.uk-card-primary a.el-link { color: #7FB5E8; }

/* --- steps --------------------------------------------------------------- */
/* Mockup uses a foam-bubble badge behind each numeral rather than a plain
   circle, which is the brand's own motif carried through from the logo. */
.uc-step { text-align: center; padding: 0 18px; }
.uc-step-title { font-size: 20px; color: var(--uc-navy); margin: 0 0 8px; }
.uc-step p { font-size: 14.5px; line-height: 1.6; color: var(--uc-muted); margin: 0; }
.uc-bubble {
    position: relative;
    display: block;
    width: 96px;
    height: 60px;
    margin: 0 auto 16px;
    color: #E3EDF8;
}
.uc-bubble svg { position: absolute; inset: 0; width: 96px; height: 60px; }
.uc-bubble-num {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding-top: 4px;
    font-weight: 700;
    font-size: 24px;
    color: var(--uc-navy);
}

/* --- testimonials -------------------------------------------------------- */
.uc-quote {
    background: #fff;
    border-radius: 18px;
    padding: 32px 34px;
    margin: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    min-height: 230px;
}
.uc-quote blockquote {
    font-size: 21px;
    line-height: 1.4;
    font-weight: 600;
    color: var(--uc-navy);
    margin: 0 0 24px;
    border: 0;
    padding: 0;
}
.uc-quote figcaption { display: flex; align-items: center; gap: 12px; }
.uc-avatar {
    width: 42px; height: 42px; flex: none;
    border-radius: 99px;
    background: var(--uc-blue);
    color: #fff;
    display: inline-flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: 14px;
}
.uc-who { display: flex; flex-direction: column; }
.uc-who strong { font-size: 13px; font-weight: 600; color: var(--uc-navy); }
.uc-who span { font-size: 12px; color: var(--uc-quiet); }
.uc-quote .uc-verified { margin-left: auto; }

/* Slider chrome for the testimonials: round outline arrows top-right and a
   dot row underneath, both driven by UIkit's own slider so they actually work
   rather than being decorative. */
.uc-slider-nav { display: flex; gap: 10px; align-items: center; }
/* Widgetkit draws the slideset arrows as bare uk-slidenav icons. The mockup
   uses the same round outline buttons as the old inline slider, so give the
   widget's arrows the identical treatment rather than a second style. */
.uc-testimonial-widget .uk-slidenav {
    width: 44px;
    height: 44px;
    border-radius: 99px;
    border: 1.5px solid #C3D3E6;
    background: #fff;
    color: var(--uc-navy);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: border-color .15s ease, background .15s ease;
}
.uc-testimonial-widget .uk-slidenav:hover {
    border-color: var(--uc-blue);
    background: var(--uc-wash);
    color: var(--uc-navy);
}
.uc-testimonial-widget .uk-slidenav + .uk-slidenav { margin-left: 10px; }

/* Widgetkit marks the arrow container uk-hidden-hover in EVERY slidenav
   variant - there is no persistent option in the widget - so the controls only
   appear on mouseover and never on touch. The mockup shows them standing.
   Overriding the opacity is the only way to get them, short of forking the
   widget template. */
.uc-testimonial-widget .uk-slidenav-container.uk-hidden-hover {
    opacity: 1 !important;
}
/* And lift them out of the slides, up beside the heading where the mockup puts
   them, rather than floating over the first card.
   The container collapsed to 0x0 because its anchors are absolutely positioned,
   so it had no content to size to and a percentage transform resolved against
   nothing. Put the anchors back in flow and give the container real dimensions. */
.uc-testimonial-widget { position: relative; }
.uc-testimonial-widget .uk-slidenav-container.uk-position-top-right {
    position: absolute;
    top: -58px;
    right: 0;
    left: auto;
    bottom: auto;
    transform: none;
    width: auto;
    height: auto;
    /* The container still measures 0x0 and was CLIPPING the anchors, so they
       had geometry but painted nothing. Give it real dimensions and stop it
       hiding its own controls. */
    min-width: 98px;
    min-height: 46px;
    overflow: visible;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    z-index: 3;
}
.uc-testimonial-widget .uk-slidenav-container > a {
    position: static;
    margin: 0;
    font-size: 17px;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
}
/* UIkit is meant to swap the uk-slidenav-previous/next attribute for an inline
   SVG, but here it renders a broken image with the alt text showing through.
   Draw the glyphs instead - it matches the mockup's arrows and removes the
   dependency on the icon injection working at all. */
.uc-testimonial-widget .uk-slidenav-container > a > * { display: none; }
.uc-testimonial-widget .uk-slidenav-container > a::before { content: '\2190'; }
.uc-testimonial-widget .uk-slidenav-container > a + a::before { content: '\2192'; }
/* The lifted arrows need room above the slides to sit in. */
.uc-testimonials .uc-testimonial-widget { padding-top: 62px; }
/* On a phone the heading block is tall and the arrows would collide with it;
   swipe and the dots cover paging there, as they do on the hero. */
@media (max-width: 639px) {
    .uc-testimonial-widget .uk-slidenav-container { display: none; }
    .uc-testimonials .uc-testimonial-widget { padding-top: 0; }
}

.uc-slider-btn {
    width: 44px;
    height: 44px;
    border-radius: 99px;
    border: 1.5px solid #C3D3E6;
    background: #fff;
    color: var(--uc-navy);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    font-weight: 600;
    text-decoration: none;
}
.uc-slider-btn:hover { border-color: var(--uc-blue); color: var(--uc-blue); }

/* With only the three seeded quotes all slides fit at once, so UIkit correctly
   marks both arrows hidden. Respect that, and drop the dot row too, rather
   than showing dead controls. Both come back on their own as soon as the
   client publishes a fourth testimonial. */
.uc-slider-btn[hidden] { display: none; }
.uc-slider-nav:not(:has(.uc-slider-btn:not([hidden]))) { display: none; }
.uc-slider:not(:has(.uc-slider-btn:not([hidden]))) .uc-dots { display: none; }
.uc-slider .uk-slider-items { margin-top: 30px; }
.uc-slider .uk-slider-items > li { display: flex; }
.uc-dots { justify-content: center; margin-top: 26px; }
.uc-dots > * > * {
    width: 9px;
    height: 5px;
    border-radius: 99px;
    background: #C3D3E6;
    border: 0;
    transition: width .2s ease, background .2s ease;
}
.uc-dots > .uk-active > * { width: 28px; background: var(--uc-blue); }

/* --- locations ----------------------------------------------------------- */
/* The mockup gives the pill group a fixed 640px box pushed to the right edge.
   Inside a plain half-width column it came out 597px, which fits five pills per
   row instead of six and wraps Adelaide onto the second line. */
.uc-pills {
    display: flex;
    gap: 9px;
    flex-wrap: wrap;
    max-width: 640px;
    margin-left: auto;
}
.uc-pill {
    background: var(--uc-wash);
    border-radius: 99px;
    padding: 8px 18px;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--uc-navy);
}
.uc-pill:hover { background: #E2EDF8; }
.uc-pill-link { font-weight: 600; color: var(--uc-blue); }

/* --- franchise band ------------------------------------------------------ */
/* Accent teal is only ever a ground with a navy label: #64BFA2 measures 2.2:1
   on white and fails AA, so it must never carry white text. */
/* Scoped to the section's OWN row. An unscoped `.uc-franchise-band .uk-grid`
   also matches the button group's internal grid, which painted a stray teal
   box around the two buttons and collapsed the two-column split. */
.uc-franchise-band > .uk-container > .uk-grid {
    background: #EDF8F4;
    border: 1px solid #C6E7DC;
    border-radius: 20px;
    padding: 52px 56px;
    margin-left: 0;
    align-items: center;
}
.uc-franchise-band > .uk-container > .uk-grid > * { padding-left: 0; }
.uc-franchise-band > .uk-container > .uk-grid > * + * { padding-left: 48px; }
.uc-franchise-band .uc-eyebrow { color: var(--uc-navy); font-weight: 700; }
.uc-franchise-image img { border-radius: 14px; }
.uc-franchise-buttons .uk-button-secondary { background: var(--uc-teal); color: var(--uc-deep); border-color: var(--uc-teal); }
.uc-franchise-buttons .uk-button-secondary:hover { background: #53AE91; color: var(--uc-deep); }

/* --- news ---------------------------------------------------------------- */
.uc-news-card {
    display: flex;
    flex-direction: column;
    border-radius: 14px;
    overflow: hidden;
    background: #fff;
    height: 100%;
    color: inherit;
    text-decoration: none;
}
.uc-news-card:hover { border-color: #C9D8EA; }
.uc-news-media { display: block; height: 150px; background: center/cover no-repeat; }
/* Article without a thumbnail yet. The mockup carries a centred glyph here, so
   the slot reads as "image to come" rather than as a blank grey box. */
.uc-news-media-empty {
    background:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 26 26' fill='none' stroke='%237C97BC' stroke-width='1.6'%3E%3Ccircle cx='13' cy='13' r='10'/%3E%3Cpath d='M13 8v10M8 13h10'/%3E%3C/svg%3E") center / 40px 40px no-repeat,
        linear-gradient(135deg, var(--uc-wash), #DCE9F7);
}
.uc-news-body { display: block; padding: 20px; }
.uc-news-kicker { display: block; font-size: 11.5px; color: var(--uc-quiet); margin-bottom: 6px; }
.uc-news-title {
    display: block;
    font-size: 17px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--uc-navy);
    margin-bottom: 6px;
}
.uc-news-excerpt { display: block; font-size: 13.5px; line-height: 1.55; color: var(--uc-muted); }

/* News cards and the close doors are raw HTML blocks, so YOOtheme's
   height_expand (which only applies to panels) cannot match them. Stretch the
   grid cell instead so each row lands on one baseline. YOOtheme wraps every
   html element in its own .uk-panel, so the stretch has to be carried down two
   levels, not one.

   Scoped with :has() to the grid that actually holds the cards. Unscoped, it
   also caught the section's heading row, which made .uc-head-row a flex item:
   it then shrank to its content instead of spanning the container, so
   "All articles" sat next to the heading rather than at the right edge. */
.uc-news .uk-grid:has(.uc-news-card) > *,
.uc-close .uk-grid > * { display: flex; }
.uc-news .uk-grid:has(.uc-news-card) > * > *,
.uc-close .uk-grid > * > * { display: flex; flex: 1; }
.uc-news-card, .uc-door { flex: 1; }

/* --- split-door close ---------------------------------------------------- */
.uc-door { border-radius: 20px; padding: 44px 46px; height: 100%; }
.uc-door h2 { font-size: 27px; line-height: 1.2; color: var(--uc-navy); margin: 10px 0; }
.uc-door p { font-size: 14.5px; line-height: 1.6; color: var(--uc-muted); margin: 0 0 22px; }
.uc-close-blue { background: var(--uc-wash); border-top: 5px solid var(--uc-blue); }
.uc-close-teal { background: #EDF8F4; border-top: 5px solid var(--uc-teal); }
.uc-close-teal .uc-eyebrow { color: var(--uc-navy); }
.uc-close-teal .uk-button-secondary { background: var(--uc-teal); color: var(--uc-deep); border-color: var(--uc-teal); }
.uc-close-teal .uk-button-secondary:hover { background: #53AE91; color: var(--uc-deep); }
.uc-door-buttons { display: flex; gap: 12px; flex-wrap: wrap; }
.uc-close-teal .uk-button-default {
    background: transparent;
    border: 1.5px solid var(--uc-teal);
    color: var(--uc-navy);
}
.uc-close-teal .uk-button-default:hover { background: #DFF2EA; color: var(--uc-navy); }

/* --- foam dividers ------------------------------------------------------- */
/* Brand motif from the mockup. Previously two standalone sections, which gave
   them their own vertical padding and inherited the container's max-width, so
   the bubbles floated in a gap and stopped short of the viewport edges. They
   are now a pseudo-element on the section they belong to: pinned to its bottom
   edge, 100vw wide, so the transition is genuinely flush and full-bleed.
   Inline SVG (as a data URI) rather than a flat image: no HTTP request, fluid
   at any width, and the bubble colour is the next section's ground. */
.uc-foam-to-wash,
.uc-foam-to-navy {
    position: relative;
    overflow: hidden;
}
.uc-foam-to-wash { padding-bottom: 126px; }
.uc-foam-to-navy { padding-bottom: 126px; }
.uc-foam-to-wash::after,
.uc-foam-to-navy::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 56px;
    background-repeat: no-repeat;
    background-position: bottom center;
    background-size: 100% 100%;
    pointer-events: none;
}
.uc-foam-to-wash::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1360 70' preserveAspectRatio='none'%3E%3Cg fill='%23EEF4FA'%3E%3Cellipse cx='120' cy='70' rx='150' ry='34'/%3E%3Cellipse cx='420' cy='70' rx='190' ry='46'/%3E%3Cellipse cx='720' cy='70' rx='160' ry='30'/%3E%3Cellipse cx='1000' cy='70' rx='200' ry='42'/%3E%3Cellipse cx='1290' cy='70' rx='150' ry='28'/%3E%3Crect x='0' y='56' width='1360' height='14'/%3E%3C/g%3E%3C/svg%3E");
}
.uc-foam-to-navy::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1360 70' preserveAspectRatio='none'%3E%3Cg fill='%2300234E'%3E%3Cellipse cx='120' cy='70' rx='150' ry='34'/%3E%3Cellipse cx='420' cy='70' rx='190' ry='46'/%3E%3Cellipse cx='720' cy='70' rx='160' ry='30'/%3E%3Cellipse cx='1000' cy='70' rx='200' ry='42'/%3E%3Cellipse cx='1290' cy='70' rx='150' ry='28'/%3E%3Crect x='0' y='56' width='1360' height='14'/%3E%3C/g%3E%3C/svg%3E");
}

/* --- footer -------------------------------------------------------------- */
/* The footer now uses a reversed (white) lockup, so the white chip the logo
   previously sat on is gone. That asset is DERIVED from the supplied blue logo
   by build/scripts/make_inverse_logo.ps1, not client-supplied artwork; swap in
   Kirsten's official reversed logo when it arrives. */
.uc-footer-logo img { background: none; padding: 0; }

/* The rule above the acknowledgement was a solid #ffffff hairline, which on the
   navy ground read as a bright white stripe. The mockup separates that block
   with spacing and, where it does draw a line on navy, uses #33587F.
   The theme paints it from `.uk-section-secondary:not(.uk-preserve-color) hr`,
   which scores (0,3,1); :not() counts, so a plain `.uc-footer hr` at (0,1,1)
   loses. Same trap as the footer headings above. */
.uc-footer.uk-section-secondary:not(.uk-preserve-color) hr,
.uc-footer.uk-section-secondary:not(.uk-preserve-color) .uk-hr {
    border-top-color: #33587F;
    opacity: 1;
}

/* Footer type scale. The theme renders the footer at body size (16px); the
   mockup runs it at 13.5px with a tighter list rhythm, which is most of why
   the live footer stood 100px taller than the design. */
.uc-footer .uk-list > li { margin-top: 9px; }
.uc-footer .uk-list > li:first-child { margin-top: 0; }
.uc-footer .uk-list > li > a,
.uc-footer .uk-panel > p { font-size: 13.5px; line-height: 1.6; }
.uc-footer .uk-panel > p { color: #B9CDE4; }
.uc-footer p.uk-text-small { color: #7A96B8; font-size: 12px; font-weight: 400; }
.uc-footer .uc-footer-quote { font-size: 14px; }
/* Column headings are 700 in the mockup; uk-h6 renders them 600. */
.uc-footer .uk-h6 { font-weight: 700; }
.uc-footer-phone.uk-h4 { font-size: 13.5px; }
/* Mockup's quote button fills its column rather than hugging its label. */
.uc-footer-quote { display: block; text-align: center; }

/* The footer wrapper is a bare <footer> with no tm- class, and the section's
   inverse rules paint every heading white. Scoping to the section beats them
   without !important. */
/* The theme's inverse heading rule is
   `.uk-section-secondary:not(.uk-preserve-color) .uk-h6`, and :not() counts
   towards specificity, so it scores (0,3,0). Matching that and landing later
   in the cascade is what wins, without reaching for !important. */
.uc-footer:not(.uk-preserve-color) .uc-col-business { color: #7FB5E8; }
.uc-footer:not(.uk-preserve-color) .uc-col-franchise { color: var(--uc-teal); }
.uc-footer-badges { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 18px; }
.uc-footer-badges span {
    border: 1px solid #33587F;
    border-radius: 99px;
    padding: 4px 11px;
    font-size: 10.5px;
    font-weight: 600;
}
.uc-footer-contact { display: flex; flex-direction: column; gap: 11px; align-items: flex-start; }
.uc-footer-phone { font-weight: 600; display: inline-flex; align-items: center; gap: 8px; color: #fff; }
.uc-social { display: flex; gap: 9px; margin: 4px 0 6px; }
.uc-social a {
    width: 36px;
    height: 36px;
    border-radius: 99px;
    border: 1px solid #33587F;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.uc-social a:hover { border-color: #7FB5E8; background: rgba(255, 255, 255, .06); }
.uc-footer-quote {
    display: inline-block;
    font-weight: 600;
    background: rgba(255, 255, 255, .1);
    border: 1px solid #33587F;
    border-radius: 99px;
    padding: 9px 18px;
    color: #fff;
}
.uc-footer-quote:hover { background: rgba(255, 255, 255, .18); }

/* --- accessibility ------------------------------------------------------- */
/* The mockup defines no hover, focus or active states at all. Accessibility is
   a stated non-negotiable in the brief, so a visible focus ring is added here
   for every interactive element. */
a:focus-visible,
button:focus-visible,
.uk-button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
    outline: 3px solid var(--uc-blue);
    outline-offset: 2px;
}

/* --- hero slideshow ------------------------------------------------------
 * The hero image is a slideshow. Its dot navigation is deliberately the same
 * control as the testimonial dots (9x5 pill, 28px when active) rather than
 * UIkit's default round dotnav, so the two sliders on the page read as one
 * system. Sat bottom-right, inside the image.
 *
 * This block MUST stay above the responsive section: the breakpoint rules use
 * the same selectors at the same specificity, so whichever lands later wins.
 * Sitting below them, these desktop values overrode the touch sizing inside
 * the media query and the dots stayed 5px tall on a tablet. */
.uc-hero .uk-grid { align-items: center; }

.uc-hero-slider .uk-slideshow-items,
.uc-hero-slider .uk-slideshow-items > li > img { border-radius: 16px; }
.uc-hero-slider .uk-dotnav { gap: 8px; }
.uc-hero-slider .uk-dotnav > * > * {
    width: 9px;
    height: 5px;
    border-radius: 99px;
    background: rgba(255, 255, 255, .55);
    border: 0;
    transition: width .2s ease, background .2s ease;
}
.uc-hero-slider .uk-dotnav > .uk-active > * { width: 28px; background: #fff; }
/* The dots sit over photography, so they need a shadow to stay legible on a
   light frame. */
.uc-hero-slider .uk-position-bottom-right { filter: drop-shadow(0 1px 3px rgba(0, 35, 78, .45)); }

/* --- responsive ----------------------------------------------------------
 * Two bands, split by what each is for. Everything below 960 is a touch device
 * (UIkit's @m column classes only engage from 960 up), so the 959 block carries
 * the touch ergonomics: hit areas and minimum text sizes. The 639 block is
 * phone LAYOUT, where a single narrow column changes what the design should do.
 * Desktop is verified against the approved mockup and must not be disturbed by
 * either, so nothing here leaks upward. */
@media (max-width: 959px) {
    /* The device stack is 240px + a report card; below the desktop breakpoint
       it stacks so neither gets crushed. The report is capped because at 768 a
       full-width card stretched its two photo thumbnails into 700px letterbox
       strips. Capped, it stays a credible report next to the 260px phone. */
    .uc-device-stack { flex-direction: column; align-items: center; }
    .uc-report { margin-top: 0; width: 100%; max-width: 420px; }
    /* Same scoping as the desktop rule above, and for the same reason. While
       this was unscoped it lost to that rule on specificity, so the card padding
       never actually shrank; all it did was pad the button group's internal
       grid, pushing both buttons in by 28px and adding 36px of dead space. */
    .uc-franchise-band > .uk-container > .uk-grid { padding: 36px 28px; }
    .uc-door { padding: 32px 28px; }

    /* Hit areas: 44px per WCAG 2.5.5. Measured at 375 and 768 - location pills
       and footer social icons were 36px, the hamburger's hit area 20px wide, the
       "All ..." section links 23px tall, the footer phone 15px, each service
       card's "Learn more" 18px, and the slider dots 9x5. */
    .uk-button { min-height: 44px; }
    .uc-pill { min-height: 44px; display: inline-flex; align-items: center; }
    .uc-social a { width: 44px; height: 44px; }
    .uc-slider-btn { width: 44px; height: 44px; }
    .uk-navbar-toggle { min-width: 44px; justify-content: center; }
    .uc-footer-quote,
    .uc-head-link,
    .uc-footer-phone,
    .uc-service-card .el-link { min-height: 44px; display: inline-flex; align-items: center; }

    /* The mobile menu opens as a full-screen uk-modal, so none of the above
       reaches it. Its top-level items are 45px but every child item - the eight
       service pages and the seven locations, 15 of 23 links - was 33px. Only
       opening the menu shows this; a page-level sweep never touches it. */
    .uk-modal-full .uk-nav a { min-height: 44px; display: flex; align-items: center; }

    /* Dots were a 9x5 pill. Pad the anchor out and draw the dot as a
       pseudo-element so the visual size is unchanged. Width is 30px, not 44:
       a full 44px square pushed the dots so far apart they stopped reading as
       one control. 30x44 still clears the 24px minimum in WCAG 2.5.8. */
    .uc-dots > * > * {
        width: 30px;
        height: 44px;
        display: flex;
        align-items: center;
        justify-content: center;
        background: none;
    }
    .uc-dots > * > *::before {
        content: '';
        width: 9px;
        height: 5px;
        border-radius: 99px;
        background: #C3D3E6;
        transition: width .2s ease, background .2s ease;
    }
    .uc-dots > .uk-active > * { width: 30px; background: none; }
    .uc-dots > .uk-active > *::before { width: 28px; background: var(--uc-blue); }

    /* The testimonials moved from inline markup (.uc-dots) to a Widgetkit
       slideset, which emits a plain .uk-dotnav - so the rule above stopped
       matching and the dots went back to 9x9. */
    .uc-testimonial-widget .uk-dotnav > * > * {
        width: 30px;
        height: 44px;
        display: flex;
        align-items: center;
        justify-content: center;
        background: none;
        border: 0;
    }
    .uc-testimonial-widget .uk-dotnav > * > *::before {
        content: '';
        width: 9px;
        height: 5px;
        border-radius: 99px;
        background: #C3D3E6;
        transition: width .2s ease, background .2s ease;
    }
    .uc-testimonial-widget .uk-dotnav > .uk-active > *::before {
        width: 28px;
        background: var(--uc-blue);
    }

    /* Hero slideshow dots are the same control and need the same hit area. */
    .uc-hero-slider .uk-dotnav > * > * {
        width: 30px;
        height: 44px;
        display: flex;
        align-items: center;
        justify-content: center;
        background: none;
    }
    .uc-hero-slider .uk-dotnav > * > *::before {
        content: '';
        width: 9px;
        height: 5px;
        border-radius: 99px;
        background: rgba(255, 255, 255, .55);
        transition: width .2s ease, background .2s ease;
    }
    .uc-hero-slider .uk-dotnav > .uk-active > * { width: 30px; background: none; }
    .uc-hero-slider .uk-dotnav > .uk-active > *::before { width: 28px; background: #fff; }

    /* Body text under 12px. The report card is no longer a scaled-down
       illustration of an app screen once it is this size. */
    .uc-badge,
    .uc-stat-label,
    .uc-footer-badges span,
    .uc-report-meta,
    .uc-report-link { font-size: 12px; }

    /* --- tablet layout ---------------------------------------------------
       Below 960 the columns stack, which left three images floating at their
       intrinsic size in a full-width column instead of filling it. */
    .uc-hero-image img,
    .uc-hero-slider,
    .uc-franchise-image img { width: 100%; }
    .uc-hero-slider .uk-slideshow-items { min-height: 320px; }

    /* The pill group is centred on a phone (below), but on a tablet it has the
       full width and should start at the left edge like everything else. */
    .uc-pills { justify-content: flex-start; }

    /* Two quicklinks columns side by side rather than stacked - there is plenty
       of width for them at this size and stacking made the footer very long. */
    .uc-footer .uc-col-business,
    .uc-footer .uc-col-franchise { width: 50%; }
}

@media (max-width: 639px) {
    .uc-trust-row { justify-content: center; text-align: center; }
    .uc-trust-logos { gap: 20px; justify-content: center; flex: 1 1 100%; }
    /* flex:none plus justify-end held the four pills on one line and ran them
       22px off the left edge of a phone. Let them wrap and centre. */
    .uc-trust-badges {
        flex: 1 1 100%;
        justify-content: center;
        max-width: 100%;
    }
    .uc-head-row { align-items: flex-start; }
    /* Foam is proportionally taller on narrow screens, so give it more room. */
    .uc-foam-to-wash, .uc-foam-to-navy { padding-bottom: 90px; }
    .uc-foam-to-wash::after, .uc-foam-to-navy::after { height: 34px; }
    .uc-phone { width: 100%; max-width: 260px; }

    /* Three testimonials fit one-up on a phone, so UIkit un-hides "next" while
       "prev" stays hidden and a single arrow floats under the heading with
       nothing beside it. Swipe and the dots already cover paging on touch. */
    .uc-slider-nav { display: none; }
    /* Name, role and the verified badge cannot share a 375px line without the
       role wrapping to three. Once the badge wraps to its own line the auto
       margin that pushed it right on desktop strands it in the far corner, so
       drop it and let it sit under the name. */
    .uc-quote figcaption { flex-wrap: wrap; }
    .uc-quote .uc-verified { margin-left: 54px; }

    /* Full-bleed CTAs. Left to shrink-wrap, each pair came out a different width
       (291 vs 309 in the hero) and "Master Franchise" wrapped to two lines. */
    .uc-hero-buttons .uk-button,
    .uc-franchise-buttons .uk-button,
    .uc-door-buttons .uk-button { width: 100%; justify-content: center; }
    .uc-hero-buttons .uk-child-width-auto > *,
    .uc-franchise-buttons .uk-child-width-auto > * { width: 100%; }

    /* Stacked, the phone's 380px screen left ~120px of empty dark space under
       the last notification. */
    .uc-phone-screen { min-height: 280px; }

    /* The franchise image sat in a 48px-guttered column at 183px inside a 231px
       cell. Nothing else on the page is inset like that. */
    .uc-franchise-band > .uk-container > .uk-grid { margin-left: 0; }
    .uc-franchise-band > .uk-container > .uk-grid > * { padding-left: 0; }
    .uc-franchise-image img { width: 100%; height: 200px; object-fit: cover; }
}

/* --- mobile menu ---------------------------------------------------------
 * The full-screen dialog was stock: a bare link list on white, no logo, no
 * brand. Content comes from two YOOtheme Builder modules in the `dialog-mobile`
 * position (see build/scripts/set_mobile_menu.php) so Marketing Magic can edit
 * the links, the phone number and the social profiles in the admin. Only the
 * treatment lives here.
 *
 * Scoped to #tm-dialog-mobile rather than .uk-modal-full so it cannot reach any
 * other modal on the site. */
#tm-dialog-mobile .uk-modal-dialog { background: #fff; }

/* Stock centres the sheet vertically, so on a screen taller than the menu the
   whole thing floated with a void above "Home". A menu should start at the top.
   UIkit declares its margin utilities !important, so this has to as well. */
#tm-dialog-mobile .uk-margin-auto-vertical {
    margin-top: 0 !important;
    margin-bottom: auto !important;
}
#tm-dialog-mobile .uk-modal-body { padding: 24px 24px 40px; }

/* The theme injects the menu as its own pseudo-module and renders it before any
   real module in the position, so `ordering` cannot lift the logo above it -
   ordering 0 still came out second. The grid is flex, so order does the job. */
#tm-dialog-mobile .uk-grid-stack > *:has(.uc-menu-logo) {
    order: -1;
    margin-top: 0;
}

#tm-dialog-mobile .uk-modal-close-full {
    color: var(--uc-navy);
    background: transparent;
    padding: 14px;
}

.uc-menu-logo { margin-bottom: 22px; }
.uc-menu-logo img { height: 52px; width: auto; }

/* Top-level items carry the section weight; children sit under a rail so the
   two levels read apart at a glance rather than as one long list. */
#tm-dialog-mobile .uk-nav > li > a {
    font-size: 17px;
    font-weight: 600;
    color: var(--uc-navy);
    padding: 11px 0;
}
#tm-dialog-mobile .uk-nav > li + li { border-top: 1px solid #EDF2F8; }
#tm-dialog-mobile .uk-nav-sub {
    padding: 2px 0 8px 14px;
    border-left: 2px solid #DCE7F4;
    margin-left: 2px;
}
#tm-dialog-mobile .uk-nav-sub a {
    font-size: 15px;
    font-weight: 400;
    color: var(--uc-muted);
    padding: 7px 0;
}
#tm-dialog-mobile .uk-nav-sub a:hover,
#tm-dialog-mobile .uk-nav > li > a:hover { color: var(--uc-blue); }
#tm-dialog-mobile .uk-nav > li.uk-active > a { color: var(--uc-blue); }
/* The sub-list is inside the parent <li>, so the divider would otherwise draw
   between a parent and its own children. */
#tm-dialog-mobile .uk-nav > li.uk-parent > a { padding-bottom: 6px; }

/* Franchise Opportunities keeps the teal pill it has in the desktop bar. */
#tm-dialog-mobile .uk-nav > li > a.uc-nav-cta {
    margin: 14px 0 0;
    justify-content: center;
    font-size: 15.5px;
}
#tm-dialog-mobile .uk-nav > li:has(> a.uc-nav-cta) { border-top: 0; }

/* Contact block: separated from the nav, then the two CTAs and the socials. */
.uc-menu-foot {
    border-top: 1px solid #E4EAF2;
    margin-top: 22px;
    padding-top: 22px;
}
.uc-menu-cta .uk-button { width: 100%; justify-content: center; font-size: 15.5px; }
/* Second CTA is the phone number. Default buttons are the teal franchise
   treatment elsewhere, which would read as a third franchise link here. */
.uc-menu-cta .uk-button-default {
    background: var(--uc-wash);
    border-color: #CBDCEE;
    color: var(--uc-navy);
}
.uc-menu-cta .uk-button-default:hover { background: #E3EDF8; color: var(--uc-navy); }

.uc-menu-social { margin-top: 18px; }
.uc-menu-social .uk-icon-button {
    background: var(--uc-wash);
    color: var(--uc-navy);
    width: 44px;
    height: 44px;
}
.uc-menu-social .uk-icon-button:hover { background: var(--uc-navy); color: #fff; }

/* --- typeface ------------------------------------------------------------
 * Poppins is applied here rather than through the Customizer's font variables.
 * Those expect a REGISTERED font name (AXM's were "museo"/"museo-sans"), not a
 * raw CSS stack: setting a stack stages fine in the database but compiles to
 * nothing, verified 13/08 (0 occurrences of "Poppins" in theme.12.css).
 *
 * This is the one place a token legitimately lives in CSS. Font SIZES stay in
 * the Customizer, so swapping to the licensed brand faces later is still a
 * change to this block plus the @import, not a sweep through the layouts.
 */
/* The selector list is NOT hand-maintained. templates/yootheme_child/css/
 * theme.12.css is still the AXM Law compile and sets font-family: museo-sans in
 * 71 places, starting with `html`. museo-sans was AXM's Adobe Fonts family and
 * is not loaded here, so anything not overridden below falls back to the
 * browser's default serif. That is why the mobile menu rendered in Times: the
 * previous version of this rule listed only body, navbar links, buttons,
 * blockquote and form fields, and .uk-nav-default was not among them. It would
 * have hit article titles, FAQ accordion titles, card titles and form labels on
 * every subpage too.
 *
 * Regenerate the list after any theme recompile:
 *   node build/scripts/find_stale_fonts.mjs
 *
 * The real fix is the Customizer, which recompiles theme.12.css with the right
 * family - but YOOtheme only compiles LESS in the browser, so it needs a
 * browser session. This block is the interim, and is why the token lives in CSS
 * at all. */
.awesomplete > ul,
.blockquote-footer,
.btn,
.display-1, .display-2, .display-3, .display-4, .display-5, .display-6,
.form-label,
.h1, .h2, .h3, .h4, .h5, .h6,
.lead,
.tm-section-title,
.uk-accordion-default .uk-accordion-title,
.uk-article-meta,
.uk-article-title,
.uk-badge,
.uk-breadcrumb > * > *,
.uk-button,
.uk-card-badge,
.uk-card-title,
.uk-comment-meta,
.uk-description-list > dt,
.uk-dropdown-nav,
.uk-font-primary, .uk-font-secondary, .uk-font-tertiary,
.uk-form-label,
.uk-h1, .uk-h2, .uk-h3, .uk-h4, .uk-h5, .uk-h6,
.uk-heading-2xlarge, .uk-heading-3xlarge, .uk-heading-large,
.uk-heading-medium, .uk-heading-small, .uk-heading-xlarge,
.uk-label,
.uk-logo,
.uk-modal-title,
.uk-nav-default, .uk-nav-primary, .uk-nav-secondary,
.uk-navbar-dropdown-nav,
.uk-navbar-item,
.uk-navbar-nav > li > a,
.uk-navbar-toggle,
.uk-pagination > * > *,
.uk-search-navbar .uk-search-input,
.uk-subnav > * > :first-child,
.uk-tab > * > a,
.uk-text-lead,
.uk-text-meta,
blockquote, blockquote footer, blockquote p, q, figure, figcaption,
h1, h2, h3, h4, h5, h6,
html, body,
joomla-tab button[role="tab"],
input, textarea, select {
    font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

h1, h2, h3, h4, h5, h6,
.uk-h1, .uk-h2, .uk-h3, .uk-h4, .uk-h5, .uk-h6,
.uk-card-title, .uk-logo {
    font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-weight: 600;
}

h1, .uk-h1 { font-weight: 700; }

/* compiled-LESS override.
 * theme.12.css sets `b, strong { font-weight: bolder }`. `bolder` is RELATIVE
 * to the inherited weight, and against this theme's light body weight it
 * resolves to 400, so no <strong> anywhere on the site actually rendered bold
 * (caught on the hero's "Frustration Free Cleaning." lead-in). An absolute
 * weight is what the mockup assumes. */
b, strong { font-weight: 700; }

/* --- type metrics from the token diff -----------------------------------
 * Measured against the mockup at 1360px on 13/08 (build/token-diff.md).
 * Only genuine drift is corrected here; most of the raw diff was probe noise
 * from the two documents ordering elements differently.
 *
 * h1 line-height was the clearest miss: 1.2 rendered (69.6px) against the
 * mockup's 1.05 (60.9px), which is nearly 9px of extra leading on the single
 * biggest element on the page.
 */
h1, .uk-h1 { line-height: 1.05; }
h2, .uk-h2 { line-height: 1.15; }

/* Mockup cards are 28px padding, not the theme's 40px. */
.uk-card-body { padding: 28px; }

/* Mockup buttons carry real vertical padding rather than relying on
 * line-height alone, so they keep their proportions when text wraps. */
.uk-button:not(.uk-button-text) {
    line-height: 1.4;
    padding-top: 13px;
    padding-bottom: 13px;
    display: inline-flex;
    align-items: center;
}
