/*
    assets/css/product-shop.css

    The product page, matched to ozroofracks.shop. Added 2026-08-21, the last
    component of the restyle after the header, slider, grids and footer.

    Loaded last in template/css.php, so it beats main.css and products.css.

    Two things happened together and this file only makes sense with both:

    1. THE TABS BECAME SECTIONS. Five radio inputs labelled with bare icons
       hid four fifths of the page. product/parts/product-sections.php now
       stacks the same content -- details, specs, compatible vehicles,
       downloads -- and this styles those bands.

    2. THEY MOVED OUT OF THE NARROW COLUMN. They used to render inside the
       .col-5 that holds the price and Add to Cart, so a specifications table
       had a third of the page. They are full width now.

    NOT TOUCHED, by request: #customerPanel and #cartPanel keep their current
    look, Proceed to Checkout included. Nothing here can reach them.
*/

/* ==================================================================
   The purchase column
   ================================================================== */

/*
.shop's .product-summary. The AU column is .col-5.productes and carries the
breadcrumb, title, price, stock, Add to Cart and the shipping estimate.
*/
#main .productes .max {
    margin: 0 0 6px;
    font-family: var(--font-display);
    font-size: clamp(23px, 2.5vw, 33px);
    font-weight: 800;
    line-height: 1.14;
    letter-spacing: -.03em;
    color: var(--ink);
    text-transform: none;
}

/* the breadcrumb line above the title */
#main .productes > small:first-of-type {
    display: block;
    margin-bottom: 14px;
    color: var(--muted);
    font-size: 12px;
    line-height: 1.6;
}

/*
.shop's .price-line strong is 35px/800. main.css has .bigprice at 2.5em in a
lighter weight, which next to a 33px title reads as the same size as the name
rather than the number you came for.
*/
#main .productes .bigprice,
#main #bigprice {
    font-family: var(--font-display);
    font-size: 35px;
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: -.03em;
    color: var(--ink);
}

/* ==================================================================
   The stacked sections
   ================================================================== */

.product-sections {
    margin-top: 54px;
}

.product-section {
    padding: 62px 0;
}

/*
FULL-BLEED BANDS FROM INSIDE A CONTAINER.

.shop's sections are top-level, so a tinted one simply spans the window. Here
they render inside #main > .inner, which is width-constrained -- so a
background would stop at the container edge and read as a wide card rather
than a band.

The -50vw + 50% pair pushes each section's box out to the viewport edges while
its inner keeps the container width. 100vw includes the scrollbar, hence the
matching padding rather than `width: 100vw`, which would overflow by the
scrollbar width and add a horizontal scrollbar to the page.
*/
.product-section {
    margin-left: calc(-50vw + 50%);
    margin-right: calc(-50vw + 50%);
    padding-left: calc(50vw - 50%);
    padding-right: calc(50vw - 50%);
}

.product-section-inner {
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 1.5em;
}

/*
ALTERNATING GROUNDS, AS .shop DOES -- and every one stated explicitly.

#details came out at rgb(245,248,250) without being given a background: some
existing rule paints sections inside #main, and that grey is within three
points of --surface. So details and specs rendered as one continuous slab and
the alternation that separates them did nothing. Setting all four means none
of them depends on what happens to be inherited.
*/
.product-details-section,
.downloads-section {
    background: var(--white);
}

.compatible-section {
    background: var(--sky);
}

/* ---------------------------------------------------- section headings */

.product-section .detail-heading {
    max-width: 620px;
}

.product-section .detail-heading {
    margin-bottom: 34px;
}

.product-section .eyebrow {
    display: block;
    margin: 0 0 12px;
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .16em;
    text-transform: uppercase;
}

.product-section .eyebrow.blue {
    color: var(--blue);
}

.product-section h2 {
    margin: 0 0 12px;
    font-family: var(--font-display);
    font-size: clamp(24px, 2.6vw, 34px);
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -.035em;
    color: var(--ink);
    text-transform: none;
}

.product-section .detail-heading > p:last-child {
    margin: 0;
    color: var(--muted);
    font-size: 15px;
    line-height: 1.7;
}

/* ---------------------------------------------------- the details cards */

.detail-columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 20px;
    align-items: start;
}

/*
auto-fit collapses to one very wide column when there is a single card, which
looks like a mistake rather than a choice. Cap it.
*/
.detail-columns.is-single {
    grid-template-columns: minmax(0, 760px);
}

.detail-card {
    padding: 28px;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: 14px;
}

/*
A card that needs the whole row rather than a column. Nothing uses it on the
database path any more -- specifications went inside the package card -- but
product/tabs.php still renders specs as its own card, and a specs table in a
third of the width is what moving all this out of the narrow column was meant
to fix.
*/
.detail-card.is-wide {
    grid-column: 1 / -1;
}

/*
    THE DOWNLOADS BAND SPLITS IN TWO: GUIDES LEFT, 3D MODEL RIGHT.

    The band is full width, so half of it is still wider than the third of a
    row the model got as a detail-card -- which is why it moved here.

    minmax(0, 1fr) rather than 1fr on both tracks. A grid track's default
    min-width is auto, and <model-viewer> reports a large intrinsic size, so
    plain 1fr lets the right column push the left one narrow and then overflow
    the row. minmax(0, ...) is what stops that.

    align-items:start so a short list of PDFs does not stretch to match a
    420px viewer.
*/
.downloads-split.is-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 28px;
    align-items: start;
}

/* One column below the point where two would each be too narrow to use. */
@media screen and (max-width: 860px) {
    .downloads-split.is-split {
        grid-template-columns: minmax(0, 1fr);
    }
}

/*
SUB-HEADINGS INSIDE A CARD.

The package card now runs contents -> Specifications -> Shipping, and both of
those are <h2> in markup that predates the card (shipment-info.php prints its
own). An h2 inside a card that is titled by an h3 reads as bigger than its
own parent, so they are stepped down here rather than by rewriting partials
the cart and the legacy tabs path also use.
*/
.detail-body h2,
.detail-body h3 {
    margin: 26px 0 12px;
    font-family: var(--font-display);
    font-size: 15px;
    font-weight: 800;
    line-height: 1.3;
    letter-spacing: .01em;
    color: var(--ink);
    text-transform: none;
}

.detail-body > *:first-child {
    margin-top: 0;
}

.detail-icon {
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    margin-bottom: 16px;
    border-radius: 12px;
    background: var(--sky);
    color: var(--blue);
    font-size: 19px;
}

.detail-card h3 {
    margin: 0 0 14px;
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 800;
    line-height: 1.25;
    letter-spacing: -.02em;
    color: var(--ink);
    text-transform: none;
}

.detail-body {
    color: var(--ink-soft);
    font-size: 15px;
    line-height: 1.7;
}

.detail-body p:last-child {
    margin-bottom: 0;
}

/*
The tab content is author-written HTML out of the database, so it arrives with
whatever markup the admin typed. These keep it inside the card rather than
assuming a shape.
*/
.detail-body img,
.downloads-body img,
.specs-body img {
    max-width: 100%;
    height: auto;
    border-radius: 10px;
}

.detail-body ul,
.detail-body ol {
    margin: 0 0 1em;
    padding-left: 1.2em;
}

.detail-body li {
    margin-bottom: 7px;
}

/* ---------------------------------------------------------- the specs */

/*
A specs table is the one thing on this page that genuinely cannot reflow, so
it scrolls inside its own box rather than widening the page.
*/
.specs-body {
    overflow-x: auto;
}

/*
ONE TABLE TREATMENT FOR BOTH TABLES IN THE CARD.

The package card holds two: Specifications, then Shipping. They arrived from
different places and looked it -- Specifications had Poppins labels in the
muted tone with 13/16 padding; Shipping had Fira Sans labels in #444 with 8px
padding. Side by side in one card that reads as two different components.

Unified on the SPECIFICATIONS treatment. I did this the other way round first
-- flattening specs to the Shipping shape -- which was backwards: the specs
table is the one already wearing the restyle, and the Shipping table is the
one that had not been touched yet. The left column is the tell, and it should
be the Poppins label everywhere.
*/
.detail-body table {
    width: 100%;
    margin: 0;
    background: none;
    border: 0;
    border-collapse: collapse;
    font-size: 14px;
}

.detail-body th,
.detail-body td {
    padding: 13px 16px 13px 0;
    border: 0;
    border-bottom: 1px solid var(--line);
    text-align: left;
    line-height: 1.5;
    vertical-align: top;
}

.detail-body tr:last-child th,
.detail-body tr:last-child td {
    border-bottom: 0;
}

/*
The label column: Poppins, small, letter-spaced, muted -- the same treatment
as the .eyebrow that heads every section, so a row label reads as a label
rather than as quieter body text.
*/
.detail-body th {
    width: 42%;
    color: var(--muted);
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
}

.detail-body td {
    color: var(--ink);
    font-size: 14px;
    font-weight: 600;
}

/* no zebra: products.css tints alternate rows, which fights the rules above */
.detail-body tr:nth-child(even) th,
.detail-body tr:nth-child(even) td,
.detail-body tr:nth-child(odd) th,
.detail-body tr:nth-child(odd) td {
    background: none;
}

/* ------------------------------------------------- compatible vehicles */

/*
The vehicle cards reuse .ozfa-product, the same tile the Fitment Assistant
draws, so the two lists of "vehicles this fits" look like one feature. On a
tinted band they need a white ground to stay legible.
*/
.compatible-section .ozfa-products {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 12px;
    margin-top: 0;
}

.compatible-section .ozfa-product {
    background: var(--white);
}

/*
The AI/database disclaimer. It is legal text under a list of vehicle
suggestions, so it stays quiet -- but it must not disappear.
*/
.compatible-section .ozfa-about-panel {
    margin-top: 22px;
    padding: 18px 20px;
    background: rgba(255, 255, 255, .6);
    border: 1px solid var(--line);
    border-radius: 12px;
    color: var(--muted);
    font-size: 12px;
    line-height: 1.7;
}

/* ------------------------------------------------------- the downloads */

.downloads-body ul {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 12px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.downloads-body li {
    padding: 16px 18px;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: 12px;
    transition: border-color .18s ease, box-shadow .18s ease;
}

.downloads-body li:hover {
    border-color: var(--blue);
    box-shadow: 0 6px 18px rgba(11, 27, 42, .07);
}

.downloads-body li a {
    display: block;
    font-family: var(--font-display);
    font-size: 14px;
    font-weight: 700;
    line-height: 1.4;
    color: var(--ink);
    text-decoration: none;
}

.downloads-body li:hover a {
    color: var(--blue);
}

.downloads-body li small {
    display: block;
    margin-top: 5px;
    color: var(--muted);
    font-size: 12px;
    line-height: 1.6;
}

/* the <br> between the link and its description is a layout artifact here */
.downloads-body li br {
    display: none;
}

/* ------------------------------------------------------------ narrow */

@media screen and (max-width: 736px) {
    .product-sections {
        margin-top: 34px;
    }

    .product-section {
        padding-top: 42px;
        padding-bottom: 42px;
    }

    .detail-card {
        padding: 22px;
    }
}

/* ==================================================================
   The stock badge
   ================================================================== */

/*
It was an <h2> with an inline solid #ff0000 / #4CAF50 / #ff9800 background --
a saturated block beside a 35px price, and the loudest thing in the purchase
column. stock-on-product.php now emits classes instead (the inline styles
could not be overridden from here at all), so it can be the tinted pill .shop
uses: coloured enough to be read at a glance, quiet enough not to outrank the
price.

The four states and their conditions are untouched; this is only their paint.
*/
#main .productes .stock-badge {
    display: inline-block;
    margin: 0;
    padding: 6px 12px;
    border-radius: 999px;
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 800;
    line-height: 1.35;
    letter-spacing: .1em;
    text-transform: uppercase;
}

#main .productes .stock-badge.is-instock {
    background: #e7f6ec;
    color: #1c7a3e;
}

#main .productes .stock-badge.is-low {
    background: #fdeaea;
    color: #b3261e;
}

#main .productes .stock-badge.is-out {
    background: var(--surface);
    color: var(--muted);
}

#main .productes .stock-badge.is-presale {
    background: #fff3e0;
    color: #a35200;
}

.stock-badge-note {
    display: block;
    margin-top: 3px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: none;
    opacity: .85;
}

/*
THE BLINK NEVER REACHES ZERO NOW.

.blink-hard toggles the "N units left" text fully invisible, so for half of
every cycle the one urgent thing in the column is not on screen -- a
screenshot of this page caught it blank, and a customer glancing at it can
just as easily miss it.

Keeping the class (the urgency is deliberate) but pulsing between 1 and .45
instead of 1 and 0: still obviously moving, always readable. Anyone who has
asked their system not to animate gets a static badge.
*/
#main .productes .stock-badge .blink-hard {
    animation: oz-stock-pulse 1.4s ease-in-out infinite;
}

@keyframes oz-stock-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: .45; }
}

@media (prefers-reduced-motion: reduce) {
    #main .productes .stock-badge .blink-hard {
        animation: none;
    }
}

/*
The compatibility disclaimer's toggle. It reuses .ozfa-about-toggle so it
matches "About Ozzy" in the Fitment Assistant drawer, but that class is
styled in vehicle/assistant/assistant.css, which is only loaded when the
assistant is on the page. These few properties make the control readable on
its own.
*/
.compatible-section .oz-compat-about-toggle {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 20px;
    padding: 0;
    background: none;
    border: 0;
    color: var(--muted);
    font-family: var(--font-display);
    font-size: 12px;
    font-weight: 700;
    line-height: 1.4;
    text-align: left;
    text-decoration: underline;
    cursor: pointer;
}

.compatible-section .oz-compat-about-toggle:hover,
.compatible-section .oz-compat-about-toggle:focus-visible {
    color: var(--blue);
}

/* a caret that turns, so the control reads as a disclosure rather than a link */
.compatible-section .oz-compat-about-toggle::before {
    content: "\25B8";
    font-size: 11px;
    text-decoration: none;
    transition: transform .18s ease;
}

.compatible-section .oz-compat-about-toggle[aria-expanded="true"]::before {
    transform: rotate(90deg);
}

/* the panel sits under the toggle rather than floating away from it */
.compatible-section .ozfa-about-panel {
    margin-top: 12px;
}

/*
A BUNDLE WITH NO PHOTO ANYWHERE.

product/bundle.php prefers the bundle's own first image, then the first image
of any component, and only reaches this when neither exists. It used to point
an <img> at /images/no-image.jpg, which is not a file -- here or on the server
-- so three of the four active bundles rendered a broken-image icon as the
main picture of the page.

Sized to the gallery frame it replaces, so the purchase panel beside it does
not shift between a bundle that has a photo and one that does not.
*/
.bundle-photo-pending {
    display: grid;
    place-items: center;
    aspect-ratio: 1;
    padding: 24px;
    border: 1px dashed var(--line);
    border-radius: 14px;
    background: var(--surface);
    text-align: center;
}

.bundle-photo-pending span {
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .02em;
    color: var(--muted);
}

/* ==================================================================
   The fitment page  --  /find/<slug>
   ================================================================== */

/*
Ported from .shop's /fitment. This is where the Fitment Assistant sends
people once their vehicle resolves to a real roof profile, so it is the page
that has to answer "does this fit?" before it sells anything.

.fitment-container rather than reusing .product-section-inner: these sections
are top-level siblings of #main here, not nested inside a constrained .inner,
so they need the container but not the full-bleed margin trick.
*/
.fitment-container {
    width: min(1180px, 100% - 40px);
    margin-inline: auto;
}

.fitment-hero {
    padding: calc(var(--utility-h) + var(--header-h) + 46px) 0 46px;
    background: var(--ink);
    color: var(--white);
}

.fitment-hero .eyebrow {
    display: block;
    margin: 0 0 12px;
    color: #7cc4f5;
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .16em;
    text-transform: uppercase;
}

.fitment-hero h1 {
    margin: 0 0 10px;
    font-family: var(--font-display);
    font-size: clamp(28px, 3.6vw, 44px);
    font-weight: 800;
    line-height: 1.08;
    letter-spacing: -.035em;
    color: var(--white);
    text-transform: none;
}

.fitment-vehicle {
    margin: 0;
    color: #b8ccdb;
    font-size: 16px;
    line-height: 1.6;
}

.fitment-vehicle span {
    padding: 0 4px;
    opacity: .6;
}

/* --------------------------------------------------------- status card */

.fitment-band {
    /* 34px top and bottom -- it had none underneath, so the facts row ran
       straight into the product list heading below it. */
    padding: 34px 0;
}

.fitment-status {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 18px;
    padding: 22px 24px;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: 14px;
    box-shadow: 0 5px 22px rgba(15, 34, 49, .06);
}

/* a matched profile is the good outcome, so it gets the green edge */
.fitment-status.is-match {
    border-left: 3px solid #1c7a3e;
}

.fitment-status-icon {
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    border-radius: 12px;
    background: var(--sky);
    color: var(--blue);
    font-size: 20px;
}

.fitment-status h2 {
    margin: 0 0 4px;
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 800;
    line-height: 1.25;
    letter-spacing: -.02em;
    color: var(--ink);
    text-transform: none;
}

.fitment-status p {
    margin: 0;
    color: var(--muted);
    font-size: 14px;
    line-height: 1.6;
}

.fitment-status .button {
    margin: 0;

    /*
        FLEX CENTRING, not min-height alone.

        This set min-height:42px with `padding: 0 18px` and left the label to
        find its own vertical position. main.css's .button does not carry a
        line-height that matches, so the computed value was `normal` and the
        text sat at the TOP of the box -- measured 10px above centre on
        /find/toyota-hiace-h100-1989-high-roof, which is what made the button
        look broken rather than merely plain.

        Padding-based centring would work too, but it breaks again the moment
        the label wraps or the min-height changes; centring the flex line
        holds at any size.
    */
    display: inline-flex;
    align-items: center;
    justify-content: center;

    min-height: 42px;
    padding: 0 18px;
    border-radius: 8px;
    background: var(--white);
    border: 1px solid var(--line);
    color: var(--ink);
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 700;
    text-transform: none;
    white-space: nowrap;
}

.fitment-status .button:hover {
    border-color: var(--blue);
    background: var(--sky);
    color: var(--ink);
}

@media screen and (max-width: 760px) {
    .fitment-status {
        grid-template-columns: auto minmax(0, 1fr);
    }

    .fitment-status .button {
        grid-column: 1 / -1;
        justify-self: start;
    }
}

/* -------------------------------------------------------------- facts */

.fitment-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 14px;
    margin-top: 14px;
}

.fitment-facts article {
    padding: 18px 20px;
    background: var(--surface);
    border-radius: 12px;
}

.fitment-facts small {
    display: block;
    margin-bottom: 5px;
    color: var(--muted);
    font-family: var(--font-display);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.fitment-facts strong {
    font-family: var(--font-display);
    font-size: 16px;
    font-weight: 800;
    letter-spacing: -.01em;
    color: var(--ink);
    /*
    No text-transform. capitalize turned "high-roof-brackets" into
    "High-Roof-Brackets" and "1450 mm" into "1450 Mm" -- profile.php formats
    these values properly instead.
    */
}

/* ------------------------------------------------------- list heading */

.fitment-heading {
    max-width: 620px;
    margin: 0 0 26px;
}

.fitment-heading .eyebrow {
    display: block;
    margin: 0 0 10px;
    color: var(--blue);
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .16em;
    text-transform: uppercase;
}

.fitment-heading h2 {
    margin: 0 0 10px;
    font-family: var(--font-display);
    font-size: clamp(22px, 2.4vw, 30px);
    font-weight: 800;
    line-height: 1.18;
    letter-spacing: -.03em;
    color: var(--ink);
    text-transform: none;
}

.fitment-heading p {
    margin: 0;
    color: var(--muted);
    font-size: 14.5px;
    line-height: 1.7;
}

/*
"YOU MAY ALSO NEED" -- BAND FULL WIDTH, CONTENT IN THE CONTAINER.

The strip carries id="sets", so it picks up the --band background with every
other product grid. But on a product page it renders inside #main > .inner,
which is width-constrained -- so the band stopped at the container edge and
read as a wide grey card rather than a section.

Same -50vw margin / matching padding pair the stacked sections above it use:
the box reaches the viewport edges while its inner keeps the 1180 container.
Padding rather than `width: 100vw`, which overflows by the scrollbar width.
*/
.related-section {
    /*
    width:auto is doing real work here. The negative margins alone left the
    band at 1180px and merely shifted it left, because something upstream
    gives this section an explicit width -- with a fixed width a negative
    margin moves the box instead of growing it. Releasing the width lets it
    expand into the margins as intended.
    */
    width: auto;
    max-width: none;
    margin-left: calc(-50vw + 50%);
    margin-right: calc(-50vw + 50%);
    padding-left: calc(50vw - 50%);
    padding-right: calc(50vw - 50%);
}

.related-section > .inner {
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 1.5em;
}
