/* ==========================================================================
   rp-shop.css — the merchant storefront
   --------------------------------------------------------------------------
   Loaded on top of rp-core.css, which supplies the tokens (--rp-*), the
   body.rp-site base and the shared .rp-shell / .rp-btn / .rp-card primitives.

   Deliberately NOT loaded alongside the legacy assets/web/css/styles.css. That
   sheet ships !important rules on generic class names and has already produced
   an invisible red-on-red button once (see the rp-* traps note). The shop is a
   transactional surface and a new layout, so it takes the tokens and skips the
   legacy cascade entirely.

   No data-parallax / data-reveal on this surface either. Motion belongs on the
   marketing site; here every animation is a delay between a shopper and a
   basket, and the transform-owner collision rule stops being a hazard if
   nothing on the page owns a scroll transform.

   Merchant branding: a shop with an accent colour re-declares --rp-red and
   friends in an inline <style> after this file. Every accent below therefore
   reads from a token — hard-coding #C52127 anywhere here would ignore it.
   ========================================================================== */

/* Border-box, because skipping the legacy cascade also skipped its reset.
   styles.css carries the only `* { box-sizing: border-box }` on the public
   site, and this surface deliberately does not load it — so every
   `width: 100%` element that also has padding was rendering WIDER than its
   container: the search input, the quantity box, the checkout fields, the
   card's Add button and the basket's checkout CTA. Each one pushed the page
   past the viewport, which is why the shop could be scrolled sideways on a
   phone. Scoped here rather than added to rp-core.css, which is shared with
   the marketing site where styles.css already supplies it. */
*,
*::before,
*::after {
    box-sizing: border-box;
}

body.rp-shop {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    /* A second line of defence, not the fix. Anything that still overflows is
       a bug to find, but a shopper should never be able to drag the page off
       to one side while we do. */
    overflow-x: hidden;
}

body.rp-shop main {
    flex: 1 0 auto;
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.rp-shop-nav {
    position: sticky;
    top: 0;
    z-index: 60;
    background: rgba(255, 255, 255, .88);
    backdrop-filter: saturate(160%) blur(14px);
    border-block-end: 1px solid var(--rp-border);
}

.rp-shop-nav__inner {
    display: flex;
    align-items: center;
    gap: 1rem;
    min-height: 68px;
}

.rp-shop-brand {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin-inline-end: auto;
    min-width: 0;
}

.rp-shop-brand__logo {
    width: 40px;
    height: 40px;
    border-radius: var(--rp-r-sm);
    object-fit: cover;
    flex: 0 0 auto;
    background: var(--rp-surface);
}

/* Falls back to a monogram when the merchant has not uploaded a logo — an
   empty square reads as a broken image, a letter reads as a brand. */
.rp-shop-brand__mark {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    border-radius: var(--rp-r-sm);
    background: var(--rp-grad-ember);
    color: #fff;
    font-family: var(--rp-font-display);
    font-weight: 700;
    font-size: 1.05rem;
    line-height: 1;
}

.rp-shop-brand__text { min-width: 0; }

.rp-shop-brand__name {
    display: block;
    font-family: var(--rp-font-display);
    font-weight: 600;
    font-size: 1.05rem;
    color: var(--rp-fg);
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.rp-shop-brand__tagline {
    display: block;
    font-size: .78rem;
    color: var(--rp-fg-dim);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.rp-shop-nav__actions {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex: 0 0 auto;
}

/* --------------------------------------------------------------------------
   Search
   -------------------------------------------------------------------------- */

.rp-shop-search {
    position: relative;
    flex: 1 1 320px;
    max-width: 420px;
}

.rp-shop-search input {
    width: 100%;
    height: 42px;
    padding-inline: 2.5rem 1rem;
    border: 1px solid var(--rp-border-strong);
    border-radius: 999px;
    background: var(--rp-bg);
    font-family: var(--rp-font-body);
    font-size: .9rem;
    color: var(--rp-fg);
    transition: border-color .2s var(--rp-ease), box-shadow .2s var(--rp-ease);
}

.rp-shop-search input:focus {
    outline: none;
    border-color: var(--rp-red);
    box-shadow: 0 0 0 4px var(--rp-glow);
}

.rp-shop-search__icon {
    position: absolute;
    inset-inline-start: .9rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--rp-fg-dim);
    font-size: .9rem;
    pointer-events: none;
}

@media (max-width: 860px) {
    .rp-shop-search {
        order: 3;
        flex-basis: 100%;
        max-width: none;
        margin-block-end: .85rem;
    }

    .rp-shop-nav__inner { flex-wrap: wrap; padding-block-start: .85rem; }

    /* Keep the basket in the top-right corner, beside the brand.
       ⚠ `flex-basis: 0` is the whole fix, and it is not cosmetic. A wrapping
       flex container breaks lines using each item's base size BEFORE any
       shrinking, and the brand's base size is its max-content width — logo
       plus shop name plus tagline. On a phone that is wider than the screen,
       so the brand claimed the entire first line and the basket wrapped
       underneath it, left-aligned, instead of sitting in the corner. Giving
       the brand a zero basis lets the basket share the line; the brand then
       grows into whatever is left and its name and tagline ellipsis as they
       always could.
       The auto end-margin goes with it: with the basket back on the line there
       is no free space for it to absorb, and leaving it in only muddies which
       rule does the work. */
    .rp-shop-brand {
        flex: 1 1 0;
        margin-inline-end: 0;
    }

    .rp-shop-nav__actions { flex: 0 0 auto; }
}

/* --------------------------------------------------------------------------
   Category rail
   -------------------------------------------------------------------------- */

.rp-shop-cats {
    display: flex;
    gap: .5rem;
    overflow-x: auto;
    overflow-y: hidden;          /* a vertical bar here is always a bug */
    padding-block: .75rem;
    scrollbar-width: thin;
    border-block-end: 1px solid var(--rp-border);
}

/* Auto-margin spacers rather than justify-content:center — centring an
   overflowing scroll row makes its first item unreachable. */
.rp-shop-cats::before,
.rp-shop-cats::after {
    content: '';
    flex: 0 0 0;
    margin: auto;
}

.rp-shop-cat {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .5rem 1rem;
    border: 1px solid var(--rp-border);
    border-radius: 999px;
    background: var(--rp-bg);
    font-size: .85rem;
    font-weight: 500;
    color: var(--rp-fg-muted);
    white-space: nowrap;
    transition: color .2s var(--rp-ease), border-color .2s var(--rp-ease), background .2s var(--rp-ease);
}

.rp-shop-cat:hover {
    color: var(--rp-fg);
    border-color: var(--rp-border-strong);
    background: var(--rp-surface);
}

.rp-shop-cat.is-active {
    color: #fff;
    background: var(--rp-red);
    border-color: var(--rp-red);
}

.rp-shop-cat__count {
    font-family: var(--rp-font-mono);
    font-size: .72rem;
    opacity: .7;
}

/* --- Row variant: home page, under the banner, and the product page foot ----
   The categories left the site header, so this no longer needs the rule that
   separated it from the nav above it. */
.rp-shop-cats--row {
    border-block-end: none;
    padding-block: 1rem 0;
}

/* --- Side variant: the listing page's menu --------------------------------
   Mobile first, and mobile is deliberately the SAME scrollable strip as
   everywhere else: a vertical list of every category stacked above the grid
   would push the products themselves off a phone screen. The menu only becomes
   a menu once there is a column to put it in. */
.rp-shop-cats--side {
    border-block-end: none;
    padding-block: 0 1rem;
}

.rp-shop-cats__heading {
    /* Hidden on mobile, where the strip reads as a filter row and a heading
       above it is noise. Shown in the desktop menu, below. */
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

@media (min-width: 900px) {
    .rp-shop-cats--side {
        flex-direction: column;
        align-items: stretch;
        gap: .3rem;
        overflow: visible;      /* a column has nothing to scroll */
        padding-block: 0;
    }

    /* The auto-margin spacers exist to centre an overflowing SCROLL row. In a
       column they would push the first and last item apart to fill the height,
       which is how a five-item menu ends up spread over 600px. */
    .rp-shop-cats--side::before,
    .rp-shop-cats--side::after {
        content: none;
    }

    .rp-shop-cats--side .rp-shop-cat {
        width: 100%;
        justify-content: space-between;
        border-radius: 10px;
        border-color: transparent;
        background: transparent;
        padding-inline: .75rem;
    }

    .rp-shop-cats--side .rp-shop-cat:hover {
        background: var(--rp-surface);
        border-color: var(--rp-border);
    }

    /* Restated, and it MUST be. The rule above strips the background and border
       off every pill in the menu, and it out-ranks `.rp-shop-cat.is-active` on
       source order at equal specificity — but it does not touch that rule's
       `color: #fff`. The active item was rendering white on white and vanishing
       from the menu entirely. */
    .rp-shop-cats--side .rp-shop-cat.is-active {
        background: var(--rp-red);
        border-color: var(--rp-red);
        color: #fff;
    }

    .rp-shop-cats__heading {
        position: static;
        width: auto;
        height: auto;
        clip-path: none;
        margin: 0 0 .35rem;
        padding-inline: .75rem;
        font-size: .72rem;
        font-weight: 600;
        letter-spacing: .08em;
        text-transform: uppercase;
        color: var(--rp-fg-dim);
    }
}

/* --------------------------------------------------------------------------
   Browse layout — the listing page's menu + grid
   -------------------------------------------------------------------------- */

.rp-shop-browse {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
}

/* minmax(0, 1fr) on the main column, not 1fr: a grid item's default min-width
   is auto, so the product grid would refuse to shrink below its widest card and
   push the whole layout wider than the viewport. */
@media (min-width: 900px) {
    .rp-shop-browse {
        grid-template-columns: 216px minmax(0, 1fr);
        gap: 2.5rem;
        align-items: start;
    }

    .rp-shop-browse__aside {
        position: sticky;
        top: 1.5rem;
    }
}

/* --------------------------------------------------------------------------
   Category as a way back, on the product page
   -------------------------------------------------------------------------- */

.rp-shop-card__cat--link {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    color: var(--rp-fg-muted);
    transition: color .2s var(--rp-ease);
}

.rp-shop-card__cat--link:hover {
    color: var(--rp-red);
}

.rp-shop-card__cat--link i {
    font-size: .62rem;
}

/* --------------------------------------------------------------------------
   Hero / banner
   -------------------------------------------------------------------------- */

.rp-shop-hero {
    position: relative;
    overflow: hidden;
    border-radius: var(--rp-r-xl);
    margin-block: 2rem;
    padding: clamp(2rem, 5vw, 3.5rem);
    background: var(--rp-surface);
    border: 1px solid var(--rp-border);
    isolation: isolate;
}

.rp-shop-hero--image { color: #fff; border-color: transparent; }

.rp-shop-hero__bg {
    position: absolute;
    inset: 0;
    z-index: -2;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The scrim is what makes arbitrary merchant photography safe to put text on.
   Without it a bright banner renders white text invisible, and we do not get to
   pick the photo. */
.rp-shop-hero--image::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(105deg, rgba(10, 12, 16, .82) 0%, rgba(10, 12, 16, .55) 55%, rgba(10, 12, 16, .30) 100%);
}

.rp-shop-hero__title {
    font-family: var(--rp-font-display);
    font-weight: 700;
    font-size: clamp(1.7rem, 4vw, 2.6rem);
    line-height: 1.15;
    margin: 0 0 .6rem;
    max-width: 22ch;
}

.rp-shop-hero--image .rp-shop-hero__title { color: #fff; }

.rp-shop-hero__sub {
    font-size: 1rem;
    max-width: 46ch;
    margin: 0 0 1.5rem;
    color: var(--rp-fg-muted);
}

.rp-shop-hero--image .rp-shop-hero__sub { color: rgba(255, 255, 255, .86); }

/* The banner was sized for a desktop lede and took most of a phone screen
   before a shopper saw a single product. On a small screen the shop itself is
   the point, so the hero gives back its height: tighter padding, a smaller
   headline, and a normal-scale button instead of the 56px --lg one. */
@media (max-width: 600px) {
    .rp-shop-hero {
        margin-block: 1.25rem;
        padding: 1.5rem 1.25rem;
        border-radius: var(--rp-r-lg);
    }

    .rp-shop-hero__title {
        font-size: 1.35rem;
        margin-block-end: .4rem;
    }

    .rp-shop-hero__sub {
        font-size: .9rem;
        margin-block-end: 1.1rem;
    }

    /* Overrides .rp-btn--lg on the hero's CTA only. */
    .rp-shop-hero .rp-btn--lg {
        min-height: 44px;
        padding: .65rem 1.25rem;
        font-size: .9rem;
    }
}

/* --------------------------------------------------------------------------
   Product grid
   -------------------------------------------------------------------------- */

.rp-shop-section { padding-block: 2.5rem; }

.rp-shop-section__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-block-end: 1.4rem;
}

.rp-shop-section__head h2 {
    font-family: var(--rp-font-display);
    font-size: clamp(1.25rem, 2.4vw, 1.6rem);
    font-weight: 600;
    margin: 0;
}

/* A plain responsive grid. No stagger, no auto-fill column wobble: a shop with
   three products has to look deliberate, and a stagger with an odd last row is
   the exact failure the bento layout shipped with. */
.rp-shop-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 1.25rem;
}

@media (max-width: 600px) {
    .rp-shop-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: .85rem;
    }
}

.rp-shop-card {
    display: flex;
    flex-direction: column;
    background: var(--rp-card);
    border: 1px solid var(--rp-border);
    border-radius: var(--rp-r-md);
    overflow: hidden;
    transition: border-color .25s var(--rp-ease), box-shadow .25s var(--rp-ease), translate .25s var(--rp-ease);
}

.rp-shop-card:hover {
    border-color: var(--rp-border-strong);
    box-shadow: var(--rp-shadow-md);
    translate: 0 -3px;
}

.rp-shop-card__media {
    position: relative;
    display: block;
    aspect-ratio: 1 / 1;
    background: var(--rp-surface);
    overflow: hidden;
}

.rp-shop-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: scale .5s var(--rp-ease-out);
}

.rp-shop-card:hover .rp-shop-card__media img { scale: 1.04; }

/* Placeholder for the many catalogue rows that have no photo — a merchant
   publishing 200 products will not have photographed all of them, and a broken
   image icon on a shop reads as a broken shop. */
.rp-shop-card__placeholder {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    color: var(--rp-fg-dim);
    font-size: 1.6rem;
    background:
        linear-gradient(135deg, var(--rp-surface) 0%, var(--rp-surface-2) 100%);
}

.rp-shop-card__body {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    padding: .9rem 1rem 1rem;
    flex: 1 0 auto;
}

.rp-shop-card__cat {
    font-size: .72rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--rp-fg-dim);
}

.rp-shop-card__name {
    font-weight: 600;
    font-size: .95rem;
    line-height: 1.35;
    color: var(--rp-fg);
    /* Two lines, fixed height: product names in this catalogue run from "Milk"
       to a 90-character import, and a ragged card baseline across a grid is the
       content-count trap in a different costume. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 2.7em;
}

.rp-shop-card__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin-block-start: auto;
    padding-block-start: .5rem;
}

.rp-shop-price {
    font-family: var(--rp-font-mono);
    font-weight: 500;
    font-size: 1rem;
    color: var(--rp-fg);
}

.rp-shop-price--lg { font-size: 1.6rem; }

.rp-shop-unit {
    font-family: var(--rp-font-body);
    font-size: .75rem;
    color: var(--rp-fg-dim);
}

/* --------------------------------------------------------------------------
   Badges
   -------------------------------------------------------------------------- */

.rp-shop-badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .2rem .55rem;
    border-radius: 999px;
    font-size: .7rem;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
}

.rp-shop-badge--out {
    background: var(--rp-surface-2);
    color: var(--rp-fg-dim);
}

.rp-shop-badge--low {
    background: #FEF6E7;
    color: var(--rp-amber);
}

.rp-shop-badge--in {
    background: var(--rp-green-soft);
    color: var(--rp-green);
}

.rp-shop-badge--float {
    position: absolute;
    inset-block-start: .6rem;
    inset-inline-start: .6rem;
    z-index: 2;
    background: rgba(255, 255, 255, .94);
    box-shadow: var(--rp-shadow-sm);
}

.rp-shop-card--out .rp-shop-card__media img { filter: grayscale(1); opacity: .55; }

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

.rp-shop-detail {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 3.5rem);
    padding-block: 2.5rem;
}

@media (max-width: 860px) {
    .rp-shop-detail { grid-template-columns: minmax(0, 1fr); }
}

.rp-shop-detail__media {
    position: relative;
    aspect-ratio: 1 / 1;
    border-radius: var(--rp-r-lg);
    overflow: hidden;
    background: var(--rp-surface);
    border: 1px solid var(--rp-border);
}

.rp-shop-detail__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.rp-shop-detail__title {
    font-family: var(--rp-font-display);
    font-size: clamp(1.5rem, 3.5vw, 2.1rem);
    font-weight: 700;
    line-height: 1.2;
    margin: .35rem 0 .75rem;
}

.rp-shop-detail__desc {
    color: var(--rp-fg-muted);
    line-height: 1.7;
    white-space: pre-line;   /* merchants type descriptions with line breaks */
}

.rp-shop-meta {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem 1.5rem;
    padding-block: 1.25rem;
    margin-block: 1.25rem;
    border-block: 1px solid var(--rp-border);
}

.rp-shop-meta__item { font-size: .85rem; color: var(--rp-fg-dim); }
.rp-shop-meta__item strong { color: var(--rp-fg); font-weight: 500; }

/* --------------------------------------------------------------------------
   Empty states
   -------------------------------------------------------------------------- */

.rp-shop-empty {
    text-align: center;
    padding: clamp(3rem, 10vw, 6rem) 1.5rem;
    border: 1px dashed var(--rp-border-strong);
    border-radius: var(--rp-r-lg);
    background: var(--rp-bg-2);
}

.rp-shop-empty__icon {
    font-size: 2.2rem;
    color: var(--rp-ember);
    margin-block-end: .9rem;
}

.rp-shop-empty h3 {
    font-family: var(--rp-font-display);
    font-size: 1.2rem;
    margin: 0 0 .4rem;
}

.rp-shop-empty p { margin: 0 auto; max-width: 46ch; }

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

.rp-shop-pager {
    display: flex;
    justify-content: center;
    margin-block-start: 2.5rem;
}

.rp-shop-pager .pagination {
    display: flex;
    gap: .35rem;
    list-style: none;
    padding: 0;
    margin: 0;
    flex-wrap: wrap;
}

.rp-shop-pager .page-link {
    display: grid;
    place-items: center;
    min-width: 38px;
    height: 38px;
    padding-inline: .6rem;
    border: 1px solid var(--rp-border);
    border-radius: var(--rp-r-sm);
    background: var(--rp-bg);
    color: var(--rp-fg-muted);
    font-size: .875rem;
}

.rp-shop-pager .page-link:hover { border-color: var(--rp-border-strong); color: var(--rp-fg); }

.rp-shop-pager .active .page-link {
    background: var(--rp-red);
    border-color: var(--rp-red);
    color: #fff;
}

.rp-shop-pager .disabled .page-link { opacity: .45; pointer-events: none; }

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

.rp-shop-foot {
    margin-block-start: 3rem;
    padding-block: 2.5rem;
    border-block-start: 1px solid var(--rp-border);
    background: var(--rp-bg-2);
}

.rp-shop-foot__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 2rem;
}

.rp-shop-foot h4 {
    font-family: var(--rp-font-display);
    font-size: .95rem;
    font-weight: 600;
    margin: 0 0 .6rem;
}

.rp-shop-foot p,
.rp-shop-foot a { font-size: .875rem; color: var(--rp-fg-muted); }

.rp-shop-foot a:hover { color: var(--rp-red); }

.rp-shop-foot__legal {
    margin-block-start: 2rem;
    padding-block-start: 1.25rem;
    border-block-start: 1px solid var(--rp-border);
    display: flex;
    flex-wrap: wrap;
    gap: .5rem 1.5rem;
    justify-content: space-between;
    font-size: .8rem;
    color: var(--rp-fg-dim);
}

/* --------------------------------------------------------------------------
   Holding page (shop connected but not published)
   -------------------------------------------------------------------------- */

.rp-shop-holding {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 2rem;
    text-align: center;
}

.rp-shop-holding__inner { max-width: 34rem; }

/* The shop's initials, standing in for a logo nobody has uploaded yet.
   Deliberately quieter than the 40px mark in the shop header: this one is the
   only graphic on an otherwise empty page, and at 72px the header's saturated
   gradient stops reading as a placeholder and starts reading as a logo. A soft
   tint with the letters in ink says "no logo yet" without shouting. */
.rp-shop-monogram {
    display: grid;
    place-items: center;
    width: 72px;
    height: 72px;
    margin: 0 auto;
    border-radius: var(--rp-r-md);
    background: var(--rp-red-soft);
    color: var(--rp-red-deep);
    font-family: var(--rp-font-display);
    font-weight: 700;
    font-size: 1.6rem;
    line-height: 1;
    letter-spacing: .02em;
    /* Latin initials sit optically high in a box this size. */
    padding-block-start: .06em;
    user-select: none;
}

.rp-shop-holding h1 {
    font-family: var(--rp-font-display);
    font-size: clamp(1.6rem, 5vw, 2.4rem);
    margin: 1rem 0 .75rem;
}

/* --------------------------------------------------------------------------
   Basket, checkout, order
   -------------------------------------------------------------------------- */

.rp-shop-basket {
    position: relative;
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    border-radius: 999px;
    border: 1px solid var(--rp-border);
    color: var(--rp-fg-muted);
    background: var(--rp-bg);
    transition: border-color .2s var(--rp-ease), color .2s var(--rp-ease);
}

.rp-shop-basket:hover,
.rp-shop-basket.is-active { border-color: var(--rp-red); color: var(--rp-red); }

.rp-shop-basket__count {
    position: absolute;
    inset-block-start: -4px;
    inset-inline-end: -4px;
    min-width: 19px;
    height: 19px;
    padding-inline: 5px;
    display: grid;
    place-items: center;
    border-radius: 999px;
    background: var(--rp-red);
    color: #fff;
    font-family: var(--rp-font-mono);
    font-size: .68rem;
    line-height: 1;
}

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

.rp-shop-notice {
    display: flex;
    align-items: flex-start;
    gap: .7rem;
    padding: .85rem 1.1rem;
    margin-block: 1.25rem;
    border-radius: var(--rp-r-sm);
    border: 1px solid var(--rp-border);
    background: var(--rp-surface);
    font-size: .9rem;
    line-height: 1.5;
    color: var(--rp-fg-muted);
}

.rp-shop-notice i { margin-block-start: .15rem; flex: 0 0 auto; }

.rp-shop-notice--ok   { background: var(--rp-green-soft); border-color: transparent; color: var(--rp-green); }
.rp-shop-notice--bad  { background: var(--rp-red-soft);   border-color: transparent; color: var(--rp-red); }
.rp-shop-notice--warn { background: #FEF6E7;              border-color: transparent; color: var(--rp-amber); }

/* Lines ------------------------------------------------------------------ */

.rp-shop-lines {
    border: 1px solid var(--rp-border);
    border-radius: var(--rp-r-md);
    overflow: hidden;
    background: var(--rp-card);
}

.rp-shop-line {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr) 90px 110px 40px;
    align-items: center;
    gap: 1rem;
    padding: .9rem 1rem;
    border-block-end: 1px solid var(--rp-border);
}

.rp-shop-line:last-child { border-block-end: 0; }

.rp-shop-line.is-gone { opacity: .55; }

.rp-shop-line__media {
    width: 64px;
    height: 64px;
    border-radius: var(--rp-r-sm);
    overflow: hidden;
    background: var(--rp-surface);
}

.rp-shop-line__media img { width: 100%; height: 100%; object-fit: cover; }

.rp-shop-line__name { font-weight: 600; font-size: .95rem; color: var(--rp-fg); }
.rp-shop-line__name a { color: inherit; }
.rp-shop-line__name a:hover { color: var(--rp-red); }

.rp-shop-line__meta { font-size: .82rem; color: var(--rp-fg-dim); margin-block-start: .2rem; }

.rp-shop-line__qty input {
    width: 100%;
    height: 40px;
    padding-inline: .6rem;
    text-align: center;
    border: 1px solid var(--rp-border-strong);
    border-radius: var(--rp-r-sm);
    background: var(--rp-bg);
    font-family: var(--rp-font-mono);
    font-size: .9rem;
    color: var(--rp-fg);
}

.rp-shop-line__qty input:focus {
    outline: none;
    border-color: var(--rp-red);
    box-shadow: 0 0 0 4px var(--rp-glow);
}

.rp-shop-line__total {
    text-align: end;
    font-family: var(--rp-font-mono);
    font-weight: 500;
    color: var(--rp-fg);
}

.rp-shop-iconbtn {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 999px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--rp-fg-dim);
    cursor: pointer;
}

.rp-shop-iconbtn:hover { color: var(--rp-red); background: var(--rp-red-soft); }

/* The remove forms live outside the update form (HTML forbids nesting them)
   and must not occupy layout where they happen to sit. */
.rp-shop-hidden-form { display: none; }

@media (max-width: 700px) {
    .rp-shop-line {
        grid-template-columns: 56px minmax(0, 1fr) 40px;
        grid-template-areas:
            "media body remove"
            "media qty  total";
        row-gap: .6rem;
    }

    .rp-shop-line__media  { grid-area: media; width: 56px; height: 56px; }
    .rp-shop-line__body   { grid-area: body; }
    .rp-shop-line__qty    { grid-area: qty; }
    .rp-shop-line__total  { grid-area: total; text-align: end; }
    .rp-shop-line__remove { grid-area: remove; justify-self: end; }
}

.rp-shop-cart-actions {
    display: flex;
    justify-content: flex-end;
    margin-block-start: 1rem;
}

/* Summary ---------------------------------------------------------------- */

.rp-shop-summary {
    margin-block-start: 1.5rem;
    padding: 1.25rem;
    border: 1px solid var(--rp-border);
    border-radius: var(--rp-r-md);
    background: var(--rp-bg-2);
}

.rp-shop-summary__title {
    font-family: var(--rp-font-display);
    font-size: 1rem;
    font-weight: 600;
    margin: 0 0 .9rem;
}

.rp-shop-summary__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding-block: .4rem;
    font-size: .92rem;
}

.rp-shop-summary__row--muted { color: var(--rp-fg-dim); font-size: .85rem; }
.rp-shop-summary__row--muted small { font-family: var(--rp-font-mono); }

.rp-shop-summary__row--total {
    margin-block-start: .5rem;
    padding-block-start: .8rem;
    border-block-start: 1px solid var(--rp-border-strong);
    font-size: 1.05rem;
}

.rp-shop-summary__row--total strong { font-family: var(--rp-font-mono); font-size: 1.25rem; }

/* Checkout sits at the END of the row, with "keep shopping" beside it, rather
   than as a full-width slab across the card. Both buttons size to their text.
   On a narrow phone they wrap onto two lines and stay right-aligned; they are
   not stretched, because a stretched pill on a 380px screen is the shape that
   made this look broken in the first place. */
.rp-shop-summary__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: .6rem;
    margin-block-start: 1rem;
}

.rp-shop-summary__cta { justify-content: center; }

/* Checkout's "Place order" keeps the full-width slab, and should. It is the
   last action on the page, sitting alone at the foot of a narrow summary
   column with nothing to sit beside — the opposite of the basket, where it was
   one of two choices and stretching it made the page overflow. */
.rp-shop-summary > .rp-shop-summary__cta {
    width: 100%;
    margin-block-start: 1rem;
}

/* A disabled link is still clickable, so it has to be made inert as well as
   look inert. aria-disabled and tabindex are set on the element itself. */
.rp-shop-summary__cta.is-disabled {
    opacity: .5;
    pointer-events: none;
}

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

.rp-shop-checkout {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 3rem);
    align-items: start;
}

@media (max-width: 860px) {
    .rp-shop-checkout { grid-template-columns: minmax(0, 1fr); }
}

.rp-shop-checkout__aside { position: sticky; top: calc(var(--rp-nav-h) + 1rem); }

@media (max-width: 860px) {
    .rp-shop-checkout__aside { position: static; }
}

.rp-shop-fieldset {
    border: 1px solid var(--rp-border);
    border-radius: var(--rp-r-md);
    padding: 1.25rem;
    margin-block-end: 1.25rem;
    background: var(--rp-card);
}

.rp-shop-fieldset legend {
    padding-inline: .5rem;
    font-family: var(--rp-font-display);
    font-weight: 600;
    font-size: .95rem;
    color: var(--rp-fg);
}

.rp-shop-field { margin-block-end: 1rem; }
.rp-shop-field:last-child { margin-block-end: 0; }

.rp-shop-field label {
    display: block;
    margin-block-end: .35rem;
    font-size: .88rem;
    font-weight: 500;
    color: var(--rp-fg);
}

.rp-shop-field input,
.rp-shop-field textarea {
    width: 100%;
    padding: .7rem .9rem;
    border: 1px solid var(--rp-border-strong);
    border-radius: var(--rp-r-sm);
    background: var(--rp-bg);
    font-family: var(--rp-font-body);
    font-size: .95rem;
    color: var(--rp-fg);
    resize: vertical;
}

.rp-shop-field input:focus,
.rp-shop-field textarea:focus {
    outline: none;
    border-color: var(--rp-red);
    box-shadow: 0 0 0 4px var(--rp-glow);
}

.rp-shop-field small { display: block; margin-block-start: .3rem; font-size: .78rem; color: var(--rp-fg-dim); }

.rp-shop-optional {
    font-weight: 400;
    font-size: .78rem;
    color: var(--rp-fg-dim);
}

.rp-shop-choices { display: grid; gap: .75rem; }

.rp-shop-choice {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: .9rem 1rem;
    border: 1px solid var(--rp-border-strong);
    border-radius: var(--rp-r-sm);
    cursor: pointer;
    transition: border-color .2s var(--rp-ease), background .2s var(--rp-ease);
}

.rp-shop-choice:hover { border-color: var(--rp-red); }

/* :has() so the whole card reads as selected, not just the radio dot.
   Degrades to the plain border where it is unsupported; nothing breaks. */
.rp-shop-choice:has(input:checked) {
    border-color: var(--rp-red);
    background: var(--rp-red-tint);
}

.rp-shop-choice input { margin-block-start: .25rem; accent-color: var(--rp-red); }
.rp-shop-choice strong { display: block; font-size: .95rem; color: var(--rp-fg); }
.rp-shop-choice small { display: block; margin-block-start: .15rem; font-size: .8rem; color: var(--rp-fg-dim); }

/* Variant choice --------------------------------------------------------- */

/* Same visual grammar as .rp-shop-choice above — a bordered card that reads as
   selected — but laid out as a wrapping row, because a colour or a size is a
   short label and stacking six of them full width buries the Add button below
   the fold on a phone.

   NOTE the widths: this stylesheet is loaded WITHOUT the site-wide box-sizing
   reset (the shop skips styles.css), so nothing here may combine a percentage
   width with padding or a border. These are content-sized instead. */

.rp-shop-variants {
    margin-block-start: 1.5rem;
    padding: 0;
    border: 0;
}

.rp-shop-variants legend {
    padding: 0;
    margin-block-end: .5rem;
    font-size: .82rem;
    color: var(--rp-fg-dim);
}

.rp-shop-variants__list {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.rp-shop-variant {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .55rem .8rem;
    border: 1px solid var(--rp-border-strong);
    border-radius: var(--rp-r-sm);
    cursor: pointer;
    transition: border-color .2s var(--rp-ease), background .2s var(--rp-ease);
}

.rp-shop-variant:hover { border-color: var(--rp-red); }

.rp-shop-variant:has(input:checked) {
    border-color: var(--rp-red);
    background: var(--rp-red-tint);
}

/* Keyboard focus has to be visible on the CARD, not only on the 13px radio. */
.rp-shop-variant:has(input:focus-visible) {
    border-color: var(--rp-red);
    box-shadow: 0 0 0 4px var(--rp-glow);
}

.rp-shop-variant input { accent-color: var(--rp-red); }

.rp-shop-variant__name { font-size: .9rem; color: var(--rp-fg); }

.rp-shop-variant__price {
    font-family: var(--rp-font-mono);
    font-size: .85rem;
    color: var(--rp-fg-dim);
}

/* Still listed, plainly unavailable. Removing sold-out options would leave the
   shopper wondering whether the shop ever had their size. */
.rp-shop-variant.is-gone {
    opacity: .55;
    cursor: not-allowed;
    border-style: dashed;
}

.rp-shop-variant.is-gone:hover { border-color: var(--rp-border-strong); }

/* The chosen option, wherever a line is listed back to the shopper. */
.rp-shop-line__variant {
    margin-block-start: .2rem;
    font-size: .82rem;
    font-weight: 600;
    color: var(--rp-fg);
}

/* Add to basket ---------------------------------------------------------- */

.rp-shop-addform {
    display: flex;
    align-items: flex-end;
    gap: .75rem;
    flex-wrap: wrap;
    margin-block-start: 1.5rem;
}

.rp-shop-addform__qty { display: block; }
.rp-shop-addform__qty span { display: block; margin-block-end: .3rem; }

.rp-shop-addform__qty input {
    width: 92px;
    height: 56px;              /* matches .rp-btn--lg standing beside it */
    padding-inline: .7rem;
    text-align: center;
    border: 1px solid var(--rp-border-strong);
    border-radius: var(--rp-r-sm);
    background: var(--rp-bg);
    font-family: var(--rp-font-mono);
    font-size: 1rem;
    color: var(--rp-fg);
}

.rp-shop-addform__qty input:focus {
    outline: none;
    border-color: var(--rp-red);
    box-shadow: 0 0 0 4px var(--rp-glow);
}

.rp-shop-card__add {
    width: 100%;
    justify-content: center;
    margin-block-start: .6rem;
    min-height: 38px;
    padding: .45rem 1rem;
    font-size: .82rem;
}

/* Order status ----------------------------------------------------------- */

.rp-shop-orderhead { margin-block-end: 1.5rem; }
.rp-shop-orderhead .rp-shop-detail__title { margin-block: .5rem .25rem; }

.rp-shop-badge--pending   { background: #FEF6E7;              color: var(--rp-amber); }
.rp-shop-badge--accepted  { background: var(--rp-green-soft); color: var(--rp-green); }
.rp-shop-badge--rejected  { background: var(--rp-red-soft);   color: var(--rp-red); }
.rp-shop-badge--cancelled { background: var(--rp-surface-2);  color: var(--rp-fg-dim); }

/* Transfer slips ---------------------------------------------------------- */

/*
 * The proof a shopper transferred the money, listed on their order page.
 *
 * Sized as a list of documents rather than as a gallery: at this point the
 * shopper knows what they uploaded, and the merchant is the one who needs to
 * open it. A thumbnail grid would cost a full-size image fetch per slip on a
 * mobile connection to tell them something they already know.
 */
.rp-shop-slips {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    margin-block: .75rem;
}

.rp-shop-slip {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .6rem .75rem;
    border: 1px solid var(--rp-border);
    border-radius: var(--rp-r-sm);
    background: var(--rp-card);
}

.rp-shop-slip__link {
    display: flex;
    align-items: center;
    gap: .65rem;
    flex: 1 1 auto;
    min-width: 0;
    color: inherit;
    text-decoration: none;
    font-size: .9rem;
}

.rp-shop-slip__link i {
    flex: 0 0 auto;
    color: var(--rp-red);
}

.rp-shop-slip__link span {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.rp-shop-slip__link small {
    color: var(--rp-fg-muted);
    font-size: .78rem;
}

.rp-shop-slip__link:hover { text-decoration: underline; }

.rp-shop-slip__remove {
    flex: 0 0 auto;
    border: 0;
    background: transparent;
    color: var(--rp-fg-muted);
    cursor: pointer;
    padding: .25rem .4rem;
    border-radius: var(--rp-r-sm);
    line-height: 1;
}

.rp-shop-slip__remove:hover { color: var(--rp-red); background: var(--rp-red-soft); }

/* A bare file input is unstyleable across browsers, so the box around it is
   what carries the design rather than the control itself. */
.rp-shop-slip__input {
    display: block;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
    padding: .55rem .7rem;
    border: 1px dashed var(--rp-border);
    border-radius: var(--rp-r-sm);
    background: var(--rp-surface);
    font-size: .85rem;
    color: var(--rp-fg-muted);
}

.rp-shop-slip__error {
    margin: .4rem 0 0;
    font-size: .85rem;
    color: var(--rp-red);
}
