/* ==========================================================================
   EVA — Red Light Therapy | Product Page Stylesheet
   Author : IT Geeks
   File   : pdp.css  (pdp.html only — loaded after style.css/responsive.css)
   Note   : Page-scoped. Every value comes from :root in style.css; nothing
            global is redefined. The luxury here is restraint — hairline
            rules instead of boxes, wide letterspaced micro-caps, one
            champagne accent used sparingly, and a great deal of air.
            Breakpoints live at the foot of the file.
   ========================================================================== */

/* ==========================================================================
   00. PAGE SCALE
   ========================================================================== */
.page-pdp {
    /* one height for every content section on the page, so they share a
       rhythm rather than each taking whatever their contents ask for.
       720px is the figure .hero already uses on the home page. */
    --panel-h: 720px;

    /* how far below the viewport top the sticky gallery parks — the header
       height plus a breath, so it can never slide under the stuck bar */
    --stick-top: calc(var(--header-height) + var(--space-24));

    /* The benefits section runs from the page's own background down into
       lilac, and the comparison below picks that exact colour back up — the
       same trick --gradient-pink-to-lilac plays on the home page, so the two
       meet without a seam. Page-scoped: the shared tokens are untouched. */
    --gradient-bg-to-lilac: linear-gradient(180deg,
        var(--color-bg) 0%,
        #FAF7FB 40%,
        #F2ECFA 72%,
        #EBE1F9 100%);
    /* and the comparison carries that lilac on down into the blush the
       reviews section starts on, so that join is seamless too */
    --gradient-lilac-to-blush: linear-gradient(180deg,
        #EBE1F9 0%,
        #F4E9F7 42%,
        #FBEBF3 78%,
        var(--color-bg-alt) 100%);

    /* the hairline this page draws every rule with */
    --rule: var(--border-thin) solid var(--color-line);
    --rule-soft: var(--border-thin) solid var(--color-line-soft);
}

/* ==========================================================================
   01. BREADCRUMB
   ========================================================================== */
.crumbs {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-10);
    font-size: var(--font-11);
    font-weight: var(--fw-medium);
    letter-spacing: var(--ls-wider);
    text-transform: var(--tt-uppercase);
    color: var(--color-muted);
}

.crumbs a {
    color: var(--color-muted);
    transition: color var(--transition-fast);
}

.crumbs a:hover {
    color: var(--color-rose-gold-deep);
}

.crumbs span {
    color: var(--color-ink);
}

.crumbs i {
    font-size: var(--font-10);
}

/* ==========================================================================
   02. THE PRODUCT
   ========================================================================== */
.product {
    display: flex;
    flex-direction: row;
    justify-content: center;
    width: 100%;
    /* clears the absolutely-positioned header, tied to its height */
    padding: calc(var(--header-height) + var(--space-24)) var(--gutter-width) var(--space-96);
    background-image: var(--gradient-pearl);
    position: relative;
}

.product .container {
    gap: var(--space-32);
}

.product-layout {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: var(--space-80);
    width: 100%;
}

/* ---------- gallery ---------- */
.gallery {
    display: flex;
    /* the thumb rail runs down the left of the stage, not under it */
    flex-direction: row;
    align-items: stretch;
    gap: var(--space-16);
    /* the images hold their place while the buy panel scrolls past them */
    position: sticky;
    top: var(--stick-top);
    flex: 1 1 54%;
    min-width: 0;
    /* the sticky column is one panel tall, like every section below it */
    height: var(--panel-h);
}

.gallery-stage {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    width: 100%;
    /* takes the panel's height minus the thumb strip, rather than a ratio
       that would push the column past --panel-h */
    flex: 1 1 auto;
    min-height: 0;
    padding: var(--space-48);
    background-color: var(--color-white);
    border-radius: var(--radius-2xl);
    box-shadow: var(--shadow-sm);
    position: relative;
    overflow: hidden;
}

.gallery-glow {
    display: block;
    position: absolute;
    inset: 0;
    background-image: var(--gradient-glow);
    opacity: 0.7;
    pointer-events: none;
}

.gallery-main {
    display: block;
    width: auto;
    max-width: 84%;
    max-height: 100%;
    position: relative;
    z-index: var(--z-base);
    /* invisible on the transparent product cutouts, but it stops a
       photograph with its own background reading as a bare rectangle */
    border-radius: var(--radius-lg);
    /* the swap is a cross-fade, not a cut */
    transition: opacity 0.4s ease, transform var(--transition-slow);
}

.gallery-stage:hover .gallery-main {
    transform: scale(1.04);
}

.gallery.is-swapping .gallery-main {
    opacity: 0;
}

/* the FDA flag and the frame counter, both riding the stage corners */
.gallery-flag,
.gallery-count {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-8);
    position: absolute;
    z-index: var(--z-raised);
    padding: var(--space-8) var(--space-16);
    font-size: var(--font-11);
    font-weight: var(--fw-medium);
    letter-spacing: var(--ls-wider);
    text-transform: var(--tt-uppercase);
    border-radius: var(--radius-pill);
}

.gallery-flag {
    top: var(--space-24);
    left: var(--space-24);
    color: var(--color-ink);
    background-color: var(--color-champagne-soft);
}

.gallery-count {
    right: var(--space-24);
    bottom: var(--space-24);
    color: var(--color-muted);
    background-color: rgba(255, 255, 255, 0.8);
    border: var(--rule-soft);
}

.gallery-thumbs {
    display: flex;
    flex-direction: column;
    /* the rail stacks from the top of the stage, not from its middle */
    justify-content: flex-start;
    gap: var(--space-12);
    flex: 0 0 auto;
    width: 96px;
    height: 100%;
}

.gallery-thumb {
    /* The image used to size this tile: its percentage height had nothing
       definite to resolve against, so it fell back to its own intrinsic
       ratio and stretched the tile with it — the five squares came out
       96x113, 96x96, 96x105, 96x96, 96x96. Taking the image out of flow
       (absolute, below) breaks that loop: the tile's height now comes from
       aspect-ratio alone, and the image resolves against it. */
    display: block;
    position: relative;
    flex: 0 0 auto;
    width: 100%;
    aspect-ratio: 1 / 1;
    background-color: var(--color-white);
    border: var(--border-thin) solid transparent;
    border-radius: var(--radius-lg);
    cursor: pointer;
    transition: border-color var(--transition-base), transform var(--transition-base);
}

.gallery-thumb img {
    display: block;
    position: absolute;
    inset: var(--space-12);
    width: calc(100% - (var(--space-12) * 2));
    height: calc(100% - (var(--space-12) * 2));
    object-fit: contain;
    border-radius: var(--radius-sm);
}

.gallery-thumb:hover {
    /* it moves toward the stage now, not up */
    transform: translateX(3px);
}

.gallery-thumb.is-active {
    border-color: var(--color-rose-gold-deep);
}

/* ---------- buy panel ---------- */
.buy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-24);
    flex: 1 1 46%;
    min-width: 0;
    /* the panel is the reading column: never let it run past a comfortable
       measure, however wide the screen gets */
    max-width: 560px;
}

.buy-head {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-12);
    width: 100%;
}

.buy-head h1 {
    font-size: var(--font-h2);
    line-height: var(--lh-snug);
    letter-spacing: var(--ls-tight);
}

.buy-meta {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-16);
    width: 100%;
    padding-bottom: var(--space-20);
    border-bottom: var(--rule);
}

.buy-meta .rating {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-10);
}

.buy-meta .rating-label {
    font-size: var(--font-13);
    color: var(--color-body);
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-color: var(--color-line);
    transition: text-decoration-color var(--transition-fast);
}

.buy-meta .rating-label:hover {
    text-decoration-color: var(--color-rose-gold-deep);
}

.buy-sku {
    font-size: var(--font-11);
    letter-spacing: var(--ls-wider);
    text-transform: var(--tt-uppercase);
    color: var(--color-muted);
}

.buy-lead {
    font-size: var(--font-17);
    line-height: var(--lh-relaxed);
    color: var(--color-body);
}

/* ---------- price ---------- */
.buy-price {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    gap: var(--space-16);
}

.buy-price-now {
    font-family: var(--font-heading);
    font-size: var(--font-display-xl);
    line-height: var(--lh-tight);
    color: var(--color-heading);
}

.buy-price-was {
    font-size: var(--font-19);
    color: var(--color-muted);
    text-decoration: line-through;
}

.buy-price-save {
    padding: var(--space-6) var(--space-12);
    font-size: var(--font-11);
    font-weight: var(--fw-medium);
    letter-spacing: var(--ls-wider);
    text-transform: var(--tt-uppercase);
    color: var(--color-ink);
    background-color: var(--color-champagne-soft);
    border-radius: var(--radius-pill);
}

.buy-stock {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-8);
    font-size: var(--font-13);
    color: var(--color-body);
}

.buy-stock i {
    font-size: var(--icon-md);
    color: var(--color-success);
}

/* ---------- light mode swatcher ---------- */
.swatch {
    display: flex;
    flex-direction: column;
    gap: var(--space-12);
    width: 100%;
    padding: var(--space-20) 0;
    border-top: var(--rule);
    border-bottom: var(--rule);
}

.swatch-head {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-12);
    width: 100%;
}

.swatch-label {
    font-size: var(--font-11);
    font-weight: var(--fw-medium);
    letter-spacing: var(--ls-widest);
    text-transform: var(--tt-uppercase);
    color: var(--color-muted);
}

.swatch-current {
    font-family: var(--font-heading);
    font-size: var(--font-h6);
    color: var(--color-heading);
}

.swatch-row {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-12);
}

/* each swatch is the panel itself, lit in that mode. The artwork is a
   transparent PNG, so it sits straight on the page rather than on a tile. */
.swatch-dot {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    width: 64px;
    padding: var(--space-6);
    aspect-ratio: 62 / 70;
    background-color: transparent;
    border: var(--border-thin) solid var(--color-line);
    border-radius: var(--radius-md);
    cursor: pointer;
    overflow: hidden;
    transition: box-shadow var(--transition-base), border-color var(--transition-base), transform var(--transition-base);
}

.swatch-dot img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.swatch-dot:hover {
    transform: translateY(-2px);
}

/* the ring is the mode's own tone, so the selection names its colour */
.swatch-dot.is-active {
    border-color: transparent;
    box-shadow: 0 0 0 2px var(--tone);
}

.swatch-dot:focus-visible {
    outline: var(--border-base) solid var(--color-ink);
    outline-offset: 3px;
}

.swatch-note {
    font-size: var(--font-13);
    line-height: var(--lh-base);
    color: var(--color-body);
}

/* the stage's glow takes the selected mode's colour — the product photograph
   is never faked, only the light behind it changes */
.gallery-tint {
    display: block;
    position: absolute;
    inset: 0;
    background-image: radial-gradient(circle at 50% 50%,
        var(--tone, transparent) 0%,
        rgba(0, 0, 0, 0) 72%);
    opacity: 0.24;
    pointer-events: none;
    transition: background-image var(--transition-slow), opacity var(--transition-slow);
}

/* ---------- the free neck piece ---------- */
.buy-bundle {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-16);
    width: 100%;
    padding: var(--space-16);
    background-color: var(--color-white);
    border: var(--rule-soft);
    border-radius: var(--radius-lg);
}

.buy-bundle-thumb {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    overflow: hidden;
    background-color: var(--color-black);
    border-radius: var(--radius-md);
}

.buy-bundle-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.buy-bundle-copy {
    display: block;
    flex: 1 1 auto;
    font-size: var(--font-13);
    line-height: var(--lh-base);
    color: var(--color-body);
}

.buy-bundle-copy strong {
    display: block;
    font-weight: var(--fw-medium);
    color: var(--color-heading);
}

.buy-bundle-tag {
    flex: 0 0 auto;
    padding: var(--space-4) var(--space-10);
    font-size: var(--font-10);
    font-weight: var(--fw-medium);
    letter-spacing: var(--ls-wider);
    text-transform: var(--tt-uppercase);
    color: var(--color-rose-gold-deep);
    border: var(--border-thin) solid var(--color-rose-gold-soft);
    border-radius: var(--radius-pill);
}

/* ---------- quantity + add to bag ---------- */
.buy-row {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    gap: var(--space-12);
    width: 100%;
}

.buy-secure {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-8);
    width: 100%;
    font-size: var(--font-12);
    color: var(--color-muted);
}

/* ---------- the four assurances ---------- */
.buy-assurance {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-12) var(--space-24);
    width: 100%;
    padding: var(--space-20) 0;
    border-top: var(--rule);
    border-bottom: var(--rule);
}

.buy-assurance li {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-8);
    font-size: var(--font-13);
    color: var(--color-body);
}

.buy-assurance i {
    font-size: var(--icon-md);
    color: var(--color-rose-gold-deep);
}

/* ---------- the detail accordion ---------- */
.buy-accordion {
    display: flex;
    flex-direction: column;
    /* the same gap the shared .faq-list uses — these are the same cards, and
       with none at all they sat edge to edge as one undivided block */
    gap: var(--space-12);
    width: 100%;
}

.buy-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
    padding-bottom: var(--space-12);
}

.buy-list li {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: var(--space-10);
    font-size: var(--font-15);
    color: var(--color-body);
}

.buy-list li::before {
    content: "";
    display: block;
    flex: 0 0 auto;
    width: 5px;
    height: 5px;
    margin-top: 0.6em;
    background-color: var(--color-rose-gold-deep);
    border-radius: var(--radius-circle);
}

/* ==========================================================================
   03. THE SECTION RHYTHM
   --------------------------------------------------------------------------
   Every section below the buy block holds --panel-h and centres its contents
   in it. .section is a flex row, so align-items is what does the centring.
   The compact padding is what buys the room: at the full --section-padding-y
   four of these ran 90-180px past the height.
   ========================================================================== */
.spectrum,
.fit,
.benefits,
.compare,
.reviews,
.faq {
    min-height: var(--panel-h);
    align-items: center;
    padding-top: var(--section-padding-y-sm);
    padding-bottom: var(--section-padding-y-sm);
}

/* The assurance strip is deliberately NOT one of them. It is a rule between
   the buy block and the wavelengths — 124px of hairline row — and holding it
   to --panel-h left 326px of empty screen above it and 270px below. A band
   takes the height of the thing it is banding. */
.assure {
    min-height: 0;
    align-items: center;
    padding-top: var(--section-padding-y);
    padding-bottom: var(--section-padding-y);
}

/* ==========================================================================
   04. ASSURANCE RULE — five figures on one hairline
   ========================================================================== */
.assure {
    background-color: var(--color-bg);
}

.assure-row {
    display: flex;
    flex-direction: row;
    width: 100%;
    border-top: var(--rule);
    border-bottom: var(--rule);
}

.assure-row li {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-8);
    flex: 1 1 0;
    padding: var(--space-32) var(--space-16);
    text-align: center;
}

/* hairlines between, not around — a box would coarsen the row */
.assure-row li + li {
    border-left: var(--rule-soft);
}

.assure-value {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    gap: var(--space-4);
    font-family: var(--font-heading);
    font-size: var(--font-display-md);
    line-height: var(--lh-tight);
    color: var(--color-heading);
}

.assure-value i {
    font-family: var(--font-body);
    font-size: var(--font-12);
    font-style: normal;
    font-weight: var(--fw-medium);
    letter-spacing: var(--ls-wide);
    color: var(--color-muted);
}

.assure-label {
    font-size: var(--font-12);
    line-height: var(--lh-base);
    color: var(--color-muted);
}

/* ==========================================================================
   04. WAVELENGTHS — the home page's spectrum, given its own room
   ========================================================================== */
/* the shelves sit 2px into the neighbours so no sliver of the tint shows at
   either seam; the section clips that overhang rather than bleeding it */
.spectrum {
    overflow: hidden;
}

.spectrum .spec-layout {
    align-items: center;
}

/* ==========================================================================
   05. EXACT FIT
   ========================================================================== */
.fit-layout {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-80);
    width: 100%;
}

.fit-copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-16);
    flex: 1 1 54%;
}

.fit-list {
    display: flex;
    flex-direction: column;
    width: 100%;
    padding-top: var(--space-8);
}

.fit-item {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-12) 0;
    border-top: var(--rule);
}

.fit-item:last-child {
    border-bottom: var(--rule);
}

.fit-item dt {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-12);
    font-family: var(--font-heading);
    font-size: var(--font-h5);
    color: var(--color-heading);
}

.fit-item dt i {
    font-size: var(--icon-lg);
    color: var(--color-rose-gold-deep);
}

.fit-item dd {
    padding-left: calc(var(--icon-lg) + var(--space-12));
    font-size: var(--font-13);
    line-height: var(--lh-base);
    color: var(--color-body);
}

.fit-figure {
    display: flex;
    flex-direction: column;
    gap: var(--space-12);
    flex: 1 1 46%;
}

.fit-figure img {
    width: 100%;
    height: auto;
    /* square, not 4:5 — a portrait figure alone ran the section 110px past
       --panel-h, and the copy beside it is what sets the section's height */
    aspect-ratio: 1 / 1;
    object-fit: cover;
    border-radius: var(--radius-2xl);
    box-shadow: var(--shadow-md);
}

.fit-figure figcaption {
    font-size: var(--font-11);
    letter-spacing: var(--ls-wider);
    text-transform: var(--tt-uppercase);
    text-align: center;
    color: var(--color-muted);
}

/* ==========================================================================
   06. BENEFITS
   ========================================================================== */
/* the lilac arrives over the last third, so it reads as the section turning
   rather than as a line at the very bottom */
.benefits {
    background-image: var(--gradient-bg-to-lilac);
}

/* starts on the exact lilac the benefits section ended on, and ends on the
   blush the reviews section below opens with */
.compare {
    background-image: var(--gradient-lilac-to-blush);
    padding-bottom: var(--space-40);
}

.benefit-grid {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--grid-gap-sm);
    width: 100%;
}

.benefit {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-10) var(--space-12);
    /* three across, and the row still holds at two */
    flex: 1 1 calc(33.333% - var(--grid-gap-sm));
    min-width: 260px;
    padding: var(--space-24);
    background-color: var(--color-white);
    border: var(--rule-soft);
    border-radius: var(--radius-xl);
    transition: box-shadow var(--transition-base), transform var(--transition-base);
}

.benefit:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-4px);
}

/* the icon sits on the title's line rather than above it — stacked, two
   rows of six cards ran the section 130px past --panel-h */
.benefit i {
    flex: 0 0 auto;
    font-size: var(--icon-lg);
    color: var(--color-rose-gold-deep);
}

.benefit h3 {
    flex: 1 1 auto;
    font-size: var(--font-h5);
}

.benefit p {
    flex: 1 1 100%;
    font-size: var(--font-14);
    line-height: var(--lh-base);
}

/* ==========================================================================
   08. FAQ TAIL
   ========================================================================== */
/* two pixels over the panel on the stock 56px gap */
.reviews .container {
    gap: var(--space-48);
}

/* ==========================================================================
   09. STICKY BUY BAR
   ========================================================================== */
.buybar {
    display: flex;
    flex-direction: row;
    justify-content: center;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-sticky);
    padding: var(--space-12) var(--gutter-width);
    background-color: rgba(253, 251, 248, 0.92);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-top: var(--rule);
    /* parked below the fold until the buy panel has scrolled away */
    transform: translateY(100%);
    opacity: 0;
    pointer-events: none;
    transition: transform var(--transition-base), opacity var(--transition-base);
}

.buybar.is-up {
    transform: translateY(0);
    opacity: 1;
    pointer-events: auto;
}

.buybar-inner {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-16);
    width: 100%;
    max-width: var(--container-width);
}

.buybar-thumb {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 48px;
    height: 48px;
    overflow: hidden;
    background-color: var(--color-black);
    border-radius: var(--radius-md);
}

.buybar-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.buybar-name {
    flex: 1 1 auto;
    font-family: var(--font-heading);
    font-size: var(--font-h6);
    color: var(--color-heading);
}

.buybar-price {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    gap: var(--space-10);
    flex: 0 0 auto;
}

.buybar-price strong {
    font-family: var(--font-heading);
    font-size: var(--font-display-sm);
    font-weight: var(--fw-regular);
    color: var(--color-heading);
}

.buybar-price s {
    font-size: var(--font-13);
    color: var(--color-muted);
}

/* the back-to-top button would sit on the bar; lift it clear */
.buybar.is-up ~ .back-to-top,
body:has(.buybar.is-up) .back-to-top {
    bottom: calc(var(--space-80) + var(--space-24));
}

/* ==========================================================================
   10. RESPONSIVE — page-scoped breakpoints
   ========================================================================== */

/* ---------- ≤ 1200px ---------- */
@media (max-width: 1200px) {

    .product-layout,
    .fit-layout {
        gap: var(--space-48);
    }

    .gallery-stage {
        padding: var(--space-32);
    }
}

/* ---------- ≤ 992px : the product goes to one column ---------- */
@media (max-width: 992px) {

    .product {
        padding-bottom: var(--space-64);
    }

    .product-layout {
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-40);
    }

    /* Nothing to stick to once the two columns are stacked — and the panel
       height goes with the stickiness. Left on, --panel-h forced a 720px
       column at every width below this, so the stage became a huge empty
       box the product filled barely a third of. */
    .gallery {
        position: static;
        flex: 0 0 auto;
        height: auto;
    }

    /* the stacked gallery does not need the container's full width — at
       952px the stage was four times the area of the product inside it */
    .gallery {
        max-width: 620px;
        margin-inline: auto;
    }

    /* flex sizing beats aspect-ratio, so the stage has to stop flexing
       before the ratio below can govern its height */
    .gallery-stage {
        flex: 0 0 auto;
        aspect-ratio: 1 / 1;
    }

    .buy {
        flex: 0 0 auto;
        max-width: none;
    }

    .fit-layout {
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-40);
    }

    .fit-figure img {
        aspect-ratio: 16 / 10;
    }

    .benefit {
        flex-basis: calc(50% - var(--grid-gap-sm));
    }

    .assure-row li {
        padding: var(--space-24) var(--space-12);
    }
}

/* ---------- ≤ 768px ---------- */
@media (max-width: 768px) {

    /* 56px shelves eat a 390px screen the way they never do a 1440px one, and
       at full height they were sitting 22px over the heading */
    .spectrum .shelf__wave {
        height: 36px;
        -webkit-mask-size: 1440px 36px;
        mask-size: 1440px 36px;
    }

    /* the section is taller than --panel-h here, so the shelves take their
       clearance from the padding rather than from centring slack */
    .spectrum {
        padding-top: calc(var(--section-padding-y-sm) + 36px);
        padding-bottom: calc(var(--section-padding-y-sm) + 36px);
    }

    .product {
        padding-top: calc(var(--header-height) + var(--space-16));
    }

    .crumbs {
        font-size: var(--font-10);
        gap: var(--space-6);
    }

    .gallery-stage {
        aspect-ratio: 1 / 1;
        padding: var(--space-24);
        border-radius: var(--radius-xl);
    }

    .gallery-flag,
    .gallery-count {
        top: var(--space-12);
        left: var(--space-12);
    }

    .gallery-count {
        top: auto;
        left: auto;
        right: var(--space-12);
        bottom: var(--space-12);
    }

    /* a left rail costs a phone too much width, so the thumbs go back under
       the image as a scrolling strip */
    .gallery {
        flex-direction: column;
        /* NOT `none`: with no cap the gallery took its max-content width —
           408px, set by the five-thumb strip — and hung 32px off the right
           of a 390px screen. 100% keeps it inside the column and lets the
           strip scroll, which is what it is set up to do. */
        max-width: 100%;
    }

    /* the rail comes first in the DOM so the desktop tab order reads left to
       right; on a phone the image leads, so the stage is pulled above it */
    .gallery-stage {
        order: -1;
    }

    .gallery-thumbs {
        flex-direction: row;
        /* NOT centred: with content wider than the strip, centring overflows
           both ends and the first thumb can never be scrolled back to */
        justify-content: flex-start;
        width: 100%;
        height: auto;
        /* Without this the strip's min-content width — five 72px thumbs plus
           four 12px gaps, 408px — propagated up through the gallery and the
           layout, pushing the whole product block 32px off the right of a
           390px screen instead of scrolling. */
        min-width: 0;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }

    .gallery-thumbs::-webkit-scrollbar {
        display: none;
    }

    .gallery-thumb {
        flex: 0 0 72px;
        scroll-snap-align: start;
    }

    /* five modes, one row: at the desktop size they wrapped 4 + 1, which
       read as an odd split when the remote has five settings in a line */
    .swatch-row {
        gap: var(--space-8);
    }

    .swatch-dot {
        width: 58px;
    }

    .buy-price-now {
        font-size: var(--font-display-lg);
    }

    .buy-row {
        flex-direction: column;
    }

    .buy-row .qty {
        align-self: flex-start;
    }

    /* the figures wrap rather than squeezing five onto one phone row */
    .assure-row {
        flex-wrap: wrap;
    }

    .assure-row li {
        flex: 1 1 calc(50% - 1px);
        padding: var(--space-20) var(--space-12);
    }

    /* with rows wrapping, a left border on every cell draws stray hairlines */
    .assure-row li + li {
        border-left: none;
    }

    .assure-row li:nth-child(odd) {
        border-right: var(--rule-soft);
    }

    .assure-row li:nth-child(n + 3) {
        border-top: var(--rule-soft);
    }

    .benefit {
        flex-basis: 100%;
        min-width: 0;
        padding: var(--space-24);
    }

    /* --panel-h is a desktop rhythm. On a phone the sections that overflow
       it stay tall anyway, and the ones that do not were left holding up to
       306px of empty screen — so here they size to their contents. */
    .spectrum,
    .fit,
    .benefits,
    .compare,
    .reviews,
    .faq {
        min-height: 0;
    }

    /* the bar keeps the price and the button; the name is the first thing
       a 390px row can afford to lose */
    .buybar-name,
    .buybar-thumb {
        display: none;
    }

    .buybar-price {
        flex: 1 1 auto;
    }
}

/* ---------- ≤ 480px ---------- */
@media (max-width: 480px) {

    .swatch-row {
        gap: var(--space-6);
    }

    .swatch-dot {
        width: 50px;
    }

    .buy-head h1 {
        font-size: var(--font-h3);
    }

    .buy-bundle {
        flex-wrap: wrap;
    }

    .buy-bundle-copy {
        flex-basis: 100%;
        order: 3;
    }

    .fit-item dd {
        padding-left: 0;
    }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {

    .gallery-stage:hover .gallery-main,
    .gallery-thumb:hover,
    .benefit:hover {
        transform: none;
    }

    .gallery-main {
        transition: none;
    }
}
