/*
 * Homepage Builder - storefront rendering layer.
 *
 * Everything the Visual Homepage Builder draws on the public site. The published CSS
 * for an element's own style bag is generated by PageBuilder\Support\StyleCompiler and
 * inlined per request; this file owns the design system plus the rules shared by every
 * page: container, 12-column row, the grid engine, carousel chrome, every widget skin
 * and the empty states.
 *
 * Direction handling: horizontal space uses CSS logical properties throughout, so the
 * same sheet is correct for English LTR and Arabic RTL. No rule below uses a physical
 * left/right property.
 *
 * Cascade contract - what keeps the editor honest:
 *   1. this sheet is the design DEFAULT. It is deliberately good, so a widget dropped
 *      on an empty canvas is already presentable;
 *   2. the inline style StyleCompiler emits from an element's style bag always wins
 *      over a rule here, so an editor change is immediately visible;
 *   3. inline styles a widget blade writes for its own layout contract (grid template,
 *      aspect ratio, monospace code) are never fought with - this sheet only adds
 *      properties those blades do not declare.
 */

.lv-pb-page {
    --pb-container: 1280px;
    --pb-gap: 24px;

    /* ------------------------------------------------------------ tokens */
    /* Warm neutrals, chosen to sit under fashion photography instead of competing
       with it: warm off-white canvas, paper-white cards, ink that is not pure black. */
    --pb-ink: #141210;
    --pb-ink-soft: #3d3833;
    --pb-muted: #6f6a63;
    --pb-line: #e8e3db;
    --pb-line-soft: #f1ede6;
    --pb-surface: #faf8f5;
    --pb-paper: #fff;
    --pb-accent: #088178;
    /* Sale red the white badge text actually clears on. The theme's --danger is a light
       coral that lands at 4.48:1 under text-xs, which fails AA for small text by a hair;
       this is the same idea, darkened until it is readable. */
    --pb-sale: #b42318;

    /* Three radii and three elevations, so one page cannot accidentally look like
       three different design systems. */
    --pb-radius-s: 12px;
    --pb-radius-m: 18px;
    --pb-radius-l: 26px;
    --pb-shadow-1: 0 1px 2px rgba(20, 18, 16, .04), 0 2px 6px rgba(20, 18, 16, .05);
    --pb-shadow-2: 0 2px 4px rgba(20, 18, 16, .04), 0 12px 28px -10px rgba(20, 18, 16, .14);
    --pb-shadow-3: 0 10px 20px rgba(20, 18, 16, .07), 0 32px 64px -16px rgba(20, 18, 16, .22);

    /* One easing curve and two durations, reused everywhere, is what makes motion
       read as intentional rather than decorative. */
    --pb-ease: cubic-bezier(.22, .61, .36, 1);
    --pb-fast: 180ms;
    --pb-slow: 420ms;

    /* Vertical rhythm: a section reads as a section because of the air around it. */
    --pb-section-y: clamp(2.5rem, 5vw, 5.5rem);
    --pb-gutter: clamp(1rem, 2.6vw, 2rem);

    font-family: "DM Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
    color: var(--pb-ink);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* ------------------------------------------------------------- structure */

.lv-pb-section {
    position: relative;
    isolation: isolate;
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center;
    padding-block: var(--pb-section-y);
}

/* A full-bleed section exists to hold edge-to-edge media; that media owns its own
   height, so the section adds no air of its own. */
.lv-pb-section--full {
    padding-block: 0;
}

.lv-pb-container {
    width: 100%;
    max-width: var(--pb-container);
    margin-inline: auto;
    padding-inline: var(--pb-gutter);
}

.lv-pb-fullwidth {
    width: 100%;
    max-width: 100%;
}

.lv-pb-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lv-pb-gap, var(--pb-gap));
    align-items: stretch;
}

.lv-pb-row--stack {
    flex-wrap: wrap;
}

.lv-pb-column {
    position: relative;
    min-width: 0; /* keep children from forcing sideways scroll */
    flex-grow: 0;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: clamp(1rem, 2vw, 1.5rem);
    background-repeat: no-repeat;
    background-size: cover;
}

/*
 * Column widths are twelfths, emitted as data-pb-width by the renderer. The tablet and
 * mobile variants only appear on the element when the administrator pinned one, so the
 * cascade below expresses "inherit the larger breakpoint, stack on phones" without the
 * editor having to repeat a value three times.
 *
 * The calc() keeps a row of N columns plus (N-1) gaps inside 100% instead of wrapping
 * at the twelfth pixel.
 */
.lv-pb-column[data-pb-width="1"]  { flex-basis: calc(8.3333% - var(--lv-pb-gap, var(--pb-gap)) * 11 / 12); }
.lv-pb-column[data-pb-width="2"]  { flex-basis: calc(16.6667% - var(--lv-pb-gap, var(--pb-gap)) * 10 / 12); }
.lv-pb-column[data-pb-width="3"]  { flex-basis: calc(25% - var(--lv-pb-gap, var(--pb-gap)) * 9 / 12); }
.lv-pb-column[data-pb-width="4"]  { flex-basis: calc(33.3333% - var(--lv-pb-gap, var(--pb-gap)) * 8 / 12); }
.lv-pb-column[data-pb-width="5"]  { flex-basis: calc(41.6667% - var(--lv-pb-gap, var(--pb-gap)) * 7 / 12); }
.lv-pb-column[data-pb-width="6"]  { flex-basis: calc(50% - var(--lv-pb-gap, var(--pb-gap)) * 6 / 12); }
.lv-pb-column[data-pb-width="7"]  { flex-basis: calc(58.3333% - var(--lv-pb-gap, var(--pb-gap)) * 5 / 12); }
.lv-pb-column[data-pb-width="8"]  { flex-basis: calc(66.6667% - var(--lv-pb-gap, var(--pb-gap)) * 4 / 12); }
.lv-pb-column[data-pb-width="9"]  { flex-basis: calc(75% - var(--lv-pb-gap, var(--pb-gap)) * 3 / 12); }
.lv-pb-column[data-pb-width="10"] { flex-basis: calc(83.3333% - var(--lv-pb-gap, var(--pb-gap)) * 2 / 12); }
.lv-pb-column[data-pb-width="11"] { flex-basis: calc(91.6667% - var(--lv-pb-gap, var(--pb-gap)) * 1 / 12); }
.lv-pb-column[data-pb-width="12"] { flex-basis: 100%; }

@media (max-width: 1024px) {
    .lv-pb-column[data-pb-width-tablet="1"]  { flex-basis: calc(8.3333% - var(--lv-pb-gap, var(--pb-gap)) * 11 / 12); }
    .lv-pb-column[data-pb-width-tablet="2"]  { flex-basis: calc(16.6667% - var(--lv-pb-gap, var(--pb-gap)) * 10 / 12); }
    .lv-pb-column[data-pb-width-tablet="3"]  { flex-basis: calc(25% - var(--lv-pb-gap, var(--pb-gap)) * 9 / 12); }
    .lv-pb-column[data-pb-width-tablet="4"]  { flex-basis: calc(33.3333% - var(--lv-pb-gap, var(--pb-gap)) * 8 / 12); }
    .lv-pb-column[data-pb-width-tablet="5"]  { flex-basis: calc(41.6667% - var(--lv-pb-gap, var(--pb-gap)) * 7 / 12); }
    .lv-pb-column[data-pb-width-tablet="6"]  { flex-basis: calc(50% - var(--lv-pb-gap, var(--pb-gap)) * 6 / 12); }
    .lv-pb-column[data-pb-width-tablet="7"]  { flex-basis: calc(58.3333% - var(--lv-pb-gap, var(--pb-gap)) * 5 / 12); }
    .lv-pb-column[data-pb-width-tablet="8"]  { flex-basis: calc(66.6667% - var(--lv-pb-gap, var(--pb-gap)) * 4 / 12); }
    .lv-pb-column[data-pb-width-tablet="9"]  { flex-basis: calc(75% - var(--lv-pb-gap, var(--pb-gap)) * 3 / 12); }
    .lv-pb-column[data-pb-width-tablet="10"] { flex-basis: calc(83.3333% - var(--lv-pb-gap, var(--pb-gap)) * 2 / 12); }
    .lv-pb-column[data-pb-width-tablet="11"] { flex-basis: calc(91.6667% - var(--lv-pb-gap, var(--pb-gap)) * 1 / 12); }
    .lv-pb-column[data-pb-width-tablet="12"] { flex-basis: 100%; }
}

/* Phones stack every column unless a mobile width was deliberately pinned. */
@media (max-width: 640px) {
    .lv-pb-row--stack > .lv-pb-column { flex-basis: 100%; }

    .lv-pb-column[data-pb-width-mobile="1"]  { flex-basis: calc(8.3333% - var(--lv-pb-gap, var(--pb-gap)) * 11 / 12); }
    .lv-pb-column[data-pb-width-mobile="2"]  { flex-basis: calc(16.6667% - var(--lv-pb-gap, var(--pb-gap)) * 10 / 12); }
    .lv-pb-column[data-pb-width-mobile="3"]  { flex-basis: calc(25% - var(--lv-pb-gap, var(--pb-gap)) * 9 / 12); }
    .lv-pb-column[data-pb-width-mobile="4"]  { flex-basis: calc(33.3333% - var(--lv-pb-gap, var(--pb-gap)) * 8 / 12); }
    .lv-pb-column[data-pb-width-mobile="5"]  { flex-basis: calc(41.6667% - var(--lv-pb-gap, var(--pb-gap)) * 7 / 12); }
    .lv-pb-column[data-pb-width-mobile="6"]  { flex-basis: calc(50% - var(--lv-pb-gap, var(--pb-gap)) * 6 / 12); }
}

/* ------------------------------------------------------------------ visibility */

@media (min-width: 1025px) {
    [data-pb-hide-desktop] { display: none !important; }
}

@media (max-width: 1024px) and (min-width: 641px) {
    [data-pb-hide-tablet] { display: none !important; }
}

@media (max-width: 640px) {
    [data-pb-hide-mobile] { display: none !important; }
}

/* ------------------------------------------------------------- grid engine
 *
 * Every commerce widget follows one contract (documented in categories.blade.php):
 *   - the ROOT declares the breakpoint trio, either inline (--lv-pb-cols /
 *     --lv-pb-cols-tablet / --lv-pb-cols-mobile) or as the data-pb-cols* attributes
 *     that lv-builder.js hydrates into those properties;
 *   - the item container lays itself out with repeat(var(--lv-pb-cols), minmax(0,1fr)).
 *
 * What this block supplies is the one thing no widget blade declares inline:
 * display:grid. Without it a grid-template is inert and every tile stacks into one
 * long column, so this rule is load-bearing rather than decorative.
 *
 * minmax(0,1fr) is non-negotiable: it is what stops one long Arabic compound word from
 * widening a column past a 320px screen.
 */
.lv-pb-items,
.lv-pb-grid {
    display: grid;
    grid-template-columns: repeat(var(--lv-pb-cols, var(--lv-pb-cols-fallback, 4)), minmax(0, 1fr));
    gap: var(--lv-pb-gap, 24px);
    align-items: start;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* No-JS fallback. lv-builder.js writes the resolved column count into --lv-pb-cols on
   every resize; before that runs - or if it never runs - the attribute alone must still
   produce a sane grid instead of one enormous stack. */
[data-pb-cols="1"] { --lv-pb-cols-fallback: 1; }
[data-pb-cols="2"] { --lv-pb-cols-fallback: 2; }
[data-pb-cols="3"] { --lv-pb-cols-fallback: 3; }
[data-pb-cols="4"] { --lv-pb-cols-fallback: 4; }
[data-pb-cols="5"] { --lv-pb-cols-fallback: 5; }
[data-pb-cols="6"] { --lv-pb-cols-fallback: 6; }

@media (max-width: 1024px) {
    [data-pb-cols-tablet="1"] { --lv-pb-cols-fallback: 1; }
    [data-pb-cols-tablet="2"] { --lv-pb-cols-fallback: 2; }
    [data-pb-cols-tablet="3"] { --lv-pb-cols-fallback: 3; }
    [data-pb-cols-tablet="4"] { --lv-pb-cols-fallback: 4; }
    [data-pb-cols-tablet="5"] { --lv-pb-cols-fallback: 5; }
}

@media (max-width: 640px) {
    [data-pb-cols-mobile="1"] { --lv-pb-cols-fallback: 1; }
    [data-pb-cols-mobile="2"] { --lv-pb-cols-fallback: 2; }
    [data-pb-cols-mobile="3"] { --lv-pb-cols-fallback: 3; }
}

/*
 * The tablet/mobile swap re-declares the TEMPLATE on the container. It never re-declares
 * --lv-pb-cols on the element that declares it: a custom property referring to itself is
 * invalid at computed-value time, which is exactly how a silent one-column bug is born.
 */
@media (max-width: 1024px) {
    .lv-pb-items,
    .lv-pb-grid {
        grid-template-columns: repeat(var(--lv-pb-cols-tablet, var(--lv-pb-cols, var(--lv-pb-cols-fallback, 3))), minmax(0, 1fr));
    }
}

@media (max-width: 640px) {
    .lv-pb-items,
    .lv-pb-grid {
        grid-template-columns: repeat(var(--lv-pb-cols-mobile, var(--lv-pb-cols-tablet, var(--lv-pb-cols, var(--lv-pb-cols-fallback, 2)))), minmax(0, 1fr));
    }
}

/* Rails are the shared carousel's no-JS shape: a real swipeable, snap-scrolling row.
   The scrollbar is hidden because the engine adds arrows; the row stays keyboard and
   touch scrollable, so nothing becomes unreachable without script. */
.lv-pb-rail {
    display: flex;
    gap: var(--lv-pb-gap, 24px);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.lv-pb-rail::-webkit-scrollbar { display: none; }

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

/*
 * One header pattern for every listing widget. The grid puts the title top-left, the
 * "view more" link opposite it on the SAME line, and the subtitle on a line of its own
 * under the title - which is why it is a two-row grid and not a flex row: the widgets
 * emit title and subtitle as siblings, and a flex row would fling the subtitle across
 * to the far edge of the container.
 */
.lv-pb-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    column-gap: 2rem;
    row-gap: .5rem;
    margin-block-end: clamp(1.5rem, 3vw, 2.5rem);
}

.lv-pb-head > * { min-width: 0; }

.lv-pb-head > .lv-pb-title,
.lv-pb-head > div { grid-column: 1; grid-row: 1; }

.lv-pb-head > .lv-pb-subtitle { grid-column: 1 / -1; grid-row: 2; }

.lv-pb-head > .lv-pb-view-more { grid-column: 2; grid-row: 1; align-self: end; }

.lv-pb-title {
    margin: 0;
    font-size: clamp(1.375rem, 2.4vw, 2rem);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -.02em;
    /* inherit: an administrator colouring the widget must recolour its own heading. */
    color: inherit;
    text-wrap: balance;
    overflow-wrap: anywhere;
}

.lv-pb-subtitle {
    margin: .5rem 0 0;
    max-width: 58ch;
    font-size: clamp(.9375rem, 1.1vw, 1.0625rem);
    line-height: 1.6;
    color: var(--pb-muted);
    overflow-wrap: anywhere;
}

/* A listing link reads as a control, not a stray word: a 40px hit area, a hairline that
   becomes a fill, and an arrow that travels on hover. */
.lv-pb-view-more {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    min-height: 40px;
    padding-inline: 1.1rem;
    border: 1px solid var(--pb-line);
    border-radius: 999px;
    font-size: .875rem;
    font-weight: 600;
    letter-spacing: .01em;
    color: var(--pb-ink);
    text-decoration: none;
    white-space: nowrap;
    transition: background-color var(--pb-fast) var(--pb-ease), color var(--pb-fast) var(--pb-ease),
        border-color var(--pb-fast) var(--pb-ease), transform var(--pb-fast) var(--pb-ease);
}

.lv-pb-view-more:hover {
    background: var(--pb-ink);
    border-color: var(--pb-ink);
    color: #fff;
    transform: translateY(-1px);
}

.lv-pb-view-more::after {
    content: "\2192";
    line-height: 1;
    transition: transform var(--pb-fast) var(--pb-ease);
}

.lv-pb-view-more:hover::after { transform: translateX(3px); }

/* ------------------------------------------------------- headings and prose */

/*
 * :where() is load-bearing here, not decoration.
 *
 * The renderer compiles an element's own style bag to a single-class selector
 * (.lv-pb-el-<id>, specificity 0-1-0) and inlines it in a <style> in <head>, BEFORE this
 * file is linked. Written plainly, a rule like `.lv-pb-heading { color: … }` ties with
 * that selector and wins on source order, so the sheet would silently outvote whatever
 * the administrator picked in the style panel - a white heading on a dark section would
 * render ink-on-ink and become invisible.
 *
 * :where() drops the specificity of what it wraps to zero. The default still beats an
 * inherited value (inheritance carries no declaration), and it loses to any real
 * declaration on the same element - which is exactly the precedence the builder needs:
 * sensible house style until an administrator overrules it, never after.
 *
 * Only rules that set properties the style panel can set (colour, type, spacing) belong
 * in :where(). Structural rules for inner parts (__nav, __tile, …) stay plain on purpose:
 * the administrator cannot style those, and the layout must not be outvoted.
 */
/*
 * Typography defaults live on the wrapper the style panel paints (.lv-pb-widget--<type>),
 * and the text element underneath inherits them. That ordering is what makes the panel
 * work at all: the compiler writes the admin's choice onto the wrapper, the element
 * inherits it, and the house style only shows when the admin set nothing. Without the
 * inherit list the theme's bare h2 / p element rules would beat an inherited value and
 * half of the Typography panel would silently do nothing.
 */
:where(.lv-pb-widget--heading) {
    font-size: clamp(1.5rem, 2.4vw, 2.25rem);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -.02em;
}

:where(.lv-pb-heading) {
    margin: 0;
    font-family: inherit;
    font-size: inherit;
    font-weight: inherit;
    font-style: inherit;
    line-height: inherit;
    letter-spacing: inherit;
    word-spacing: inherit;
    color: inherit;
    text-align: inherit;
    text-transform: inherit;
    text-decoration: inherit;
    text-shadow: inherit;
    text-wrap: balance;
    overflow-wrap: anywhere;
}

.lv-pb-heading a { color: inherit; text-decoration: none; }
.lv-pb-heading a:hover { color: var(--pb-accent); }

:where(.lv-pb-widget--text) {
    font-size: 1rem;
    line-height: 1.7;
}

:where(.lv-pb-text) {
    font-family: inherit;
    font-size: inherit;
    font-weight: inherit;
    line-height: inherit;
    letter-spacing: inherit;
    color: inherit;
    text-align: inherit;
    text-transform: inherit;
    overflow-wrap: anywhere;
}

/* The same argument one level down: a paragraph is a declaration of its own, so an
   inherited size would lose to it without this. Zero specificity keeps theme utility
   classes (text-sm and friends) in front of it. */
:where(.lv-pb-text) :is(p, ul, ol, li, blockquote) {
    font-size: inherit;
    line-height: inherit;
    color: inherit;
}

.lv-pb-text > :first-child { margin-top: 0; }
.lv-pb-text > :last-child { margin-bottom: 0; }

.lv-pb-prose p { margin: 0 0 1rem; }
.lv-pb-prose h1, .lv-pb-prose h2, .lv-pb-prose h3, .lv-pb-prose h4 {
    margin: 1.75rem 0 .75rem;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -.015em;
    /* Follows the element's colour for the same reason as .lv-pb-heading above. */
    color: inherit;
}
.lv-pb-prose ul, .lv-pb-prose ol { margin: 0 0 1rem; padding-inline-start: 1.25rem; }
.lv-pb-prose li { margin-block: .375rem; }
.lv-pb-prose a { color: var(--pb-accent); text-decoration: underline; text-underline-offset: 3px; }
.lv-pb-prose a:hover { text-decoration: none; }
.lv-pb-prose strong { font-weight: 600; color: inherit; }
.lv-pb-prose blockquote {
    margin: 1.5rem 0;
    padding-inline-start: 1.25rem;
    border-inline-start: 2px solid var(--pb-accent);
    color: var(--pb-ink-soft);
    font-style: normal;
}
.lv-pb-prose hr { border: 0; border-block-start: 1px solid var(--pb-line); margin-block: 2rem; }

/* ------------------------------------------------------------------ buttons */

.lv-pb-button-row { display: flex; flex-wrap: wrap; gap: .75rem; }
.lv-pb-button-row[data-align="start"] { justify-content: flex-start; }
.lv-pb-button-row[data-align="center"] { justify-content: center; }
.lv-pb-button-row[data-align="end"] { justify-content: flex-end; }

/*
 * Same precedence as the headings above: the variant IS the house style, so it is written
 * at zero specificity and an administrator's own colour, radius or padding on the button
 * outvotes it. The :hover rules stay plain (0-2-0) on purpose - hover feedback must survive
 * a custom colour, and no style panel rule sets one with a pseudo-class.
 */
:where(.lv-pb-button) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-height: 44px; /* a touch target, not a label */
    border: 1px solid transparent;
    border-radius: 999px;
    font-family: inherit;
    font-weight: 600;
    letter-spacing: .01em;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--pb-fast) var(--pb-ease), color var(--pb-fast) var(--pb-ease),
        border-color var(--pb-fast) var(--pb-ease), box-shadow var(--pb-fast) var(--pb-ease),
        transform var(--pb-fast) var(--pb-ease);
}

:where(.lv-pb-button--sm) { min-height: 38px; padding: .5rem 1.15rem; font-size: .8125rem; }
:where(.lv-pb-button--md) { padding: .688rem 1.75rem; font-size: .9375rem; }
:where(.lv-pb-button--lg) { min-height: 52px; padding: .875rem 2.25rem; font-size: 1.0625rem; }

:where(.lv-pb-button--primary) { background: var(--pb-primary, #088178); color: #fff; box-shadow: var(--pb-shadow-1); }
.lv-pb-button--primary:hover {
    background: var(--pb-primary-dark, #056d6e);
    color: #fff;
    box-shadow: var(--pb-shadow-2);
    transform: translateY(-1px);
}

:where(.lv-pb-button--secondary) { background: var(--pb-secondary, #3366ff); color: #fff; }
.lv-pb-button--secondary:hover { filter: brightness(.92); color: #fff; transform: translateY(-1px); }

:where(.lv-pb-button--outline) { background: transparent; color: var(--pb-primary, #088178); border-color: currentColor; }
.lv-pb-button--outline:hover { background: var(--pb-primary, #088178); color: #fff; }

:where(.lv-pb-button--ghost) { background: rgba(20, 18, 16, .06); color: inherit; }
.lv-pb-button--ghost:hover { background: rgba(20, 18, 16, .11); }

:where(.lv-pb-button--link) { background: none; padding-inline: 0; color: var(--pb-primary, #088178); text-decoration: underline; }
:where(.lv-pb-button--block) { width: 100%; }

.lv-pb-button:active { transform: translateY(0); box-shadow: var(--pb-shadow-1); }

/* --------------------------------------------------------- carousel chrome
 *
 * One shared engine (lv-builder.js) drives every rail and slider and looks for its
 * arrows and dots inside the widget root. That root therefore has to be the positioned
 * ancestor, or the controls anchor to the section and drift off the media. The list is
 * explicit rather than :has() so the sheet behaves identically everywhere.
 */
.lv-pb-slider,
.lv-pb-products,
.lv-pb-categories,
.lv-pb-brands,
.lv-pb-reviews,
.lv-pb-recent {
    position: relative;
}

.lv-pb-carousel-nav {
    position: absolute;
    inset-block-start: 50%;
    inset-inline: 0;
    z-index: 20;
    display: flex;
    justify-content: space-between;
    padding-inline: max(.25rem, calc(var(--pb-gutter, 1rem) * .5));
    pointer-events: none; /* only the buttons are interactive, never the strip */
}

.lv-pb-carousel-nav[hidden] { display: none; }

.lv-pb-carousel-prev,
.lv-pb-carousel-next {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 1px solid var(--pb-line);
    border-radius: 999px;
    background: rgba(255, 255, 255, .94);
    color: var(--pb-ink);
    font-size: 1.125rem;
    line-height: 1;
    box-shadow: var(--pb-shadow-2);
    backdrop-filter: blur(6px);
    cursor: pointer;
    pointer-events: auto;
    transform: translateY(-50%);
    transition: background-color var(--pb-fast) var(--pb-ease), color var(--pb-fast) var(--pb-ease),
        box-shadow var(--pb-fast) var(--pb-ease), transform var(--pb-fast) var(--pb-ease);
}

.lv-pb-carousel-prev:hover,
.lv-pb-carousel-next:hover {
    background: var(--pb-ink);
    border-color: var(--pb-ink);
    color: #fff;
    transform: translateY(calc(-50% - 2px));
}

.lv-pb-carousel-prev:active,
.lv-pb-carousel-next:active { transform: translateY(-50%); }

.lv-pb-carousel-dots {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .5rem;
    margin-block-start: 1.5rem;
}

.lv-pb-carousel-dots[hidden] { display: none; }

/*
 * The dot is 8px wide on purpose - a row of pagination dots is not a row of buttons -
 * but the HIT AREA is 24 x 32: padding is part of the box and the background is clipped
 * back to the content box. Small ink, comfortable target, no zoom-and-pray on a phone.
 */
.lv-pb-carousel-dot {
    box-sizing: content-box;
    width: 8px;
    height: 8px;
    padding: 12px 8px;
    border: 0;
    border-radius: 999px;
    background: rgba(20, 18, 16, .18);
    background-clip: content-box;
    cursor: pointer;
    transition: width var(--pb-fast) var(--pb-ease), background-color var(--pb-fast) var(--pb-ease);
}

.lv-pb-carousel-dot:hover { background: rgba(20, 18, 16, .38); }

/* The engine marks the live slide with aria-current, so the indicator reflects a real
   state instead of a class this stylesheet invented. */
.lv-pb-carousel-dot[aria-current="true"] {
    width: 26px;
    background: var(--pb-ink);
}

/* ------------------------------------------------------------- hero slider */

.lv-pb-slider__slide {
    position: relative;
    display: flex;
    align-items: center;
    min-width: 0;
    overflow: hidden;
    background: var(--pb-surface);
}

.lv-pb-slider__media { position: absolute; inset: 0; }

.lv-pb-slider__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

/*
 * Editorial scrim. The widget paints its own flat overlay from the editor's colour and
 * opacity; this adds a directional wash that keeps headline contrast stable however
 * bright the photograph is. It lives on a pseudo-element of the slide, so the overlay's
 * inline background cannot override it and it cannot be painted over by accident.
 */
.lv-pb-slider__slide::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(to top, rgba(12, 10, 9, .68) 0%, rgba(12, 10, 9, .26) 42%, rgba(12, 10, 9, 0) 72%);
}

.lv-pb-slider__slide > .lv-pb-container { position: relative; z-index: 10; }

.lv-pb-slider__content {
    max-width: 40rem;
    text-shadow: 0 2px 28px rgba(12, 10, 9, .32);
}

.lv-pb-slider__kicker {
    display: flex;
    align-items: center;
    gap: .625rem;
    margin: 0 0 .875rem;
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: .18em;
    text-transform: uppercase;
    opacity: .92;
}

.lv-pb-slider__kicker::before {
    content: "";
    flex: 0 0 28px;
    width: 28px;
    height: 1px;
    background: currentColor;
    opacity: .8;
}

.lv-pb-slider__badge {
    display: inline-flex;
    align-items: center;
    margin-block-end: .875rem;
    padding: .375rem .875rem;
    border: 1px solid rgba(255, 255, 255, .38);
    border-radius: 999px;
    background: rgba(12, 10, 9, .34);
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    backdrop-filter: blur(8px);
}

.lv-pb-slider__title {
    margin: 0 0 .75rem;
    max-width: 18ch;
    /*
     * inherit, explicitly: the theme styles bare h2/h3 element selectors, which beat an
     * inherited colour from the slide's own text-tone declaration. Without this line a
     * "light" slide renders its headline in near-black over the photograph.
     */
    color: inherit;
    font-size: clamp(2rem, 5.2vw, 3.75rem);
    font-weight: 600;
    line-height: 1.04;
    letter-spacing: -.03em;
    text-wrap: balance;
}

.lv-pb-slider__subtitle {
    margin: 0 0 1.75rem;
    max-width: 46ch;
    color: inherit;
    font-size: clamp(1rem, 1.35vw, 1.1875rem);
    line-height: 1.55;
    opacity: .94;
}

/*
 * A solid brand pill disappears into a photograph. On imagery the primary button flips
 * to a paper plate with ink text - the one treatment that holds contrast across every
 * frame in the library. Both colours are tokens, so an editor can retune the hero without
 * touching this file.
 */
.lv-pb-slider__content .lv-pb-button--primary {
    background: var(--pb-on-image-bg, #fff);
    color: var(--pb-on-image-ink, #141210);
    box-shadow: var(--pb-shadow-2);
}

.lv-pb-slider__content .lv-pb-button--primary:hover {
    background: var(--pb-on-image-ink, #141210);
    color: var(--pb-on-image-bg, #fff);
}

.lv-pb-slider__content .lv-pb-button--outline {
    background: rgba(255, 255, 255, .08);
    color: #fff;
    border-color: rgba(255, 255, 255, .55);
    backdrop-filter: blur(4px);
}

.lv-pb-slider__content .lv-pb-button--outline:hover { background: #fff; color: var(--pb-ink); }

/* Hero controls sit at the block end, the way editorial sliders do, instead of floating
   across the middle of the model's face. */
.lv-pb-slider .lv-pb-carousel-nav {
    inset-block-start: auto;
    inset-block-end: clamp(1rem, 3vw, 2rem);
    inset-inline: auto;
    inset-inline-end: clamp(1rem, 3vw, 2rem);
    gap: .625rem;
    padding: 0;
}

.lv-pb-slider .lv-pb-carousel-prev,
.lv-pb-slider .lv-pb-carousel-next {
    width: 48px;
    height: 48px;
    border-color: rgba(255, 255, 255, .35);
    background: rgba(12, 10, 9, .42);
    color: #fff;
    backdrop-filter: blur(10px);
    transform: none;
}

.lv-pb-slider .lv-pb-carousel-prev:hover,
.lv-pb-slider .lv-pb-carousel-next:hover {
    background: #fff;
    border-color: #fff;
    color: var(--pb-ink);
    transform: translateY(-2px);
}

.lv-pb-slider .lv-pb-carousel-dots {
    position: absolute;
    inset-block-end: clamp(1.7rem, 3.6vw, 2.7rem);
    inset-inline-start: clamp(1rem, 3vw, 2rem);
    z-index: 20;
    margin: 0;
}

.lv-pb-slider .lv-pb-carousel-dot { background: rgba(255, 255, 255, .45); }
.lv-pb-slider .lv-pb-carousel-dot:hover { background: rgba(255, 255, 255, .75); }
.lv-pb-slider .lv-pb-carousel-dot[aria-current="true"] { background: #fff; }

@media (max-width: 640px) {
    .lv-pb-slider__content { max-width: 100%; }
    .lv-pb-slider__title { max-width: 16ch; }
    .lv-pb-slider__subtitle { margin-block-end: 1.25rem; }
}

/* ------------------------------------------------------- package offer badge */

/*
 * The widget paints the discount with the theme's bg-error + text-white. That pairing is
 * 4.48:1 at text-xs - a hair under the 4.5:1 AA floor for small text - and it is the one
 * place on the page where the number a shopper is being asked to trust is the least
 * readable thing around. Same badge, house red, 6.3:1.
 */
.lv-pb-package-offer__discount {
    background: var(--pb-sale);
    letter-spacing: .02em;
    box-shadow: var(--pb-shadow-1);
}

/* ------------------------------------------------------------ product card
 *
 * The storefront's shared <x-product-card> is reused verbatim - the builder must not
 * grow a second idea of what a price or an add-to-cart button is - so the skin here is an
 * override scoped to the builder's own containers. Anchoring every rule to a builder
 * class is what stops a homepage restyle from leaking into the catalogue.
 */
.lv-pb-products .lv-pb-item,
.lv-pb-package-offer .lv-pb-item,
.lv-pb-recent .lv-pb-item { min-width: 0; }

/*
 * Nothing inside a card is allowed to be wider than the card. The shared card puts a
 * wishlist button beside the add-to-cart in one row; in a tight grid the cart button had
 * a natural width that ran 56px past the card border and drew over its neighbour.
 * min-width:0 is what lets a flex child shrink below its content size.
 */
.lv-pb-page .product-card-1 form,
.lv-pb-page .product-card-1 .btn { min-width: 0; max-width: 100%; }

.lv-pb-products .product-card-1,
.lv-pb-package-offer .product-card-1,
.lv-pb-recent .product-card-1 {
    padding: .625rem .625rem 1rem;
    border: 1px solid var(--pb-line);
    border-radius: var(--pb-radius-m);
    background: var(--pb-paper);
    transition: box-shadow var(--pb-slow) var(--pb-ease), transform var(--pb-slow) var(--pb-ease),
        border-color var(--pb-slow) var(--pb-ease);
}

.lv-pb-products .product-card-1:hover,
.lv-pb-package-offer .product-card-1:hover,
.lv-pb-recent .product-card-1:hover {
    border-color: transparent;
    box-shadow: var(--pb-shadow-3);
    transform: translateY(-4px);
}

.lv-pb-products .product-image,
.lv-pb-package-offer .product-image,
.lv-pb-recent .product-image {
    aspect-ratio: 4 / 5;
    border-radius: var(--pb-radius-s);
    background: var(--pb-surface);
}

.lv-pb-products .product-image img,
.lv-pb-package-offer .product-image img,
.lv-pb-recent .product-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    transition: transform var(--pb-slow) var(--pb-ease);
}

/* Deliberate override of the theme's "scale and rotate" hover: a tilted garment reads as
   a sticker, a straight zoom reads as a boutique. */
.lv-pb-products .product-card-1:hover .product-image img,
.lv-pb-package-offer .product-card-1:hover .product-image img,
.lv-pb-recent .product-card-1:hover .product-image img { transform: scale(1.06); }

.lv-pb-products .product-card-1 h5,
.lv-pb-package-offer .product-card-1 h5,
.lv-pb-recent .product-card-1 h5 {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    margin-block-end: .5rem;
    overflow: hidden;
    /*
     * Without this the two-line limit is a guillotine, not an ellipsis. Chromium implements
     * line-clamp as a hard height limit plus overflow clipping, and clipping alone cuts a
     * title mid-glyph ("Baby Essentials 5-Piece Newborn Clothi|"). Measured on mobile: 8 of
     * 11 card titles were severed with no visual cue that text continued. `ellipsis` is what
     * turns the same limit into "…".
     */
    text-overflow: ellipsis;
    font-size: .9375rem;
    font-weight: 500;
    line-height: 1.4;
    letter-spacing: -.01em;
    color: var(--pb-ink);
}

.lv-pb-products .product-card-1 h5 a { color: inherit; text-decoration: none; }
.lv-pb-products .product-card-1 h5 a:hover { text-decoration: underline; text-underline-offset: 3px; }

.lv-pb-products .lv-price-current,
.lv-pb-package-offer .lv-price-current,
.lv-pb-recent .lv-price-current {
    font-size: .9375rem;
    font-weight: 600;
    color: var(--pb-ink);
    font-variant-numeric: tabular-nums;
}

.lv-pb-products .rating-section span.text-sm,
.lv-pb-package-offer .rating-section span.text-sm { color: var(--pb-muted); }

/* The hover action pair: a paper pill lifting out of the media. Sizes are fixed so the
   hit area is 40px even though the theme nests the buttons tightly. */
.lv-pb-products .product-btn-actions,
.lv-pb-package-offer .product-btn-actions {
    inset-block-end: .5rem;
    inset-inline: .5rem;
    display: flex;
    justify-content: flex-end;
}

.lv-pb-products .product-btn-actions ul,
.lv-pb-package-offer .product-btn-actions ul {
    gap: 0;
    padding: .25rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, .96);
    box-shadow: var(--pb-shadow-2);
    backdrop-filter: blur(8px);
}

.lv-pb-products .product-btn-action-item,
.lv-pb-package-offer .product-btn-action-item {
    width: 40px;
    height: 40px;
    border-radius: 999px;
    color: var(--pb-ink);
}

.lv-pb-products .product-btn-action-item:hover,
.lv-pb-package-offer .product-btn-action-item:hover { background: var(--pb-ink); color: #fff; }

.lv-pb-products .btn-section .btn,
.lv-pb-package-offer .btn-section .btn { min-height: 42px; font-size: .8125rem; }

.lv-pb-products .btn-section .wishlist-toggle-btn,
.lv-pb-package-offer .btn-section .wishlist-toggle-btn {
    width: 42px;
    height: 42px;
    border-color: var(--pb-line);
    background: var(--pb-paper);
    transition: background-color var(--pb-fast) var(--pb-ease), border-color var(--pb-fast) var(--pb-ease);
}

.lv-pb-products .btn-section .wishlist-toggle-btn:hover,
.lv-pb-package-offer .btn-section .wishlist-toggle-btn:hover {
    border-color: var(--pb-ink);
    background: var(--pb-surface);
}

/* -------------------------------------------------------- category tiles */

/*
 * A category tile is one link, not a link plus a second link holding the same words:
 * the whole card is the hit area, the photograph is the artwork, the name sits on it.
 */
.lv-pb-category { min-width: 0; }

.lv-pb-category__card {
    position: relative;
    display: block;
    border-radius: var(--pb-radius-m);
    overflow: hidden;
    background: var(--pb-surface);
    color: #fff;
    text-decoration: none;
    box-shadow: var(--pb-shadow-1);
    transition: box-shadow var(--pb-slow) var(--pb-ease), transform var(--pb-slow) var(--pb-ease);
}

.lv-pb-category__card:hover { box-shadow: var(--pb-shadow-3); transform: translateY(-4px); }

.lv-pb-category__media {
    position: relative;
    display: block;
    width: 100%;
    overflow: hidden;
    background: var(--pb-line-soft);
}

.lv-pb-category__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    transition: transform var(--pb-slow) var(--pb-ease);
}

.lv-pb-category__card:hover .lv-pb-category__img { transform: scale(1.06); }

/* Wash under the label, so a wordmark stays readable on a pale garment photograph. */
.lv-pb-category__scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(12, 10, 9, .74) 0%, rgba(12, 10, 9, .28) 38%, rgba(12, 10, 9, 0) 66%);
}

.lv-pb-category__label {
    position: absolute;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: 2;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .375rem;
    padding: clamp(.875rem, 2vw, 1.25rem);
}

.lv-pb-category__name {
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: -.01em;
    line-height: 1.25;
    overflow-wrap: anywhere;
}

.lv-pb-category__card:hover .lv-pb-category__name { text-decoration: underline; text-underline-offset: 4px; }

.lv-pb-category__count {
    font-size: .75rem;
    font-weight: 500;
    opacity: .82;
    font-variant-numeric: tabular-nums;
}

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

.lv-pb-banner {
    border-radius: var(--pb-radius-l);
    box-shadow: var(--pb-shadow-2);
}

.lv-pb-banner__img { transition: transform 900ms var(--pb-ease); }
.lv-pb-banner:hover .lv-pb-banner__img { transform: scale(1.04); }

.lv-pb-banner__kicker {
    margin: 0 0 .75rem;
    font-size: .75rem;
    letter-spacing: .18em;
    text-transform: uppercase;
    opacity: .9;
}

.lv-pb-banner__title {
    margin: 0 0 .75rem;
    max-width: 20ch;
    /* Same reason as the slider headline: the theme's h2 rule must not win here. */
    color: inherit;
    font-size: clamp(1.5rem, 3.2vw, 2.5rem);
    font-weight: 600;
    line-height: 1.08;
    letter-spacing: -.025em;
    text-wrap: balance;
}

.lv-pb-banner__subtitle {
    margin: 0 0 1.5rem;
    max-width: 48ch;
    color: inherit;
    font-size: clamp(.9375rem, 1.2vw, 1.0625rem);
    line-height: 1.6;
    opacity: .92;
}

.lv-pb-banner--light { color: #fff; text-shadow: 0 2px 22px rgba(12, 10, 9, .3); }
.lv-pb-banner--dark { color: var(--pb-ink); text-shadow: none; }

.lv-pb-banner__cta .lv-pb-button--primary {
    background: #fff;
    color: var(--pb-ink);
    box-shadow: var(--pb-shadow-2);
}

.lv-pb-banner__cta .lv-pb-button--primary:hover { background: var(--pb-ink); color: #fff; }
.lv-pb-banner--dark .lv-pb-banner__cta .lv-pb-button--primary { background: var(--pb-ink); color: #fff; }
.lv-pb-banner--dark .lv-pb-banner__cta .lv-pb-button--primary:hover { background: #000; }

/* ------------------------------------------------------------- brand tiles */

.lv-pb-brand__card {
    min-height: 108px;
    padding: 1.25rem;
    border: 1px solid var(--pb-line) !important;
    border-radius: var(--pb-radius-s) !important;
    background: var(--pb-paper);
    text-decoration: none;
    transition: box-shadow var(--pb-slow) var(--pb-ease), transform var(--pb-slow) var(--pb-ease),
        border-color var(--pb-slow) var(--pb-ease);
}

.lv-pb-brand__card:hover {
    border-color: var(--pb-ink) !important;
    box-shadow: var(--pb-shadow-2);
    transform: translateY(-2px);
}

/* Logos arrive in every colour and aspect ratio; one grey-scale rule turns a strip of
   mismatched uploads into a single row of marks that the eye reads at once. */
.lv-pb-brand__img {
    max-height: 44px;
    filter: grayscale(1);
    opacity: .68;
    transition: filter var(--pb-slow) var(--pb-ease), opacity var(--pb-slow) var(--pb-ease);
}

.lv-pb-brand__card:hover .lv-pb-brand__img { filter: grayscale(0); opacity: 1; }

.lv-pb-brand__fallback {
    font-size: .9375rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--pb-ink-soft);
}

.lv-pb-brand__name { margin-block-start: .625rem; font-size: .8125rem; font-weight: 500; color: var(--pb-muted); }
.lv-pb-brand__name a { color: inherit; text-decoration: none; }
.lv-pb-brand__name a:hover { color: var(--pb-ink); text-decoration: underline; text-underline-offset: 3px; }

/* ------------------------------------------------------------ benefits strip */

.lv-pb-benefits,
.lv-pb-icon-list { margin: 0; padding: 0; list-style: none; }

.lv-pb-benefit { min-width: 0; }

.lv-pb-benefit__card {
    height: 100%;
    border: 1px solid var(--pb-line) !important;
    border-radius: var(--pb-radius-m) !important;
    background: var(--pb-paper);
    transition: box-shadow var(--pb-slow) var(--pb-ease), transform var(--pb-slow) var(--pb-ease),
        border-color var(--pb-slow) var(--pb-ease);
}

.lv-pb-benefit__card:hover {
    border-color: transparent !important;
    box-shadow: var(--pb-shadow-2);
    transform: translateY(-2px);
}

/* The icon is a mark, not decoration: the same circle and ink whatever the editor picked. */
.lv-pb-benefit__icon {
    width: 48px;
    height: 48px;
    border-radius: 999px;
    background: var(--pb-surface);
    color: var(--pb-accent);
}

.lv-pb-benefit__body { display: flex; flex-direction: column; gap: .25rem; padding-block-start: .125rem; }

.lv-pb-benefit__title { font-size: .9375rem; font-weight: 600; letter-spacing: -.005em; color: var(--pb-ink); }
.lv-pb-benefit__text { font-size: .8125rem; line-height: 1.55; color: var(--pb-muted); }

/*
 * min-height: 24px on a text link is not padding for looks. WCAG 2.2 SC 2.5.8 measures
 * the target box, and these two links are flex boxes whose box was the 20px text line —
 * a phone number and a product name a thumb has to hit precisely. The flex container
 * honours min-height, so the hit area grows to the norm without the type moving.
 */
.lv-pb-benefit__text--link { color: var(--pb-ink); text-decoration: none; align-self: flex-start; min-height: 24px; }
.lv-pb-benefit__text--link i { transition: transform var(--pb-fast) var(--pb-ease); }
.lv-pb-benefit__text--link:hover i { transform: translateX(3px); }

/* Dividers are opt-in (data-pb-dividers). On phones the strip becomes one column, where
   a vertical rule would read as a stray line, so it flips to a horizontal hairline. */
.lv-pb-benefits--dividers .lv-pb-benefit:not(:first-child) .lv-pb-benefit__card {
    border-inline-start: 1px solid var(--pb-line) !important;
}

@media (max-width: 640px) {
    .lv-pb-benefits--dividers .lv-pb-benefit:not(:first-child) .lv-pb-benefit__card {
        border-block-start: 1px solid var(--pb-line) !important;
    }
}

/* ------------------------------------------------------------------- coupon */

/*
 * The offer panel is deliberately the one dark surface on a light page: a discount code
 * is the loudest promise a storefront makes, and it should read like a ticket rather
 * than like a form field.
 */
.lv-pb-coupon--code_card,
.lv-pb-coupon--banner {
    position: relative;
    padding: clamp(1.5rem, 3vw, 2.25rem) !important;
    border: 0 !important;
    border-radius: var(--pb-radius-l) !important;
    background: var(--pb-ink);
    color: #fff;
    box-shadow: var(--pb-shadow-3);
}

.lv-pb-coupon__title { margin: 0; font-size: 1.125rem; font-weight: 600; letter-spacing: -.01em; color: #fff; }

.lv-pb-coupon__discount {
    font-size: clamp(1.75rem, 3vw, 2.25rem);
    font-weight: 600;
    letter-spacing: -.02em;
    line-height: 1.1;
    color: #e8c79a;
    font-variant-numeric: tabular-nums;
}

.lv-pb-coupon__text { color: rgba(255, 255, 255, .82); line-height: 1.6; }
.lv-pb-coupon__side { padding-block-start: 1rem; }

/* A dashed rule is the perforation: it tells the eye the code is the tear-off half. */
.lv-pb-coupon--code_card .lv-pb-coupon__side {
    width: 100%;
    border-block-start: 1px dashed rgba(255, 255, 255, .28);
}

.lv-pb-coupon__code,
.lv-pb-coupon__code--copy {
    border: 1px dashed rgba(255, 255, 255, .45) !important;
    border-radius: var(--pb-radius-s) !important;
    background: rgba(255, 255, 255, .1) !important;
    color: #fff !important;
    cursor: pointer;
    transition: background-color var(--pb-fast) var(--pb-ease), border-color var(--pb-fast) var(--pb-ease);
}

.lv-pb-coupon__code--copy:hover {
    background: rgba(255, 255, 255, .2) !important;
    border-style: solid !important;
}

/* lv-builder.js adds .is-copied for 1.5s after a successful clipboard write. */
.lv-pb-coupon__code--copy.is-copied {
    background: #fff !important;
    border-color: #fff !important;
    color: var(--pb-ink) !important;
}

.lv-pb-coupon__expiry { color: rgba(255, 255, 255, .72); }

/* ----------------------------------------------------------- package offer */

.lv-pb-package-offer {
    padding: clamp(1.25rem, 2.5vw, 2rem);
    border: 1px solid var(--pb-line);
    border-radius: var(--pb-radius-l);
    background: var(--pb-surface);
}

.lv-pb-package-offer__name {
    margin-block-end: .5rem;
    font-size: 1.25rem;
    font-weight: 600;
    letter-spacing: -.015em;
    color: var(--pb-ink);
}

.lv-pb-package-offer__desc { color: var(--pb-muted); }
.lv-pb-package-offer__save strong { color: var(--pb-accent); }
.lv-pb-package-offer__count,
.lv-pb-package-offer__group { color: var(--pb-muted); letter-spacing: .06em; }

.lv-pb-package-offer__media {
    border: 0 !important;
    border-radius: var(--pb-radius-m) !important;
    background: var(--pb-paper);
}

/* Tailwind's col-span classes do the split; restating it here keeps the block correct if
   the theme build ever drops those utilities, and it costs nothing when they exist. */
.lv-pb-package-offer__summary,
.lv-pb-package-offer__products { grid-column: span 12; }

@media (min-width: 1024px) {
    .lv-pb-package-offer__summary { grid-column: span 4; }
    .lv-pb-package-offer__products { grid-column: span 8; }
}

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

.lv-pb-review__card {
    height: 100%;
    border: 1px solid var(--pb-line) !important;
    border-radius: var(--pb-radius-m) !important;
    background: var(--pb-paper);
    box-shadow: var(--pb-shadow-1);
    transition: box-shadow var(--pb-slow) var(--pb-ease), transform var(--pb-slow) var(--pb-ease);
}

.lv-pb-review__card:hover { box-shadow: var(--pb-shadow-2); transform: translateY(-2px); }

.lv-pb-review__avatar {
    width: 44px;
    height: 44px;
    border-radius: 999px;
    background: var(--pb-surface);
    color: var(--pb-ink);
    font-size: .9375rem;
    font-weight: 600;
}

.lv-pb-review__avatar img { width: 100%; height: 100%; object-fit: cover; }

.lv-pb-review__author { font-size: .9375rem; font-weight: 600; color: var(--pb-ink); }
.lv-pb-review__date { margin-block-start: .125rem; color: var(--pb-muted); }

.lv-pb-review__star { font-size: .9375rem; color: var(--pb-line); }
.lv-pb-review__star--on { color: #e9a83c; }
.lv-pb-review__rating-value { color: var(--pb-muted); font-variant-numeric: tabular-nums; }

.lv-pb-review__text {
    margin-block: 1rem;
    font-size: .9375rem;
    line-height: 1.7;
    color: var(--pb-ink-soft);
}

.lv-pb-review__product { color: var(--pb-accent); text-decoration: none; font-weight: 500; min-height: 24px; }
.lv-pb-review__product i { transition: transform var(--pb-fast) var(--pb-ease); }
.lv-pb-review__product:hover i { transform: translateX(3px); }

/* ------------------------------------------------------- instagram / gallery */

.lv-pb-ig-tile__link { text-decoration: none; color: inherit; }

.lv-pb-ig-tile__media {
    position: relative;
    display: block;
    border: 0 !important;
    border-radius: var(--pb-radius-m) !important;
    background: var(--pb-surface);
}

.lv-pb-ig-tile__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--pb-slow) var(--pb-ease);
}

.lv-pb-ig-tile__link:hover .lv-pb-ig-tile__img { transform: scale(1.07); }

/* The hover wash is what tells a visitor the tile opens something; without JS the same
   anchor still navigates, so this is an affordance and never the only path. */
.lv-pb-ig-tile__media::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: rgba(12, 10, 9, .38);
    opacity: 0;
    transition: opacity var(--pb-slow) var(--pb-ease);
}

.lv-pb-ig-tile__link:hover .lv-pb-ig-tile__media::after,
.lv-pb-ig-tile__link:focus-visible .lv-pb-ig-tile__media::after { opacity: 1; }

.lv-pb-ig-tile__caption {
    margin-block-start: .5rem;
    font-size: .75rem;
    line-height: 1.5;
    color: var(--pb-muted);
}

/* --------------------------------------------------------------- icon list */

.lv-pb-icon-list__item { min-width: 0; }

.lv-pb-icon-list__entry {
    display: flex;
    align-items: center;
    gap: .75rem;
    min-height: 44px;
    color: var(--pb-ink);
    text-decoration: none;
    font-size: .9375rem;
    font-weight: 500;
    line-height: 1.45;
}

.lv-pb-icon-list__entry i {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 999px;
    background: var(--pb-surface);
    color: var(--pb-accent);
}

.lv-pb-icon-list__entry--link { transition: color var(--pb-fast) var(--pb-ease); }
.lv-pb-icon-list__entry--link:hover { color: var(--pb-accent); }
.lv-pb-icon-list__text { overflow-wrap: anywhere; }

/* -------------------------------------------------------------------- video */

.lv-pb-video {
    border-radius: var(--pb-radius-m);
    box-shadow: var(--pb-shadow-2);
    background: #0f0e0d;
}

/*
 * A clip uploaded to this shop knows its own shape. The widget's default 16/9 box suits an
 * embedded YouTube film, but a product clip shot for a phone is 704x1280 - forced into
 * 16/9 it rendered as a 684px slab with the picture in a strip across the top.
 *
 * When the ratio is "auto" the view emits no inline aspect-ratio, and that absence is the
 * signal used here: the media leaves the absolute layer and takes its intrinsic height, so
 * the box becomes the clip rather than a frame cut to it. Chosen ratios keep the existing
 * letterbox-safe behaviour.
 */
.lv-pb-video--file:not([style*="aspect-ratio"]),
.lv-pb-video--youtube:not([style*="aspect-ratio"]) {
    position: relative;
    aspect-ratio: auto;
}

.lv-pb-video--file:not([style*="aspect-ratio"]) video {
    position: static;
    width: 100%;
    height: auto;
    display: block;
    object-fit: contain;
    background: #0f0e0d;
}

.lv-pb-video__poster {
    gap: .75rem;
    background: linear-gradient(to top, rgba(12, 10, 9, .62), rgba(12, 10, 9, .22));
    color: #fff;
    font: inherit;
}

.lv-pb-video__poster:hover { background: linear-gradient(to top, rgba(12, 10, 9, .72), rgba(12, 10, 9, .34)); }

/* The play control is a real 72px button, not a glyph, so it reads as tappable on a
   phone and as deliberate on a desktop. */
.lv-pb-video__poster i,
.lv-pb-video__play i {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 72px;
    border: 1px solid rgba(255, 255, 255, .5);
    border-radius: 999px;
    background: rgba(255, 255, 255, .16);
    font-size: 1.75rem !important;
    line-height: 1;
    backdrop-filter: blur(6px);
    transition: transform var(--pb-fast) var(--pb-ease), background-color var(--pb-fast) var(--pb-ease);
}

.lv-pb-video__poster:hover i,
.lv-pb-video__play:hover i { background: #fff; color: var(--pb-ink); transform: scale(1.06); }

.lv-pb-video__caption {
    margin-block-start: .625rem;
    font-size: .8125rem;
    color: var(--pb-muted);
}

/* ----------------------------------------------------------- divider/spacer */

.lv-pb-divider {
    border: 0;
    border-block-start: 1px solid var(--pb-line);
    margin-block: .5rem;
}

.lv-pb-divider--dashed { border-block-start-style: dashed; }
.lv-pb-divider--dotted { border-block-start-style: dotted; }
/* A double rule only reads as a double rule if it has room to breathe. */
.lv-pb-divider--double { border-block-start: 3px double var(--pb-line); }

.lv-pb-spacer { width: 100%; }

/* -------------------------------------------------------------------- image */

.lv-pb-image {
    position: relative;
    display: block;
    margin: 0;
    line-height: 0;
    border-radius: var(--pb-radius-m);
    overflow: hidden;
}

.lv-pb-image img {
    width: 100%;
    height: auto;
    display: block;
    transition: transform var(--pb-slow) var(--pb-ease);
}

.lv-pb-image a:hover img,
a.lv-pb-image:hover img { transform: scale(1.03); }

.lv-pb-image figcaption {
    margin-block-start: .625rem;
    font-size: .8125rem;
    line-height: 1.5;
    color: var(--pb-muted);
    line-height: 1.5;
}

/* ------------------------------------------------------------ empty states
 * Editor-only: the storefront renders nothing at all when a widget has no data, so
 * this surface exists to explain that to the person holding the editor.
 */
.lv-pb-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .375rem;
    min-height: 140px;
    padding: 1.5rem;
    border: 1px dashed var(--pb-line);
    border-radius: var(--pb-radius-m);
    background: var(--pb-surface);
    color: var(--pb-muted);
    font-size: .8125rem;
    text-align: center;
}

.lv-pb-empty i { font-size: 1.5rem; color: var(--pb-ink-soft); opacity: .55; }
.lv-pb-empty strong { font-size: .875rem; font-weight: 600; color: var(--pb-ink); }

/* ----------------------------------------------------------------- lightbox
 * lv-builder.js creates the overlay and its minimum chrome inline; these are the
 * properties the inline sheet does not carry - a soft edge on the photograph and a
 * blurred backdrop so the page behind stops competing with it.
 */
.lv-pb-lightbox { backdrop-filter: blur(8px); }
.lv-pb-lightbox img { box-shadow: var(--pb-shadow-3); }
.lv-pb-lightbox button { transition: background-color var(--pb-fast) var(--pb-ease); }
.lv-pb-lightbox button:hover { background: rgba(0, 0, 0, .7) !important; }

/* --------------------------------------------------------------- focus ring
 * One focus treatment across every builder control. :focus-visible means keyboard
 * users get the ring and mouse users do not get a stray outline.
 */
.lv-pb-page a:focus-visible,
.lv-pb-page button:focus-visible,
.lv-pb-page [tabindex]:focus-visible {
    outline: 2px solid var(--pb-accent);
    outline-offset: 3px;
    border-radius: inherit;
}

/* ----------------------------------------------------------------- motion
 * Every transform in this sheet is a nicety. If the visitor has asked the system for
 * less motion, they get the layout and the states without the movement.
 */
@media (prefers-reduced-motion: reduce) {
    .lv-pb-page *,
    .lv-pb-page *::before,
    .lv-pb-page *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }

    .lv-pb-products .product-card-1:hover,
    .lv-pb-category__card:hover,
    .lv-pb-benefit__card:hover,
    .lv-pb-review__card:hover,
    .lv-pb-brand__card:hover,
    .lv-pb-button:hover { transform: none; }

    .lv-pb-products .product-card-1:hover .product-image img,
    .lv-pb-category__card:hover .lv-pb-category__img,
    .lv-pb-ig-tile__link:hover .lv-pb-ig-tile__img,
    .lv-pb-banner:hover .lv-pb-banner__img { transform: none; }
}

/* --------------------------------------------------------------- utilities */

/* Alternating surfaces are the cheapest way to give a long page structure, and the
   renderer applies them from the section's own background colour. These two helpers
   exist so an editor gets the tint right without guessing a hex value. */
.lv-pb-section--surface { background-color: var(--pb-surface); }
.lv-pb-section--paper { background-color: var(--pb-paper); }

/* A section whose first child is a header should not inherit extra top air. */
.lv-pb-section > .lv-pb-container > .lv-pb-row > .lv-pb-column > .lv-pb-head:first-child {
    margin-block-start: 0;
}

/* ------------------------------------------------------------------ motion */

/*
 * The entrance animations the Motion panel offers. StyleCompiler only accepts a name
 * from this exact list, so a page can never reference a keyframe that does not exist -
 * and an animation that cannot be found is the kind of bug that shows as a blank block
 * for three seconds before the content appears.
 *
 * Every one of them starts from a state the element must NOT be left in, and the
 * compiler emits `both` fill mode so the element holds its starting frame during the
 * delay instead of flashing at full opacity first.
 */
@keyframes pb-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes pb-fade-up {
    from { opacity: 0; transform: translate3d(0, 24px, 0); }
    to { opacity: 1; transform: none; }
}

@keyframes pb-fade-down {
    from { opacity: 0; transform: translate3d(0, -24px, 0); }
    to { opacity: 1; transform: none; }
}

/* Directional slides use logical translation so Arabic pages slide the sensible way. */
@keyframes pb-fade-left {
    from { opacity: 0; transform: translate3d(-28px, 0, 0); }
    to { opacity: 1; transform: none; }
}

@keyframes pb-fade-right {
    from { opacity: 0; transform: translate3d(28px, 0, 0); }
    to { opacity: 1; transform: none; }
}

@keyframes pb-zoom-in {
    from { opacity: 0; transform: scale3d(.94, .94, 1); }
    to { opacity: 1; transform: none; }
}

@keyframes pb-blur-in {
    from { opacity: 0; filter: blur(8px); }
    to { opacity: 1; filter: blur(0); }
}

/*
 * Balance issues are real: an animation that plays on every page load is also an
 * animation that a visitor with vestibular sensitivity never asked for. Honouring the
 * OS preference costs nothing and is the correct default.
 */
@media (prefers-reduced-motion: reduce) {
    .lv-pb-page *,
    .lv-pb-page *::before,
    .lv-pb-page *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}










