/**
 * MCF — Services section (public profile)  [ADJ-41, layout reworked in ADJ-54]
 *
 * Both wrappers behind [mcf_services] carry mcf-services-n{N}, where N is how
 * many cards share a row — min(the column cap, how many services there are). The
 * cap is three by default (MCF_SERVICES_MAX_COLUMNS); [mcf_services columns="N"]
 * raises or lowers it. Because it's a cap and not a fixed track count, two
 * services never sit in a three-column grid with an empty third.
 *
 *   .mcf-services      a grid, used at N services or fewer:
 *                        1 service  → a single centred card
 *                        2 services → two equal columns
 *                        3 services → three across
 *   .mcf-services-car  a carousel, used past that: N on screen, the rest an
 *                      arrow away, driven by assets/js/mcf-carousel.js
 *
 * ADJ-54 asked for "a minimum of three and then a carousel of all the other
 * services". The alternative reading — three pinned in a row and the leftovers in
 * a second, separate carousel — breaks at four and five services, which is where
 * two of the seven licensees who have filled this in actually sit: a carousel
 * only engages once it holds more cards than it can show, so a tail of one or two
 * hides its own controls and strands a short part-width row under a full one. One
 * carousel of everything has no such case, and it gives every card the same
 * height for free because they share a track.
 *
 * The item widths below are load-bearing, not cosmetic: mcf-carousel.js derives
 * how many cells are visible by dividing the viewport width by one cell plus the
 * gap. Each count class must therefore size its cells to exactly
 * (100% - (N-1) × gap) / N, or the slider will step by the wrong number of cards.
 *
 * Below 1100px both layouts step down to two across, and below 620px to one — so
 * spacing and alignment stay consistent at every count and every width.
 *
 * The card began as a deliberate copy of the hard-coded ones in the Electrical
 * and Plumbing Content Blocks, so the static rows could be swapped for the
 * shortcode without the section changing appearance. ADJ-54 is where it stops
 * imitating them, because that inheritance was doing real damage: the block's
 * title was a <strong> inside an ordinary paragraph, so the card had no headline
 * at all, and three flat grey panels of 100-word copy read as a page of text.
 *
 *   was                              now
 *   #f7f7f7 panel, no edge      →    white, hairline border, faint shadow
 *   5px accent band             →    2px, same colour
 *   title at body size          →    1.16em, tighter leading
 *   body at page colour/size    →    one step muted, .95em
 *   full copy, ragged heights   →    clamped, opened by "Read more"
 *   no hover state              →    sides warm to the accent, 2px lift
 *
 * Accent resolution: [mcf_services accent="#hex"] (inline) → the division default
 * below → orange. Defined HERE rather than borrowed from mcf-public.css, which
 * only sets --mcf-accent and only loads on profile pages, so the section is
 * correct wherever the shortcode is used.
 *
 * Knobs, all optional: --mcf-service-clamp (lines before "Read more" appears),
 * --mcf-service-title-size, --mcf-service-desc-size, --mcf-service-surface,
 * --mcf-service-border, --mcf-service-bar (accent band thickness).
 *
 * Carousel controls are shortcode-side: [mcf_services arrows="no"] drops the
 * ‹ › buttons (and adds .is-dots-only, below), [mcf_services autoplay="6000"]
 * advances it on a timer. Autoplay never runs under prefers-reduced-motion.
 *
 * So is the clamp: [mcf_services clamp="no"] omits .is-clamped and the button
 * both, printing every description in full; clamp="3" sets --mcf-service-clamp
 * on the wrapper, which the cards inherit.
 */

.mcf-services {
    display: grid;
    gap: 32px;
    align-items: stretch;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    /* Fill the column Louise puts the shortcode in — the Uncode row/column already
       controls the content width, so a cap of our own would make this section
       narrower than every other section on the profile. Set --mcf-services-max on
       the row if a particular placement ever wants one (it then centres itself). */
    width: 100%;
    max-width: var(--mcf-services-max, none);
    margin-inline: auto;
}

/* ── Division accent ──────────────────────────────────────────────────────
   Either wrapper always carries mcf-svc-{division} (the shortcode adds it), so
   the bar and the icon follow the trade. Falls back to --mcf-accent — Louise's
   own per-page override in mcf-public.css — then to orange.

   Listed for both wrappers rather than moved onto a shared base class: pages
   cached before ADJ-54 still carry the old .mcf-services markup, and they must
   keep their accent. */
.mcf-services,
.mcf-services-car                    { --mcf-service-accent: var(--mcf-accent, #ff6633); }
.mcf-services.mcf-svc-kitchen,
.mcf-services-car.mcf-svc-kitchen    { --mcf-service-accent: #008ca7; }
.mcf-services.mcf-svc-plumbing,
.mcf-services-car.mcf-svc-plumbing   { --mcf-service-accent: #ff6633; }
.mcf-services.mcf-svc-electrical,
.mcf-services-car.mcf-svc-electrical { --mcf-service-accent: #64a70b; }

/* ── Cards per row ────────────────────────────────────────────────────────
   Fixed column counts (not auto-fit) so 2 cards are two halves rather than two
   narrow tracks with dead space beside them. Anything past the row count wraps. */
.mcf-services-n1 {
    grid-template-columns: minmax(0, var(--mcf-service-solo, 460px));
    justify-content: center;
}
.mcf-services-n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.mcf-services-n3,
.mcf-services-many { grid-template-columns: repeat(3, minmax(0, 1fr)); } /* -many: legacy class, cached pages */
/* Only reachable via an explicit columns="4|5|6" on the shortcode. */
.mcf-services-n4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.mcf-services-n5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.mcf-services-n6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }

/* ── Card ─────────────────────────────────────────────────────────────────
   White panel with a hairline edge rather than a flat grey area, so a card reads
   as a discrete object on the white page — and so the carousel has something
   with edges to slide. The accent keeps the full width of the top, at 2px
   instead of 5: three 5px bands to a row was a lot of colour for a section that
   repeats down the page. */
.mcf-service-card {
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-width: 0;
    background: var(--mcf-service-surface, #fff);
    border: 1px solid var(--mcf-service-border, #e3e8ef);
    /* After the shorthand, or it loses to it. */
    border-top: var(--mcf-service-bar, 2px) solid var(--mcf-service-accent, #ff6633);
    border-radius: 2px;
    box-shadow: 0 1px 2px rgba(0, 46, 98, .05);
    transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}

/* Deliberately NOT the `border-color` shorthand: that would repaint the top edge
   too and wash the trade colour out on hover, which is the one part of the card
   that should never move. */
.mcf-service-card:hover {
    border-inline-color: color-mix(in srgb, var(--mcf-service-accent, #ff6633) 45%, var(--mcf-service-border, #e3e8ef));
    border-block-end-color: color-mix(in srgb, var(--mcf-service-accent, #ff6633) 45%, var(--mcf-service-border, #e3e8ef));
    box-shadow: 0 4px 18px -8px rgba(0, 46, 98, .28);
    transform: translateY(-2px);
}

/* The service's own picture, washed out to a texture — Uncode's back_image with
   overlay_color=white at overlay_alpha=90, expressed in plain CSS. */
.mcf-service-card-bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
}
.mcf-service-card-bg::after {
    content: "";
    position: absolute;
    inset: 0;
    background: #fff;
    opacity: .9;
}

.mcf-service-card-body {
    position: relative; /* above the backdrop */
    z-index: 1;
    flex: 1 1 auto;
    padding: clamp(24px, 2.4vw, 40px);
    text-align: left;
    /* A column so "Read more" can be pushed to the foot of the card. Cards in a
       row are equal height, so without it the link sits directly under copy that
       ends at a different place on each card — one wrapped title is enough to
       knock a row of them out of line. */
    display: flex;
    flex-direction: column;
    /* Children keep the default stretch so the title and copy stay full width —
       only the button opts out, below. */
}

/* ── The picture: full-bleed across the top of the card ───────────────────
   Edge to edge (it sits outside the padded body) and above the backdrop layer.
   A fixed crop ratio, NOT the file's own proportions: cards in a row are equal
   height, so images of differing shapes would push each card's title to a
   different line and the row would read as ragged. Set --mcf-service-img-ratio
   to auto for natural height, or to another ratio to taste. */
.mcf-service-card-media {
    position: relative;
    z-index: 1;
    margin: 0;
    line-height: 0;
}
.mcf-service-card-img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: var(--mcf-service-img-ratio, 16 / 9);
    object-fit: cover;
    object-position: center;
}

/* ── The icon: a glyph in an accent disc, above the title ─────────────────
   Its own slot — a card may have a picture, an icon, both or neither. */
.mcf-service-card-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--mcf-service-mark-size, 56px);
    height: var(--mcf-service-mark-size, 56px);
    margin: 0 0 20px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--mcf-service-accent, #ff6633) 12%, #fff);
    color: var(--mcf-service-accent, #ff6633);
    line-height: 1;
}
.mcf-service-card-icon i { font-size: 24px; }

/* The card carried the block's own title treatment until ADJ-54: a <strong>
   inside an ordinary paragraph, i.e. the SAME size as the body copy. Faithful,
   but it left the card with nothing to scan — the service name and its 100 words
   read as one undifferentiated paragraph. Now a step up with tighter leading,
   which is the single biggest readability gain in this ticket. !important beats
   Uncode's own h3 sizing; --mcf-service-title-size still overrides. */
.mcf-service-card-title {
    margin: 0 0 .55em;
    font-size: var(--mcf-service-title-size, 1.16em) !important;
    line-height: 1.28;
    font-weight: 700;
    letter-spacing: -.01em;
    color: #002e62;
}

/* One step back from the title in both size and colour, so the eye lands on the
   service name first. */
.mcf-service-card-desc {
    margin: 0;
    font-size: var(--mcf-service-desc-size, .95em);
    line-height: 1.65;
    color: var(--mcf-service-desc-color, #55637a);
}
.mcf-service-card-desc p { margin: 0 0 1em; }
.mcf-service-card-desc p:last-child { margin-bottom: 0; }

/* ── Clamped copy + "Read more" ───────────────────────────────────────────
   Head Office's descriptions run 80-120 words, so eight services was ~900 words
   in one section. Clamping to five lines makes the section scannable and gives
   the cards in a row matching heights; the button opens the rest in place, so
   nothing HO wrote is lost.

   -webkit-line-clamp is the only clamp that ellipsises, and the ellipsis is what
   signals there IS more — but it counts the box's line boxes, so the paragraph
   margins inside have to be tightened or a gap eats one of the five lines.
   Rendered clamped from the server (no flash of full text); mcf-services.js
   reveals the button only where the copy actually overflows. */
.mcf-service-card-desc.is-clamped {
    display: -webkit-box;
    -webkit-line-clamp: var(--mcf-service-clamp, 5);
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.mcf-service-card-desc.is-clamped p { margin: 0 0 .55em; }
.mcf-service-card-desc.is-clamped p:last-child { margin-bottom: 0; }

.mcf-service-more {
    /* Opts out of the body's stretch, or it would run the full card width with
       its label stranded in the middle. */
    align-self: flex-start;
    /* Auto top margin drops it to the foot of the card so a row of them lines
       up; the padding keeps a gap when a card is full and there's no slack. */
    margin: auto 0 0;
    padding: 14px 0 0;
    border: 0;
    background: none;
    font: inherit;
    font-size: .9em;
    font-weight: 700;
    line-height: 1.4;
    color: var(--mcf-service-accent, #ff6633);
    cursor: pointer;
}
.mcf-service-more:hover { text-decoration: underline; }
.mcf-service-more:focus-visible {
    outline: 2px solid var(--mcf-service-accent, #ff6633);
    outline-offset: 3px;
}
/* [hidden] loses to the display above on its own. */
.mcf-service-more[hidden] { display: none; }

/* ── Carousel ─────────────────────────────────────────────────────────────
   The shell mcf-carousel.js drives. Every rule is scoped to .mcf-services-car
   and so carries two classes to the one in mcf-public.css's designer-carousel
   shell — it wins on specificity wherever both load, and stands on its own on
   pages (Head Office's "Our Services") where mcf-public.css never loads at all.

   ⚠️ The cell widths are the slider's input, not decoration. visible() divides
   the viewport by cell + gap, so each count must resolve to exactly N cells:
   (100% - (N-1) × gap) / N. Change a gap here and the matching basis changes
   with it, or the carousel will step by the wrong number of cards. */
.mcf-services-car {
    --mcf-services-gap: 32px;
    position: relative;
    width: 100%;
    max-width: var(--mcf-services-max, none);
    margin-inline: auto;
}
.mcf-services-car .mcf-carousel-viewport { overflow: hidden; }
.mcf-services-car .mcf-carousel-track {
    display: flex;
    gap: var(--mcf-services-gap);
    transition: transform .4s ease;
}
.mcf-services-car .mcf-carousel-item {
    min-width: 0;
    display: flex;          /* stretches the card to the tallest in the track */
}
.mcf-services-car .mcf-carousel-item > .mcf-service-card { width: 100%; }

.mcf-services-car.mcf-services-n1 .mcf-carousel-item { flex: 0 0 100%; }
.mcf-services-car.mcf-services-n2 .mcf-carousel-item { flex: 0 0 calc((100% - 32px) / 2); }
.mcf-services-car.mcf-services-n3 .mcf-carousel-item { flex: 0 0 calc((100% - 64px) / 3); }
.mcf-services-car.mcf-services-n4 .mcf-carousel-item { flex: 0 0 calc((100% - 96px) / 4); }
.mcf-services-car.mcf-services-n5 .mcf-carousel-item { flex: 0 0 calc((100% - 128px) / 5); }
.mcf-services-car.mcf-services-n6 .mcf-carousel-item { flex: 0 0 calc((100% - 160px) / 6); }

.mcf-services-car .mcf-carousel-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin-top: 26px;
}
.mcf-services-car .mcf-carousel-prev,
.mcf-services-car .mcf-carousel-next {
    width: 42px;
    height: 42px;
    padding: 0;
    border-radius: 50%;
    border: 1.5px solid #d7dde7;
    background: #fff;
    color: #002e62;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    transition: background .2s, border-color .2s, color .2s, opacity .2s;
}
.mcf-services-car .mcf-carousel-prev:hover,
.mcf-services-car .mcf-carousel-next:hover {
    background: var(--mcf-service-accent, #ff6633);
    border-color: var(--mcf-service-accent, #ff6633);
    color: #fff;
}
.mcf-services-car .mcf-carousel-dots { display: flex; gap: 8px; }
.mcf-services-car .mcf-carousel-dot {
    width: 8px;
    height: 8px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: #d7dde7;
    cursor: pointer;
}
.mcf-services-car .mcf-carousel-dot.is-active { background: var(--mcf-service-accent, #ff6633); }

/* ── arrows="no" ──────────────────────────────────────────────────────────
   With the arrows gone the dots are the only way through, and an 8px target is
   too small to be the only one — particularly on a phone, where this is the
   layout most likely to be used. The dot stays 8px; a transparent ::after grows
   the TARGET to 24px square. The gap widens to 16px to make room, because at
   the old 8px the neighbouring targets would overlap and a tap near the edge
   would land on the wrong dot.

   Only under .is-dots-only, so every carousel that kept its arrows is untouched. */
.mcf-services-car.is-dots-only .mcf-carousel-dots { gap: 16px; }
.mcf-services-car.is-dots-only .mcf-carousel-dot { position: relative; }
.mcf-services-car.is-dots-only .mcf-carousel-dot::after {
    content: "";
    position: absolute;
    inset: -8px;
}
.mcf-services-car .mcf-carousel-prev:focus-visible,
.mcf-services-car .mcf-carousel-next:focus-visible,
.mcf-services-car .mcf-carousel-dot:focus-visible {
    outline: 2px solid var(--mcf-service-accent, #ff6633);
    outline-offset: 3px;
}

/* Nothing here is information — the cards are all still reachable by arrow, and
   the section reads the same without any of it moving. */
@media (prefers-reduced-motion: reduce) {
    .mcf-services-car .mcf-carousel-track { transition: none; }
    .mcf-service-card { transition: none; }
    .mcf-service-card:hover { transform: none; }
}

/* ── Responsive ───────────────────────────────────────────────────────────── */
@media (max-width: 1100px) {
    /* Every multi-column count drops to two. NOT `.mcf-services` itself — that
       would out-specify .mcf-services-n1 (same weight, later in the file) and put
       a lone card in a two-column grid with an empty half beside it. */
    .mcf-services-n3,
    .mcf-services-n4,
    .mcf-services-many,
    .mcf-services-n5,
    .mcf-services-n6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* An ODD number of cards in a two-column grid leaves a lone last one — centre
       it across both tracks (half a gap either side) instead of stranding it
       left. :nth-child(odd):last-child is what makes this odd-only: with an even
       count the last card has a partner and must stay in its own track. (The
       count class alone can't tell us — mcf-services-n3 now means "three per
       row", so it covers 3, 6, 8 … services.) */
    :not(.mcf-services-n1) > .mcf-service-card:nth-child(odd):last-child {
        grid-column: 1 / -1;
        max-width: calc(50% - 16px);
        margin-inline: auto;
    }

    /* Two cells across. Enumerated per count rather than written once against
       .mcf-services-car, which would carry one class fewer than the rules above
       and lose to them. Gap is still 32, so the basis stays (100% - 32px) / 2. */
    .mcf-services-car.mcf-services-n3 .mcf-carousel-item,
    .mcf-services-car.mcf-services-n4 .mcf-carousel-item,
    .mcf-services-car.mcf-services-n5 .mcf-carousel-item,
    .mcf-services-car.mcf-services-n6 .mcf-carousel-item { flex-basis: calc((100% - 32px) / 2); }
}

@media (max-width: 620px) {
    .mcf-services { gap: 20px; grid-template-columns: minmax(0, 1fr); }
    .mcf-services-n1,
    .mcf-services-n2,
    .mcf-services-n3,
    .mcf-services-n4,
    .mcf-services-many,
    .mcf-services-n5,
    .mcf-services-n6 { grid-template-columns: minmax(0, 1fr); }
    /* Undo the two-column orphan centring — every card is full width now. Same
       selector shape, so it reliably overrides rather than losing on specificity. */
    :not(.mcf-services-n1) > .mcf-service-card:nth-child(odd):last-child {
        grid-column: auto;
        max-width: none;
    }

    /* One cell across, and the tighter gap the grid uses at this width — so the
       basis is a plain 100% and step() becomes viewport + gap. */
    .mcf-services-car { --mcf-services-gap: 20px; }
    .mcf-services-car.mcf-services-n2 .mcf-carousel-item,
    .mcf-services-car.mcf-services-n3 .mcf-carousel-item,
    .mcf-services-car.mcf-services-n4 .mcf-carousel-item,
    .mcf-services-car.mcf-services-n5 .mcf-carousel-item,
    .mcf-services-car.mcf-services-n6 .mcf-carousel-item { flex-basis: 100%; }
    .mcf-services-car .mcf-carousel-controls { margin-top: 20px; }
}
