/*
Theme Name: Voltloft
Theme URI: https://voltloft.com/
Description: Voltloft storefront: a WoodMart child theme that keeps the catalogue filters, the visibility rule and the legal pages.
Author: Voltloft
Template: woodmart
Version: 0.7.0
Text Domain: dropship
Requires at least: 6.6
Requires PHP: 8.2
*/

/*
 * Section tiles on the home page.
 *
 * The template's tiles were lifestyle photographs cropped to fill, with the
 * caption lying on the picture. Ours are single products the supplier shot on
 * white: cropped to fill, each came out as a bleeding fragment with the words
 * across it, and the row read as one pale smear.
 *
 * So the picture is CONTAINED and sits to the right, the tile carries a colour
 * of ours behind it, and the caption is a solid card in the corner. The colour
 * classes are written into the page next to each tile (dr-tile--mint and the
 * rest): a rule keyed to the block's own id would break the day the block is
 * rebuilt, because that id is generated.
 */
.dr-tile {
    border-radius: 18px;
    overflow: hidden;
    border: 1px solid rgba(0, 0, 0, 0.05);
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.dr-tile:hover {
    transform: translateY(-3px);
    box-shadow: 0 14px 30px rgba(0, 0, 0, 0.1);
}

.dr-tile--mint  { background-color: #e8f1ec; }
.dr-tile--sand  { background-color: #f2eee4; }
.dr-tile--lilac { background-color: #eceaf2; }
.dr-tile--sky   { background-color: #e9f0f5; }
.dr-tile--stone { background-color: #efeeea; }

/*
 * The mesh routers are white on white: the cutout eats the product together
 * with the ground, so that one tile keeps the supplier's photograph and stays
 * white, and the white square of the photo has nothing to stand out against.
 */
.dr-tile--plain { background-color: #fff; }

/*
 * Where the product sits depends on how wide the tile is, and the tiles in one
 * row are not the same width. A media query cannot see that — it sees the
 * window — so the tile asks about itself: narrow means the picture stands above
 * the caption, wide means it stands beside it. Without this the caption landed
 * on top of the iron.
 */
.dr-tile {
    container-type: inline-size;
}

.dr-tile .wd-block-cover-img {
    /* The caption grew by the VIEW MORE link: three lines of name plus it. */
    inset: 18px 18px 222px;
    background-size: contain;
    background-position: center;
}

@container (min-width: 420px) {
    .dr-tile .wd-block-cover-img {
        inset: 18px;
        background-position: right center;
    }
}

/*
 * The caption: a solid card, not a translucent one. Over a colour the blur read
 * as a smudge, and the point of the card is that the words are legible whatever
 * the photograph behind them.
 */
.dr-tile .wp-block-wd-container {
    padding: 16px 20px;
    border-radius: 12px;
    background: #fff;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.07);
}

.dr-tile .wp-block-wd-title,
.dr-tile .wp-block-wd-paragraph {
    color: var(--wd-title-color, #242424);
}

.dr-tile .wp-block-wd-button span {
    color: var(--wd-primary-color, #1c7a17);
}

/*
 * The home slider.
 *
 * Its width and height live in the block's own settings on the page, not here:
 * the theme writes a rule per block id (.wd-<hash>) after this file, and it
 * wins over anything the child theme can say without !important.
 *
 * What is left here is the one thing those settings cannot express. The block
 * sets the picture's WIDTH, and our slides carry products of every proportion:
 * a square air fryer at the same width as a 5:4 toothbrush came out 541px tall
 * and pushed the slide from 520 to 721, so the picture hung out of the banner.
 * Capping the height keeps every slide the same size whatever the supplier's
 * photograph happens to be.
 */
.wd-slider .wd-block-image img {
    display: block;
    width: auto;
    max-width: 100%;
    max-height: 400px;
    margin-inline: auto;
    object-fit: contain;
}

@media (max-width: 1024.98px) {
    .wd-slider .wd-block-image img {
        max-height: 320px;
    }
}

@media (max-width: 768.98px) {
    .wd-slider .wd-block-image img {
        max-height: 260px;
    }
}

/*
 * The category strip under the banner.
 *
 * The template lays the name over the photograph and slides the product count
 * up on hover — it was built for lifestyle shots with a quiet lower edge. Ours
 * are products on white: the name sat on the product, and a two-line name
 * ("Cooking appliances", "Alarms & sensors") climbed onto it.
 *
 * So the caption leaves the overlay and goes under the picture, where nothing
 * can collide with it, and the whole thing becomes a card like the section
 * tiles below. The two !important marks answer the theme's own rules for that
 * overlay — its position and its hover shift — which a child theme cannot
 * outrank any other way.
 */
.wd-cat {
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-radius: 16px;
    /*
     * White, not a tint. The supplier photographs on pure white, and a tint
     * behind the photo draws a white square inside the card. `mix-blend-mode:
     * multiply` was tried and did not clear it: the carousel item above is a
     * stacking context of its own, so the blend never reaches the card's
     * colour. The card is told apart by its edge and its shadow instead.
     */
    background: #fff;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
    /*
     * The row is only as tidy as its shortest card: a name that needs three
     * lines ("Vacuum parts & accessories" on a phone) made its card taller than
     * its neighbours. The card fills whatever height the row settles on.
     */
    height: 100%;
    overflow: hidden;
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}

/*
 * On a phone the strip is a carousel, and it lines its cards up by the top, so
 * a three-line name ("Vacuum parts & accessories") left its neighbour short.
 * Stretching the row is what lets the card's own `height: 100%` mean anything.
 */
.wd-carousel-wrap:has(.wd-cat) {
    align-items: stretch;
}

.wd-carousel-wrap:has(.wd-cat) > .wd-carousel-item {
    align-self: stretch;
    height: auto;
}

.wd-cat:hover {
    transform: translateY(-3px);
    box-shadow: 0 12px 26px rgba(0, 0, 0, 0.09);
}

/*
 * The pictures come from the supplier, each with its own proportions — square,
 * 7:6, sometimes a wide strip. A square box of a fixed size puts every caption
 * on the same line; `contain` keeps the whole product visible instead of
 * cropping it.
 */
.wd-cat .wd-cat-thumb {
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    aspect-ratio: 1 / 1;
    /*
     * A square photograph fills its box to the last pixel, so the space between
     * the picture and the name is this padding and nothing else.
     */
    padding: 20px;
    overflow: hidden;
}

.wd-cat .wd-cat-thumb img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/*
 * The wrapper was sized to the picture alone and clipped everything under it,
 * because in the template nothing was ever under it — the caption floated on
 * top. Now that the caption is a row of its own, the wrapper has to grow.
 */
.wd-cat .wd-cat-inner {
    height: auto !important;
    overflow: visible;
    /*
     * The gutter lives here, on the wrapper, and not on the caption's own box:
     * padding set there — even with !important — never reached the page, while
     * the same value typed into the element by hand did. Rather than keep
     * guessing which rule of the template eats it, the space is taken one level
     * up, where nothing argues.
     */
    padding: 0 20px 20px;
}

/*
 * The name and the count are each pinned by the theme as well, not only their
 * box: with the box let go and the name still absolute, the name flew out of
 * the card and the strip lost its captions altogether.
 */
.wd-cat .wd-cat-content,
.wd-cat .wd-entities-title,
.wd-cat .wd-cat-count {
    position: static !important;
    transform: none !important;
}

/*
 * Two lines' worth of room whether the name needs them or not, so that one long
 * name ("Cooking appliances") does not make its card taller than the rest of
 * the row.
 */
.wd-cat .wd-entities-title {
    display: block;
    /*
     * Two lines' worth, and the line height is set here so that "two lines"
     * means the same on a phone, where the name is smaller.
     */
    line-height: 1.4;
    min-height: 2.8em;
    margin: 0;
}

/*
 * The template keeps the count invisible until the pointer is over the card.
 * On a phone there is no pointer, so it was never readable there at all.
 */
.wd-cat .wd-cat-count {
    opacity: 1 !important;
    color: #6b6b6b;
}

/*
 * Brands.
 *
 * The supplier sends no logotypes with the catalogue, so there is nothing to
 * show but names. Thirty-nine of them in a grid took half a screen to say very
 * little; as one moving line they say the same in a strip. The line stops under
 * the pointer — the names are links, and a link you cannot catch is not one.
 */
.wd-marquee .wd-marquee-item a {
    color: #4b4b4b;
}

.wd-marquee .wd-marquee-item a:hover {
    color: var(--wd-primary-color, #1c7a17);
}

/* A dot between the names, so the line does not read as one long word. */
.wd-marquee .wd-marquee-item::after {
    content: "•";
    margin-inline-start: 30px;
    color: rgba(0, 0, 0, 0.25);
}

/*
 * The band now spans the page like the row of sections under it — same left and
 * right edge as the cards there. The names fade out before they reach the edge
 * instead of being chopped in half; the mask is on the moving layer only, so
 * the band itself stays whole.
 */
.wd-brands-band .wd-marquee-content {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 80px, #000 calc(100% - 80px), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 80px, #000 calc(100% - 80px), transparent);
}

/*
 * Motion is a preference, and the browser knows it. Whoever asked their system
 * for less of it gets the line standing still, with the names still readable
 * and still clickable.
 */
@media (prefers-reduced-motion: reduce) {
    .wd-marquee .wd-marquee-content {
        animation: none;
    }
}

/*
 * The section menu, on its own row under the search.
 *
 * Eleven sections measure 1074px of text, and the theme puts 20px between them:
 * 1274px against a row 1192px wide, so the last two wrapped onto a second line
 * and the header read as two bands. A point smaller and four pixels tighter
 * brings the row to about 1150 and keeps every section in sight.
 */
.whb-header-bottom .wd-nav-main {
    column-gap: 16px;
}

.whb-header-bottom .wd-nav-main > li > a {
    font-size: 12px;
}

/*
 * The name is all we have for a logotype until the owner draws one, so it has
 * to carry the corner by itself: at the theme's body size it read as one more
 * menu item.
 */
.whb-header .dropship-wordmark {
    font-size: 22px;
    font-weight: 600;
    letter-spacing: 0.01em;
}

/*
 * The search field took the whole middle column — a thousand pixels of empty
 * box. Wide enough to type a product name into, and no wider.
 */
.whb-header .whb-column .wd-search-form {
    max-width: 560px;
    margin-inline: auto;
}

/*
 * The seller's details in the footer. While a value is missing the visitor is
 * shown nothing; the owner, signed in, sees the gap in the place it will take,
 * in a quieter colour than the real lines so the two are never confused.
 */
.dropship-company {
    margin: 0;
    padding: 0;
    list-style: none;
}

.dropship-company li {
    margin-bottom: 6px;
}

.dropship-company__gap,
.dropship-company__note {
    color: #9a9a9a;
}

.dropship-company__note {
    margin-top: 12px;
    font-size: 12px;
}

/*
 * The product grid.
 *
 * The supplier's photographs come in every proportion — a light bulb square, a
 * five-metre strip twice as tall as it is wide — and the template lets each one
 * set its own card height. A row then had its names and prices at four different
 * levels. A square box holds every photograph, `contain` keeps the whole product
 * in it, and two lines are kept for the name so the price lands on one line
 * across the row.
 */
.wd-product .product-image-link,
.wd-product .wd-product-img-hover {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1 / 1;
    overflow: hidden;
}

/*
 * The second photograph, shown on hover, is measured the same way — and neither
 * of them is ever enlarged.
 *
 * `width: 100%` stood here and stretched whatever the supplier sent to the width
 * of the box. Most of ELKO's pictures are 800px and wider, so it went unnoticed
 * until a 204px one turned up: the card blew it up to 283, the product page to
 * 449, and one gallery picture of 86px to 449 — five times its own size. A
 * photograph enlarged past its own pixels does not gain detail, it loses it, and
 * the shop looks as if it photographed the goods on a potato.
 *
 * Measured 30.09.2026: 75 of 1244 products have a main picture narrower than
 * 300px, and ELKO has nothing better — the file at its address is that size, and
 * the usual size parameters change nothing. A small picture is therefore shown
 * small, in the middle of its box.
 */
.wd-product .wd-product-thumb img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
}

/*
 * The same on the product's own page, where the box is widest and the stretching
 * was worst. WoodMart sizes the gallery picture to the column; capping it at its
 * own width leaves it sharp and centred, with the column's background around it.
 */
.single-product .woocommerce-product-gallery .wd-carousel-item img,
.single-product .woocommerce-product-gallery .woocommerce-product-gallery__image img {
    max-width: 100%;
    width: auto;
    height: auto;
    margin-inline: auto;
}

/*
 * The gallery slide keeps its width so the picture has something to sit in the
 * middle of; without this a 204px picture would drag the whole carousel in.
 */
.single-product .woocommerce-product-gallery .wd-carousel-item {
    display: flex;
    align-items: center;
    justify-content: center;
}

/*
 * The name takes exactly three lines — no fewer, and no more: the supplier
 * writes names like "Philips Sonicare DiamondClean 9000 series DiamondClean
 * 9000 HX9911 Rechargeable toothbrush", and in a four-column row that is five
 * lines, which pushed the price below its neighbours' again.
 *
 * Two other ways were tried and do not work here. Pinning the price to the foot
 * of the card needs a foot: the grid lines its cards up by the top and will not
 * stretch them. Merely reserving three lines helps until a longer name arrives,
 * and the supplier's names are long. What is cut off is repetition; the whole
 * name is on the product's own page.
 */
.wd-product .wd-entities-title {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-height: 1.4;
    min-height: 4.2em;
    overflow: hidden;
}



/*
 * The landing page's own sections: two product strips and the three steps.
 *
 * The heading copies the one WoodMart draws over "BRANDS" — 22px, 50 above and
 * 24 below — because the page already has that style and a second heading style
 * on the same screen reads as two designers arguing. The words are uppercased
 * here rather than typed in capitals: a screen reader says "BRANDS" letter by
 * letter when the text itself is capitals.
 */
.dr-strip,
.dr-steps {
    margin-bottom: 40px;
}

/*
 * Two class names, not one: the heading also carries WoodMart's `title`, and
 * the parent sets `text-transform` on it from a two-class selector. A single
 * class here loses that tie and the headings came out in sentence case while
 * the rest of the page shouted.
 */
.dr-strip .dr-strip-title,
.dr-steps .dr-strip-title {
    font-size: 22px;
    margin-top: 50px;
    margin-bottom: 24px;
    text-transform: uppercase;
}

/*
 * The way out of the strip. Underlined rather than a button: the buttons on this
 * page belong to the slides, and a third button style would compete with them.
 */
.dr-strip-more {
    margin-top: 24px;
}

.dr-strip-more a {
    border-bottom: 1px solid currentColor;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .03em;
    padding-bottom: 2px;
    text-transform: uppercase;
}

/*
 * Three steps in a row, one under the other on a narrow screen. A container
 * query, not a media query: the block is measured, not the window, so the row
 * keeps working if it is ever put into a narrower column.
 */
.dr-steps {
    container-type: inline-size;
}

.dr-step-list {
    display: grid;
    gap: 24px;
    grid-template-columns: 1fr;
    list-style: none;
    margin: 0;
    padding: 0;
}

@container (min-width: 720px) {
    .dr-step-list {
        grid-template-columns: repeat(3, 1fr);
    }
}

.dr-step {
    background: #f7f7f5;
    border-radius: 18px;
    padding: 28px 28px 32px;
}

/*
 * The number is decoration: the list is already numbered for anyone who cannot
 * see it, and the markup hides this copy from them (aria-hidden).
 */
.dr-step-number {
    color: #b8b8b2;
    display: block;
    font-size: 40px;
    font-weight: 800;
    line-height: 1;
    margin-bottom: 12px;
}

.dr-step-title {
    font-size: 16px;
    font-weight: 600;
    margin: 0 0 8px;
    text-transform: uppercase;
}

.dr-step-text {
    margin: 0;
    opacity: .8;
}

/*
 * The front page shows a smaller picture than a section does.
 *
 * The card is the same card; only the height of its picture box changes. A
 * square box gave 283px of photograph in a 391px card — three quarters of the
 * front page's product rows were picture, and the names and prices read as an
 * afterthought. In a section that is right: the visitor came to look at the
 * goods. On the front page the rows are a taste of the catalogue, and they have
 * to leave room for what is under them.
 *
 * The picture is not cropped: `object-fit: contain` still holds from the rule
 * above, so a tall product simply sits in a shorter box.
 */
.dr-strip .wd-product .product-image-link,
.dr-strip .wd-product .wd-product-img-hover {
    aspect-ratio: 4 / 3;
}
