/*
 * Plain CSS (not Tailwind) for legacy Page Builder rich-text content stored
 * in the database - CMS content written with Bootstrap-era class names
 * (.title, .btn, .btn-default, .text-center) that mean nothing under Hyva.
 * This does NOT need a Tailwind rebuild; it deploys as a normal static file
 * (but see knowledge/servair-static-deploy-keeps-stale-files.md: delete the
 * theme's pub/static dir first or the old copy is served).
 */

/*
 * MGS_Fbuilder section-builder containment, 2026-09-05.
 * The homepage main is full-width (Magento_Cms/layout/cms_index_index.xml) the way Supro's is,
 * and these rules reproduce what MGS_Fbuilder::css/styles.css does on Supro for the
 * .section-builder / .frame markup baked into CMS page 2 - Fbuilder scopes its own rules to
 * body.active-builder, which is only added when fbuilder/general/is_enabled is on, and that is
 * deliberately off for this theme. Values are Supro's: 1240px centred frame, 15px gutters,
 * full sections edge to edge.
 */
.section-builder .frame {
    max-width: 1240px;
    margin: 0 auto;
    padding: 0 15px;
    box-sizing: border-box;
}

.section-builder-full .frame,
.section-builder .frame.no-padding {
    padding: 0;
}

.section-builder-full .frame {
    max-width: 100%;
}

/*
 * Section headings baked into CMS page 2 ("Customer Favourites" / "Latest News" + subtitle).
 * Restyled 2026-09-11 to the design language: the title takes the display face and the split
 * hairline, the subtitle is muted. The markup is Magezon-stored content, so this is the one
 * place the homepage headers can be changed without touching the database. When the homepage
 * is rebuilt (design plan, rollout 4) these rules go and the markup uses .servair-eyebrow /
 * .servair-section-title / .servair-rule directly.
 */
.section-title {
    margin-bottom: 1.5rem;
}

.section-title .title {
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: 500;
    line-height: 1.3;
    color: var(--color-ink);
    margin-bottom: 0.5rem;
}

.section-title .title::after {
    content: "";
    display: block;
    width: 48px;
    height: 2px;
    margin-top: 12px;
    background: linear-gradient(to right, var(--color-brand-red) 0 23px, transparent 23px 25px, var(--color-primary) 25px);
}

.section-title .subtitle {
    font-size: 1rem;
    color: var(--color-ink-muted);
}

/*
 * Promo banner overlay text (MGS_Fbuilder/templates/widget/promobanner.phtml), measured on the
 * live Supro homepage: title 48px/400 dark, optional 16px eyebrow paragraph above it, and
 * "Browse" as a small caps-style, letter-spaced, underlined text link - not a filled button.
 * Sizes step down on small screens so a 3-across tile that has collapsed to full width still
 * fits its text.
 */
.fbuilder-banner-text .text-center {
    text-align: center;
}

.fbuilder-banner-text .title {
    font-size: clamp(1.75rem, 3.3vw, 3rem);
    font-weight: 400;
    line-height: 1;
    margin-bottom: 1.5rem;
    color: var(--color-ink);
}

.fbuilder-banner-text .title strong {
    font-weight: 400;
}

.fbuilder-banner-text p {
    font-size: 1rem;
    color: var(--color-ink);
    margin-bottom: 0.5rem;
}

.fbuilder-banner-text a.btn,
.fbuilder-banner-text a.btn-default {
    display: inline-block;
    padding: 0 0 5px;
    background: none;
    color: var(--color-ink);
    border: 0;
    border-bottom: 2px solid var(--color-ink);
    border-radius: 0;
    font-size: 12px;
    font-weight: 700;
    text-decoration: none;
}

/*
 * MGS_Brand admin-entered WYSIWYG brand descriptions (mgs_brand.description) -
 * same rationale as .fbuilder-banner-text above: unstyled headings/paragraphs/
 * links from stored HTML, no Tailwind typography plugin installed.
 */
.brand-description h1,
.brand-description h2,
.brand-description h3 {
    font-weight: 700;
    margin: 1rem 0 0.5rem;
}

.brand-description p {
    margin-bottom: 0.75rem;
}

.brand-description a {
    color: var(--color-primary);
    text-decoration: underline;
}

.brand-description ul,
.brand-description ol {
    margin: 0.5rem 0 0.75rem 1.5rem;
    list-style: revert;
}

/*
 * MGS_Blog post body/short-content (mgs_blog_post.content / short_content) -
 * same rationale as .brand-description above: unstyled admin-authored WYSIWYG
 * HTML, no Tailwind typography plugin installed.
 */
.blog-description h1,
.blog-description h2,
.blog-description h3 {
    font-weight: 700;
    margin: 1.5rem 0 0.75rem;
}

.blog-description h2 { font-size: 1.5rem; }
.blog-description h3 { font-size: 1.25rem; }

.blog-description p {
    margin-bottom: 1rem;
}

.blog-description a {
    color: var(--color-primary);
    text-decoration: underline;
}

.blog-description ul,
.blog-description ol {
    margin: 0.5rem 0 1rem 1.5rem;
    list-style: revert;
}

.blog-description img {
    max-width: 100%;
    height: auto;
    margin: 1rem 0;
}

/*
 * MGS_Blog tables, 2026-09-08. Same rationale as the .blog-description rules above:
 * no Tailwind typography plugin, so Preflight's `table{border-collapse:collapse}` is the
 * ONLY table rule in the compiled sheet - no borders, no padding, no header tint. Supro
 * is Luma-derived and styles tables well enough that this fault would not have shown up
 * until the Hyva cutover. The parts/technician blog content planned in
 * docs/blog-strategy-2026-09-08.md (servair-ops) is table-led, so it would have shipped
 * as unreadable columns of jammed text. See that doc SS 6.
 *
 * .table-scroll is the required wrapper: a part-number table must scroll sideways on a
 * phone rather than reflow, because reflowing separates a part number from its fitment.
 */
.blog-description .table-scroll {
    overflow-x: auto;
    margin: 1.5rem 0;
    -webkit-overflow-scrolling: touch;
}

.blog-description table {
    width: 100%;
    border-collapse: collapse;
    margin: 1.5rem 0;
    font-size: 0.9375rem;
    line-height: 1.45;
}

.blog-description .table-scroll table {
    margin: 0;
    min-width: 32rem;
}

.blog-description th {
    text-align: left;
    font-weight: 700;
    background-color: var(--color-bg);
    padding: 0.5rem 0.75rem;
    border-bottom: 2px solid var(--color-line);
    white-space: nowrap;
}

.blog-description td {
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--color-line);
    vertical-align: top;
}

.blog-description tbody tr:last-child td {
    border-bottom: none;
}

.blog-description caption {
    caption-side: bottom;
    padding-top: 0.5rem;
    font-size: 0.8125rem;
    color: var(--color-ink-muted);
    text-align: left;
}

/*
 * Product page, 2026-09-05: at tablet widths Hyva shows the "Add to Cart" label next to the
 * icon in a button that sits beside the qty box, and the label wrapped onto three lines on
 * the owner's phone. Keep it on one line and let the button take the row's spare width.
 */
#product-addtocart-button {
    white-space: nowrap;
    flex-grow: 1;
    justify-content: center;
}

/* Phones (2026-09-06): Hyva shows the cart icon alone below 640px; there is room for the words. */
#product-addtocart-button > span {
    display: inline !important;
}

/*
 * Desktop header, 2026-09-05 (owner request): a tighter menu so the header still fits
 * on one row when a visitor zooms the browser one or two steps. Hyva ships
 * the menu at gap-x-7 / text-md with py-4; this trims those at >= 1024px only - phones and
 * tablets keep the stock layout.
 *
 * 2026-09-08: the logo sizing rule that used to live here (and its <640px twin below) is gone.
 * It was keyed on `#header a[aria-label="Go to Home page"] img`, a selector coupled to a
 * translatable string, and it left 640-1023px uncovered so tablets rendered the logo at the raw
 * 260px HTML attribute - larger than desktop. Sizing now lives in the markup:
 * Magento_Theme/templates/html/header/logo.phtml renders the 48x48 mark below sm and the
 * 200x59 lockup from sm up.
 */
@media (min-width: 1024px) {
    #header > .container {
        padding-top: 0.5rem;
        padding-bottom: 0.5rem;
    }

    #header nav[aria-label="Main menu"] > ul {
        column-gap: 1.25rem;
        padding-top: 0.5rem;
        padding-bottom: 0.5rem;
    }

    #header nav[aria-label="Main menu"] .level-0 > span {
        font-size: 0.9375rem;
    }
}

/*
 * Header row order below lg. Started 2026-09-06 as a phone-only rule; widened to 1023px on
 * 2026-09-08 after the owner tested a Galaxy Fold 6.
 *
 * Vendor Hyva header.phtml gives the logo wrapper `sm:order-1 lg:order-0 w-full sm:w-auto` and
 * the container `flex-wrap justify-between`. Two consequences, both wrong here:
 *   - below 640px the logo is a full-width row of its own, stacked ABOVE the hamburger/icon row
 *     (~150px of header before any content);
 *   - from 640px to 1023px `sm:order-1` moves the logo to the MIDDLE of a justify-between row,
 *     so the Fold's ~700px inner screen showed hamburger far left, logo marooned in the centre.
 * `lg:order-0` only rescues it at >= 1024px.
 *
 * Fixed here rather than by overriding header.phtml: that vendor file is ~190 lines of Alpine
 * header logic (minicart, search, compare) and copying it into the theme to change two utility
 * classes would mean diffing all 190 lines against vendor after every Hyva upgrade. This
 * selector has been the hook since 2026-09-06 and is one line of CSS. Trade-off: it is coupled
 * to the container's child ORDER, so re-check it if a Hyva upgrade restructures the header.
 *
 * `margin-inline-start:auto` on the icon cluster is what right-aligns the icons: flex auto
 * margins eat all free space before justify-content runs, which makes the inherited
 * `justify-between` inert and keeps the hamburger beside the logo instead of floating mid-row.
 * >= 1024px is deliberately untouched - the vendor classes already give logo | menu | icons.
 */
@media (max-width: 1023px) {
    #header > .container {
        gap: 0.5rem;
    }

    #header > .container > div:first-child {
        width: auto;
        padding-bottom: 0;
        order: 0;
    }

    /* the icon cluster - matched by the search button it always contains, not by :last-child,
       so an extra trailing block in the container cannot silently steal the rule */
    #header > .container > div:has(> #menu-search-icon) {
        margin-inline-start: auto;
    }
}

/*
 * Phone header, 2026-09-08 (3rd pass - Galaxy Fold 6 COVER screen, ~390px).
 *
 * Root cause of the squished mark: this row is `flex-wrap:nowrap` (below), and at 390px it is
 * genuinely over-full - logo 48 + hamburger 44 + icon cluster 246.5 + 2 gaps of 8 = 354.5px
 * needed against 323px of content box (371 - 2 x px-6). Flexbox therefore had to shrink
 * something. The icon cluster and the hamburger are floored by their min-content size, but the
 * logo was not: Tailwind preflight ships `img { max-width: 100% }`, and a replaced element with
 * a PERCENTAGE max-width contributes ZERO to its flex item min-content size. So the logo
 * wrapper was the one item that could shrink to nothing, and it absorbed the whole 31.5px
 * deficit - width crushed 48 -> 16.5px while `h-12` held the height at 48px. That 1:2.9 box is
 * the "40 x 110" the owner photographed (device pixels, ~2.5x).
 *
 * `h-12 w-12` in logo.phtml was never overridden by a competing selector - `w-12` was applied
 * and then shrunk past. So the fix is not more specificity on width, it is (a) taking the logo
 * out of the shrink pool and (b) giving the row enough room that nothing else has to shrink
 * either:
 *   - `flex: none` on the logo wrapper: it is now rigid, so the deficit cannot land on it;
 *   - min-width + aspect-ratio + object-fit on the mark: belt and braces, so even if a future
 *     rule re-enables shrinking, the mark can only ever be a 1:1 box with the art letterboxed
 *     inside it rather than distorted;
 *   - gaps 8 -> 4px and padding px-6 -> px-4 below 640px: frees 40px, taking the row from a
 *     31.5px deficit to 8.5px of slack. Verified in Chrome at 390px: no horizontal scrollbar
 *     and every icon (search, WhatsApp, TTD, account, cart) still present and full size.
 *
 * px-4 does not break alignment with the page body: `.page-main` here is
 * `page-main-full-width` and has 0 horizontal padding, so the header is not aligned to a
 * content gutter at this width.
 *
 * >= 640px is untouched - the 200px lockup replaces the mark there and the row has slack.
 */
@media (max-width: 639px) {
    #header > .container {
        padding-top: 0.5rem;
        padding-bottom: 0.5rem;
        padding-left: 1rem;
        padding-right: 1rem;
        flex-wrap: nowrap;
        gap: 0.25rem;
    }

    /* the logo must never be the item flexbox chooses to crush */
    #header > .container > div:first-child {
        flex: none;
    }

    #header > .container > div:has(> #menu-search-icon) {
        gap: 0.25rem;
    }

    #logo-mark {
        width: 3rem;
        height: 3rem;
        min-width: 3rem;
        aspect-ratio: 1 / 1;
        object-fit: contain;
    }
}

/* 2026-09-05: full-width homepage sections must never produce a horizontal scrollbar (a
   full-bleed element that is 100vw wide includes the vertical scrollbar width). clip, not
   hidden, so sticky/fixed positioning keeps working. */
html { overflow-x: clip; }

/*
 * Homepage department strip (Parts / Residential Units / Refrigerant), 2026-09-08.
 * MGS_Fbuilder/templates/widget/promobanner.phtml renders each narrow banner as a card; the
 * column markup around the cards (.section-builder-full > .frame.no-padding > .line >
 * .col-des-4) is baked into CMS page 2 and cannot be changed from the theme, so this turns that
 * full-bleed 3-across strip into a 1240px frame with a 3-column card grid. :has() scopes it to
 * the one .section-builder-full that contains cards, so the hero section (also
 * .section-builder-full) and the plain full-frame LG banner further down are untouched.
 */
.section-builder-full:has(.servair-dept-card) > .frame.no-padding {
    max-width: 1240px;
    margin: 2.5rem auto 1rem;
    padding: 0 15px !important;
}

.section-builder-full:has(.servair-dept-card) > .frame > .line {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2rem 1.5rem;
}

.section-builder-full:has(.servair-dept-card) > .frame > .line > [class*="col-des"] {
    width: auto;
    max-width: none;
    flex: none;
    padding: 0 !important;
}

/* The inner .line/.panel-block wrappers Fbuilder adds around each widget: let the card fill. */
.section-builder-full:has(.servair-dept-card) .panel-block,
.section-builder-full:has(.servair-dept-card) .panel-block > div,
.section-builder-full:has(.servair-dept-card) > .frame > .line > [class*="col-des"] > .line {
    display: block;
    width: 100%;
    height: 100%;
    margin: 0;
}

@media (min-width: 768px) {
    .section-builder-full:has(.servair-dept-card) > .frame > .line {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* Department card, 2026-09-08. The media panel ground is the bg token (slate-50), the same
   cool near-white as the page ground, so the photos opaque rgb(244,245,245)/white backgrounds
   disappear into it via mix-blend-mode: darken (set on the <img> in the template); hover steps
   it to the line token. The card title is the deep token, the navy used by every statement
   panel and by the virtual-visit hero slide. No raw colours here - see DESIGN.md 4.1. */
.servair-dept-card__media {
    background-color: var(--color-bg);
    transition: background-color 0.2s ease-out;
}

.servair-dept-card:hover .servair-dept-card__media {
    background-color: var(--color-line);
}

.servair-dept-card__title {
    color: var(--color-deep);
}

/*
 * Hero slide "Book a virtual site visit" (MGS_Fbuilder/templates/widget/hero-slides/
 * virtual-site-visit.phtml), 2026-09-08. Navy-to-brand-blue ground; no photo behind the text so
 * the slide costs no LCP bytes and the white copy always passes contrast.
 */
.servair-visit-slide {
    background: linear-gradient(120deg, var(--color-deep) 0%, var(--color-primary) 100%);
}

/* Homepage, 2026-09-08 (owner): Hyva gives <main> a 32px top margin on every page; on the
   homepage that showed as a blank band between the header and the full-bleed hero. */
body.cms-index-index main.page-main {
    margin-top: 0;
}

/*
 * Navigation loading indicator + cross-document view transitions, 2026-09-08.
 * Companion to Magento_Theme/templates/html/servair/nav-progress.phtml - read that file's header
 * for why the indicator exists at all.
 *
 * These rules live here, in plain custom.css, and not in the Tailwind source, for two reasons:
 * (a) @view-transition and ::view-transition-*(root) are document-level at-rules/pseudo-elements
 *     with no utility-class equivalent, so Tailwind would only be a pass-through; and
 * (b) custom.css deploys as an ordinary static file, so a tweak here needs no npm build - only
 *     the static-content deploy (and the pub/static rm first, see
 *     knowledge/servair-static-deploy-keeps-stale-files.md).
 * The bar's colour and position come from Tailwind utilities on the element itself.
 *
 * What is deliberately NOT here any more (2026-09-08, second pass): the resting state
 * transform:scaleX(0);opacity:0. The owner reported seeing "always a full line", and one way
 * that can happen is this stylesheet not arriving - stale edge cache, blocked request, a static
 * deploy that has not landed - leaving the div as w-full bg-primary with nothing scaling it
 * down. The hidden state is now an inline style attribute on the element, which cannot fail to
 * load, and JS overwrites the same two properties. height is repeated here for the same reason:
 * h-1.5 in styles.css already sets 6px, but a bar that loses its height rule is invisible, and
 * styles.css is a generated single-line artifact that any Tailwind rebuild rewrites wholesale.
 */
#nav-progress {
    height: 6px;
    transition: transform 600ms cubic-bezier(0.16, 1, 0.3, 1), opacity 200ms linear;
    will-change: transform;
}

/*
 * Cross-document view transitions kill the white flash between pages: the browser holds the old
 * document's last frame and cross-fades it into the new one instead of painting the blank
 * canvas. Progressive enhancement - Safari and Firefox ignore the at-rule entirely and simply
 * navigate the way they do today, so there is no fallback to write. It is also independent of
 * the progress bar above: the bar covers the wait BEFORE the response arrives, the fade covers
 * the swap AFTER it does.
 */
@view-transition {
    navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 150ms;
    animation-timing-function: ease;
}

@media (prefers-reduced-motion: reduce) {
    /* No sliding bar and no cross-fade. The template's JS branch paints a STATIC scaleX(0.4)
       here - not the full-width scaleX(1) the first cut used. Samsung's "Remove animations"
       toggle sets prefers-reduced-motion, so that full bar was what the owner was seeing as
       "always a full line" on every navigation. 40% still reads as "loading" and never reads as
       a decorative rule. Navigation itself goes back to the browser's plain page swap. */
    #nav-progress {
        transition: none;
    }

    @view-transition {
        navigation: none;
    }

    ::view-transition-old(root),
    ::view-transition-new(root) {
        animation: none;
    }
}
