/* ============================================
   PRODUCT PAGE
   One page per design; the two sizes live on it
   behind a selector, the way withinmood.com puts
   mini/classic on one page.

   Loaded only by products/*.html, after
   theme-studio.css. Everything here is scoped to
   .product-page so it cannot leak onto the shop
   or the legal pages.
   ============================================ */

.product-page {
    max-width: 1360px;
    margin: 0 auto;
    padding: 2rem 5% 0;
}

/* ---- Breadcrumb ---- */
.product-breadcrumb {
    font-size: 0.7rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    margin-bottom: 2.5rem;
}

.product-breadcrumb a {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid transparent;
}

.product-breadcrumb a:hover {
    border-bottom-color: currentColor;
}

.product-breadcrumb span[aria-current] {
    color: var(--color-text);
}

/* ---- Two-column shell ---- */
.product-main {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: clamp(2rem, 5vw, 5rem);
    align-items: start;
}

/* ---- Gallery ----
   Sticky on desktop so the info column can be long without stranding the
   photography. `align-self: start` on the grid item is what makes the sticky
   work; without it the column stretches to the row height and never scrolls. */
.product-gallery {
    position: sticky;
    top: 1.5rem;
    align-self: start;
}

.product-gallery-main {
    position: relative;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Next-photograph control, bottom right of the frame. One arrow, not a pair:
   it wraps, so a single button still reaches every image, and two would crowd a
   corner of a photograph that is the point of the page. 44px because it is a
   real tap target on a phone, even though it reads as small. */
.product-gallery-next {
    position: absolute;
    right: 0.75rem;
    bottom: 0.75rem;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
    /* Translucent white rather than solid: these frames have pale backdrops and
       a hard white disc reads as a hole punched in the photograph. */
    background: rgba(255, 255, 255, 0.82);
    border: 1px solid var(--color-border);
    color: var(--color-text);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
    transition: background .15s, border-color .15s;
}

.product-gallery-next:hover {
    background: #FFFFFF;
    border-color: #111111;
}

.product-gallery-next:focus-visible {
    outline: 2px solid #111111;
    outline-offset: 2px;
}

/* product-page.js sets this when the selected size has only one photograph. */
.product-gallery-next[hidden] {
    display: none;
}

/* Contain, never cover. The gallery holds square cup shots and 2:3 lifestyle
   frames in one 4:5 slot, so something always has to give: cover cropped 17%
   off a portrait's height, which is enough to take the top of a head off. What
   contain leaves over is page white, not a panel — the tint is gone — so the
   letterboxing is invisible and nothing is ever cut. */
.product-gallery-main img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

/* Four columns. Only one size's photographs are on screen at a time, and after
   the studio shoot each size carries its cup shot, up to seven shoot frames and
   one or two editorial ones — seven to nine items, so four across keeps it to
   two or three rows without shrinking the thumbs to nothing.
   A design's page only ever shows its own cup — the ribbon's other photos are
   of the other design and would misdescribe this one. */
.product-thumbs {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.5rem;
    margin-top: 0.5rem;
    list-style: none;
    padding: 0;
}

/* The gallery follows the size selector. display: none rather than visibility,
   so the hidden items leave the grid entirely and the visible ones pack from
   the left instead of leaving holes where the other size's photos were.
   js/product-page.js owns .is-active; the <noscript> block in each page reveals
   all of them, so no photograph is unreachable without JavaScript. */
.product-thumbs [data-size-media] { display: none; }
.product-thumbs [data-size-media].is-active { display: block; }

.product-thumb {
    aspect-ratio: 1 / 1;
    border: 1px solid transparent;
    padding: 0;
    cursor: pointer;
    overflow: hidden;
    transition: border-color .15s;
}

.product-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.product-thumb img.is-product-shot {
    object-fit: contain;
}

.product-thumb:hover { border-color: #CFCFCF; }
.product-thumb[aria-current="true"] { border-color: #111111; }

.product-thumb:focus-visible {
    outline: 2px solid #111111;
    outline-offset: 2px;
}

/* ---- Info column ---- */
.product-info {
    padding-top: 0.5rem;
}

.product-eyebrow {
    font-size: 0.7rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    display: block;
    margin-bottom: 0.75rem;
}

/* Caps come from text-transform, not from the markup, so the <h1> still holds
   "Morning Crush" for anything that reads its text — the breadcrumb above it
   works the same way, and .design-name on the shop page already did.
   The <br> that used to split the name is gone, so the size ramp now has to
   keep it on one line by itself. "MORNING CRUSH" measures ~8.9em at this weight
   and spacing; 4.5vw overran the info column between roughly 900px and 1300px
   and wrapped it back to two lines, which 3.6vw clears at every width. The
   1.5rem floor is what a phone gets, and 8.9em of 24px fits 320px. */
.product-title {
    font-size: clamp(1.5rem, 3.6vw, 3.5rem);
    line-height: 1.02;
    font-weight: 700;
    letter-spacing: -0.02em;
    text-transform: uppercase;
    margin: 0 0 0.5rem;
}

.product-tagline {
    font-size: 1.05rem;
    color: var(--color-text-muted);
    margin: 0 0 1.75rem;
}

.product-price {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    margin-bottom: 0.35rem;
}

.product-price-amount {
    font-size: 1.6rem;
    font-weight: 500;
    letter-spacing: -0.01em;
}

.product-price-note {
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

/* Kleinunternehmer — no VAT is charged, so this may not say "incl. VAT".
   See LAUNCH.md section 4. */
.product-tax-note {
    font-size: 0.75rem;
    color: var(--color-text-muted);
    margin: 0 0 1.75rem;
}

.product-tax-note a {
    color: inherit;
}

/* ---- Size selector ---- */
.product-option {
    margin-bottom: 1.5rem;
}

.product-option-label {
    font-size: 0.7rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    display: block;
    margin-bottom: 0.6rem;
}

.product-sizes {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
}

.product-size {
    background: #FFFFFF;
    border: 1px solid var(--color-border);
    padding: 0.9rem 0.75rem;
    font-family: var(--font-body);
    font-size: 0.8rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text);
    cursor: pointer;
    text-align: center;
    transition: border-color .15s, background .15s;
}

.product-size:hover { border-color: #A8A8A8; }

.product-size[aria-checked="true"] {
    border-color: #111111;
    background: #111111;
    color: #FFFFFF;
}

.product-size:focus-visible {
    outline: 2px solid #111111;
    outline-offset: 2px;
}

/* The toggle used to carry each size's price under its label. Removed from the
   markup, so the rule went with it -- the headline price above the toggle is
   the one the customer reads, and product-page.js rewrites it from data-price
   when the size changes. */

/* ---- Buy ----
   Both sizes render their own Shopify button (shopify-buy.js wires every
   .shopify-buy-node on the page); the selector shows one and hides the other.
   Swapping the node beats re-rendering it — the checkout path stays the same
   code that the shop page already uses. */
.product-buy [data-size-panel] { display: none; }
.product-buy [data-size-panel].is-active { display: block; }

/* Only needed in the no-JS layout, where both panels are shown at once and
   each add-to-cart button has to say which cup it is for. The <noscript>
   block in the page turns it back on. */
.product-buy-label {
    display: none;
    font-size: 0.8rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    margin: 0 0 0.5rem;
}

.product-delivery {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    font-size: 0.8rem;
    color: var(--color-text-muted);
    margin-top: 1rem;
    line-height: 1.5;
}

.product-delivery-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #2E7D32;
    flex: 0 0 auto;
    transform: translateY(-1px);
}

/* ---- Spec table ---- */
.product-specs {
    margin-top: 2rem;
    border-top: 1px solid var(--color-border);
}

/* One table per size — the espresso and cappuccino are different objects with
   different capacities, so the table follows the selector the price does. */
.product-specs [data-size-spec] { display: none; }
.product-specs [data-size-spec].is-active { display: block; }

/* Like .product-buy-label: only needed in the no-JS layout, where both tables
   are shown at once and each needs to say which cup it describes. */
.product-spec-size {
    display: none;
    font-size: 0.7rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    margin: 1rem 0 0;
}

.product-specs dl {
    display: grid;
    grid-template-columns: 40% 60%;
    margin: 0;
    font-size: 0.85rem;
}

.product-specs dt,
.product-specs dd {
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--color-border);
    margin: 0;
}

.product-specs dt {
    color: var(--color-text-muted);
    letter-spacing: 0.04em;
}

/* ---- Accordions ---- */
.product-accordions {
    margin-top: 2rem;
}

.product-accordion {
    border-bottom: 1px solid var(--color-border);
}

.product-accordion:first-child {
    border-top: 1px solid var(--color-border);
}

.product-accordion > summary {
    list-style: none;
    cursor: pointer;
    padding: 1.05rem 0;
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
}

.product-accordion > summary::-webkit-details-marker { display: none; }

.product-accordion > summary::after {
    content: "+";
    font-size: 1.1rem;
    line-height: 1;
    color: var(--color-text-muted);
}

.product-accordion[open] > summary::after { content: "\2013"; }

.product-accordion > summary:focus-visible {
    outline: 2px solid #111111;
    outline-offset: 2px;
}

.product-accordion-body {
    padding: 0 0 1.25rem;
    font-size: 0.9rem;
    line-height: 1.7;
    color: var(--color-text-muted);
}

.product-accordion-body p { margin: 0 0 0.75rem; }
.product-accordion-body p:last-child { margin-bottom: 0; }
.product-accordion-body a { color: var(--color-text); }

/* ---- Editorial story blocks below the fold ---- */
.product-story {
    margin: clamp(4rem, 9vw, 8rem) auto 0;
    max-width: 1360px;
    padding: 0 5%;
}

.product-story-block {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(2rem, 5vw, 4.5rem);
    align-items: center;
    margin-bottom: clamp(3rem, 6vw, 5.5rem);
}

.product-story-block--flip .product-story-media { order: 2; }

/* Portrait, because the photographs are. A 2:3 frame cover-fitted into the
   4:3 slot this used to be kept only the middle half of its height — which put
   the cup in view and the model's head outside it. At 3/4 the crop is 11%,
   about 5% off each edge. */
.product-story-media {
    background: #F6F6F4;
    aspect-ratio: 3 / 4;
    overflow: hidden;
}

.product-story-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.product-story-heading {
    font-size: 0.7rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    margin: 0 0 0.9rem;
}

/* Matched to .product-section-label on the shop page — same size ramp, same 700
   and same -0.01em, so the two pages set their section titles identically. The
   font family is already shared: both --font-display and --font-body resolve to
   DM Sans in theme-studio.css, so neither rule states one.
   These were 400 at -0.02em, which read as a lighter, tighter face than the
   landing page next to it. */
.product-story-title {
    font-size: clamp(1.5rem, 2.5vw, 2.25rem);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.01em;
    margin: 0 0 1rem;
}

.product-story-text {
    font-size: 0.95rem;
    line-height: 1.75;
    color: var(--color-text-muted);
    margin: 0;
}

/* ---- Cross-sell to the other design ---- */
.product-crosssell {
    max-width: 1360px;
    margin: clamp(3rem, 7vw, 6rem) auto 0;
    padding: 0 5% clamp(3rem, 7vw, 6rem);
    border-top: 1px solid var(--color-border);
    padding-top: clamp(2.5rem, 5vw, 4rem);
}

.product-crosssell-label {
    font-size: 0.7rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    margin: 0 0 1.75rem;
}

.product-crosssell-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(1rem, 3vw, 2.5rem);
    max-width: 620px;
}

.product-crosssell-card {
    text-decoration: none;
    color: inherit;
    display: block;
}

.product-crosssell-img {
    aspect-ratio: 1 / 1;
    overflow: hidden;
    margin-bottom: 0.75rem;
}

.product-crosssell-img img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    transition: transform .3s ease;
}

.product-crosssell-card:hover .product-crosssell-img img {
    transform: scale(1.04);
}

.product-crosssell-name {
    font-size: 0.9rem;
    font-weight: 500;
    margin: 0 0 0.15rem;
}

.product-crosssell-price {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    margin: 0;
}

/* ---- Mobile ---- */
@media (max-width: 900px) {
    .product-page { padding-top: 1rem; }

    .product-main {
        grid-template-columns: 1fr;
        gap: 2rem;
    }

    /* Sticky in a single column would pin the gallery over the buy button. */
    .product-gallery {
        position: static;
    }

    .product-breadcrumb { margin-bottom: 1.5rem; }

    .product-story-block {
        grid-template-columns: 1fr;
        gap: 1.5rem;
    }

    /* The flip only exists to alternate sides; stacked, it would put the
       photo below its own caption. */
    .product-story-block--flip .product-story-media { order: 0; }

    .product-crosssell-grid { max-width: none; }
}

@media (max-width: 480px) {
    .product-specs dl { grid-template-columns: 45% 55%; }
}

@media (prefers-reduced-motion: reduce) {
    .product-crosssell-img img { transition: none; }
    .product-crosssell-card:hover .product-crosssell-img img { transform: none; }
}
