/* ==========================================================================
   Storefront stylesheet
   --------------------------------------------------------------------------
   Self-contained: no Bootstrap, no CDN, no webfont request. The old storefront
   pulled Bootstrap 5 + Bootstrap Icons from cdnjs, swiffy-slider from jsDelivr
   (without SRI) and twelve Google Fonts weights, across eleven third-party
   origins. The markup here is semantic and BEM-named, so it needs none of that.

   The design tokens in :root are carried over verbatim from the metroshop theme
   (assets/metroshop/css/style-less.css) so the palette, spacing scale, radii and
   shadows match the live site exactly.
   ========================================================================== */

:root {
    /* Brand */
    --color-primary: #920F1F;
    --color-primary-light: #b11010;
    --color-primary-hover: #B2303F;

    /* Text */
    --color-text: #555;
    --color-text-dark: #333;
    --color-text-light: #aaa;
    --color-heading: #777;
    --color-link: #787878;
    --color-link-hover: #323232;

    /* Accents */
    --color-bg: #fff;
    --color-price: #f75353;
    --color-rating: #f0c808;
    --color-notification: #ff6a00;

    /* Surfaces */
    --color-footer-bg: #1a1a2e;
    --color-surface: #f8f9fa;
    --color-border: #e9ecef;
    --color-border-light: #f1f3f5;

    /* Spacing scale */
    --spacing-xs: 4px;
    --spacing-sm: 8px;
    --spacing-md: 16px;
    --spacing-lg: 24px;
    --spacing-xl: 32px;
    --spacing-2xl: 48px;

    /* Border radius */
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --radius-full: 9999px;

    /* Layered shadows */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 3px rgba(0, 0, 0, .08);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, .04), 0 10px 20px rgba(0, 0, 0, .06);
    --shadow-hover: 0 8px 30px rgba(146, 15, 31, .10), 0 4px 12px rgba(0, 0, 0, .06);

    /* Font weights */
    --fw-normal: 400;
    --fw-medium: 500;
    --fw-semibold: 600;
    --fw-bold: 700;

    --transition-fast: .2s ease-in-out;

    /* Layout */
    --page-max-width: 1280px;
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    /* The same stack the metroshop theme declares, resolved locally instead of
       fetching twelve Google Fonts weights. */
    font-family: "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif;
    font-size: 16px;
    line-height: 1.65;
    color: var(--color-text);
    background-color: var(--color-bg);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
    margin: 0 0 var(--spacing-md);
    font-weight: var(--fw-semibold);
    color: var(--color-text-dark);
    line-height: 1.3;
}

h1 { font-size: 1.75rem; }
h2 { font-size: 1.375rem; }
h3 { font-size: 1.125rem; }

p {
    margin: 0 0 var(--spacing-md);
}

a {
    color: var(--color-text-dark);
    text-decoration: none;
    transition: color var(--transition-fast);
}

a:hover {
    color: var(--color-primary);
}

img {
    max-width: 100%;
    height: auto;
}

/* Both list types, not just ul. Breadcrumbs are an <ol> (an ordered trail is what they are), and with
   only ul reset they kept list-style: decimal and padding-left: 40px. In a flex row each marker is
   painted outside its item's box, so "2." and "3." landed on top of the tail of the preceding crumb.
   CMS-authored lists opt markers back in via `.cms-content ul, .cms-content ol { list-style: revert }`. */
ul,
ol {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Visible keyboard focus, matching the theme's focus ring. */
:focus-visible {
    outline: 2px solid rgba(146, 15, 31, .45);
    outline-offset: 2px;
}

button {
    font: inherit;
    cursor: pointer;
}

input,
select {
    font: inherit;
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: #fff;
    color: var(--color-text-dark);
    transition: border-color var(--transition-fast);
}

input:focus,
select:focus {
    border-color: var(--color-primary-light);
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: var(--spacing-sm) var(--spacing-md);
    background: var(--color-primary);
    color: #fff;
    border-radius: 0 0 var(--radius-sm) 0;
}

.skip-link:focus {
    left: 0;
    color: #fff;
}

#main-content {
    max-width: var(--page-max-width);
    margin: 0 auto;
    padding: var(--spacing-lg) var(--spacing-md) var(--spacing-2xl);
}

/* --------------------------------------------------------------------------
   Header and navigation
   -------------------------------------------------------------------------- */

/* Two tiers: a light utility bar, then the dark red navigation band. Values are taken from the
   live site so the two storefronts are visually interchangeable during the route-by-route cutover. */

.site-header {
    background: var(--color-bg);
}

.header-top {
    background: var(--color-surface);
    font-size: .875rem;
}

.header-top__inner,
.site-nav__inner,
.site-search__form {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    max-width: var(--page-max-width);
    margin: 0 auto;
    padding: 0 var(--spacing-md);
}

/* Required for the mobile menu: the collapsed list carries flex-basis: 100% to claim its own row,
   which nowrap silently ignores — the list then squeezed into the leftover space as a narrow column
   pinned to the right of the bar instead of opening as a full-width panel underneath it. */
.site-nav__inner {
    flex-wrap: wrap;
}

.header-top__brand {
    padding: var(--spacing-sm) 0;
    color: var(--color-primary-light);
    font-size: .875rem;
    font-weight: var(--fw-bold);
}

.header-top__actions {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
    margin-left: auto;
}

.header-top__action {
    padding: var(--spacing-sm) var(--spacing-md);
    color: var(--color-text-dark);
}

/* The sign-out control is a <button> because signing out is a POST, but it sits beside the links so
   it has to read as one. */
.header-top__action--button {
    border: 0;
    background: transparent;
    font: inherit;
}

.header-top__action--button:hover {
    color: var(--color-primary);
}

.mini-cart {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
    padding: var(--spacing-sm) var(--spacing-md);
    color: var(--color-text-dark);
    white-space: nowrap;
}

.mini-cart__icon {
    width: 1em;
    height: 1em;
}

/* The badge stays visible at zero, matching the live header, so the control never reflows. */
.mini-cart__count {
    min-width: 1.5em;
    padding: 2px 7px;
    border-radius: var(--radius-full);
    background: var(--color-notification);
    color: #fff;
    font-size: .75rem;
    font-weight: var(--fw-semibold);
    line-height: 1.4;
    text-align: center;
}

.site-nav {
    background: var(--color-primary);
    box-shadow: var(--shadow-sm);
}

.site-nav__inner {
    padding-top: var(--spacing-sm);
    padding-bottom: var(--spacing-sm);
    /* Positioning context for the full-width brands panel; see .site-nav__item--mega. */
    position: relative;
}

.site-nav__brand img {
    display: block;
    width: 52px;
    height: 52px;
    border-radius: var(--radius-full);
}

/* Shown only where the menu collapses; see the narrow-viewport block below. */
.site-nav__toggle {
    display: none;
    margin-left: auto;
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid rgba(255, 255, 255, .5);
    border-radius: var(--radius-sm);
    background: transparent;
    color: #fff;
    font-weight: var(--fw-semibold);
}

.site-nav__list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
}

.site-nav__item {
    position: relative;
}

.site-nav__item > a,
.site-nav__button {
    display: block;
    padding: var(--spacing-sm) var(--spacing-md);
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: #fff;
    font-size: 1rem;
    font-weight: var(--fw-medium);
    white-space: nowrap;
    transition: background var(--transition-fast), color var(--transition-fast);
}

.site-nav__item > a:hover,
.site-nav__button:hover {
    background: var(--color-primary-light);
    color: #fff;
}

/* The open tab inverts to the panel colour so the dropdown reads as attached to it. */
.site-nav__button[aria-expanded="true"] {
    background: #fff;
    color: var(--color-primary);
}

.site-nav__button::after {
    content: "";
    display: inline-block;
    margin-left: var(--spacing-xs);
    border: 4px solid transparent;
    border-top-color: currentColor;
    vertical-align: middle;
}

/* Grid rather than CSS `columns`. A multi-column box with a max-height flows its overflow into
   further columns sideways instead of scrolling, which gave the brands panel a horizontal
   scrollbar; grid has no such behaviour, so the max-height below is a safety valve that actually
   scrolls vertically on a short screen. */
.site-nav__sublist {
    display: none;
    /* Column minimum sized to the longest category names ("Dầu gội- xả, thuốc nhuộm, dưỡng tóc"),
       so entries stay on one line. auto-fit then takes as many columns as the width allows. */
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 0 var(--spacing-sm);
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 20;
    max-height: 80vh;
    overflow-y: auto;
    padding: 10px;
    background: #fff;
    border-radius: var(--radius-md);
    box-shadow: 0 10px 25px rgba(0, 0, 0, .06), 0 20px 48px rgba(0, 0, 0, .06);
}

/* Panels anchor to the nav bar rather than to their own item, so they all open at the same height
   and span the bar's width. Anchored to its own item, a wide panel ran off the right of the screen
   whenever that item sat well along the bar. */
.site-nav__item--mega {
    position: static;
}

.site-nav__item--mega > .site-nav__sublist {
    left: var(--spacing-md);
    right: var(--spacing-md);
}

/* Bridges the dead zone between the button and the panel.
   Anchoring the panel to the nav row rather than to its own item means it opens below the row's
   bottom padding, leaving ~13px inside the red band that belongs to neither the button nor the
   panel. Crossing that strip dropped :hover and the menu vanished mid-reach. This transparent strip
   is a child of the button, so the pointer stays inside the item the whole way down.
   Kept to the button's own width so it never covers the neighbouring menu entries. */
.site-nav__item--mega > .site-nav__button {
    position: relative;
}

.site-nav__item--mega > .site-nav__button::before {
    content: "";
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    height: var(--spacing-md);
}

/* Brand names are shorter than category names, so this panel packs tighter — but not below the
   width of the longest of them ("Yves Saint Laurent", "Bath & Body Works"), which wrapped to two
   lines at 175px once the bar narrowed to the 992px breakpoint. */
.site-nav__sublist--wide {
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
}

/* Click/touch opening. JS keeps aria-expanded in step; this is the only rule that reveals a
   dropdown on a touch device, where :hover never fires. */
.site-nav__button[aria-expanded="true"] + .site-nav__sublist {
    display: grid;
}

.site-nav__sublist a {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
    padding: var(--spacing-sm) var(--spacing-md);
    border-radius: var(--radius-sm);
    color: var(--color-text-dark);
}

.site-nav__sublist a:hover {
    background: var(--color-surface);
    color: var(--color-primary);
}

/* The small outlined arrow that spins on hover - the detail that gives the live menu its character. */
.site-nav__bullet {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    border: 1px solid #ccc;
    border-radius: var(--radius-full);
    line-height: 18px;
    text-align: center;
    font-size: 10px;
    transition: transform .3s linear, border-color var(--transition-fast);
}

.site-nav__bullet::before {
    content: "\2192";
}

.site-nav__sublist a:hover .site-nav__bullet {
    transform: rotate(-360deg);
    border-color: var(--color-primary);
}

.site-nav__search-toggle {
    display: flex;
    align-items: center;
    margin-left: auto;
    padding: var(--spacing-sm) var(--spacing-md);
    border: 0;
    background: transparent;
    color: #fff;
}

.site-nav__search-toggle svg {
    width: 1.125rem;
    height: 1.125rem;
}

.site-search {
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
}

.site-search__form {
    gap: var(--spacing-sm);
    padding-top: var(--spacing-sm);
    padding-bottom: var(--spacing-sm);
}

.site-search__form input {
    flex: 1;
    border-radius: var(--radius-full);
}

.site-search__form button {
    padding: var(--spacing-sm) var(--spacing-lg);
    border: 0;
    border-radius: var(--radius-full);
    background: var(--color-primary);
    color: #fff;
    font-weight: var(--fw-medium);
}

/* Pointer devices get the familiar hover-open in addition to click. Guarded by a media query so it
   never applies on touch, where a hover rule would otherwise require two taps to follow a link. */
/* Also gated on the expanded breakpoint: below it the menu is a collapsed panel, where a hover-open
   dropdown fights the click-to-open one. */
@media (min-width: 992px) and (hover: hover) and (pointer: fine) {
    .site-nav__item--has-menu:hover .site-nav__sublist,
    .site-nav__item--has-menu:focus-within .site-nav__sublist {
        display: grid;
    }

    .site-nav__item--has-menu:hover .site-nav__button {
        background: #fff;
        color: var(--color-primary);
    }
}

/* Collapses below 992px, matching the live site's navbar-expand-lg. At 768px the expanded menu
   wrapped onto three rows with the search icon stranded on its own. */
@media (max-width: 991px) {
    /* Logo, search, then MENU on the right — the live mobile bar's order. */
    .site-nav__brand {
        order: 1;
    }

    .site-nav__search-toggle {
        order: 2;
        margin-left: 0;
        padding: var(--spacing-sm);
    }

    /* Plain white text like the live site, not a bordered box. A heavy outlined button next to a
       logo is most of what made this bar look wrong on a phone. */
    .site-nav__toggle {
        display: block;
        order: 3;
        margin-left: auto;
        padding: var(--spacing-sm);
        border: 0;
        font-size: 1rem;
        font-weight: var(--fw-normal);
        letter-spacing: .04em;
    }

    .site-nav__list {
        display: none;
        order: 4;
        flex-basis: 100%;
        flex-direction: column;
        align-items: stretch;
        margin-top: var(--spacing-sm);
        padding-bottom: var(--spacing-sm);
        border-top: 1px solid rgba(255, 255, 255, .2);
    }

    .site-nav__toggle[aria-expanded="true"] ~ .site-nav__list {
        display: flex;
    }

    /* Full-width rows, so the whole strip is the tap target rather than just the label. */
    .site-nav__item > a,
    .site-nav__button {
        width: 100%;
        padding: var(--spacing-md);
        border-radius: 0;
        text-align: left;
    }

    /* The open dropdown reads as a nested list here, not as a detached white card. */
    .site-nav__button[aria-expanded="true"] {
        background: rgba(255, 255, 255, .12);
        color: #fff;
    }

    /* In the collapsed menu a floating panel has nothing to float over, so submenus join the flow,
       and there is no width for a second column. */
    .site-nav__sublist,
    .site-nav__sublist--wide {
        grid-template-columns: 1fr;
        position: static;
        min-width: 0;
        max-height: 60vh;
        padding: 0;
        overflow-x: hidden;
        border-radius: 0;
        background: rgba(0, 0, 0, .12);
        box-shadow: none;
    }

    .site-nav__sublist a {
        padding: var(--spacing-sm) var(--spacing-md) var(--spacing-sm) var(--spacing-xl);
        border-radius: 0;
        color: #fff;
    }

    .site-nav__sublist a:hover {
        background: rgba(255, 255, 255, .12);
        color: #fff;
    }

    .site-nav__bullet {
        border-color: rgba(255, 255, 255, .5);
    }

    .header-top__brand {
        font-size: .8125rem;
    }

    .header-top__action,
    .mini-cart {
        padding: var(--spacing-sm);
    }
}



/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

/* Dark navy panel with a red hairline on top, as on the live site. */
.site-footer {
    border-top: 2px solid var(--color-primary-light);
    background: var(--color-footer-bg);
    color: rgba(255, 255, 255, .8);
    font-size: .875rem;
}

.site-footer__inner {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--spacing-xl);
    max-width: var(--page-max-width);
    margin: 0 auto;
    padding: 40px var(--spacing-md) var(--spacing-lg);
}

.site-footer__heading {
    margin-bottom: var(--spacing-md);
    padding-bottom: var(--spacing-sm);
    border-bottom: 1px solid rgba(255, 255, 255, .15);
    font-size: .8rem;
    font-weight: var(--fw-semibold);
    color: #fff;
}

.site-footer__list li + li {
    margin-top: var(--spacing-sm);
}

.site-footer__list a {
    color: rgba(255, 255, 255, .7);
    line-height: 1.7;
}

.site-footer__list a:hover {
    color: #fff;
}

.site-footer__list--inline {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-md);
}

.site-footer__list--inline li + li {
    margin-top: 0;
}

/* The shop's pages and the customer's own shortcuts, side by side under one heading — the shape the
   old footer used. Collapses to one list where the column is too narrow to split. */
.site-footer__split {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: var(--spacing-sm) var(--spacing-md);
}

/* Rows of logos: social profiles, app store badges. */
.site-footer__badges {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-lg);
}

.site-footer__badges img {
    display: block;
    width: auto;
    max-height: 42px;
    /* These are full-colour logos on a dark footer, so they are dimmed until pointed at rather than
       left shouting over the text around them. */
    opacity: .85;
    transition: opacity var(--transition-fast), transform var(--transition-fast);
}

.site-footer__badges a:hover img {
    opacity: 1;
    transform: translateY(-2px);
}

/* Store badges carry their own wordmark and are read, not just recognised, so they sit a little
   larger than the social icons — the size the old footer gave them. */
.site-footer__badges--large img {
    max-height: 48px;
}

/* The Ministry of Industry and Trade mark is supplied as artwork on white, so it keeps its own
   background rather than being dimmed into the dark footer. */
.site-footer__registration {
    display: inline-block;
    margin-top: var(--spacing-md);
}

.site-footer__registration img {
    display: block;
    width: auto;
    max-height: 48px;
}

.site-footer__copyright {
    max-width: var(--page-max-width);
    margin: 0 auto;
    padding: var(--spacing-md);
    border-top: 1px solid rgba(255, 255, 255, .12);
    font-size: .8125rem;
    color: rgba(255, 255, 255, .6);
    text-align: center;
}

/* --------------------------------------------------------------------------
   Reasons to buy, contact rail, back to top
   -------------------------------------------------------------------------- */

.promises {
    max-width: var(--page-max-width);
    margin: var(--spacing-2xl) auto 0;
    padding: var(--spacing-xl) var(--spacing-md);
    border-top: 1px solid var(--color-border);
}

.promises__title {
    margin: 0 0 var(--spacing-lg);
    color: var(--color-text);
    font-size: 1.125rem;
    font-weight: var(--fw-semibold);
    text-align: center;
}

.promises__list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--spacing-md);
}

.promises__item {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    padding: var(--spacing-md) var(--spacing-lg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: #fff;
}

.promises__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 48px;
    height: 48px;
    border-radius: var(--radius-full);
    background: rgba(146, 15, 31, .06);
    color: var(--color-primary);
}

.promises__icon svg {
    width: 24px;
    height: 24px;
}

.promises__headline {
    display: block;
    color: var(--color-text-dark);
    font-size: 1rem;
}

.promises__detail {
    display: block;
    margin-top: 2px;
    color: var(--color-text-light);
    font-size: .8125rem;
    line-height: 1.5;
}

/* The rail sits against the right edge, vertically centred. Hidden on narrow screens, where it would
   cover the content it floats over. */
.contact-rail {
    position: fixed;
    top: 50%;
    right: 0;
    z-index: 30;
    display: none;
    flex-direction: column;
    align-items: center;
    gap: var(--spacing-xs);
    padding: var(--spacing-xs);
    border: 1px solid var(--color-border);
    border-right: 0;
    border-radius: var(--radius-md) 0 0 var(--radius-md);
    background: #fff;
    box-shadow: var(--shadow-md);
    transform: translateY(-50%);
}

@media (min-width: 576px) {
    .contact-rail {
        display: flex;
    }
}

.contact-rail__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-full);
    background: none;
    color: var(--color-text-light);
    cursor: pointer;
    transition: color var(--transition-fast), transform var(--transition-fast);
}

.contact-rail__toggle svg {
    width: 14px;
    height: 14px;
}

.contact-rail__toggle:hover {
    color: var(--color-primary);
}

/* Collapsed, the cross becomes a plus and the links fold away. */
.contact-rail.is-collapsed .contact-rail__toggle {
    transform: rotate(45deg);
}

.contact-rail.is-collapsed .contact-rail__links {
    display: none;
}

.contact-rail__links {
    display: grid;
    gap: var(--spacing-xs);
}

.contact-rail__link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-full);
    background: var(--color-surface);
    color: var(--color-text-dark);
    transition: background var(--transition-fast), transform var(--transition-fast);
}

.contact-rail__link:hover {
    background: rgba(146, 15, 31, .08);
    transform: translateX(-2px);
}

.contact-rail__link svg {
    width: 18px;
    height: 18px;
}

.contact-rail__link--phone {
    background: var(--color-primary);
    color: #fff;
}

.contact-rail__link--phone:hover {
    background: var(--color-primary-hover);
}

.contact-rail__link img {
    width: 24px;
    height: 24px;
    object-fit: contain;
}

/* Bottom-right, clear of the rail above it. */
.to-top {
    position: fixed;
    right: var(--spacing-md);
    bottom: var(--spacing-md);
    z-index: 30;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    background: #fff;
    color: var(--color-text-dark);
    box-shadow: var(--shadow-md);
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast),
                transform var(--transition-fast);
}

/* [hidden] alone loses to the display above, so the button would never actually hide. */
.to-top[hidden] {
    display: none;
}

.to-top:hover {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
    transform: translateY(-2px);
}

.to-top svg {
    width: 20px;
    height: 20px;
}

/* --------------------------------------------------------------------------
   Breadcrumbs
   -------------------------------------------------------------------------- */

.breadcrumbs {
    margin-bottom: var(--spacing-md);
    font-size: .875rem;
    color: #666;
}

.breadcrumbs__list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
}

.breadcrumbs__list li + li::before {
    content: "›";
    margin-right: var(--spacing-sm);
    color: var(--color-text-light);
}

.breadcrumbs__list a {
    color: #666;
}

.breadcrumbs__list a:hover {
    color: #000;
}

/* --------------------------------------------------------------------------
   Banner carousel
   -------------------------------------------------------------------------- */

.banner {
    position: relative;
    margin-bottom: var(--spacing-xl);
    border-radius: var(--radius-md);
    overflow: hidden;
}

/* A native scroll-snap strip, so the banner is swipeable and readable with JavaScript off.
   banner.js only layers arrows, dots and autoplay on top. */
.banner__track {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
}

.banner__track::-webkit-scrollbar {
    display: none;
}

.banner__slide {
    flex: 0 0 100%;
    scroll-snap-align: start;
}

.banner__image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.banner__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 0;
    border-radius: var(--radius-full);
    background: rgba(255, 255, 255, .85);
    color: var(--color-text-dark);
    opacity: 0;
    transition: opacity var(--transition-fast), background var(--transition-fast);
}

/* Arrows stay hidden until the banner is hovered or focused, as on the live site, so they do not
   sit on top of the artwork the whole time. Keyboard users get them via :focus-visible. */
.banner:hover .banner__nav,
.banner:focus-within .banner__nav {
    opacity: 1;
}

.banner__nav:hover {
    background: #fff;
}

.banner__nav--prev {
    left: var(--spacing-md);
}

.banner__nav--next {
    right: var(--spacing-md);
}

.banner__nav::before {
    content: "";
    width: 10px;
    height: 10px;
    border-top: 2px solid currentColor;
    border-right: 2px solid currentColor;
}

.banner__nav--prev::before {
    transform: rotate(-135deg);
    margin-left: 4px;
}

.banner__nav--next::before {
    transform: rotate(45deg);
    margin-right: 4px;
}

.banner__dots {
    position: absolute;
    left: 50%;
    bottom: var(--spacing-md);
    transform: translateX(-50%);
    display: flex;
    gap: var(--spacing-sm);
}

.banner__dot {
    width: 10px;
    height: 10px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-full);
    background: rgba(255, 255, 255, .6);
    transition: background var(--transition-fast), transform var(--transition-fast);
}

.banner__dot.is-current {
    background: #fff;
    transform: scale(1.3);
}

/* Touch devices have no hover, so the arrows would never appear; the strip is swipeable instead. */
@media (hover: none) {
    .banner__nav {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .banner__track {
        scroll-behavior: auto;
    }
}

/* --------------------------------------------------------------------------
   Product card
   -------------------------------------------------------------------------- */

.listing__grid,
.collection-teaser__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: var(--spacing-lg);
    margin-bottom: var(--spacing-xl);
}

/* Two columns on a phone, as the live grid does. auto-fill with a 200px minimum collapses to a
   single very wide card below ~430px, which spends the whole screen on one product. This must stay
   after the rule above: a media query adds no specificity, so ordering is what decides. */
@media (max-width: 575px) {
    .listing__grid,
    .collection-teaser__grid {
        grid-template-columns: repeat(2, 1fr);
        gap: var(--spacing-md);
    }
}

.listing__count {
    color: var(--color-text-light);
    font-size: .875rem;
}

.listing__empty,
.reviews__empty {
    padding: var(--spacing-2xl) 0;
    text-align: center;
    color: var(--color-text-light);
}

/* Matches the live site's sale-item: a flat white tile, the discount flag pinned to the image, and
   price and rating centred beneath the title. No border and no resting shadow - the live cards sit
   directly on the page background. */

.product-card {
    position: relative;
    padding: var(--spacing-md);
    border-radius: var(--radius-md);
    background: #fff;
    transition: box-shadow var(--transition-fast), transform var(--transition-fast);
}

.product-card:hover {
    box-shadow: var(--shadow-hover);
    transform: translateY(-2px);
}

.product-card__flag {
    position: absolute;
    top: var(--spacing-sm);
    left: var(--spacing-sm);
    z-index: 1;
    padding: 3px 8px;
    border-radius: var(--radius-sm);
    background: linear-gradient(135deg, #e63946, #d62828);
    color: #fff;
    font-size: .6875rem;
    font-weight: var(--fw-semibold);
    line-height: 1.4;
}

.product-card__link {
    display: block;
}

.product-card__image {
    display: block;
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    border-radius: var(--radius-sm);
}

.product-card__title {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin: var(--spacing-sm) 0 var(--spacing-xs);
    color: #000;
    font-size: .875rem;
    font-weight: var(--fw-medium);
    line-height: 1.7;
}

.product-card__title:hover {
    color: var(--color-primary);
}

.product-card__price {
    margin: 0;
    text-align: center;
    font-size: .875rem;
}

.product-card__price--now {
    color: var(--color-primary);
    font-weight: var(--fw-semibold);
}

.product-card__price--was {
    margin-right: var(--spacing-xs);
    color: var(--color-text-dark);
    font-weight: var(--fw-normal);
    text-decoration: line-through;
}

/* The live site sets the currency mark as a superscript rather than inline. */
.product-card__price sup {
    font-size: .75em;
}

/* Time-limited offers: what you save, and how long is left. Two halves of one strip, as the old
   card had, so the pair reads as a single claim rather than two stray labels. */
.product-card__deal {
    display: grid;
    grid-template-columns: 1fr 1fr;
    margin: var(--spacing-sm) var(--spacing-sm) 0;
    border: 1px solid rgba(146, 15, 31, .18);
    border-radius: var(--radius-sm);
    background: rgba(146, 15, 31, .04);
    overflow: hidden;
    text-align: center;
}

.product-card__deal-part {
    padding: var(--spacing-xs) var(--spacing-xs);
}

/* The divider belongs between the halves only, so it is drawn on the second one. */
.product-card__deal-part + .product-card__deal-part {
    border-left: 1px solid rgba(146, 15, 31, .18);
}

.product-card__deal-label {
    display: block;
    color: var(--color-text-light);
    font-size: .6875rem;
    line-height: 1.4;
}

.product-card__deal-value {
    display: block;
    color: var(--color-primary);
    font-size: .875rem;
    font-weight: var(--fw-bold);
    /* The countdown changes width as it counts down; tabular figures stop the card twitching. */
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.product-card__rating {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-xs);
    margin: var(--spacing-xs) 0 0;
    font-size: .8125rem;
}

.product-card__star {
    color: var(--color-border);
    letter-spacing: -1px;
}

.product-card__star.is-filled {
    color: var(--color-rating);
}

.product-card__rating-count {
    color: var(--color-text-light);
}

.product-card__offer,
.product-card__stock {
    margin: var(--spacing-xs) 0 0;
    text-align: center;
    font-size: .8125rem;
}

.product-card__offer {
    color: var(--color-notification);
}

.product-card__stock {
    color: var(--color-text-light);
}


/* --------------------------------------------------------------------------
   Pagination
   -------------------------------------------------------------------------- */

.pagination__list {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--spacing-xs);
    margin: var(--spacing-xl) 0;
}

.pagination__list a,
.pagination__list span {
    display: block;
    min-width: 40px;
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    text-align: center;
    color: var(--color-text);
}

.pagination__list a:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.pagination__list [aria-current="page"] {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
    font-weight: var(--fw-semibold);
}

/* --------------------------------------------------------------------------
   Collection teaser
   -------------------------------------------------------------------------- */

.collection-teaser {
    margin-bottom: var(--spacing-2xl);
}

/* The live site's section heading: muted grey, understated, separated by a hairline rather than a
   heavy brand-coloured rule. The products are meant to carry the colour, not the heading. */
.collection-teaser__title {
    margin: 0 0 var(--spacing-sm);
    padding: 0 0 var(--spacing-md);
    border-bottom: 2px solid var(--color-border);
    color: var(--color-text);
    font-size: 1.125rem;
    font-weight: var(--fw-semibold);
}

.collection-teaser__title a {
    color: var(--color-text);
}

.collection-teaser__title a:hover {
    color: var(--color-primary);
}

/* --------------------------------------------------------------------------
   Category showcase ("Phân loại")
   -------------------------------------------------------------------------- */

.category-showcase {
    margin-bottom: var(--spacing-2xl);
}

/* Matches the collection strips either side of it, so the home page reads as one column of sections
   rather than three unrelated blocks. */
.category-showcase__title {
    margin: 0 0 var(--spacing-md);
    padding: 0 0 var(--spacing-md);
    border-bottom: 2px solid var(--color-border);
    color: var(--color-text);
    font-size: 1.125rem;
    font-weight: var(--fw-semibold);
}

/* auto-fill, not auto-fit: with only a few categories the cards keep their size and sit left, rather
   than each stretching across a third of the page. */
.category-showcase__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: var(--spacing-md);
}

.category-showcase__card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--spacing-sm);
    height: 100%;
    padding: var(--spacing-md) var(--spacing-sm);
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-text-dark);
    text-align: center;
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast),
                transform var(--transition-fast);
}

.category-showcase__card:hover {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-hover);
    transform: translateY(-2px);
    color: var(--color-primary);
}

.category-showcase__image {
    width: 96px;
    height: 96px;
    /* Category pictures are not all the same shape; contain keeps them whole rather than cropping a
       product out of its own thumbnail. */
    object-fit: contain;
}

.category-showcase__name {
    font-size: .8125rem;
    font-weight: var(--fw-medium);
    line-height: 1.4;
}

@media (max-width: 575px) {
    .category-showcase__grid {
        grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
        gap: var(--spacing-sm);
    }

    .category-showcase__image {
        width: 72px;
        height: 72px;
    }
}

/* --------------------------------------------------------------------------
   Product detail
   -------------------------------------------------------------------------- */

.product {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--spacing-xl);
    margin-bottom: var(--spacing-2xl);
}

@media (min-width: 768px) {
    .product {
        grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    }

    /* The description spans both columns beneath the gallery and buy panel. */
    .product__description {
        grid-column: 1 / -1;
    }
}

.product__title {
    font-size: 1.5rem;
}

.gallery__main img {
    width: 100%;
    aspect-ratio: 1;
    object-fit: contain;
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.gallery__thumbs {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
    gap: var(--spacing-sm);
    margin-top: var(--spacing-sm);
}

.gallery__thumb {
    display: block;
    width: 100%;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: #fff;
    overflow: hidden;
    transition: border-color var(--transition-fast);
}

.gallery__thumb:hover {
    border-color: var(--color-primary);
}

.gallery__thumb img {
    display: block;
    width: 100%;
    aspect-ratio: 1;
    object-fit: contain;
}

.product__variants,
.product__buy,
.product__notify {
    margin-bottom: var(--spacing-lg);
}

.product__variants label,
.product__buy label,
.product__notify label {
    display: block;
    margin-bottom: var(--spacing-sm);
    font-weight: var(--fw-medium);
    color: var(--color-text-dark);
}

.product__variants select {
    width: 100%;
    max-width: 320px;
}

.product__buy,
.product__notify {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--spacing-sm);
    padding: var(--spacing-lg);
    background: var(--color-surface);
    border-radius: var(--radius-md);
}

.product__buy label,
.product__notify label {
    flex-basis: 100%;
    margin-bottom: 0;
}

.product__buy input[type="number"] {
    width: 90px;
}

.product__notify input[type="email"] {
    flex: 1 1 220px;
}

.product__buy button,
.product__notify button {
    padding: var(--spacing-sm) var(--spacing-xl);
    border: 0;
    border-radius: var(--radius-sm);
    background: var(--color-primary);
    color: #fff;
    font-weight: var(--fw-semibold);
    transition: background var(--transition-fast);
}

.product__buy button:hover,
.product__notify button:hover {
    background: var(--color-primary-hover);
}

.product__likes {
    color: var(--color-text-light);
    font-size: .875rem;
}

/* Confirmation or failure after adding to the cart, announced via role="status". */
.product__message {
    margin: var(--spacing-sm) 0 0;
    padding: var(--spacing-sm) var(--spacing-md);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    border-left: 3px solid #2f9e44;
    font-size: .875rem;
}

.product__message--error {
    border-left-color: var(--color-primary);
    color: var(--color-primary);
}

.product__likers {
    color: var(--color-text);
}

/* Brand / code / stock, laid out as label-value pairs like the live product page. */
.product__facts {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--spacing-xs) var(--spacing-md);
    margin: 0 0 var(--spacing-lg);
    font-size: .875rem;
}

.product__facts dt {
    color: var(--color-text-light);
}

.product__facts dd {
    margin: 0;
    color: var(--color-text-dark);
}

.product__in-stock {
    color: #2f9e44;
}

.product__out-of-stock {
    color: var(--color-primary);
}

.product__section-title {
    margin: 0 0 var(--spacing-md);
    padding: 0 0 var(--spacing-md);
    border-bottom: 2px solid var(--color-border);
    color: var(--color-text);
    font-size: 1.125rem;
    font-weight: var(--fw-semibold);
}

/* --------------------------------------------------------------------------
   Cart
   -------------------------------------------------------------------------- */

/* Available to screen readers, removed from the visual flow. Used for table captions and the
   labels on quantity inputs, which the old cart markup omitted entirely. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.cart__table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: var(--spacing-lg);
}

.cart__table th,
.cart__table td {
    padding: var(--spacing-md);
    border-bottom: 1px solid var(--color-border);
    text-align: left;
    vertical-align: middle;
}

.cart__table thead th {
    font-size: .8125rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--color-text-light);
}

.cart__table tfoot th,
.cart__table tfoot td {
    border-bottom: 0;
    font-size: 1.125rem;
    font-weight: var(--fw-bold);
    color: var(--color-price);
}

.cart__product {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
}

.cart__product img {
    width: 72px;
    height: 72px;
    object-fit: contain;
    border-radius: var(--radius-sm);
    background: var(--color-surface);
}

.cart__variant,
.cart__unavailable {
    display: block;
    font-size: .8125rem;
    color: var(--color-text-light);
}

.cart__unavailable {
    color: var(--color-primary);
    font-weight: var(--fw-medium);
}

.cart__table input[type="number"] {
    width: 80px;
}

.cart__table button {
    padding: var(--spacing-xs) var(--spacing-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: #fff;
    color: var(--color-text);
    transition: border-color var(--transition-fast), color var(--transition-fast);
}

.cart__table button:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.cart__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--spacing-md);
}

.cart__actions button {
    padding: var(--spacing-md) var(--spacing-lg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: #fff;
    color: var(--color-text);
}

.cart__checkout {
    padding: var(--spacing-md) var(--spacing-2xl);
    border-radius: var(--radius-sm);
    background: var(--color-primary);
    color: #fff;
    font-weight: var(--fw-semibold);
    transition: background var(--transition-fast);
}

.cart__checkout:hover {
    background: var(--color-primary-hover);
    color: #fff;
}

.cart__empty {
    padding: var(--spacing-2xl) 0;
    color: var(--color-text-light);
}

@media (max-width: 640px) {
    /* Stack the table into cards; a five-column cart is unusable at phone width. */
    .cart__table thead {
        display: none;
    }

    .cart__table tr {
        display: block;
        margin-bottom: var(--spacing-lg);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
    }

    .cart__table td {
        display: flex;
        justify-content: space-between;
        gap: var(--spacing-md);
        border-bottom: 1px solid var(--color-border-light);
    }
}

/* --------------------------------------------------------------------------
   Orders and address book
   -------------------------------------------------------------------------- */

.orders__table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: var(--spacing-lg);
}

.orders__table th,
.orders__table td {
    padding: var(--spacing-md);
    border-bottom: 1px solid var(--color-border);
    text-align: left;
}

.orders__table thead th {
    font-size: .8125rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--color-text-light);
}

.orders__table tfoot tr:last-child th,
.orders__table tfoot tr:last-child td {
    border-bottom: 0;
    font-size: 1.125rem;
    font-weight: var(--fw-bold);
    color: var(--color-price);
}

.order__meta {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--spacing-sm) var(--spacing-lg);
    margin-bottom: var(--spacing-xl);
    padding: var(--spacing-lg);
    background: var(--color-surface);
    border-radius: var(--radius-md);
}

.order__meta dt {
    font-weight: var(--fw-medium);
    color: var(--color-text-dark);
}

.order__meta dd {
    margin: 0;
}

.address-book {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--spacing-lg);
    margin-bottom: var(--spacing-2xl);
}

.address-book__item {
    padding: var(--spacing-lg);
    background: var(--color-surface);
    border-radius: var(--radius-md);
}

.address-book__item p {
    margin: 0 0 var(--spacing-xs);
}

.address-book__name {
    font-weight: var(--fw-semibold);
    color: var(--color-text-dark);
}

.address-book__item button {
    margin-top: var(--spacing-sm);
    padding: var(--spacing-xs) var(--spacing-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: #fff;
    color: var(--color-text);
    transition: border-color var(--transition-fast), color var(--transition-fast);
}

.address-book__item button:hover:not(:disabled) {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

@media (max-width: 640px) {
    .orders__table thead {
        display: none;
    }

    .orders__table tr {
        display: block;
        margin-bottom: var(--spacing-lg);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
    }

    .orders__table td {
        display: flex;
        justify-content: space-between;
        gap: var(--spacing-md);
        border-bottom: 1px solid var(--color-border-light);
    }
}

/* --------------------------------------------------------------------------
   Checkout
   -------------------------------------------------------------------------- */

.checkout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--spacing-xl);
    align-items: start;
}

@media (min-width: 900px) {
    .checkout {
        grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    }

    /* The summary sits alongside both panels and follows the customer down the page. */
    .checkout__summary {
        grid-row: 1 / span 2;
        grid-column: 2;
        position: sticky;
        top: var(--spacing-lg);
    }
}

.checkout__panel,
.checkout__summary {
    padding: var(--spacing-lg);
    background: var(--color-surface);
    border-radius: var(--radius-md);
}

.checkout__panel fieldset {
    margin: 0 0 var(--spacing-md);
    padding: 0;
    border: 0;
}

.checkout__panel legend {
    margin-bottom: var(--spacing-sm);
    padding: 0;
    font-weight: var(--fw-medium);
    color: var(--color-text-dark);
}

/* Saved-address picker: a returning customer chooses instead of retyping. */
.checkout__addresses {
    display: grid;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-md);
}

.checkout__address label {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0 var(--spacing-sm);
    align-items: start;
    padding: var(--spacing-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    cursor: pointer;
}

.checkout__address label:hover {
    border-color: var(--color-primary-light);
}

.checkout__address.is-selected label {
    border-color: var(--color-primary);
    background: var(--color-surface);
}

.checkout__address input {
    grid-row: 1 / span 3;
    align-self: center;
}

.checkout__address-name {
    font-weight: var(--fw-semibold);
    color: var(--color-text-dark);
}

.checkout__address-phone,
.checkout__address-summary {
    font-size: .875rem;
    color: var(--color-text);
}

.checkout__addresses-hint {
    margin-bottom: var(--spacing-md);
    font-size: .875rem;
    color: var(--color-text-light);
}

/* Delivery and payment choices. The selected row previously looked identical to the others — only
   the native radio dot distinguished it — so the customer had to squint to see what they had picked
   on the one screen where that matters most. */
.checkout__options {
    display: grid;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-sm);
}

/* Scoped through the list so this outranks `.form__field label { display: block }`, which is more
   specific than a bare `.checkout__option` and was quietly cancelling the grid — the price then sat
   against the label instead of aligning down the right-hand edge. */
.checkout__options .checkout__option {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--spacing-md);
    padding: var(--spacing-md);
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: border-color var(--transition-fast), background var(--transition-fast),
                box-shadow var(--transition-fast);
}

.checkout__option input {
    /* Native control, tinted to the brand: keeps the platform's own focus and hit behaviour, and
       leaves the selection visible if :has() below is unsupported. */
    width: 1.125rem;
    height: 1.125rem;
    margin: 0;
    accent-color: var(--color-primary);
}

.checkout__option:hover {
    border-color: var(--color-primary-light);
    background: var(--color-surface);
}

/* The selected row reads as chosen at a glance. */
.checkout__option:has(input:checked) {
    border-color: var(--color-primary);
    background: rgba(146, 15, 31, .04);
    box-shadow: inset 0 0 0 1px var(--color-primary);
}

/* Keyboard focus lands on the radio; lift the whole row so it is obvious what is focused. */
.checkout__option:focus-within {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(146, 15, 31, .15);
}

.checkout__option-name {
    color: var(--color-text-dark);
    font-weight: var(--fw-medium);
}

.checkout__option:has(input:checked) .checkout__option-name {
    color: var(--color-primary);
    font-weight: var(--fw-semibold);
}

.checkout__option-price {
    color: var(--color-text-dark);
    font-weight: var(--fw-semibold);
    /* Lining figures so prices line up down the column. */
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Free delivery is good news, so it should not be printed in the same tone as a charge. */
.checkout__option-price--free {
    color: #2f9e44;
    text-transform: uppercase;
    font-size: .75rem;
    letter-spacing: .04em;
}

/* Text-like fields fill the panel; radios and checkboxes must keep their intrinsic size. Without
   the exclusion the delivery-method radios stretched to the full panel width. */
.checkout__panel select,
.checkout__panel input:not([type="radio"]):not([type="checkbox"]),
.checkout__summary textarea {
    width: 100%;
}

.checkout__summary textarea {
    font: inherit;
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    resize: vertical;
}

.checkout__panel button[type="submit"],
.checkout__place-order {
    width: 100%;
    padding: var(--spacing-md);
    border: 0;
    border-radius: var(--radius-sm);
    background: var(--color-primary);
    color: #fff;
    font-weight: var(--fw-semibold);
    transition: background var(--transition-fast);
}

.checkout__panel button[type="submit"]:hover:not(:disabled),
.checkout__place-order:hover:not(:disabled) {
    background: var(--color-primary-hover);
}

.checkout__panel button[type="submit"]:disabled,
.checkout__place-order:disabled {
    opacity: .6;
    cursor: default;
}

.checkout__lines li {
    display: flex;
    justify-content: space-between;
    gap: var(--spacing-md);
    padding: var(--spacing-sm) 0;
    border-bottom: 1px solid var(--color-border-light);
    font-size: .875rem;
}

.checkout__totals {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--spacing-sm) var(--spacing-md);
    margin: var(--spacing-md) 0 var(--spacing-lg);
}

.checkout__totals dt {
    color: var(--color-text-light);
}

.checkout__totals dd {
    margin: 0;
    text-align: right;
}

.checkout__total-label,
.checkout__total-value {
    padding-top: var(--spacing-sm);
    border-top: 1px solid var(--color-border);
    font-size: 1.125rem;
    font-weight: var(--fw-bold);
    color: var(--color-price);
}

.order-confirmation {
    max-width: 860px;
    margin: 0 auto;
    padding: var(--spacing-xl) 0 var(--spacing-2xl);
}

.order-confirmation__header {
    text-align: center;
    padding: var(--spacing-xl) var(--spacing-md) var(--spacing-lg);
}

/* The one moment in the flow worth marking. Drawn rather than an image so it stays sharp and needs
   no request. */
.order-confirmation__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    margin-bottom: var(--spacing-md);
    border-radius: var(--radius-full);
    background: rgba(47, 158, 68, .10);
    color: #2f9e44;
}

.order-confirmation__mark svg {
    width: 32px;
    height: 32px;
}

.order-confirmation__header h1 {
    margin: 0 0 var(--spacing-lg);
}

.order-confirmation__reference-label {
    margin: 0;
    font-size: .75rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--color-text-light);
}

/* Big, spaced and selectable: this is the number the customer reads back over the phone. */
.order-confirmation__reference {
    margin: var(--spacing-xs) 0 0;
    font-size: 1.75rem;
    font-weight: var(--fw-bold);
    letter-spacing: .06em;
    color: var(--color-primary);
    font-variant-numeric: tabular-nums;
    user-select: all;
}

.order-confirmation__placed,
.order-confirmation__emailed {
    margin: var(--spacing-xs) 0 0;
    color: var(--color-text-light);
    font-size: .875rem;
}

.order-confirmation__panel {
    padding: var(--spacing-lg);
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
}

.order-confirmation__panel + .order-confirmation__panel,
.order-confirmation__columns,
.order-confirmation__actions {
    margin-top: var(--spacing-md);
}

.order-confirmation__panel h2 {
    margin: 0 0 var(--spacing-md);
    font-size: 1rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--color-heading);
}

/* What the customer must still do to pay comes before the record of what they bought, so it is
   bordered in the brand colour rather than left as one panel among three. */
.order-confirmation__instructions {
    border-left: 3px solid var(--color-primary);
}

.order-confirmation__instructions img {
    max-width: 100%;
    height: auto;
}

.order-confirmation__columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: var(--spacing-md);
    align-items: start;
}

.order-confirmation__lines {
    display: grid;
    gap: var(--spacing-sm);
}

.order-confirmation__lines li {
    display: flex;
    justify-content: space-between;
    gap: var(--spacing-md);
    padding-bottom: var(--spacing-sm);
    border-bottom: 1px solid var(--color-border-light);
}

.order-confirmation__line-variant,
.order-confirmation__line-qty {
    color: var(--color-text-light);
}

.order-confirmation__line-total {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    color: var(--color-text-dark);
}

.order-confirmation__totals,
.order-confirmation__details {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--spacing-xs) var(--spacing-md);
    margin: var(--spacing-md) 0 0;
}

.order-confirmation__totals dt,
.order-confirmation__details dt {
    color: var(--color-text-light);
}

.order-confirmation__totals dd,
.order-confirmation__details dd {
    margin: 0;
    text-align: right;
    color: var(--color-text-dark);
    font-variant-numeric: tabular-nums;
}

.order-confirmation__details dd {
    text-align: left;
}

.order-confirmation__total-label,
.order-confirmation__total-value {
    padding-top: var(--spacing-sm);
    border-top: 1px solid var(--color-border);
    font-size: 1.125rem;
    font-weight: var(--fw-bold);
}

.order-confirmation__total-value {
    color: var(--color-price);
}

.order-confirmation__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--spacing-sm);
}

.order-confirmation__action {
    padding: var(--spacing-sm) var(--spacing-lg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: #fff;
    color: var(--color-text-dark);
    transition: border-color var(--transition-fast), color var(--transition-fast);
}

.order-confirmation__action:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.order-confirmation__action--primary {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.order-confirmation__action--primary:hover {
    background: var(--color-primary-hover);
    border-color: var(--color-primary-hover);
    color: #fff;
}

/* Customers paying by transfer print or screenshot this page for the bank details. */
@media print {
    .site-nav,
    .site-header,
    .site-footer,
    .order-confirmation__actions {
        display: none;
    }

    .order-confirmation__panel {
        box-shadow: none;
        break-inside: avoid;
    }
}

/* --------------------------------------------------------------------------
   Account forms
   -------------------------------------------------------------------------- */

.auth {
    max-width: 440px;
    margin: 0 auto;
    padding: var(--spacing-xl) 0 var(--spacing-2xl);
}

.auth--wide {
    max-width: 720px;
}

/* The card carries the page. Everything needed to get in sits inside one framed block, rather than
   floating on the page as a bare grey panel. */
.auth__card {
    padding: var(--spacing-2xl) var(--spacing-xl);
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
}

.auth__header {
    margin-bottom: var(--spacing-xl);
    text-align: center;
}

.auth__mark {
    width: 52px;
    height: 52px;
    margin-bottom: var(--spacing-md);
}

.auth__title {
    margin: 0 0 var(--spacing-xs);
    font-size: 1.5rem;
    font-weight: var(--fw-semibold);
    color: var(--color-text-dark);
}

.auth__subtitle {
    margin: 0;
    color: var(--color-text-light);
    font-size: .875rem;
    line-height: 1.5;
}

.auth__intro {
    margin-bottom: var(--spacing-lg);
    color: var(--color-text);
    font-size: .875rem;
    line-height: 1.6;
}

.form__field--check {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
}

.form__field--check label {
    margin-bottom: 0;
    font-weight: var(--fw-normal);
}

.form__field--check input {
    width: auto;
    accent-color: var(--color-primary);
}

.auth__form button[type="submit"] {
    width: 100%;
    margin-top: var(--spacing-sm);
    padding: var(--spacing-md);
    border: 0;
    border-radius: var(--radius-sm);
    background: var(--color-primary);
    color: #fff;
    font-size: .9375rem;
    font-weight: var(--fw-semibold);
    transition: background var(--transition-fast), box-shadow var(--transition-fast);
}

.auth__form button[type="submit"]:hover:not(:disabled) {
    background: var(--color-primary-hover);
    box-shadow: 0 4px 12px rgba(146, 15, 31, .25);
}

.auth__form button[type="submit"]:disabled {
    opacity: .6;
    cursor: default;
}

/* Destructive submit (account deletion). Deliberately distinct from the primary action so an
   irreversible button does not look like every other "Save". */
.auth__form button[type="submit"].button--danger {
    background: var(--color-primary);
    box-shadow: inset 0 0 0 2px var(--color-primary-light);
}

.auth__form button[type="submit"].button--danger:hover:not(:disabled) {
    background: var(--color-primary-light);
}

/* The way out of a destructive form: present, but visually quiet next to the confirm button. */
.button--quiet {
    display: block;
    margin-top: var(--spacing-md);
    text-align: center;
    color: var(--color-link);
}

.auth__alt {
    margin-top: var(--spacing-lg);
    text-align: center;
    font-size: .875rem;
    color: var(--color-text-light);
}

.auth__alt a {
    color: var(--color-primary);
    font-weight: var(--fw-medium);
}

.auth__alt a:hover {
    text-decoration: underline;
}

/* A hairline with a word in it, separating the form from the way to the other account page. */
.auth__divider {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    margin: var(--spacing-lg) 0 0;
    color: var(--color-text-light);
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .08em;
}

.auth__divider::before,
.auth__divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--color-border);
}

/* The forgotten-password link belongs beside the password label, where the customer is looking when
   they realise they need it. */
.form__field-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--spacing-sm);
}

.form__field-header a {
    font-size: .75rem;
    color: var(--color-link);
}

.form__field-header a:hover {
    color: var(--color-primary);
}

/* --------------------------------------------------------------------------
   Form fields
   -------------------------------------------------------------------------- */

.form__field {
    margin-bottom: var(--spacing-md);
}

.form__field label {
    display: block;
    margin-bottom: var(--spacing-xs);
    font-size: .8125rem;
    font-weight: var(--fw-medium);
    color: var(--color-text-dark);
}

/* Text-like fields fill their row; radios and checkboxes keep their intrinsic size. Unqualified,
   this stretched every radio and checkbox inside a form field to the full width — the delivery and
   payment options each had a 648px-wide invisible control, which is what pushed those rows to
   double height. */
.form__field input:not([type="radio"]):not([type="checkbox"]),
.form__field select,
.form__field textarea {
    width: 100%;
    padding: 11px var(--spacing-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: #fff;
    color: var(--color-text-dark);
    font: inherit;
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.form__field input:not([type="radio"]):not([type="checkbox"]):focus,
.form__field select:focus,
.form__field textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(146, 15, 31, .12);
}

.form__field input::placeholder,
.form__field textarea::placeholder {
    color: var(--color-text-light);
}

/* A field that failed validation is coloured, not merely annotated: on a six-row form the message
   alone is easy to miss. :has() scopes it to the field that actually carries a message. */
.form__field:has(.form__field-error:not(:empty)) input,
.form__field:has(.form__field-error:not(:empty)) select,
.form__field:has(.form__field-error:not(:empty)) textarea {
    border-color: var(--color-primary);
}

/* A rule stated before it can be broken, rather than only as a rejection after submitting. */
.form__field-hint {
    display: block;
    margin-top: var(--spacing-xs);
    color: var(--color-text-light);
    font-size: .75rem;
}

/* Field messages occupy no space until they have text, so the form does not jump on validation. */
.form__field-error:not(:empty) {
    display: block;
    margin-top: var(--spacing-xs);
    color: var(--color-primary);
    font-size: .8125rem;
}

/* Password rows carry a reveal button inside the field.

   The button is positioned against this wrapper rather than against the whole field: the field also
   holds the label, the hint and the error message, so anchoring to it put the button below the input
   on any row that carried a hint. */
.form__control {
    position: relative;
}

.form__field--password input {
    /* Room for the button, so a long password does not run underneath it. */
    padding-right: 76px;
}

.form__field--password .form__control button {
    position: absolute;
    top: 50%;
    right: var(--spacing-sm);
    transform: translateY(-50%);
    padding: var(--spacing-xs) var(--spacing-sm);
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--color-link);
    font-size: .75rem;
    font-weight: var(--fw-medium);
}

.form__field--password .form__control button:hover {
    color: var(--color-primary);
}

.form__error {
    padding: var(--spacing-md);
    margin-bottom: var(--spacing-md);
    border-radius: var(--radius-sm);
    border-left: 3px solid var(--color-primary);
    background: rgba(146, 15, 31, .08);
    color: var(--color-primary);
    font-size: .875rem;
}

/* --------------------------------------------------------------------------
   Account area
   -------------------------------------------------------------------------- */

.account__title {
    margin-bottom: var(--spacing-lg);
}

/* One row of tabs tying the account pages together, so details, orders and addresses read as one
   place rather than three unrelated screens. */
.account__nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-xs);
    margin-bottom: var(--spacing-xl);
    border-bottom: 1px solid var(--color-border);
}

.account__nav a {
    padding: var(--spacing-sm) var(--spacing-md);
    border-bottom: 2px solid transparent;
    color: var(--color-text);
    font-size: .875rem;
    white-space: nowrap;
    transition: color var(--transition-fast), border-color var(--transition-fast);
}

.account__nav a:hover {
    color: var(--color-primary);
}

.account__nav a[aria-current="page"] {
    border-bottom-color: var(--color-primary);
    color: var(--color-primary);
    font-weight: var(--fw-semibold);
}

.account__panels {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: var(--spacing-lg);
    align-items: start;
}

.account__panel {
    padding: var(--spacing-lg);
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
}

.account__panel h2 {
    margin: 0 0 var(--spacing-xs);
    font-size: 1rem;
    font-weight: var(--fw-semibold);
    color: var(--color-text-dark);
}

.account__panel-hint {
    margin: 0 0 var(--spacing-lg);
    color: var(--color-text-light);
    font-size: .8125rem;
}

/* Inside a panel the form is already framed, so it drops the auth card's own padding. */
.account__panel .auth__form {
    padding: 0;
    background: none;
}

/* Leaving is not a primary action, so it sits below the panels rather than among them. */
.account__danger {
    margin-top: var(--spacing-xl);
    padding-top: var(--spacing-md);
    border-top: 1px solid var(--color-border);
    font-size: .8125rem;
}

.account__danger a {
    color: var(--color-text-light);
}

.account__danger a:hover {
    color: var(--color-primary);
}

/* --------------------------------------------------------------------------
   Notices
   -------------------------------------------------------------------------- */

/* Confirmation shown after a redirect, e.g. the cart after reordering. Neutral rather than
   error-coloured, so it does not read as a failure. */
.cart__notice {
    padding: var(--spacing-md);
    margin-bottom: var(--spacing-md);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    border-left: 3px solid var(--color-primary);
    color: var(--color-text-dark);
    font-size: .875rem;
}

/* Standalone message pages: unsubscribe confirmation, maintenance. */
.notice {
    max-width: 34rem;
    margin: var(--spacing-2xl) auto;
    padding: var(--spacing-xl);
    text-align: center;
}

.notice p {
    margin-bottom: var(--spacing-lg);
    color: var(--color-text);
}

/* --------------------------------------------------------------------------
   CMS content (pages, news, product descriptions)
   -------------------------------------------------------------------------- */

.cms-content {
    line-height: 1.75;
}

.cms-content img {
    height: auto;
    border-radius: var(--radius-sm);
}

.cms-content table {
    width: 100%;
    border-collapse: collapse;
    /* Editor-authored tables are frequently wider than the column. */
    display: block;
    overflow-x: auto;
}

.cms-content td,
.cms-content th {
    padding: var(--spacing-sm);
    border: 1px solid var(--color-border);
}

.cms-content ul,
.cms-content ol {
    margin: 0 0 var(--spacing-md);
    padding-left: var(--spacing-lg);
    list-style: revert;
}

/* --------------------------------------------------------------------------
   News listing
   -------------------------------------------------------------------------- */

.home-news {
    margin-top: var(--spacing-2xl);
}

.home-news__item {
    padding: var(--spacing-md) 0;
    border-bottom: 1px solid var(--color-border-light);
}

.home-news__item a {
    font-weight: var(--fw-semibold);
    color: var(--color-text-dark);
}

.home-news__item time,
.news-article__meta {
    display: block;
    color: var(--color-text-light);
    font-size: .8125rem;
}

.news-article,
.cms-page {
    max-width: 76ch;
}

/* --------------------------------------------------------------------------
   Reviews
   -------------------------------------------------------------------------- */

.reviews {
    padding-top: var(--spacing-xl);
    border-top: 1px solid var(--color-border);
}

.reviews__summary {
    font-weight: var(--fw-semibold);
    color: var(--color-rating);
}

.reviews__count {
    color: var(--color-text-light);
    font-weight: var(--fw-normal);
}

.reviews__all {
    margin: 0 0 var(--spacing-md);
    font-size: .875rem;
    font-style: italic;
}

.reviews__all a {
    color: var(--color-primary);
}

.reviews__sign-in {
    margin: var(--spacing-lg) 0 0;
    padding: var(--spacing-md);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    font-size: .875rem;
    font-style: italic;
    text-align: center;
}

.reviews__sign-in a {
    color: var(--color-primary);
    font-weight: var(--fw-semibold);
}

/* The review form is a disclosure, shut by default.

   Styled as a row of the page rather than as a button: bounded by the same hairline the sections
   around it use, so it reads as part of the reviews block instead of a stray form control stranded
   between a notice and a heading. */
.reviews__write {
    max-width: 40rem;
    margin: var(--spacing-xl) 0 0;
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
}

.reviews__write-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-md);
    padding: var(--spacing-lg) 0;
    color: var(--color-text-dark);
    font-size: 1rem;
    font-weight: var(--fw-semibold);
    cursor: pointer;
    /* Replaced by the marker below; Safari needs the -webkit rule as well. */
    list-style: none;
    transition: color var(--transition-fast);
}

.reviews__write-toggle::-webkit-details-marker {
    display: none;
}

/* A circle carrying a plus, echoing the category menu's bullets so the control belongs to this site
   rather than looking like a browser default. The two bars are drawn as backgrounds, which lets the
   vertical one collapse to nothing on open — turning the plus into a minus. */
.reviews__write-toggle::after {
    content: "";
    flex: none;
    width: 28px;
    height: 28px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    background:
        linear-gradient(currentColor, currentColor) center / 10px 1.5px no-repeat,
        linear-gradient(currentColor, currentColor) center / 1.5px 10px no-repeat;
    transition: transform var(--transition-fast), border-color var(--transition-fast),
                background-size var(--transition-fast);
}

.reviews__write[open] .reviews__write-toggle {
    color: var(--color-primary);
}

.reviews__write[open] .reviews__write-toggle::after {
    /* Vertical bar closes; the circle turns with it so the change is felt, not just seen. */
    background-size: 10px 1.5px, 1.5px 0;
    border-color: var(--color-primary);
    transform: rotate(180deg);
}

.reviews__write-toggle:hover {
    color: var(--color-primary);
}

.reviews__write-toggle:hover::after {
    border-color: var(--color-primary);
}

.reviews__write-toggle:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 3px;
    border-radius: var(--radius-sm);
}

/* Open, the form is inset and tinted so it reads as the panel this row revealed. */
.reviews__form {
    max-width: 40rem;
    margin: 0 0 var(--spacing-lg);
    padding: var(--spacing-lg);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.reviews__form button[type="submit"] {
    padding: var(--spacing-sm) var(--spacing-lg);
    border: 0;
    border-radius: var(--radius-sm);
    background: var(--color-primary);
    color: #fff;
    font-weight: var(--fw-semibold);
}

.reviews__form button[type="submit"]:hover:not(:disabled) {
    background: var(--color-primary-hover);
}

.reviews__form button[type="submit"]:disabled {
    opacity: .6;
    cursor: default;
}

.review {
    padding: var(--spacing-lg) 0;
    border-bottom: 1px solid var(--color-border-light);
}

.review__title {
    margin-bottom: var(--spacing-xs);
    font-size: 1rem;
}

.review__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-md);
    margin-bottom: var(--spacing-sm);
    font-size: .8125rem;
    color: var(--color-text-light);
}

.review__rating {
    color: var(--color-rating);
    font-weight: var(--fw-semibold);
}

.review__content {
    /* Customer text is rendered encoded; preserve their line breaks. */
    white-space: pre-line;
}

.review__images {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-sm);
}

.review__images img {
    width: 96px;
    height: 96px;
    object-fit: cover;
    border-radius: var(--radius-sm);
}

.review__usefulness {
    display: flex;
    gap: var(--spacing-sm);
    margin: 0;
}

.review__usefulness button {
    padding: var(--spacing-xs) var(--spacing-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    background: #fff;
    color: var(--color-text);
    font-size: .8125rem;
    transition: border-color var(--transition-fast), color var(--transition-fast);
}

.review__usefulness button:hover:not(:disabled) {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.review__usefulness button:disabled {
    opacity: .5;
    cursor: default;
}

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

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition-duration: .01ms !important;
        animation-duration: .01ms !important;
    }

    .product-card:hover {
        transform: none;
    }
}
