/*
 * AF Appliance — project styles layered on top of the CM-Repair template.
 *
 * Only additions and overrides live here; the template's own style.min.css
 * is left untouched so it can still be regenerated from assets/scss.
 * Palette follows the template: primary #ffaa19, blue #18305d, dark #35382f.
 */

:root {
    --af-primary: #ffaa19;
    --af-blue: #18305d;
    --af-dark: #35382f;
    --af-light-gray: #f3f3f5;
}

/* ---------------------------------------------------------------- header */

/*
 * The header is the template's stock .cm-header: a navy .header-top whose
 * .block .icon spans already supply the amber glyph and the left/right
 * divider rules, above a white .header. Almost nothing needs overriding —
 * only the top bar's links, which the template renders as plain text.
 */
.header-top .block {
    display: inline-flex;
    align-items: center;
}

a.block.text-gray:hover {
    color: var(--af-primary) !important;
    text-decoration: none;
}

a.block.text-gray:hover .icon {
    color: var(--af-primary);
}

@media (max-width: 991.98px) {
    .header-top .block {
        display: flex;
        justify-content: center;
        margin-right: 0 !important;
        padding: 3px 0;
    }
}

/*
 * The Services dropdown is filled from the database, so its longest entry is
 * whatever the admin panel holds — "Garbage Disposal Repair" and friends are
 * far wider than the template's fixed 220px menu, and Bootstrap's
 * white-space: nowrap on .dropdown-item then pushes them straight out of the
 * box. Letting the menu size to its content fixes both: short items keep one
 * line, and only a name past 340px is allowed to wrap.
 */
.cm-header .navbar .dropdown-item {
    white-space: normal;
}

@media (min-width: 992px) {
    .cm-header .navbar .dropdown-menu {
        width: auto;
        min-width: 220px;
        max-width: 340px;
    }
}

/* ------------------------------------------------------------------ banner */

/*
 * .cm-banner-03 is the template's banner: a photo behind an .overlay-dark
 * (#18305d at 50%). The template's own bg-banner-03.jpg is a placeholder
 * stamped with its pixel dimensions, so the photo layer is a navy gradient
 * until real photography is supplied — swap the background here, the
 * overlay and layout stay as the template defines them.
 */
.cm-banner-03 {
    background-color: var(--af-blue);
    background-image:
        radial-gradient(1100px 550px at 12% 12%, rgba(255, 170, 25, .20), transparent 62%),
        linear-gradient(120deg, #0b1b38 0%, #1c3868 55%, #0e2450 100%);
}

.cm-banner-03 .display-4 {
    line-height: 1.15;
    font-weight: 700;
}

/* ---------------------------------------------------------- booking form */

/*
 * .banner-form is styled by the template (1px amber border, 45px flat
 * #f3f3f5 inputs). Only the validation affordances are added here.
 */
.banner-form .js-error:empty {
    display: none !important;
}

.banner-form .invalid-feedback.js-error {
    color: #dc3545;
    font-size: 13px;
    margin-top: 4px;
}

.banner-form textarea.form-control {
    height: 90px;
}

/* Inner pages embed this card outside a banner, where it needs its own edge. */
.sidebar .banner-form,
.section .banner-form {
    box-shadow: 0 5px 25px -5px #eee;
}

/*
 * The form's paired fields use col-md-6, which keys off the viewport rather
 * than the container — inside the narrow inner-page sidebar that leaves the
 * appliance select too tight to read its own label. Stack them there.
 */
@media (min-width: 768px) {
    .sidebar .banner-form .col-md-6 {
        flex: 0 0 100%;
        max-width: 100%;
    }
}

/* -------------------------------------------------------------- sections */

.section-sub-heading {
    letter-spacing: 1.5px;
    font-size: 14px;
    margin-bottom: 0;
}

/*
 * Service cards.
 *
 * The photos are real job shots at assorted aspect ratios, so they are
 * cropped to one fixed ratio with object-fit: cover — `contain` letterboxed
 * every card differently and left ragged grey margins. The body is a flex
 * column with the "Read more" link pushed to the bottom, so the links line up
 * across a row no matter how long each description is.
 */
.service-item {
    box-shadow: 0 5px 25px -5px #eee;
    overflow: hidden;
    transition: transform .25s ease, box-shadow .25s ease;
}

.service-item:hover {
    transform: translateY(-6px);
    box-shadow: 0 14px 34px rgba(0, 0, 0, .12);
}

.service-item-media {
    display: block;
    overflow: hidden;
    background: var(--af-light-gray);
}

.service-item .card-img-top {
    display: block;
    width: 100%;
    height: 215px;
    object-fit: cover;
    border-radius: 0;
    transition: transform .4s ease;
}

.service-item:hover .card-img-top {
    transform: scale(1.06);
}

.service-item .card-body {
    display: flex;
    flex-direction: column;
    padding: 25px;
}

.service-item .service-item-title {
    margin-bottom: 10px;
}

/* Even out the ragged descriptions so every card is the same shape. */
.service-item .service-item-text {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-bottom: 18px;
    min-height: 72px;
}

.service-item .service-item-link {
    margin-top: auto;
    align-self: flex-start;
}

/* Blog cards: same treatment as the service cards so a row stays level
   regardless of how long each title and excerpt runs. */
.blog-item {
    box-shadow: 0 5px 25px -5px #eee;
    overflow: hidden;
}

.blog-item .card-img-top {
    display: block;
    width: 100%;
    height: 215px;
    object-fit: cover;
    border-radius: 0;
}

.blog-item .card-body {
    display: flex;
    flex-direction: column;
    padding: 25px;
}

.blog-item .card-body h5 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 52px;
    margin-bottom: 0;
}

.blog-item .card-body p {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 72px;
}

.blog-item .card-body > a:last-child {
    margin-top: auto;
    align-self: flex-start;
}

.service-item h5 a,
.blog-item h5 a {
    color: inherit;
}

.service-item h5 a:hover,
.blog-item h5 a:hover {
    color: var(--af-primary);
}

/* ------------------------------------------------------- why choose us */

/*
 * The template paints .icon amber (#ffaa19) and sizes the glyph to 30px.
 * The AF icons are amber line art on transparent, so on the amber tile they
 * were effectively invisible. Give the tile a light surface and let the
 * artwork carry the colour.
 */
.why-choose-us .block .icon {
    height: 84px;
    width: 84px;
    line-height: 84px;
    border-radius: 50%;
    background-color: #fff7e6;
    border: 1px solid rgba(255, 170, 25, .35);
}

.why-choose-us .block:hover .icon {
    background-color: #fff;
    border-color: var(--af-primary);
}

.why-choose-us .block .icon img {
    height: 44px;
    width: 44px;
    object-fit: contain;
    vertical-align: middle;
}

/* -------------------------------------------------------------- reviews */

/* Rating summary line under the heading. */
.google-rating {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 4px 10px;
}

/* Same wordmark, same aspect — 22px square rendered it as unreadable mush. */
.google-rating-logo {
    width: 54px;
    height: 23px;
    flex: 0 0 auto;
    object-fit: contain;
}

.google-rating-score {
    font-size: 22px;
    line-height: 1;
    color: var(--af-dark);
}

.google-rating .rating {
    letter-spacing: 3px;
    font-size: 15px;
    white-space: nowrap;
}

.google-rating-count {
    color: #7a7a85;
    font-size: 15px;
}

/*
 * Review cards.
 *
 * Avatars are the fiddly part: Google serves square-ish photos, but inside a
 * flex row an <img> with only width/height attributes gets stretched into an
 * oval. They need explicit box sizing, flex: 0 0 auto so flex can't grow them,
 * and object-fit: cover so the crop stays square.
 */
.review-card {
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 5px 25px -5px #e4e4ea;
    padding: 28px 26px;
    height: 100%;
    display: flex;
    flex-direction: column;
    border: 1px solid #ecedf2;
}

.review-card-head {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 16px;
}

/*
 * Owl ships `.owl-carousel .owl-item img { width: 100% }` (specificity 0,2,1),
 * which beats any single-class rule and stretches every image in a slide to
 * the full card width — that is what turned the avatars into ovals and let the
 * Google mark shove the name column down to zero. These selectors are scoped
 * through .owl-item on purpose so they outrank it; do not "simplify" them.
 */
.testimonial-carousel .owl-item .review-avatar,
.review-avatar {
    width: 52px;
    height: 52px;
    min-width: 52px;
    flex: 0 0 52px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--af-light-gray);
}

.review-avatar-initial {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--af-primary);
    color: #fff;
    font-weight: 700;
    font-size: 20px;
}

/* min-width: 0 lets the name ellipsis instead of forcing the row wider. */
.review-meta {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1 1 auto;
}

.review-author {
    font-weight: 600;
    color: var(--af-dark);
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.review-time {
    font-size: 13px;
    color: #8b8b95;
    white-space: nowrap;
}

/* google.svg is the 300x127 wordmark, not a square glyph — size it to that
   aspect rather than squashing it into a box. */
.testimonial-carousel .owl-item .review-source,
.review-source {
    width: 46px;
    height: 20px;
    min-width: 46px;
    flex: 0 0 46px;
    object-fit: contain;
    object-position: right center;
    opacity: .9;
}

.review-stars {
    letter-spacing: 2px;
    font-size: 14px;
    margin-bottom: 12px;
}

/*
 * Reviews run from one line to a full paragraph. Clamping to four lines keeps
 * every card the same shape in the carousel — without it the slider height
 * jumped between slides.
 */
.review-body {
    margin: 0 0 16px;
    color: #6b6b76;
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 96px;
}

.review-link {
    margin-top: auto;
    align-self: flex-start;
    font-size: 13px;
    font-weight: 600;
    color: #8b8b95;
}

.review-link:hover {
    color: var(--af-primary);
}

/* Owl sizes each item to its own content; stretch them to the tallest slide. */
.testimonial-carousel .owl-stage {
    display: flex;
}

.testimonial-carousel .owl-item {
    display: flex;
    height: auto;
}

.testimonial-carousel .owl-item > div {
    width: 100%;
}

.testimonial-carousel .owl-dots {
    margin-top: 30px;
    text-align: center;
}

/* --------------------------------------------------------------- brands */

.brand-item {
    padding: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 110px;
}

/* The brand SVGs carry a viewBox but no intrinsic width/height, so `width:auto`
   collapses them to zero. Size them explicitly and let object-fit letterbox. */
.brand-item img {
    height: 62px;
    width: 100%;
    object-fit: contain;
    filter: grayscale(100%);
    opacity: .82;
    transition: filter .25s ease, opacity .25s ease;
}

.brand-item:hover img {
    filter: grayscale(0);
    opacity: 1;
}

.brand-card {
    background: #fff;
    border-radius: 6px;
    box-shadow: 0 6px 22px rgba(0, 0, 0, .07);
    padding: 28px;
    height: 100%;
}

.brand-card img {
    height: 56px;
    width: 100%;
    object-fit: contain;
}

/* ---------------------------------------------------------- zip checker */

/* Square, flat #f3f3f5 field to match the template's form-control treatment. */
.zip-checker .input-group {
    width: 100%;
}

.zip-checker .form-control {
    height: 45px;
    border-radius: 0;
    border: 1px solid #e9e9ee;
    box-shadow: none;
    background-color: var(--af-light-gray);
}

/*
 * The template's .btn carries 17px of vertical padding, which on a 16px/1.6
 * label builds a ~60px box next to the 45px input and leaves the button
 * standing proud of it. Matching the input's height outright keeps the two
 * level regardless of the label's font metrics, and the responsive .btn
 * padding at <768px no longer pulls them apart either.
 */
.zip-checker .btn {
    border-radius: 0;
    height: 45px;
    padding: 0 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.zip-result.is-served {
    color: #1c7c3f;
    font-weight: 600;
}

.zip-result.is-not-served {
    color: #c0392b;
    font-weight: 600;
}

/* ---------------------------------------------------------------- areas */

.area-block {
    background: #fff;
    border-radius: 6px;
    padding: 26px;
    box-shadow: 0 6px 22px rgba(0, 0, 0, .06);
}

.area-block a {
    text-decoration: none;
}

.area-block a:hover {
    text-decoration: underline;
}

/* --------------------------------------------------- gradient bands */

.service-area-band {
    background:
        radial-gradient(900px 500px at 85% 20%, rgba(255, 170, 25, .16), transparent 60%),
        linear-gradient(120deg, var(--af-blue) 0%, #0b1b38 100%);
}

.cm-cta {
    background: linear-gradient(120deg, #fff7e6 0%, var(--af-light-gray) 100%);
    border-top: 1px solid #eceef2;
    border-bottom: 1px solid #eceef2;
}

.footer {
    background:
        radial-gradient(800px 400px at 10% 0%, rgba(255, 170, 25, .10), transparent 60%),
        linear-gradient(160deg, #0b1b38 0%, #0a1730 100%);
}

/* ----------------------------------------------------------- page cover */

/* Same substitute-photo treatment as .cm-banner-03; the .overlay-dark on the
   element supplies the template's navy wash on top. */
.page-cover {
    padding: 90px 0;
    background-color: var(--af-blue);
    background-image:
        radial-gradient(900px 400px at 20% 10%, rgba(255, 170, 25, .18), transparent 60%),
        linear-gradient(120deg, #0b1b38 0%, #1c3868 100%);
}

/*
 * The artwork is a 300x156 PNG, so at a 62px height it renders 119x62 CSS px —
 * 238x124 device px on a 2x screen, still inside the source and therefore
 * sharp. Anything past ~78px starts upscaling on retina and goes soft; that
 * ceiling only lifts with an SVG or a 2x export.
 */
.site-logo {
    height: 62px;
    width: auto;
}

/*
 * Below 992px the template pins .navbar-brand img to width: 160px, and its
 * three-class selector outranks the width: auto above. The logo then gets a
 * width from the template and a height from here, so the 300x156 artwork is
 * squashed to 160x46 — and 160px is 43% of a 375px screen, half of a 320px
 * one. Restating both dimensions at a higher specificity hands the ratio back
 * to the image and leaves the wordmark legible without crowding the toggler.
 */
@media (max-width: 991.98px) {
    .cm-header .header .navbar-brand .site-logo {
        width: auto;
        height: 52px;
    }
}

.footer .site-logo {
    height: 74px;
}

.breadcrumb-list li + li::before {
    content: "\f105";
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    margin: 0 10px;
    opacity: .7;
}

.breadcrumb-list a {
    color: var(--af-primary);
}

.breadcrumb-list span {
    opacity: .85;
}

/* ------------------------------------------------------- article bodies */

.article-body h2,
.article-body h3,
.article-body h4 {
    color: var(--af-dark);
    margin-top: 32px;
    margin-bottom: 14px;
}

.article-body h3 {
    font-size: 24px;
}

.article-body p {
    margin-bottom: 16px;
}

.article-body ul,
.article-body ol {
    margin: 0 0 18px 20px;
}

.article-body li {
    margin-bottom: 8px;
}

.article-body img {
    max-width: 100%;
    height: auto;
    border-radius: 6px;
    margin: 12px 0;
}

.article-body table {
    width: 100%;
    margin-bottom: 18px;
    border-collapse: collapse;
}

.article-body table td,
.article-body table th {
    border: 1px solid #e3e3e8;
    padding: 10px;
}

/* Long content tables must scroll on their own, never the page. */
.article-body .table-scroll {
    overflow-x: auto;
}

/* ------------------------------------------------------- floating icons */

/*
 * One fixed row in the bottom-right corner: WhatsApp, call, back-to-top.
 * Previously each sat at its own offset and size — the two contact buttons
 * stacked at right:18px/bottom:92px and the template's own back-to-top at
 * right:30px/bottom:0 — which read as three stray buttons rather than one bar.
 */
.social-float {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 995;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
}

.social-float-btn {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 19px;
    line-height: 1;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .22);
    transition: transform .2s ease;
}

.social-float-btn:hover {
    color: #fff;
    transform: translateY(-3px);
}

.social-float-whatsapp {
    background: #25d366;
}

.social-float-phone {
    background: var(--af-primary);
}

/*
 * The template styles a.scroll-to-top as its own fixed element and toggles it
 * with opacity/visibility — inside a flex row that would leave a permanent gap
 * before the user scrolls. Reset the positioning and swap the toggle for
 * display, so the row simply grows when the button becomes available.
 */
.social-float .scroll-to-top {
    position: static;
    right: auto;
    bottom: auto;
    height: 46px;
    width: 46px;
    line-height: 1;
    font-size: 19px;
    background: var(--af-blue);
    border-radius: 50%;
    opacity: 1;
    visibility: visible;
    display: none;
}

.social-float .scroll-to-top.show {
    bottom: auto;
    display: inline-flex;
}

.social-float .scroll-to-top.show:hover {
    transform: translateY(-3px);
}

@media (max-width: 767.98px) {
    .social-float {
        right: 14px;
        bottom: 14px;
        gap: 8px;
    }

    .social-float-btn,
    .social-float .scroll-to-top {
        width: 42px;
        height: 42px;
        font-size: 17px;
    }
}

/* --------------------------------------------------------------- footer */

.footer-links li,
.footer-contact li {
    margin-bottom: 10px;
}

.footer-links a,
.footer-contact a {
    color: #cecece;
}

.footer-links a:hover,
.footer-contact a:hover {
    color: var(--af-primary);
}

.footer .social-links li {
    display: inline-block;
    margin-right: 12px;
}

.footer .social-links a {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, .12);
    color: #fff;
}

.footer .social-links a:hover {
    background: var(--af-primary);
}

.footer-bottom {
    background: var(--af-dark);
    padding: 18px 0;
}

.footer-bottom p {
    margin: 0;
    color: #cecece;
    font-size: 14px;
}

/* ----------------------------------------------------------- preloader */

/*
 * The template's preloader is a solid amber sheet (#ffaa19), so the wait reads
 * as a colour flash with the page hidden behind it. Frosting the sheet instead
 * lets the real page show through blurred, which tells the visitor which page
 * is arriving while the spinner keeps saying that it is still on its way.
 */
.preloader-wrapper {
    /* Enough blur to read as "not ready yet", little enough that the banner
       and the booking card stay recognisable as this page. */
    background-color: rgba(243, 243, 245, .42);
    -webkit-backdrop-filter: blur(10px) saturate(140%);
    backdrop-filter: blur(10px) saturate(140%);
}

/*
 * Without backdrop-filter a half-transparent sheet leaves the page perfectly
 * legible and merely washed out — it stops looking like loading at all. Those
 * browsers get an almost-opaque sheet instead: no blur, but still not a flash.
 */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
    .preloader-wrapper {
        background-color: rgba(243, 243, 245, .94);
    }
}

/*
 * The dots are #35382f, and a see-through backdrop can now put them over the
 * banner photo, which is dark enough to swallow them. A frosted puck under the
 * spinner keeps it readable wherever on the page it lands.
 */
.preloader-inner {
    width: 104px;
    height: 104px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(255, 255, 255, .72);
    box-shadow: 0 10px 30px rgba(24, 48, 93, .16);
}

/* --------------------------------------------------------- misc helpers */

/* ---------------------------------------------------------- pagination */

/*
 * Bootstrap's stock paginator is rounded, blue-linked and collapses its items
 * into one bar with -1px margins — none of which belongs next to a template
 * built on square, amber, uppercase controls. These rules restate it in the
 * site's own language: square 45px cells, matching the zip input and its
 * button, separated rather than fused, and hovering to navy.
 */
.pagination {
    border-radius: 0;
    flex-wrap: wrap;
    gap: 8px;
}

.pagination .page-link {
    margin-left: 0;
    min-width: 45px;
    height: 45px;
    padding: 0 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #e9e9ee;
    border-radius: 0;
    background-color: var(--af-light-gray);
    color: var(--af-dark);
    font-weight: 600;
    line-height: 1;
    transition: .3s;
}

/* Bootstrap rounds the outermost cells specifically; the pair is square now. */
.pagination .page-item:first-child .page-link,
.pagination .page-item:last-child .page-link {
    border-radius: 0;
}

.pagination .page-link:hover,
.pagination .page-link:focus {
    background-color: var(--af-blue);
    border-color: var(--af-blue);
    color: #fff;
    box-shadow: none;
    text-decoration: none;
}

.pagination .page-item.active .page-link {
    background-color: var(--af-primary);
    border-color: var(--af-primary);
    color: var(--af-dark);
}

/*
 * The disabled arrow still occupies a cell, so it has to read as present but
 * inert rather than as another clickable page.
 */
.pagination .page-item.disabled .page-link {
    background-color: #fff;
    border-color: #ededf2;
    color: #c3c3cb;
}

.bg-blue {
    background-color: var(--af-blue);
}
