/* ============================================================
   REC Bloom Boutique — Public Store CSS
   Premium feminine boutique · Editorial · Clean · Sophisticated
   ============================================================ */

/* === Reset === */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* === Design Tokens === */
:root {
    --color-ivory: #FEFCF9;
    --color-blush-bg: #F7EFE8;
    --color-soft-blush: #EEDBCE;
    --color-peach: #D69F85;
    --color-copper: #B37152;
    --color-copper-dark: #9A5F43;
    --color-sage: #948A76;
    --color-text: #191512;
    --color-white: #FFFFFF;
    --color-border: #E8E4DF;

    /*
       One typeface across the storefront. --font-display and --font-body are
       now the same family on purpose: dozens of rules already reference one or
       the other, and pointing both at Cormorant changes the whole site without
       hunting down every call site — and keeps the distinction available if
       the two are ever split again.

       --font-ui is the deliberate exception. Cormorant is a fine-stroked
       serif that turns mushy at 12-14px, so anything the customer has to read
       without hesitating — a price, a form field, a NEW/SALE badge — stays on
       Inter. That is a legibility call, not a style inconsistency.
    */
    --font-display: 'Cormorant Garamond', 'Playfair Display', Georgia, serif;
    --font-body: 'Cormorant Garamond', 'Playfair Display', Georgia, serif;
    --font-ui: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;

    --radius-sm: 8px;
    --radius-md: 14px;
    --radius-lg: 22px;
    --radius-full: 999px;

    --shadow-soft: 0 10px 30px rgba(25, 21, 18, .06);
    --shadow-hover: 0 14px 40px rgba(25, 21, 18, .1);

    --transition: 0.3s ease;
    --container-max: 1280px;
    --header-h: 72px;
}

/* === Base === */
html {
    scroll-behavior: smooth;
    -webkit-font-smoothing: antialiased;
    /* body's overflow-x:hidden alone doesn't reliably stop the horizontal
       sliver some mobile browsers (notably iOS Safari) show when a child
       is a few px wider than the viewport — setting it on html too closes
       that gap. */
    overflow-x: hidden;
    width: 100%;
}

body {
    font-family: var(--font-body);
    color: var(--color-text);
    background: var(--color-ivory);
    /* Cormorant has a much smaller x-height than Inter, so the same px size
       reads noticeably smaller. Body copy is bumped ~8% and given a little
       more leading to land at the apparent size the sans-serif had. */
    font-size: 1.08rem;
    line-height: 1.7;
    overflow-x: hidden;
    width: 100%;
}

img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }

/* --- The --font-ui exception list ---------------------------------------
   Everything else on the storefront inherits Cormorant from <body>. These
   stay on Inter because they are read for accuracy, not for tone: a shopper
   must never squint at a price or mistype an email because the serif's thin
   strokes blurred a digit at 13px.

   Kept as one block rather than scattered across each component so the rule
   is visible in one place — and so nobody "fixes" a stray Inter later
   without seeing why it is there. */
input,
select,
textarea,
.checkout-input,
.newsletter-input,
.qty-input,
.price-current,
.price-original,
.product-price-current,
.product-price-original,
.cart-item-price,
.cart-summary-row,
.product-badge,
.stock-indicator {
    font-family: var(--font-ui);
}

/* Inter runs larger than Cormorant at the same size, so the fields and
   prices are stepped back down to sit level with the surrounding text
   instead of jumping out of it. */
input,
select,
textarea,
.checkout-input,
.newsletter-input,
.qty-input { font-size: 0.95rem; }

.container {
    width: 100%;
    max-width: var(--container-max);
    margin: 0 auto;
    padding: 0 1.5rem;
}

.about-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4rem;
    align-items: center;
}

.about-values-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
}

/* === Header === */
.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    background: rgba(254, 252, 249, .95);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid rgba(232, 228, 223, .5);
    height: var(--header-h);
}

.header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: var(--header-h);
    max-width: var(--container-max);
    margin: 0 auto;
    padding: 0 1.5rem;
}

.header-logo {
    /* Never let flexbox compress this — with only height fixed and width
       "auto", a shrunk flex-basis distorts a signature-style logo into an
       illegible smudge instead of just running out of room gracefully. */
    flex-shrink: 0;
}

.header-logo img {
    height: 44px;
    width: auto;
    flex-shrink: 0;
}

.header-logo .logo-text {
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--color-text);
    letter-spacing: -0.02em;
}

.lang-switch-nav {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.8rem;
}
.lang-switch {
    opacity: 0.55;
    transition: opacity var(--transition);
}
.lang-switch.is-active {
    opacity: 1;
    font-weight: 600;
}

.header-nav { display: flex; align-items: center; gap: 2rem; }
.header-nav a {
    /* Was 0.85rem/400 for Inter. Cormorant's small x-height and thin strokes
       make that look faint at nav size, so it is stepped up and given a
       little more weight to hold the same visual presence. */
    font-size: 1.02rem;
    font-weight: 500;
    color: var(--color-text);
    letter-spacing: 0.02em;
    position: relative;
    transition: color var(--transition);
}
.header-nav a:hover { color: var(--color-copper); }
.header-nav a::after {
    content: '';
    position: absolute;
    bottom: -4px;
    left: 0;
    width: 0;
    height: 1.5px;
    background: var(--color-copper);
    transition: width var(--transition);
}
.header-nav a:hover::after { width: 100%; }

.header-actions { display: flex; align-items: center; gap: 1.25rem; flex-shrink: 0; }
.header-action {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: none;
    background: none;
    color: var(--color-text);
    border-radius: 50%;
    transition: background var(--transition);
    position: relative;
    flex-shrink: 0;
}
.header-action:hover { background: var(--color-blush-bg); }

.cart-count {
    position: absolute;
    top: 2px;
    right: 2px;
    background: var(--color-copper);
    color: var(--color-white);
    font-size: 0.65rem;
    font-weight: 600;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.hamburger-menu {
    display: none;
    background: none;
    border: none;
    color: var(--color-text);
    padding: 6px;
}

/* === Mobile Nav Drawer === */
.mobile-nav-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(25,21,18,.4);
    z-index: 200;
    opacity: 0;
    transition: opacity 0.3s;
}
.mobile-nav-overlay.active { display: block; opacity: 1; }

.mobile-nav {
    position: fixed;
    top: 0;
    right: 0;
    width: min(360px, 85vw);
    height: 100vh;
    background: var(--color-ivory);
    z-index: 201;
    transform: translateX(100%);
    transition: transform 0.35s ease;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}
.mobile-nav.open { transform: translateX(0); }

.mobile-nav-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1.25rem 1.5rem;
    border-bottom: 1px solid var(--color-border);
}

.mobile-nav-close {
    background: none;
    border: none;
    color: var(--color-text);
    padding: 4px;
}

.mobile-nav-links {
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 0;
}

.mobile-nav-links a {
    display: block;
    padding: 0.85rem 0;
    font-size: 1rem;
    color: var(--color-text);
    border-bottom: 1px solid var(--color-border);
    transition: color var(--transition);
}
.mobile-nav-links a:hover { color: var(--color-copper); }

/* Language picker inside the drawer — the only place the EN/ES switch
   lives on mobile, so it gets a proper labelled block rather than the
   cramped "EN · ES" pair that was crowding the top bar. */
.mobile-lang {
    margin-top: 1.75rem;
}
.mobile-lang-label {
    display: block;
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-sage);
    margin-bottom: 0.6rem;
}
.mobile-lang-options {
    display: flex;
    gap: 0.5rem;
}
.mobile-nav-links .mobile-lang-option {
    flex: 1;
    padding: 0.6rem 0.5rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    text-align: center;
    font-size: 0.85rem;
    color: var(--color-sage);
    transition: all var(--transition);
}
.mobile-nav-links .mobile-lang-option.is-active {
    background: var(--color-text);
    border-color: var(--color-text);
    color: var(--color-white);
    font-weight: 500;
}

/* === Hero === */
.hero {
    position: relative;
    min-height: 80vh;
    display: flex;
    align-items: center;
    overflow: hidden;
    background: var(--color-blush-bg);
    /* --hero-focal-x-desktop/-mobile (and their y counterparts) come in via
       inline style from the admin's click-to-set focus pickers — one point
       per photo, since desktop and mobile can now be two entirely different
       images. --hero-focal-x/-y (no suffix) is the one .hero-bg actually
       reads; defined here from the desktop value so plain CSS specificity/
       media-query rules can override it below, which an inline-set value
       never could. */
    --hero-focal-x: var(--hero-focal-x-desktop, 50%);
    --hero-focal-y: var(--hero-focal-y-desktop, 50%);
}

/* Wraps .hero-bg so mobile can serve a different file via <source> — but
   .hero is a flex container, and unlike .hero-bg itself, <picture> has no
   position:absolute of its own. Left alone it still takes part in normal
   flex layout as an empty-ish box, which is what left a gap under the photo
   on some mobile browsers (reported on Android/Chrome, tablet width).
   display:contents removes <picture>'s own box entirely — its child renders
   exactly as if it were positioned directly against .hero, which is what
   was actually intended. */
.hero picture {
    display: contents;
}

.hero-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* --hero-focal-x/-y come from the admin's click-to-set photo focus
       picker (Settings -> Storefront -> Hero Section) via an inline style
       on the <section>, so the crop always keeps the actual subject in
       frame instead of a fixed center/left/right guess. object-position is
       the <img> equivalent of the old background-position — same custom
       properties, same admin flow, nothing changed there. Applies at every
       viewport size: it's a real coordinate now, not a mobile-only
       direction hack, so there's no reason to gate it to one breakpoint. */
    object-position: var(--hero-focal-x, 50%) var(--hero-focal-y, 50%);
    will-change: transform;
    animation: heroDrift 20s ease-out forwards;
    transform-origin: var(--hero-focal-x, 50%) var(--hero-focal-y, 50%);
}

@keyframes heroDrift {
    from { transform: scale(1); }
    to   { transform: scale(1.03); }
}

.hero-scrim {
    position: absolute;
    inset: 0;
    background:
        linear-gradient(90deg, rgba(25,21,18,.50) 0%, rgba(25,21,18,.22) 40%, rgba(25,21,18,0) 66%),
        linear-gradient(to top, rgba(25,21,18,.20) 0%, rgba(25,21,18,0) 34%);
}

.hero-content {
    position: relative;
    z-index: 2;
    max-width: 560px;
    padding: 4rem 2rem 4rem 6rem;
    color: var(--color-white);
}

@keyframes heroRise {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: none; }
}

.hero-eyebrow, .hero-title, .hero-subtitle, .hero-btn {
    animation: heroRise .7s ease-out backwards;
}
.hero-eyebrow  { animation-delay: .05s; }
.hero-title    { animation-delay: .14s; }
.hero-subtitle { animation-delay: .23s; }
.hero-btn      { animation-delay: .32s; }

.hero-eyebrow, .hero-title, .hero-subtitle {
    text-shadow: 0 1px 3px rgba(25,21,18,.35), 0 2px 14px rgba(25,21,18,.25);
}

.hero-eyebrow {
    font-size: 0.78rem;
    font-weight: 500;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    margin-bottom: 1rem;
    color: rgba(255,255,255,.85);
}

.hero-title {
    font-family: var(--font-display);
    font-size: clamp(2.5rem, 5vw, 4rem);
    font-weight: 400;
    line-height: 1.15;
    margin-bottom: 1.25rem;
    letter-spacing: -0.02em;
}

.hero-subtitle {
    font-size: 1rem;
    line-height: 1.7;
    color: rgba(255,255,255,.85);
    margin-bottom: 2rem;
    max-width: 420px;
}

.hero-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.9rem 2.25rem;
    background: var(--color-white);
    color: var(--color-text);
    border: none;
    border-radius: var(--radius-full);
    font-size: 0.9rem;
    font-weight: 500;
    transition: all var(--transition);
}
.hero-btn:hover { background: var(--color-copper); color: var(--color-white); transform: translateY(-2px); }

/* === Hero petals ===
   Deliberately restrained: the hero photo already carries real flowers, so
   these stay few, slow, translucent and softly blurred to read as depth
   rather than decoration. Purely decorative — aria-hidden in the markup and
   pointer-events:none so they can never intercept the CTA. */
.hero-petals {
    position: absolute;
    inset: 0;
    z-index: 1; /* above .hero-bg + scrim, below .hero-content (z-index 2) */
    overflow: hidden;
    pointer-events: none;
}

.hero-petals span {
    position: absolute;
    top: 0;
    display: block;
    background-repeat: no-repeat;
    background-size: contain;
    opacity: 0;
    will-change: transform;
    animation-name: petalFall;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}

@keyframes petalFall {
    0%   { opacity: 0; transform: translate3d(0, -12vh, 0) rotate(0deg); }
    12%  { opacity: var(--petal-opacity); }
    88%  { opacity: var(--petal-opacity); }
    100% { opacity: 0; transform: translate3d(var(--petal-drift), 112vh, 0) rotate(var(--petal-spin)); }
}

/* Negative delays start each petal mid-flight, so the hero never opens
   with an empty sky waiting for the first one to appear. */
.hero-petals span:nth-child(1) {
    left: 6%;  width: 22px; height: 26px;
    --petal-opacity: .30; --petal-drift: 34px;  --petal-spin: 200deg;
    animation-duration: 21s; animation-delay: -2s;  filter: blur(.3px);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2C74 22 92 52 50 98 8 52 26 22 50 2Z' fill='%23FEFCF9'/%3E%3C/svg%3E");
}
.hero-petals span:nth-child(2) {
    left: 18%; width: 14px; height: 17px;
    --petal-opacity: .22; --petal-drift: -26px; --petal-spin: -160deg;
    animation-duration: 26s; animation-delay: -11s; filter: blur(.6px);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2C74 22 92 52 50 98 8 52 26 22 50 2Z' fill='%23EEDBCE'/%3E%3C/svg%3E");
}
.hero-petals span:nth-child(3) {
    left: 34%; width: 26px; height: 31px;
    --petal-opacity: .26; --petal-drift: 20px;  --petal-spin: 240deg;
    animation-duration: 19s; animation-delay: -7s;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2C74 22 92 52 50 98 8 52 26 22 50 2Z' fill='%23FEFCF9'/%3E%3C/svg%3E");
}
.hero-petals span:nth-child(4) {
    left: 52%; width: 12px; height: 15px;
    --petal-opacity: .20; --petal-drift: -18px; --petal-spin: 180deg;
    animation-duration: 28s; animation-delay: -15s; filter: blur(.7px);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2C74 22 92 52 50 98 8 52 26 22 50 2Z' fill='%23D69F85'/%3E%3C/svg%3E");
}
.hero-petals span:nth-child(5) {
    left: 68%; width: 20px; height: 24px;
    --petal-opacity: .28; --petal-drift: 30px;  --petal-spin: -200deg;
    animation-duration: 23s; animation-delay: -5s;  filter: blur(.3px);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2C74 22 92 52 50 98 8 52 26 22 50 2Z' fill='%23FEFCF9'/%3E%3C/svg%3E");
}
.hero-petals span:nth-child(6) {
    left: 82%; width: 16px; height: 19px;
    --petal-opacity: .24; --petal-drift: -22px; --petal-spin: 220deg;
    animation-duration: 25s; animation-delay: -18s; filter: blur(.5px);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2C74 22 92 52 50 98 8 52 26 22 50 2Z' fill='%23EEDBCE'/%3E%3C/svg%3E");
}
.hero-petals span:nth-child(7) {
    left: 93%; width: 24px; height: 28px;
    --petal-opacity: .22; --petal-drift: 16px;  --petal-spin: 160deg;
    animation-duration: 20s; animation-delay: -9s;  filter: blur(.4px);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2C74 22 92 52 50 98 8 52 26 22 50 2Z' fill='%23FEFCF9'/%3E%3C/svg%3E");
}

/* Hero without an uploaded image: light variant instead of a dark, empty scrim */
.hero--plain .hero-content   { color: var(--color-text); }
.hero--plain .hero-eyebrow   { color: var(--color-copper); }
.hero--plain .hero-subtitle  { color: var(--color-sage); }
.hero--plain .hero-btn       { background: var(--color-text); color: var(--color-white); }
.hero--plain .hero-btn:hover { background: var(--color-copper); }

/* === Sections === */
.section {
    padding: 5rem 0;
}

.section-header {
    text-align: center;
    margin-bottom: 3rem;
}

.section-eyebrow {
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--color-copper);
    margin-bottom: 0.75rem;
}

.section-title {
    font-family: var(--font-display);
    font-size: clamp(1.75rem, 3vw, 2.5rem);
    font-weight: 400;
    color: var(--color-text);
    letter-spacing: -0.02em;
}

.section-subtitle {
    font-size: 0.95rem;
    color: var(--color-sage);
    margin-top: 0.75rem;
    max-width: 500px;
    margin-left: auto;
    margin-right: auto;
}

/* === Product Grid === */
.product-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.5rem;
}

.product-card {
    position: relative;
    display: flex;
    flex-direction: column;
}

.product-card-image {
    position: relative;
    aspect-ratio: 3/4;
    overflow: hidden;
    border-radius: var(--radius-md);
    background: var(--color-blush-bg);
}

.product-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s ease, opacity 0.4s ease;
}

.product-card-image .hover-image {
    position: absolute;
    inset: 0;
    opacity: 0;
}

.product-card:hover .hover-image { opacity: 1; }
.product-card:hover .primary-image { transform: scale(1.03); }

.product-badges {
    position: absolute;
    top: 0.75rem;
    left: 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    z-index: 2;
}

.product-badge {
    display: inline-block;
    padding: 0.25rem 0.65rem;
    border-radius: var(--radius-full);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.product-badge-sale { background: var(--color-copper); color: var(--color-white); }
.product-badge-new { background: var(--color-text); color: var(--color-white); }
.product-badge-soldout { background: var(--color-sage); color: var(--color-white); }

.product-card-info { padding: 0.85rem 0.25rem 0; }

.product-card-name {
    /* Same Cormorant compensation as the nav: 0.9rem was sized for Inter and
       reads faint in the serif, especially two-up on a phone. */
    font-size: 1.05rem;
    font-weight: 400;
    color: var(--color-text);
    margin-bottom: 0.3rem;
    line-height: 1.4;
}

.product-card-name a {
    transition: color var(--transition);
}
.product-card-name a:hover { color: var(--color-copper); }

.product-card-price {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.9rem;
}

.price-current { font-weight: 500; color: var(--color-text); }
.price-original { text-decoration: line-through; color: var(--color-sage); font-size: 0.85rem; }

.product-card-colors {
    display: flex;
    gap: 0.35rem;
    margin-top: 0.5rem;
}

.color-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 1.5px solid var(--color-border);
}

/* === Category Carousel === */
/*
   The track is a horizontal scroll-snap rail, not a JS slider. Swipe,
   trackpad and keyboard scrolling all work with no script; the arrow
   buttons are progressive enhancement and stay hidden until main.js
   confirms there is actually something to scroll to.
*/
.category-carousel {
    position: relative;
}

/* Three categories or fewer: the original grid, filling the row edge to
   edge. A rail sized to fixed columns would leave dead space to the right
   of three cards, which looks like a layout bug rather than a carousel. */
.category-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1.25rem;
}

/* Enough categories to actually scroll: switch to a snap rail. The view
   adds --rail based on the row count, so this flips on by itself as the
   owner adds categories in the admin.

   Column width is an explicit calc, never a fraction of the track. With
   `1fr` the browser divides the space among ALL the categories, so every
   extra one the owner adds makes every card smaller — ten categories and
   they are thumbnails. The whole point of a carousel is that the card
   keeps its size and the overflow scrolls instead. */
.category-grid--rail {
    grid-template-columns: none;
    grid-auto-flow: column;
    /* Tablet default: two cards per view. */
    grid-auto-columns: calc((100% - 1.25rem) / 2);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    /* Room for the card hover lift + shadow so neither gets clipped by
       the scroll container's own edges. */
    padding: 0.5rem 0.25rem 1rem;
    margin: -0.5rem -0.25rem -1rem;
    scrollbar-width: none;              /* Firefox */
    -ms-overflow-style: none;           /* legacy Edge */
    overscroll-behavior-x: contain;     /* don't trigger browser back-swipe */
}
.category-grid--rail::-webkit-scrollbar { display: none; }

/* Desktop: three per view — the exact card size the section had before
   it became a carousel. */
@media (min-width: 1000px) {
    .category-grid--rail { grid-auto-columns: calc((100% - 2 * 1.25rem) / 3); }
}

.category-card {
    position: relative;
    aspect-ratio: 4/5;
    border-radius: var(--radius-md);
    overflow: hidden;
    display: flex;
    align-items: flex-end;
    scroll-snap-align: start;
    transition: transform 0.4s ease, box-shadow 0.4s ease;
}

.category-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 18px 40px -18px rgba(25, 21, 18, .45);
}

/* Circular arrows floated over the rail edges. Deliberately quiet:
   off-white disc, hairline border, no chrome-heavy chevron. */
.carousel-arrow {
    position: absolute;
    top: 50%;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-top: -22px;
    border: 1px solid var(--color-border);
    border-radius: 50%;
    background: rgba(255, 255, 255, .92);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    color: var(--color-charcoal, #191512);
    cursor: pointer;
    box-shadow: 0 6px 20px -8px rgba(25, 21, 18, .35);
    transition: background 0.25s ease, transform 0.25s ease, opacity 0.25s ease;
}
.carousel-arrow:hover { background: #fff; transform: scale(1.06); }
.carousel-arrow[hidden] { display: none; }
.carousel-arrow:disabled { opacity: 0; pointer-events: none; }

.carousel-arrow--prev { left: -22px; }
.carousel-arrow--next { right: -22px; }

/* On narrower screens there is no gutter to hang the arrows in, so tuck
   them just inside the rail instead of letting them overflow the page. */
@media (max-width: 1240px) {
    .carousel-arrow--prev { left: 0.5rem; }
    .carousel-arrow--next { right: 0.5rem; }
}

/* Touch devices already have swiping — arrows would just cover a photo.
   The peeking 72nd percent of the next card is the affordance instead. */
@media (max-width: 768px) {
    .carousel-arrow { display: none !important; }
    /* One card per view, with the next one peeking in as the affordance
       that there is more to swipe to. */
    .category-grid--rail { grid-auto-columns: 78%; }
}

@media (prefers-reduced-motion: reduce) {
    .category-grid--rail { scroll-behavior: auto; }
    .category-card,
    .category-card img,
    .carousel-arrow { transition: none; }
}

.category-card img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s ease;
}
.category-card:hover img { transform: scale(1.05); }

.category-card-overlay {
    position: relative;
    z-index: 2;
    width: 100%;
    padding: 1.5rem;
    background: linear-gradient(transparent, rgba(25,21,18,.6));
    color: var(--color-white);
}

.category-card-name {
    font-family: var(--font-display);
    font-size: 1.3rem;
    font-weight: 400;
}

/* === Editorial Section === */
.editorial {
    position: relative;
    padding: 6rem 0;
    background: var(--color-blush-bg);
    overflow: hidden;
}

.editorial-content {
    text-align: center;
    max-width: 600px;
    margin: 0 auto;
}

.editorial-title {
    font-family: var(--font-display);
    font-size: clamp(2rem, 4vw, 3rem);
    font-weight: 400;
    margin-bottom: 1.25rem;
    letter-spacing: -0.02em;
}

.editorial-text {
    font-size: 1rem;
    color: var(--color-sage);
    line-height: 1.7;
    margin-bottom: 2rem;
}

/* === Brand Statement === */
.brand-statement {
    text-align: center;
    padding: 5rem 2rem;
}

.brand-statement-text {
    font-family: var(--font-display);
    font-size: clamp(1.5rem, 3vw, 2.25rem);
    font-weight: 400;
    color: var(--color-sage);
    font-style: italic;
    letter-spacing: 0.06em;
}

/* === Newsletter === */
.newsletter {
    background: var(--color-text);
    color: var(--color-white);
    padding: 4rem 0;
}

.newsletter-inner {
    text-align: center;
    max-width: 480px;
    margin: 0 auto;
}

.newsletter-title {
    font-family: var(--font-display);
    font-size: 1.75rem;
    font-weight: 400;
    margin-bottom: 0.75rem;
}

.newsletter-text {
    font-size: 0.9rem;
    opacity: .7;
    margin-bottom: 1.5rem;
}

.newsletter-form {
    display: flex;
    gap: 0.5rem;
    max-width: 400px;
    margin: 0 auto;
}

.newsletter-input {
    flex: 1;
    padding: 0.75rem 1rem;
    background: rgba(255,255,255,.1);
    border: 1px solid rgba(255,255,255,.2);
    border-radius: var(--radius-full);
    color: var(--color-white);
    font-size: 0.9rem;
    font-family: inherit;
}
.newsletter-input::placeholder { color: rgba(255,255,255,.5); }
.newsletter-input:focus { outline: none; border-color: var(--color-copper); }

.newsletter-btn {
    padding: 0.75rem 1.5rem;
    background: var(--color-copper);
    color: var(--color-white);
    border: none;
    border-radius: var(--radius-full);
    font-size: 0.85rem;
    font-weight: 500;
    transition: background var(--transition);
    white-space: nowrap;
}
.newsletter-btn:hover { background: var(--color-copper-dark); }

/* === Footer === */
.site-footer {
    background: var(--color-text);
    color: rgba(255,255,255,.7);
    padding: 4rem 0 2rem;
}

.footer-grid {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr;
    gap: 3rem;
    margin-bottom: 3rem;
}

.footer-brand p {
    font-size: 0.85rem;
    line-height: 1.7;
    margin-top: 1rem;
    max-width: 280px;
}

.footer-title {
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-white);
    margin-bottom: 1.25rem;
}

.footer-links { list-style: none; }
.footer-links li { margin-bottom: 0.65rem; }
.footer-links a { font-size: 1rem; transition: color var(--transition); }
.footer-links a:hover { color: var(--color-copper); }

.footer-social { display: flex; gap: 1rem; margin-top: 1rem; }
.footer-social a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: 1px solid rgba(255,255,255,.15);
    transition: all var(--transition);
}
.footer-social a:hover { background: var(--color-copper); border-color: var(--color-copper); }

.footer-bottom {
    border-top: 1px solid rgba(255,255,255,.08);
    padding-top: 1.5rem;
    text-align: center;
    font-size: 0.8rem;
    opacity: .5;
}

/* === Buttons === */
.btn-primary {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.85rem 2rem;
    background: var(--color-text);
    color: var(--color-white);
    border: none;
    border-radius: var(--radius-full);
    font-size: 0.9rem;
    font-weight: 500;
    transition: all var(--transition);
}
.btn-primary:hover { background: var(--color-copper); transform: translateY(-1px); }

.btn-outline {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.85rem 2rem;
    background: transparent;
    color: var(--color-text);
    border: 1.5px solid var(--color-text);
    border-radius: var(--radius-full);
    font-size: 0.9rem;
    font-weight: 500;
    transition: all var(--transition);
}
.btn-outline:hover { background: var(--color-text); color: var(--color-white); }

/* === Shop Page === */
.shop-layout {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: 2rem;
    /* Longhand, NOT the "padding: 2rem 0" shorthand. This class shares its
       element with .container, so the shorthand's implicit "0" wiped
       .container's own 0 1.5rem side padding and the page ran edge to edge —
       most visible on a phone, where the product cards touched the screen. */
    padding-top: 2rem;
    padding-bottom: 2rem;
}

.shop-filters {
    position: sticky;
    top: calc(var(--header-h) + 1rem);
    align-self: start;
}

/* Three across, not the site-wide four: the shop has a 240px sidebar eating
   into the content column, so four cards here would be narrower than the
   same cards on the homepage.

   Scoped to min-width on purpose. A plain ".shop-layout .product-grid" rule
   would out-specify every .product-grid breakpoint below and re-break the
   responsive ladder — the same trap as the inline style this replaced.
   Below 1024px the sidebar stacks on top anyway, so the normal ladder
   (3 → 2 → 2) is exactly right. */
@media (min-width: 1025px) {
    .shop-layout .product-grid { grid-template-columns: repeat(3, 1fr); }
}

.filter-group {
    margin-bottom: 1.5rem;
}

.filter-title {
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-text);
    margin-bottom: 0.75rem;
}

.filter-option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0;
    font-size: 0.875rem;
    color: var(--color-sage);
    cursor: pointer;
    transition: color var(--transition);
}
.filter-option:hover { color: var(--color-text); }
.filter-option input { accent-color: var(--color-copper); }

.shop-sort {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
    gap: 1rem;
}

.sort-results {
    font-size: 0.85rem;
    color: var(--color-sage);
}

.sort-select {
    padding: 0.5rem 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: 0.85rem;
    font-family: inherit;
    background: var(--color-white);
    color: var(--color-text);
}

/* === Product Detail Page === */
.product-detail {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3rem;
    /* Same as .shop-layout: this class sits on the .container element, so the
       padding shorthand would zero out its side padding. */
    padding-top: 2rem;
    padding-bottom: 4rem;
}

.product-gallery {}
.gallery-main {
    aspect-ratio: 3/4;
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--color-blush-bg);
    cursor: zoom-in;
    margin-bottom: 0.75rem;
}
.gallery-main img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.4s ease;
}

.gallery-thumbs {
    display: flex;
    gap: 0.5rem;
    overflow-x: auto;
}
.gallery-thumb {
    width: 72px;
    height: 96px;
    border-radius: var(--radius-sm);
    overflow: hidden;
    cursor: pointer;
    border: 2px solid transparent;
    transition: border-color var(--transition);
    flex-shrink: 0;
}
.gallery-thumb.active { border-color: var(--color-copper); }
.gallery-thumb img { width: 100%; height: 100%; object-fit: cover; }

.product-info { padding-top: 1rem; }

/* The heading is a grid sibling of the gallery so DOM order puts it first on
   a phone. On desktop it is placed back into the right-hand column above the
   info, with the gallery spanning both rows — the layout there is unchanged. */
.product-heading { padding-top: 1rem; }

@media (min-width: 1025px) {
    /* The base "gap: 3rem" is the space between the two columns; as rows, it
       would open a 3rem hole between the title and the price. Keep it
       horizontal only. */
    .product-detail { align-content: start; column-gap: 3rem; row-gap: 0; }
    .product-heading { grid-column: 2; grid-row: 1; }
    .product-gallery { grid-column: 1; grid-row: 1 / span 2; }
    .product-info    { grid-column: 2; grid-row: 2; padding-top: 0; }
}

@media (max-width: 1024px) {
    /* Stacked, the heading already provides the separation the info column's
       own top padding was for. */
    .product-heading { padding-top: 0; margin-bottom: 0.25rem; }
    .product-info { padding-top: 0.5rem; }
}

@media (max-width: 768px) {
    .breadcrumb-current { display: none; }
}
.product-category {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--color-copper);
    margin-bottom: 0.5rem;
}

.product-title {
    font-family: var(--font-display);
    font-size: 2rem;
    font-weight: 400;
    margin-bottom: 0.75rem;
    letter-spacing: -0.02em;
}

.product-price-display {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}

.product-price-current {
    font-size: 1.4rem;
    font-weight: 600;
    color: var(--color-text);
}
.product-price-original {
    font-size: 1.1rem;
    text-decoration: line-through;
    color: var(--color-sage);
}

.product-sku {
    font-size: 0.8rem;
    color: var(--color-sage);
    margin-bottom: 1.5rem;
}

.variant-section { margin-bottom: 1.25rem; }
.variant-label {
    font-size: 0.85rem;
    font-weight: 500;
    margin-bottom: 0.5rem;
}

.color-options { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.color-option {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: 2px solid var(--color-border);
    cursor: pointer;
    transition: all var(--transition);
    position: relative;
}
.color-option.active { border-color: var(--color-copper); box-shadow: 0 0 0 2px var(--color-copper); }
.color-option.disabled { opacity: .3; cursor: not-allowed; }

.size-options { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.size-option {
    padding: 0.5rem 1.25rem;
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: 0.85rem;
    cursor: pointer;
    transition: all var(--transition);
    background: var(--color-white);
}
.size-option:hover { border-color: var(--color-text); }
.size-option.active { background: var(--color-text); color: var(--color-white); border-color: var(--color-text); }
.size-option.disabled { opacity: .3; cursor: not-allowed; text-decoration: line-through; }

.stock-indicator {
    font-size: 0.8rem;
    margin: 1rem 0;
}
.stock-in { color: #16a34a; }
.stock-low { color: #d97706; }
.stock-out { color: #dc2626; }

.quantity-selector {
    display: flex;
    align-items: center;
    gap: 0;
    margin-bottom: 1.5rem;
}
.qty-btn {
    width: 40px;
    height: 40px;
    border: 1.5px solid var(--color-border);
    background: var(--color-white);
    font-size: 1.1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background var(--transition);
}
.qty-btn:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.qty-btn:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.qty-btn:hover { background: var(--color-blush-bg); }
.qty-input {
    width: 56px;
    height: 40px;
    border: 1.5px solid var(--color-border);
    border-left: none;
    border-right: none;
    text-align: center;
    font-size: 0.95rem;
    font-family: inherit;
}
.qty-input:focus { outline: none; }

.add-to-cart-btn {
    width: 100%;
    padding: 1rem;
    background: var(--color-text);
    color: var(--color-white);
    border: none;
    border-radius: var(--radius-sm);
    font-size: 1rem;
    font-weight: 500;
    transition: all var(--transition);
}
.add-to-cart-btn:hover:not(:disabled) { background: var(--color-copper); }
.add-to-cart-btn:disabled { opacity: .5; cursor: not-allowed; }

.product-description {
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--color-border);
}
.product-description h3 {
    font-size: 0.95rem;
    font-weight: 600;
    margin-bottom: 0.75rem;
}
.product-description p {
    font-size: 0.9rem;
    color: var(--color-sage);
    line-height: 1.7;
}

/* === Model Measurements ===
   A reference card so the customer can compare her own measurements against
   the model's. Set apart with its own background (not just a hairline like
   .product-description) so it reads as a distinct spec sheet, not more copy. */
.model-measurements {
    margin-top: 1.5rem;
    padding: 1.5rem;
    background: var(--color-ivory);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}
.model-measurements h3 {
    font-size: 0.95rem;
    font-weight: 600;
    margin-bottom: 0.75rem;
}
.model-size-worn {
    font-size: 0.9rem;
    color: var(--color-sage);
    margin-bottom: 1rem;
}
.model-size-worn span {
    font-family: var(--font-ui);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text);
}
.measurement-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.25rem;
}
@media (max-width: 480px) {
    .measurement-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}
.measurement-item dt {
    font-family: var(--font-ui);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-sage);
    margin-bottom: 0.35rem;
}
.measurement-item dd {
    margin: 0;
    font-family: var(--font-display);
    font-size: 1.6rem;
    color: var(--color-text);
}

/* Emphasis produced by rich_text() from the owner's ##markers##.
   Sized in em, not px, so the same marker scales correctly whether it lands
   in a body paragraph or in the smaller values text below it. line-height is
   pulled in because Cormorant at 1.35em inherits leading meant for body copy
   and would otherwise sit too loose. */
.rt-lg {
    font-size: 1.35em;
    line-height: 1.45;
}

/* === Complete the Look ===
   Sits directly above "You May Also Like", so it is deliberately quieter
   than a product grid: smaller cards, ivory ground instead of blush, a
   hairline rule under the title. It should read as a footnote to the
   product, not as a second storefront competing with the section below. */
.accessory-section { padding: 4rem 0 3rem; }

.accessory-section-title {
    font-size: 1.75rem;
    text-align: center;
    margin-bottom: 2.5rem;
    position: relative;
}
.accessory-section-title::after {
    content: '';
    display: block;
    width: 48px;
    height: 1px;
    margin: 0.9rem auto 0;
    background: var(--color-copper);
}

.accessory-strip {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.5rem;
}

.accessory-card { text-align: center; }

.accessory-card-image {
    display: block;
    aspect-ratio: 3/4;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--color-blush-bg);
    margin-bottom: 0.85rem;
}
.accessory-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.5s ease;
}
.accessory-card-image:hover img { transform: scale(1.05); }

.accessory-card-name {
    font-size: 0.9rem;
    font-weight: 400;
    line-height: 1.4;
    margin-bottom: 0.35rem;
}
.accessory-card-name a { color: inherit; }
.accessory-card-name a:hover { color: var(--color-copper); }

.accessory-card-price {
    font-size: 0.9rem;
    margin-bottom: 0.75rem;
    display: flex;
    justify-content: center;
    gap: 0.5rem;
}

/* One shared look for all three states — add, choose options, sold out —
   so the row stays visually even however the products differ. */
.accessory-btn {
    display: block;
    width: 100%;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--color-text);
    border-radius: var(--radius-sm);
    background: none;
    color: var(--color-text);
    font-family: inherit;
    font-size: 0.78rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-align: center;
    cursor: pointer;
    transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.accessory-btn:hover { background: var(--color-text); color: var(--color-white); }
.accessory-btn:disabled {
    border-color: var(--color-border);
    color: var(--color-sage);
    cursor: not-allowed;
}
.accessory-btn:disabled:hover { background: none; color: var(--color-sage); }

@media (max-width: 900px) {
    .accessory-strip { grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
}

/* Phones get the same scroll-snap rail as the category carousel rather than
   a 2-up grid: at this card size two columns leave the images too small to
   judge an accessory by. */
@media (max-width: 640px) {
    .accessory-strip {
        grid-template-columns: none;
        grid-auto-flow: column;
        grid-auto-columns: 46%;
        gap: 1rem;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        padding-bottom: 0.75rem;
        scrollbar-width: none;
        -ms-overflow-style: none;
        overscroll-behavior-x: contain;
    }
    .accessory-strip::-webkit-scrollbar { display: none; }
    .accessory-card { scroll-snap-align: start; }
    .accessory-section-title { font-size: 1.45rem; }
}

/* === Cart ===
   The .cart-table rules that used to live here were left over from an
   older table-based cart; the view is card-based and referenced none of
   them, which is why the page rendered essentially unstyled. */
/* Items column + summary rail. Matches .checkout-layout below so the two
   steps of the funnel don't visibly reflow between each other. */
.cart-layout {
    display: grid;
    grid-template-columns: 1fr 380px;
    gap: 3rem;
    align-items: start;
}

.cart-item {
    display: grid;
    /* Fixed image column. The image lives inside an <a>, and an inline
       element ignores width/height — which is why the photo previously
       rendered at its full natural size and blew the row apart. The link
       is made a block below. */
    grid-template-columns: 110px 1fr;
    gap: 1.5rem;
    padding: 1.75rem 0;
    border-bottom: 1px solid var(--color-border);
}
.cart-item:first-child { padding-top: 0; }

.cart-item-image {
    display: block;
    width: 110px;
    aspect-ratio: 3/4;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--color-blush-bg);
}
.cart-item-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.5s ease;
}
.cart-item-image:hover img { transform: scale(1.04); }

.cart-item-details {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.cart-item-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
}

.cart-item-title {
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 400;
    line-height: 1.35;
}
.cart-item-title a { color: inherit; }
.cart-item-title a:hover { color: var(--color-copper, var(--color-sage)); }

.cart-item-meta {
    margin-top: 0.4rem;
    font-size: 0.85rem;
    color: var(--color-sage);
    letter-spacing: 0.02em;
}

.cart-item-remove {
    flex-shrink: 0;
    font-size: 1.4rem;
    line-height: 1;
    color: var(--color-sage);
    opacity: 0.55;
    transition: opacity var(--transition), color var(--transition);
}
.cart-item-remove:hover { opacity: 1; color: #dc2626; }

/* margin-top:auto pins the controls to the bottom of the row, so the
   quantity stepper lines up with the photo's base no matter how many
   lines the product name wraps to. */
.cart-item-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    margin-top: auto;
    padding-top: 1rem;
}

.cart-item-price {
    font-size: 1.05rem;
    font-weight: 600;
    white-space: nowrap;
}

/* === Cart Summary === */
.cart-summary {
    background: var(--color-blush-bg);
    border-radius: var(--radius-md);
    padding: 1.75rem;
    position: sticky;
    top: calc(var(--header-h, 80px) + 1.5rem);
}

.cart-summary-title {
    font-family: var(--font-display);
    font-size: 1.35rem;
    font-weight: 400;
    padding-bottom: 1rem;
    margin-bottom: 0.5rem;
    border-bottom: 1px solid var(--color-border);
}

.cart-summary-row {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.5rem 0;
    font-size: 0.9rem;
}
.cart-summary-total {
    border-top: 1px solid var(--color-border);
    margin-top: 0.75rem;
    padding-top: 1rem;
    font-weight: 600;
    font-size: 1.15rem;
}
/* The grand total is a price like any other — Inter, per the --font-ui rule.
   Size and weight carry the emphasis instead of a change of typeface. */
.cart-summary-total span:last-child { font-family: var(--font-ui); font-size: 1.25rem; }

@media (max-width: 900px) {
    .cart-layout { grid-template-columns: 1fr; gap: 2.5rem; }
    .cart-summary { position: static; }
}

@media (max-width: 480px) {
    .cart-item { grid-template-columns: 88px 1fr; gap: 1rem; padding: 1.25rem 0; }
    .cart-item-image { width: 88px; }
    .cart-item-title { font-size: 1rem; }
    /* Stack the stepper above the price rather than letting them squeeze
       each other on a narrow screen. */
    .cart-item-actions { flex-direction: column; align-items: flex-start; gap: 0.75rem; }
}

/* === Checkout ===
   This whole page was previously unstyled beyond the bare input/label/row
   rules below: .checkout-section-title had no rule at all (rendering as a
   raw browser <h2>) and .checkout-summary-section had no card treatment,
   so the order summary just floated on the page background. That — not
   any one property — is what read as "doesn't look designed" on a phone,
   where there's no second column to visually separate it from the form. */
.checkout-layout {
    display: grid;
    grid-template-columns: 1fr 400px;
    gap: 3rem;
    padding: 2rem 0 4rem;
}

/* Both explicitly on --font-ui (Inter), not inherited: .checkout-input used
   to say "font-family: inherit", which silently pulled in Cormorant Garamond
   from <body> instead of the Inter every other form field/price on the site
   uses — thin serif digits at a small size is exactly what read as "too
   small to read" here even though the cart/product prices right next to
   this same font-size never had that complaint. font-size is also bumped to
   a true 16px (1rem): below that, Safari on iPhone zooms the whole page in
   on focus, which is its own separate annoyance beyond legibility. */
.checkout-label {
    display: block;
    font-family: var(--font-ui);
    font-size: 0.92rem;
    font-weight: 500;
    margin-bottom: 0.4rem;
}
.checkout-input {
    width: 100%;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: 1rem;
    font-family: var(--font-ui);
    background: var(--color-white);
    transition: border-color var(--transition);
}
.checkout-input:focus { outline: none; border-color: var(--color-copper); }
.checkout-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }

.checkout-section-title {
    font-family: var(--font-display);
    font-size: 1.4rem;
    font-weight: 400;
    color: var(--color-text);
    letter-spacing: -0.01em;
}
/* Every field between two titles is a flex child of #payment-form (below)
   with its own gap already — this adds the CLEAR break between whole
   sections (Contact -> Shipping -> Payment) on top of that, but only
   between sections, not before the very first one. */
.checkout-section-title:not(:first-child) {
    padding-top: 1.75rem;
    border-top: 1px solid var(--color-border);
}

/* The form's actual rhythm: one consistent gap between every field group
   and heading, driven by the parent instead of a different hand-picked
   margin on each element (which is what had left some gaps doubled and
   others at zero). */
#payment-form {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

/* The item/subtotal/shipping/tax rows below are bare divs with no class
   (styled inline), so unlike the input fields above they were never
   overriding anything explicitly — they just fell through to <body>'s
   Cormorant Garamond by default, the same "thin serif at reading size"
   problem as .checkout-input. Setting the font here means every one of
   them gets Inter/legible size for free; "Order Summary" itself keeps its
   own explicit --font-display from .checkout-section-title regardless,
   since an element's own font-family always wins over an inherited one. */
.checkout-summary-section {
    background: var(--color-blush-bg);
    border-radius: var(--radius-md);
    padding: 1.75rem;
    align-self: start;
    font-family: var(--font-ui);
    font-size: 0.97rem;
}

@media (max-width: 1024px) {
    .checkout-layout { gap: 2rem; }
    #payment-form { gap: 1.25rem; }
    .checkout-section-title:not(:first-child) { padding-top: 1.5rem; }
    .checkout-summary-section { padding: 1.5rem; }
}

/* === Page Title === */
.page-banner {
    background: var(--color-blush-bg);
    padding: 3rem 0;
    text-align: center;
}

.page-banner h1 {
    font-family: var(--font-display);
    font-size: 2.25rem;
    font-weight: 400;
    letter-spacing: -0.02em;
}

/* === Pagination === */
.pagination {
    display: flex;
    justify-content: center;
    gap: 0.25rem;
    margin-top: 2.5rem;
}
.pagination a, .pagination span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 40px;
    padding: 0 0.5rem;
    border-radius: var(--radius-sm);
    font-size: 0.85rem;
    color: var(--color-sage);
    transition: all var(--transition);
}
.pagination a:hover { background: var(--color-blush-bg); color: var(--color-text); }
.pagination .active { background: var(--color-text); color: var(--color-white); }

/* === Lightbox === */
.lightbox-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,.9);
    z-index: 300;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    cursor: zoom-out;
}
.lightbox-overlay.active { display: flex; }
.lightbox-overlay img { max-width: 90vw; max-height: 90vh; object-fit: contain; }
.lightbox-close {
    position: absolute;
    top: 1rem;
    right: 1rem;
    background: none;
    border: none;
    color: white;
    font-size: 2rem;
    cursor: pointer;
}

/* === Contact === */
.contact-page { padding: 3rem 0; max-width: 600px; margin: 0 auto; }

/* === Flash Messages === */
.flash-message {
    position: fixed;
    top: calc(var(--header-h) + 1rem);
    right: 1rem;
    z-index: 150;
    padding: 0.85rem 1.5rem;
    border-radius: var(--radius-sm);
    font-size: 0.875rem;
    animation: slideIn 0.3s ease;
    max-width: 400px;
}

.flash-success { background: #f0fdf4; color: #16a34a; border: 1px solid #bbf7d0; }
.flash-error { background: #fef2f2; color: #dc2626; border: 1px solid #fecaca; }

@keyframes slideIn {
    from { opacity: 0; transform: translateX(20px); }
    to { opacity: 1; transform: translateX(0); }
}

/* === Responsive === */
@media (max-width: 1024px) {
    .product-grid { grid-template-columns: repeat(3, 1fr); }
    .footer-grid { grid-template-columns: 1fr 1fr; gap: 2rem; }
    .product-detail { grid-template-columns: 1fr; gap: 2rem; }
    .checkout-layout { grid-template-columns: 1fr; }
    .shop-layout { grid-template-columns: 1fr; }

    /* Once the sidebar stacks on top, its vertical stack of full-width
       controls pushed the first product most of a screen down. Laid out as a
       wrapping row it costs one or two lines instead of four, and the
       products start near the top where they belong. */
    .shop-filters {
        position: static;
        padding-bottom: 1.25rem;
        margin-bottom: 1.5rem;
        border-bottom: 1px solid var(--color-border);
    }
    .shop-filters form {
        display: flex;
        flex-wrap: wrap;
        align-items: flex-end;
        gap: 1rem;
    }
    .shop-filters .filter-group {
        margin-bottom: 0;
        flex: 1 1 190px;   /* wraps on its own once a phone is too narrow */
    }
    .filter-title { margin-bottom: 0.4rem; }
}

@media (max-width: 768px) {
    .header-nav { display: none; }
    .hamburger-menu { display: block; }

    /* Premium-boutique mobile header: hamburger left, logo centered and
       given real presence, and only the two icons a shopper actually needs
       mid-session on the right. A single flex row with five competing
       children was what squashed the logo into an illegible smudge; a
       1fr/auto/1fr grid centers the logo against the true page center
       regardless of how wide the side clusters are. */
    :root { --header-h: 72px; }
    .header-inner {
        display: grid;
        grid-template-columns: 1fr auto 1fr;
        align-items: center;
        gap: 0.5rem;
        padding: 0 1rem;
    }
    .hamburger-menu { justify-self: start; }
    .header-logo { justify-self: center; min-width: 0; }
    /* max-height + max-width with both dimensions auto = contain: the logo
       scales down proportionally on a narrow screen instead of being
       squeezed on one axis. */
    .header-logo img {
        height: auto;
        width: auto;
        max-height: 42px;
        max-width: 100%;
    }
    .header-actions { justify-self: end; gap: 0.25rem; }

    /* Both already live in the drawer (opened by the hamburger), and
       keeping duplicates in the top bar is exactly what left no room for
       the logo. */
    .lang-switch-nav { display: none; }
    .header-action--account { display: none; }
    .product-grid { grid-template-columns: repeat(2, 1fr); gap: 1rem; }
    .footer-grid { grid-template-columns: 1fr; }
    .hero-content {
        max-width: 100%;
        padding: 2rem 1.5rem;
    }
    /* A boxed/blurred panel behind the text read as a clumsy gray rectangle
       cutting across the photo — not the elegant look this site wants. A
       plain top-to-bottom darkening didn't hold up either, since the photo's
       own light areas still showed through wherever the text happened to
       land vertically. Instead: the same horizontal "dark on the text side,
       fading into the photo" treatment the desktop version already uses,
       tuned stronger for the narrower mobile crop — reliable contrast that
       reads as photo-grade lighting, not an overlay. */
    .hero-scrim {
        background:
            linear-gradient(100deg, rgba(25,21,18,.82) 0%, rgba(25,21,18,.62) 45%, rgba(25,21,18,.15) 75%, rgba(25,21,18,0) 100%),
            linear-gradient(to top, rgba(25,21,18,.35) 0%, rgba(25,21,18,0) 40%);
    }
    .hero-eyebrow, .hero-title, .hero-subtitle {
        text-shadow: 0 1px 4px rgba(25,21,18,.5), 0 2px 18px rgba(25,21,18,.4);
    }
    /* Small underline accent below the eyebrow label — a quiet divider
       between the label and the headline instead of relying on spacing
       alone to separate them. */
    .hero-eyebrow {
        padding-bottom: 0.75rem;
        margin-bottom: 1.1rem;
        position: relative;
    }
    .hero-eyebrow::after {
        content: '';
        position: absolute;
        left: 0;
        bottom: 0;
        width: 2rem;
        height: 1px;
        background: rgba(255,255,255,.55);
    }
    /* Fewer petals on a narrow screen: less clutter, less compositing work */
    .hero-petals span:nth-child(2),
    .hero-petals span:nth-child(4),
    .hero-petals span:nth-child(6) { display: none; }
    .section { padding: 3.5rem 0; }
    .newsletter-form { flex-direction: column; }
    .about-grid { grid-template-columns: 1fr; gap: 2.5rem; }
    .about-values-grid { grid-template-columns: 1fr; gap: 2rem; }
}

@media (max-width: 480px) {
    .product-grid { grid-template-columns: repeat(2, 1fr); gap: 0.75rem; }
    /* Fixed proportion instead of a viewport-height slice: on a tall phone
       60vh grows with the screen, so object-fit:cover had to enlarge the
       photo to fill it. 4/5 depends only on width. The 24rem floor keeps the
       text from being clipped on very narrow screens, since overflow:hidden
       stops the aspect-ratio box from growing to fit its content. */
    .hero { min-height: 24rem; aspect-ratio: 4 / 5; }
    :root { --header-h: 64px; }
    .header-inner { padding: 0 0.75rem; }
    .header-actions { gap: 0.15rem; }
    .header-action { width: 36px; height: 36px; }
    .header-logo img { max-height: 34px; }
    /* Matches the <picture><source media="(max-width:480px)"> breakpoint in
       home/index.php — 480px, not 768px, so a portrait tablet (a classic
       iPad is exactly 768px wide) still gets the desktop photo, and only
       genuine phones get the dedicated mobile one. --hero-focal-x-mobile is
       only emitted inline when a mobile photo actually exists (see
       home/index.php) — without one, <picture> keeps showing the desktop
       photo on phones too, so the fallback here chains to the desktop value
       instead of a blind 50%, or that photo would get re-centered away from
       its own correct focal point. */
    .hero {
        --hero-focal-x: var(--hero-focal-x-mobile, var(--hero-focal-x-desktop, 50%));
        --hero-focal-y: var(--hero-focal-y-mobile, var(--hero-focal-y-desktop, 50%));
    }
}

/* === Prefers Reduced Motion === */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }

    .hero-bg { animation: none; transform: none; }
    .hero-eyebrow, .hero-title, .hero-subtitle, .hero-btn { animation: none; }

    /* Removed outright rather than left to the blanket rule above: the petals
       loop forever, so a 0.01ms duration would spin the compositor instead of
       stopping the motion. */
    .hero-petals { display: none; }
}
