/* /Components/Layout/AdminLayout.razor.rz.scp.css */
/* Styles moved to AdminLayout.razor <style> block so they are global
   and correctly pierce the NavLink child component scope. */
/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* ── Page shell ─────────────────────────────── */
.page[b-df72mtkjlo] {
    display: flex;
    flex-direction: row;
    /* `vh` first as the fallback for browsers that don't recognize `dvh`
       (cascade leaves them on this line). Modern browsers use the `dvh`
       declaration below — important on mobile (Firefox Android, Safari iOS)
       where the URL bar collapses on scroll: `vh` measures the
       largest-possible viewport so the page would overshoot when the URL
       bar is visible; `dvh` tracks the actually-visible area and the page
       doesn't end with a strip of empty space below the footer. */
    min-height: calc(100vh - 56px);
    min-height: calc(100dvh - 56px);
}

main[b-df72mtkjlo] {
    flex: 1 1 0;
    min-width: 0;
    overflow-x: hidden;
    background-color: var(--bg-page);
}

/* ── Sidebar (desktop) ──────────────────────── */
.sidebar[b-df72mtkjlo] {
    width: 210px;
    min-width: 210px;
    max-width: 210px;
    background-color: var(--bg-sidebar);
    border-right: 1px solid var(--border-subtle);
    /* No sticky/fixed-height/overflow — the sidebar lives in normal
       flow and stretches via .page's flex container (default
       align-items: stretch) to the full page height, so the sidebar
       background reaches the footer. Categories render at their
       natural height inside; long lists simply extend further down
       the page. The customer scrolls the main page to navigate —
       never an inner scrollbar inside the sidebar. */
    display: flex;
    flex-direction: column;
    transition: background-color 0.25s ease, border-color 0.25s ease;
}

/* ── Sidebar (mobile — off-canvas drawer) ─────
   Fluid width scales with the viewport so 360 px phones still have room to
   read long category names without truncation, while wider phones cap at
   320 px so a slice of main content stays visible on the right as an
   affordance ("tap outside to close"). Height intentionally uses 100dvh
   where supported so the drawer content isn't clipped behind iOS Safari's
   collapsible URL bar during scroll; falls back to 100vh - 56px otherwise. */
@media (max-width: 767.98px) {
    .sidebar[b-df72mtkjlo] {
        position: fixed;
        top: 56px;
        left: 0;
        height: calc(100vh - 56px);
        height: calc(100dvh - 56px);
        width: min(86vw, 320px);
        min-width: min(86vw, 320px);
        max-width: 320px;
        z-index: 1040;
        transform: translateX(-100%);
        transition: transform 0.3s cubic-bezier(0.32, 0.72, 0.24, 1),
                    background-color 0.25s ease,
                    border-color 0.25s ease;
        box-shadow: none;
        border-right: none;
    }

    .sidebar.sidebar-open[b-df72mtkjlo] {
        transform: translateX(0);
        box-shadow: 8px 0 32px rgba(0, 0, 0, 0.55),
                    2px 0 12px rgba(0, 0, 0, 0.35);
    }
}

/* ── Overlay (mobile) ───────────────────────── */
.sidebar-overlay[b-df72mtkjlo] {
    display: none;
}

@media (max-width: 767.98px) {
    .sidebar-overlay[b-df72mtkjlo] {
        display: block;
        position: fixed;
        inset: 56px 0 0 0;
        background: rgba(0, 0, 0, 0.55);
        z-index: 1039;
        backdrop-filter: blur(3px);
        -webkit-backdrop-filter: blur(3px);
        animation: fadeIn-b-df72mtkjlo 0.22s ease;
    }
}

@keyframes fadeIn-b-df72mtkjlo {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* ── Error UI ───────────────────────────────── */
/* Routes through the warning-alert tokens so the strip is readable in both
   themes — previously hardcoded `lightyellow` with `color-scheme: light only`,
   which made the dismiss icon invisible against a dark-theme browser chrome. */
#blazor-error-ui[b-df72mtkjlo] {
    background-color: rgba(var(--alert-warning-bg-rgb), 0.95);
    color: var(--alert-warning-fg);
    border-top: 1px solid var(--accent-yellow);
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem;
    position: fixed;
    width: 100%;
    z-index: 2000;
}

#blazor-error-ui .dismiss[b-df72mtkjlo] {
    color: inherit;
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}
/* /Components/Layout/NavMenu.razor.rz.scp.css */
/* Scoped styles for elements directly in NavMenu */

/* Thin scrollbar for sidebar nav (scoped override) */
.sidebar-nav[b-z1dsinqopx]::-webkit-scrollbar { width: 3px; }
.sidebar-nav[b-z1dsinqopx]::-webkit-scrollbar-track { background: transparent; }
.sidebar-nav[b-z1dsinqopx]::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 2px; }
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-dflvh5cudg],
.components-reconnect-repeated-attempt-visible[b-dflvh5cudg],
.components-reconnect-failed-visible[b-dflvh5cudg],
.components-pause-visible[b-dflvh5cudg],
.components-resume-failed-visible[b-dflvh5cudg],
.components-rejoining-animation[b-dflvh5cudg] {
    display: none;
}

.components-reconnect-title[b-dflvh5cudg] {
    font-size: 1.1rem;
    font-weight: 600;
    margin: 0;
    color: var(--text-primary);
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-dflvh5cudg],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-dflvh5cudg],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-dflvh5cudg],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-dflvh5cudg],
#components-reconnect-modal.components-reconnect-retrying[b-dflvh5cudg],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-dflvh5cudg],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-dflvh5cudg],
#components-reconnect-modal.components-reconnect-failed[b-dflvh5cudg],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-dflvh5cudg] {
    display: block;
}


#components-reconnect-modal[b-dflvh5cudg] {
    background-color: var(--bg-card);
    color: var(--text-primary);
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 1px solid var(--border-color, transparent);
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-dflvh5cudg 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-dflvh5cudg 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-dflvh5cudg 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-dflvh5cudg]::backdrop {
    background-color: var(--modal-backdrop, rgba(0, 0, 0, 0.5));
    animation: components-reconnect-modal-fadeInOpacity-b-dflvh5cudg 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-dflvh5cudg {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-dflvh5cudg {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-dflvh5cudg {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-dflvh5cudg] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-dflvh5cudg] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-dflvh5cudg] {
    border: 0;
    background-color: var(--accent-red);
    color: var(--on-accent-fg, #fff);
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-dflvh5cudg] {
        background-color: var(--accent-red-hover);
    }

    #components-reconnect-modal button:active[b-dflvh5cudg] {
        background-color: var(--accent-red);
    }

.components-rejoining-animation[b-dflvh5cudg] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-dflvh5cudg] {
        position: absolute;
        /* Match the brand-red ring used elsewhere in the app instead of
           Bootstrap blue. Theme-aware via the --accent-red token. */
        border: 3px solid var(--accent-red);
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-dflvh5cudg 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-dflvh5cudg] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-dflvh5cudg {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Pages/Cart.razor.rz.scp.css */
/* Scoped CSS for Cart.razor — Blazor's CSS isolation appends a b-* attribute
   to each selector here, so these rules only apply to elements rendered by
   Cart.razor. Generic classes used in other pages (.qty-group, .qty-btn,
   .qty-input, .skeleton) must stay in wwwroot/app.css so other pages still
   pick them up. */

/* ── Line items ── */
.cart-item-row[b-xq77px4vnr] { display: flex; align-items: center; gap: 1rem; padding: 1rem 1.25rem; border-bottom: 1px solid var(--border-color); }
.cart-item-row:last-child[b-xq77px4vnr] { border-bottom: none; }

/* Fixed square thumbnail wrapper. aspect-ratio:1 + width:80px gives an 80×80
   box regardless of the image's native ratio, so rows line up vertically and
   there's no layout shift as images load. The <img> fills it via
   object-fit:cover. The .cart-no-img placeholder inherits width/height:100%
   from its parent so both branches render identically. */
.cart-item-img[b-xq77px4vnr]      { flex-shrink: 0; width: 80px; aspect-ratio: 1 / 1; }
.cart-item-img img[b-xq77px4vnr]  { width: 100%; height: 100%; object-fit: cover; border-radius: 6px; display: block; }
.cart-no-img[b-xq77px4vnr]        { width: 100%; height: 100%; background-color: var(--bg-input); border-radius: 6px; display: flex; align-items: center; justify-content: center; color: var(--text-muted); font-size: 1.5rem; }
.cart-item-details[b-xq77px4vnr]  { flex: 1; min-width: 0; }
/* Variant axis label sits between the title and the unit price. Slightly
   smaller and dimmer than the title so it reads as metadata. Theme-aware
   color via var(--text-muted) so it works in both light and dark. */
.cart-variant-label[b-xq77px4vnr] {
    color: var(--text-muted);
    font-style: italic;
    margin-bottom: 0.125rem;
}
.cart-item-qty[b-xq77px4vnr]      { flex-shrink: 0; }
.cart-item-subtotal[b-xq77px4vnr] { flex-shrink: 0; text-align: right; min-width: 80px; }
.cart-item-remove[b-xq77px4vnr]   { flex-shrink: 0; }

@media (max-width: 576px) {
    .cart-item-row[b-xq77px4vnr] { flex-wrap: wrap; gap: 0.75rem; padding: 0.875rem 1rem; }
    .cart-item-details[b-xq77px4vnr] { flex: 1 1 calc(100% - 96px); }
    .cart-item-qty[b-xq77px4vnr], .cart-item-subtotal[b-xq77px4vnr], .cart-item-remove[b-xq77px4vnr] { flex: 0 0 auto; }
}

/* ── Toasts ── */
/* Undo toast shown right after a cart item is removed. */
.cart-undo-toast[b-xq77px4vnr] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    background-color: var(--bg-input);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    /* Logical property: border-inline-start auto-flips to the trailing edge
       under RTL, so the accent stripe always sits on the leading edge of the
       row regardless of writing direction. The dedicated [dir="rtl"] override
       below is now unnecessary but kept as a safety net for older browsers
       that don't support border-inline-* (Safari < 14.1, Edge legacy). */
    border-inline-start: 4px solid var(--accent-yellow);
    border-radius: 6px;
    padding: 0.625rem 1rem;
    margin-bottom: 1rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    animation: cart-undo-toast-in-b-xq77px4vnr 0.2s ease-out;
}
.cart-undo-btn[b-xq77px4vnr] {
    color: var(--accent-yellow);
    font-weight: 600;
    text-decoration: underline;
    padding: 0 0.5rem;
}
.cart-undo-btn:hover[b-xq77px4vnr], .cart-undo-btn:focus[b-xq77px4vnr] { color: var(--accent-yellow-hover); }

.cart-error-toast[b-xq77px4vnr] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    background-color: var(--bg-input);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    /* Same logical-property treatment as .cart-undo-toast above. */
    border-inline-start: 4px solid var(--validation-error);
    border-radius: 6px;
    padding: 0.625rem 1rem;
    margin-bottom: 1rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    animation: cart-undo-toast-in-b-xq77px4vnr 0.2s ease-out;
}
.cart-error-dismiss[b-xq77px4vnr] {
    color: var(--text-muted);
    font-weight: 600;
    text-decoration: underline;
    padding: 0 0.5rem;
}
.cart-error-dismiss:hover[b-xq77px4vnr], .cart-error-dismiss:focus[b-xq77px4vnr] { color: var(--text-primary); }

@keyframes cart-undo-toast-in-b-xq77px4vnr {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ── RTL adjustments ──────────────────────────────────────────────
   These overrides have to live in the scoped file (Cart.razor.css)
   because Blazor CSS isolation appends a [b-XXX] attribute to every
   selector here, raising specificity to (0,2,0). An unscoped
   `[dir="rtl"]` rule in app.css has the same specificity, but
   eshop.server.styles.css (the scoped bundle) loads AFTER app.css,
   so the unscoped rule loses on source order and silently does
   nothing. Keep the flips co-located with the rules they correct. */

/* The price column lives at the trailing edge of the row in LTR
   (right-aligned text inside a flex item that's last). Flexbox flips
   the items under RTL automatically, so `.cart-item-subtotal` ends up
   on the left of the row visually — but the cell's `text-align: right`
   keeps the number hugging the *inside* edge. Flip the alignment so
   the number hugs the row's outer edge in either direction. */
[dir="rtl"] .cart-item-subtotal[b-xq77px4vnr] { text-align: left; }

/* Undo / error toasts use a colour-coded accent stripe on the leading
   (left) edge in LTR. Move it to the trailing (right) edge under RTL
   so it stays on the same visual side as the text-start. */
[dir="rtl"] .cart-undo-toast[b-xq77px4vnr] {
    border-left: 1px solid var(--border-color);
    border-right: 4px solid var(--accent-yellow);
}
[dir="rtl"] .cart-error-toast[b-xq77px4vnr] {
    border-left: 1px solid var(--border-color);
    border-right: 4px solid var(--validation-error);
}

/* ── Summary card emphasis ── */
.cart-summary-total[b-xq77px4vnr] { font-size: 1.2rem; }

/* ── Empty-cart quick-shop chips ─────────────────────────────────────────────
   Replaces the dead-end "your cart is empty" view with a row of category
   chips so the user can pivot back into the catalog without leaving the
   card. Tappable chips honor the 44 px touch-target minimum on mobile. */
.cart-empty-quickshop[b-xq77px4vnr] {
    margin-top: 1.75rem;
    padding-top: 1.25rem;
    border-top: 1px dashed var(--border-color);
}
.cart-empty-quickshop-label[b-xq77px4vnr] {
    display: block;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 0.85rem;
}
.cart-empty-quickshop-chips[b-xq77px4vnr] {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem;
}
.cart-empty-chip[b-xq77px4vnr] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.55rem 1rem;
    background: var(--bg-input);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    border-radius: 999px;
    font-size: 0.875rem;
    font-weight: 500;
    text-decoration: none;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
    /* 44px minimum keeps hybrid-input devices (touchscreen laptops where
       pointer: coarse may not match) inside the WCAG 2.5.5 tap target
       spec, since this chip is the primary CTA on the empty-cart state. */
    min-height: 44px;
}
.cart-empty-chip i[b-xq77px4vnr] {
    color: var(--accent-yellow);
    font-size: 1rem;
}
.cart-empty-chip:hover[b-xq77px4vnr],
.cart-empty-chip:focus-visible[b-xq77px4vnr] {
    background: var(--bg-input-focus);
    border-color: rgba(var(--accent-yellow-rgb), 0.55);
    color: var(--text-primary);
    text-decoration: none;
    transform: translateY(-1px);
}
.cart-empty-chip:focus-visible[b-xq77px4vnr] {
    outline: 2px solid var(--accent-yellow);
    outline-offset: 2px;
}
@media (pointer: coarse) {
    .cart-empty-chip[b-xq77px4vnr] { padding: 0.6rem 1.05rem; }
}

/* Skeleton placeholder shape for the remove-button column — overrides the
   shared .sk-btn 100% width because the remove button is a 32×32 icon
   square, not a full-width control. Replaces an inline style attribute. */
.cart-skeleton-remove-btn[b-xq77px4vnr] { width: 32px; height: 32px; }
/* /Components/Pages/Contact.razor.rz.scp.css */
/* Scoped styles for Contact.razor.
   The .contact-info-icon class replaces the inline
   `style="font-size: 1.5rem; color: var(--accent-yellow);"` that was
   repeated on the address / phone / email rows. Pulled out so a future
   theme tweak (e.g. dialing the icon size for tablet, or a per-icon
   tint) only has to land in one place. */
.contact-info-icon[b-z0rw2emzq6] {
    font-size: 1.5rem;
    color: var(--accent-yellow);
}
/* /Components/Pages/Home.razor.rz.scp.css */
/* Scoped styles for Home.razor — slideshow only.
   The plain `.hero` block, its ::before accent, and child typography are
   intentionally NOT here: About.razor and Contact.razor also render
   <section class="hero">, and Blazor's scoped CSS would only attach the
   per-page attribute selector to elements rendered by Home.razor itself,
   so those other pages' heroes would render unstyled. The shared base
   stays in wwwroot/app.css; Home.razor adds the slideshow on top. */

/* ── Hero slideshow (Home only) ─────────────────────────────────────────────
   Admin-managed rotating background behind the welcome content. Layering
   (z-index): slides (0) ← scrim (1) ← content (2). Every slide lives at
   inset:0; only `.active` is currently visible. */
.hero-has-slides[b-3muzz0t73z]::before { display: none; }
.hero-slides[b-3muzz0t73z] {
    position: absolute; inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: hidden;
    border-radius: inherit;
}
.hero-slide[b-3muzz0t73z] {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 1200ms ease, filter 1200ms ease, transform 1200ms ease;
    will-change: opacity, filter, transform;
}
.hero-slide.active[b-3muzz0t73z] { opacity: 0.55; }

/* ── Effect: blur (default) ── */
.hero-slides[data-effect="blur"] .hero-slide[b-3muzz0t73z],
.hero-slides:not([data-effect]) .hero-slide[b-3muzz0t73z] {
    filter: blur(16px);
    transform: scale(1.04);
}
.hero-slides[data-effect="blur"] .hero-slide.active[b-3muzz0t73z],
.hero-slides:not([data-effect]) .hero-slide.active[b-3muzz0t73z] {
    filter: blur(0);
    transform: scale(1);
}

/* ── Effect: fade ── */
.hero-slides[data-effect="fade"] .hero-slide[b-3muzz0t73z] {
    filter: none;
    transform: none;
}

/* ── Effect: slide ── */
.hero-slides[data-effect="slide"] .hero-slide[b-3muzz0t73z] {
    transform: translateX(8%);
}
.hero-slides[data-effect="slide"] .hero-slide.active[b-3muzz0t73z] {
    transform: translateX(0);
}

/* ── Effect: zoom ── */
.hero-slides[data-effect="zoom"] .hero-slide[b-3muzz0t73z] {
    transform: scale(1.12);
}
.hero-slides[data-effect="zoom"] .hero-slide.active[b-3muzz0t73z] {
    transform: scale(1);
}

/* ── Effect: kenburns ── */
.hero-slides[data-effect="kenburns"] .hero-slide[b-3muzz0t73z] {
    transform: scale(1.08);
    transform-origin: 50% 50%;
}
.hero-slides[data-effect="kenburns"] .hero-slide.active[b-3muzz0t73z] {
    animation: heroKenBurns-b-3muzz0t73z 7000ms ease-in-out both;
}
@keyframes heroKenBurns-b-3muzz0t73z {
    0%   { transform: scale(1.08) translate(0%, 0%); }
    50%  { transform: scale(1.14) translate(-2%, 1.5%); }
    100% { transform: scale(1.08) translate(0%, 0%); }
}

.hero-scrim[b-3muzz0t73z] {
    position: absolute; inset: 0;
    z-index: 1;
    pointer-events: none;
    --scrim-intensity: 1;
    background:
        radial-gradient(
            ellipse at 50% 50%,
            rgba(0, 0, 0, calc(0.35 * var(--scrim-intensity))) 0%,
            rgba(0, 0, 0, calc(0.70 * var(--scrim-intensity))) 100%
        );
    border-radius: inherit;
}
.hero-content[b-3muzz0t73z] {
    position: relative;
    z-index: 2;
}

@media (prefers-reduced-motion: reduce) {
    .hero-slides .hero-slide[b-3muzz0t73z],
    .hero-slides[data-effect] .hero-slide[b-3muzz0t73z] {
        transition: opacity 200ms linear;
        filter: none;
        transform: none;
        animation: none;
    }
    .hero-slides .hero-slide.active[b-3muzz0t73z],
    .hero-slides[data-effect] .hero-slide.active[b-3muzz0t73z] {
        filter: none;
        transform: none;
        animation: none;
    }
}

/* ── Hero pill-shaped search ─────────────────────────────────────────────────
   Input + Search button are visually merged into one rounded surface so they
   read as a single affordance rather than two adjacent controls. The pill is
   capped at 560 px so it stays comfortable for one-line scanning on wide
   screens; padding scales down on phones. */
.hero-search[b-3muzz0t73z] {
    margin: 1.75rem auto 1.5rem;
    max-width: 560px;
}
.hero-search-pill[b-3muzz0t73z] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    background: rgba(255, 255, 255, 0.10);
    border: 1px solid rgba(255, 255, 255, 0.20);
    border-radius: 999px;
    padding: 0.4rem 0.4rem 0.4rem 1rem;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);
    transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}
.hero-search-pill:focus-within[b-3muzz0t73z] {
    border-color: var(--accent-yellow);
    background: rgba(255, 255, 255, 0.16);
    box-shadow: 0 0 0 3px rgba(var(--accent-yellow-rgb), 0.30);
}
.hero-search-icon[b-3muzz0t73z] {
    color: rgba(255, 255, 255, 0.70);
    font-size: 1rem;
    flex-shrink: 0;
}
.hero-search-input[b-3muzz0t73z] {
    flex: 1 1 auto;
    background: transparent;
    border: 0;
    color: #fff;
    font-size: 1rem;
    padding: 0.55rem 0.5rem;
    min-width: 0;
    outline: none;
    /* iOS Safari otherwise zooms the page on focus when the input is < 16 px */
    font-size: max(1rem, 16px);
}
.hero-search-input[b-3muzz0t73z]::placeholder { color: rgba(255, 255, 255, 0.55); }
.hero-search-input[b-3muzz0t73z]::-webkit-search-decoration,
.hero-search-input[b-3muzz0t73z]::-webkit-search-cancel-button { -webkit-appearance: none; }
.hero-search-btn[b-3muzz0t73z] {
    flex-shrink: 0;
    border: 0;
    border-radius: 999px;
    background: var(--accent-yellow);
    color: #000;
    font-weight: 600;
    padding: 0.55rem 1.4rem;
    font-size: 0.95rem;
    cursor: pointer;
    transition: background 0.15s ease, transform 0.12s ease;
}
.hero-search-btn:hover[b-3muzz0t73z] { background: var(--accent-yellow-hover); }
.hero-search-btn:active[b-3muzz0t73z] { transform: scale(0.97); }
.hero-search-btn:focus-visible[b-3muzz0t73z] {
    outline: 2px solid #fff;
    outline-offset: 2px;
}
@media (max-width: 480px) {
    .hero-search-pill[b-3muzz0t73z] { padding: 0.35rem 0.35rem 0.35rem 0.85rem; }
    .hero-search-btn[b-3muzz0t73z] { padding: 0.5rem 1.05rem; font-size: 0.9rem; }
    .hero-search-icon[b-3muzz0t73z] { display: none; }
}

/* Hero CTA tweak — slight letter-spacing makes the pill button match the
   search button's weight when they sit one above the other. */
.hero-shop-now[b-3muzz0t73z] {
    letter-spacing: 0.02em;
    padding-inline: 1.85rem;
}

/* Anchor offset — the fixed 56 px navbar would otherwise overlap the
   "Featured Products" heading when the user clicks Shop Now. */
.section-heading-anchored[b-3muzz0t73z] {
    scroll-margin-top: 80px;
}
/* /Components/Pages/ItemDetail.razor.rz.scp.css */
/* Scoped styles for ItemDetail.razor — review widgets and the .product-details
   panel. Gallery + related-products styles live in their own scoped sheets
   (ItemGallery.razor.css, ItemRelatedProducts.razor.css). */

/* Right-column container around the title/price/qty/add-to-cart block. */
.product-details[b-eu2vwha45b] {
    display: flex;
    flex-direction: column;
}

/* ── Reviews ── */
.review-stars-sm[b-eu2vwha45b] {
    display: inline-flex;
    gap: 2px;
    color: var(--accent-yellow);
    font-size: 0.9rem;
}
.review-stars-sm .bi-star[b-eu2vwha45b] { color: var(--text-muted); opacity: 0.5; }

.reviews-section[b-eu2vwha45b] { margin-top: 2rem; }

.review-form-card[b-eu2vwha45b] {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 1.25rem;
}

.star-picker[b-eu2vwha45b] {
    display: inline-flex;
    gap: 4px;
}

.star-btn[b-eu2vwha45b] {
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: 1.6rem;
    padding: 0 2px;
    line-height: 1;
    cursor: pointer;
    transition: color 0.15s ease, transform 0.1s ease;
}
.star-btn:hover[b-eu2vwha45b] { transform: scale(1.15); }
.star-btn.filled[b-eu2vwha45b] { color: var(--accent-yellow); }

.reviews-list[b-eu2vwha45b] { display: flex; flex-direction: column; gap: 0.875rem; }

.review-card[b-eu2vwha45b] {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 1rem 1.125rem;
}
.review-header[b-eu2vwha45b] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.4rem;
}
.review-stars[b-eu2vwha45b] { color: var(--accent-yellow); font-size: 0.95rem; }
.review-stars .bi-star[b-eu2vwha45b] { color: var(--text-muted); opacity: 0.5; }
.review-title[b-eu2vwha45b] {
    color: var(--text-primary);
    font-weight: 600;
    font-size: 0.95rem;
    margin: 0.15rem 0 0.25rem;
}
.review-text[b-eu2vwha45b] {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin: 0;
    line-height: 1.5;
    white-space: pre-line;
}

/* "No reviews yet" empty-state glyph — replaces an inline style. */
.reviews-empty-icon[b-eu2vwha45b] {
    font-size: 2rem;
    opacity: 0.3;
}

/* Stock-back subscribe card on the OOS branch. Sits in the same column
   as the OOS alert; visual weight intentionally lower so the alert
   stays the primary signal. */
.stock-back-card[b-eu2vwha45b] {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 0.875rem 1rem;
}
.stock-back-card h6[b-eu2vwha45b] { color: var(--text-primary); font-size: 0.95rem; }

/* "Product Details" extra-text panel (admin's free-form description block).
   Themed surface that respects light/dark instead of Bootstrap's hardcoded
   bg-secondary/border-secondary, which rendered an off-grey slab against the
   light theme's white card chrome. The text uses pre-line so admin line
   breaks are preserved while HTML is escaped. */
.item-detail-extra[b-eu2vwha45b] {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
}
.item-detail-extra .card-title[b-eu2vwha45b] {
    color: var(--text-primary);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.8rem;
    margin-bottom: 0.65rem;
    color: var(--text-muted);
}
.item-detail-extra-text[b-eu2vwha45b] {
    white-space: pre-line;
    color: var(--text-secondary);
    margin-bottom: 0;
    line-height: 1.6;
}

/* ── Mobile sticky buy bar ─────────────────────────────────────────────────
   Pinned to the bottom of the viewport on phones so the buy affordance is
   always one tap away even when the user has scrolled deep into the
   description / reviews / FBT block. Hidden on tablets and desktop where
   the primary in-column Add-to-Cart button is always visible alongside the
   product image. The page already pads the footer; we add extra body
   padding inside the same ≤767 px breakpoint so the bar doesn't sit on top
   of the closing footer.

   safe-area-inset-bottom honours the iPhone home-indicator gutter so the
   button text never sits under the indicator on devices that have one.
   The inset behaves as 0 on Android and older iOS so it's a no-op there. */
.mobile-buy-bar[b-eu2vwha45b] {
    display: none;
}
@media (max-width: 767.98px) {
    .mobile-buy-bar[b-eu2vwha45b] {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 1030;
        display: flex;
        align-items: center;
        gap: 0.5rem;
        padding: 0.55rem 0.85rem calc(0.55rem + env(safe-area-inset-bottom, 0px));
        background: var(--bg-card);
        border-top: 1px solid var(--border-color);
        box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.18);
    }
    /* Reserve space at the bottom of the page so the sticky bar never sits
       on top of the footer copyright row. The bar is ~64 px tall + safe-area;
       80 px gives the closing margin a visible gap above it. */
    :root .mobile-buy-bar ~ *[b-eu2vwha45b] { /* no-op selector — keeps this rule scoped */ }
}
.mobile-buy-bar-info[b-eu2vwha45b] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    line-height: 1.1;
    flex: 0 0 auto;
    min-width: 0;
}
.mobile-buy-bar-old[b-eu2vwha45b] {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-decoration: line-through;
}
.mobile-buy-bar-price[b-eu2vwha45b] {
    font-size: 1rem;
    font-weight: 700;
    color: var(--accent-yellow);
    white-space: nowrap;
}
.mobile-buy-bar-price.sale[b-eu2vwha45b] { color: var(--accent-red); }
.mobile-buy-bar-heart[b-eu2vwha45b] {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
}
.mobile-buy-bar-cta[b-eu2vwha45b] {
    flex: 1 1 auto;
    min-width: 0;
    /* min-height instead of fixed height — German "In den Warenkorb"
       wraps on a 360px viewport; nowrap+ellipsis silently truncated it
       to "In den Warenk…". Allow wrapping; keep the 44px touch target. */
    min-height: 44px;
    padding: 0.4rem 0.75rem;
    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1.15;
    white-space: normal;
    text-align: center;
}

/* Variant picker styles moved to ItemDetailParts/VariantPicker.razor.css
   when the picker was extracted — Blazor scoped CSS only matches markup
   rendered by THIS component, so leaving them here would silently
   un-style the extracted child. */

/* /Components/Pages/ItemDetailParts/ItemGallery.razor.rz.scp.css */
/* Scoped styles for ItemGallery — main image, thumbnails, and the
   placeholder shown when an item has no images at all. */
.gallery-main-wrap[b-lgrgwvvxbw] {
    position: relative;
    width: 100%;
    aspect-ratio: 1 / 1;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    overflow: hidden;
    cursor: zoom-in;
    display: flex;
    align-items: center;
    justify-content: center;
}
.gallery-main-img[b-lgrgwvvxbw] {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    transition: transform 0.3s ease;
}
.gallery-main-wrap:hover .gallery-main-img[b-lgrgwvvxbw] { transform: scale(1.04); }

.gallery-zoom-hint[b-lgrgwvvxbw] {
    position: absolute;
    bottom: 10px;
    right: 10px;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 0.75rem;
    padding: 4px 8px;
    border-radius: 4px;
    display: flex;
    align-items: center;
    gap: 4px;
    opacity: 0;
    transition: opacity 0.2s ease;
    pointer-events: none;
}
.gallery-main-wrap:hover .gallery-zoom-hint[b-lgrgwvvxbw] { opacity: 1; }

.gallery-thumbs[b-lgrgwvvxbw] {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 10px;
}
.gallery-thumb[b-lgrgwvvxbw] {
    width: 64px;
    height: 64px;
    border: 2px solid var(--border-color);
    border-radius: 6px;
    background: var(--bg-card);
    padding: 0;
    cursor: pointer;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: border-color 0.15s ease, transform 0.15s ease;
}
.gallery-thumb:hover[b-lgrgwvvxbw] { border-color: var(--text-muted); transform: translateY(-1px); }
.gallery-thumb.active[b-lgrgwvvxbw] {
    border-color: var(--accent-red);
    box-shadow: 0 0 0 2px rgba(var(--accent-red-rgb), 0.25);
}
.gallery-thumb img[b-lgrgwvvxbw] {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* Empty-image placeholder — used when item has no Image and no
   ItemImage rows. Square frame matching the gallery main wrap. */
.img-placeholder[b-lgrgwvvxbw] {
    width: 100%;
    aspect-ratio: 1 / 1;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    font-size: 4rem;
}
/* /Components/Pages/ItemDetailParts/ItemRelatedProducts.razor.rz.scp.css */
/* Scoped styles for ItemRelatedProducts. Only .related-grid is owned by
   this component; the inner .pcard-* classes are shared with the storefront
   listings (Items, Wishlist, RecentlyViewed) and stay in app.css.

   Blazor's ::deep selector reaches into descendant components — the .pcard
   children we render aren't scoped to this component, but the grid layout
   is, so we don't need ::deep here. */
.related-grid[b-l0w4gi8epw] { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; }
@media (max-width: 991px) { .related-grid[b-l0w4gi8epw] { grid-template-columns: repeat(2, 1fr); } }
/* Phones: one related product per row, same as the primary pcard grids.
   We drop the horizontal-scroll carousel so "related products" reads
   the same as a category listing — predictable and tap-friendly. */
@media (max-width: 575.98px) { .related-grid[b-l0w4gi8epw] { grid-template-columns: 1fr; gap: 1rem; } }
/* /Components/Pages/ItemDetailParts/VariantPicker.razor.rz.scp.css */
/* ── Variant picker ──
   Renders one block per axis (Color, Size, …). Chips are 48 px tall on
   every viewport so they comfortably exceed the WCAG 2.5.5 tap-target
   minimum (44×44) — touch users were complaining the previous 44 px
   chips felt cramped against the partner axis row. Theme tokens for
   surface + accent so the picker honours both light and dark themes —
   no hardcoded colors.

   Scoped CSS lives here (not in ItemDetail.razor.css) because Blazor's
   scoped-CSS attaches a per-component attribute selector to every rule;
   after the picker was extracted into VariantPicker.razor, the selectors
   in ItemDetail.razor.css stopped matching anything because they only
   carry the parent's scope attribute. The visible regression was the
   chips reverting to unstyled <button>s. Keeping the styles next to the
   component also means dropping VariantPicker into a different parent
   "just works" with no parent-css coupling. */
.variant-picker[b-bhn943rzym] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.variant-axis-header[b-bhn943rzym] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.variant-axis-label[b-bhn943rzym] {
    font-weight: 600;
    color: var(--text-secondary);
    font-size: 0.95rem;
}

.variant-axis-value[b-bhn943rzym] {
    color: var(--text-primary);
    font-weight: 500;
}

.variant-options[b-bhn943rzym] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.variant-chip[b-bhn943rzym] {
    position: relative;
    min-height: 48px;
    min-width: 56px;
    padding: 0.55rem 1rem;
    border-radius: 10px;
    border: 1.5px solid var(--border-color);
    background: var(--bg-input);
    color: var(--text-primary);
    font-size: 0.95rem;
    font-weight: 500;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
}

.variant-chip:hover[b-bhn943rzym] {
    border-color: var(--accent-yellow);
    background: rgba(var(--accent-yellow-rgb), 0.08);
}

.variant-chip:focus-visible[b-bhn943rzym] {
    outline: 2px solid var(--accent-yellow);
    outline-offset: 2px;
}

.variant-chip:active[b-bhn943rzym] {
    transform: scale(0.97);
}

.variant-chip.selected[b-bhn943rzym] {
    border-color: var(--accent-yellow);
    background: var(--accent-yellow);
    color: var(--bg-page);
    box-shadow: 0 0 0 2px rgba(var(--accent-yellow-rgb), 0.25);
}

/* Out-of-stock state. Strikethrough the label, drop opacity, AND show a
   small "OOS" pill so colour-blind users have a non-color signal. The
   chip stays clickable so picking it re-resolves the partner axis. */
.variant-chip.out[b-bhn943rzym] {
    opacity: 0.55;
    text-decoration: line-through;
    text-decoration-thickness: 1.5px;
}

.variant-chip.out.selected[b-bhn943rzym] {
    opacity: 0.7;
}

.variant-oos-pill[b-bhn943rzym] {
    display: inline-block;
    margin-inline-start: 0.25rem;
    padding: 1px 6px;
    border-radius: 999px;
    background: var(--accent-red, #dc3545);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-decoration: none;
    line-height: 1.2;
    /* Re-enable text-decoration: none on the pill so the .out parent's
       line-through doesn't strike the badge text too — looks broken. */
}
.variant-chip.out .variant-oos-pill[b-bhn943rzym] { text-decoration: none; }

/* Colour-axis swatch chips — the value renders as a circle followed by
   the label. The circle is the actual colour; we keep the label so
   accessible names + low-vision users don't lose information. */
.variant-options-swatches .variant-chip[b-bhn943rzym] {
    padding-inline-start: 0.6rem;
}

.variant-swatch[b-bhn943rzym] {
    display: inline-block;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    /* Theme-aware: see --swatch-border / --swatch-inset in app.css.
       Previously hardcoded rgba(0,0,0,.15) + rgba(255,255,255,.15);
       the border vanished in dark mode (black on near-black) and the
       inner sheen vanished in light mode (white on white). */
    border: 1.5px solid var(--swatch-border);
    box-shadow: inset 0 0 0 1px var(--swatch-inset);
    flex-shrink: 0;
}

.variant-chip.selected .variant-swatch[b-bhn943rzym] {
    border-color: var(--bg-page);
    box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.55);
}

.variant-chip-label[b-bhn943rzym] {
    line-height: 1.2;
}

.variant-pick-prompt[b-bhn943rzym] {
    display: inline-flex;
    align-items: center;
    padding: 6px 10px;
    border-radius: 8px;
    background: rgba(var(--accent-yellow-rgb), 0.08);
    border: 1px solid rgba(var(--accent-yellow-rgb), 0.25);
    font-weight: 500;
}
