/* ============================================================================
   Cape Coast Mall 2.0 — storefront
   ----------------------------------------------------------------------------
   The customer-facing shop. Shares the locked brand palette with app.css
   (docs/BRAND-TOKENS.md) and adds nothing to it — every colour below is a
   token taken from the live capecoastmall.com.

   Mobile is the primary design target (SRS 3): Ghanaian customers shop on
   phones, so every layout here starts single-column and widens.
   ============================================================================ */

:root {
    --ccm-amber:     #FCB800;
    --ccm-amber-ink: #000000;
    --ccm-red:       #FF3300;
    --ccm-red-band:  #F60202;
    --ccm-orange:    #F14705;
    --ccm-badge-ink: #FFFFFF;
    --ccm-mint:      #EFFFF2;
    --ccm-link:      #0066CC;
    --ccm-ink:       #000000;
    --ccm-body:      #666666;
    --ccm-bg:        #FFFFFF;
    --ccm-rule:      #E1E1E1;
    --ccm-surface:   #FAFAFA;
    --ccm-rule-soft: #EDEDED;
    --ccm-muted:     #8A8A8A;

    --ccm-font: "Work Sans", Arial, Helvetica, sans-serif;
    --ccm-container: 1170px;   /* matches the live site */
    --ccm-radius: 4px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--ccm-font);
    font-size: 14px;
    line-height: 1.6;
    color: var(--ccm-body);
    background: var(--ccm-bg);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { color: var(--ccm-ink); margin: 0; font-weight: 600; }
a { color: var(--ccm-link); text-decoration: none; }
/* Underline links in prose, not designed components.
   -----------------------------------------------------------------------------
   `a:hover` is more specific than `.dept-link`, so this rule beat every
   component that had carefully set `text-decoration: none` — the department
   bar grew an underline on hover, and so did anything else shaped like a
   button or a card. Patching each one as it was noticed is how a stylesheet
   ends up with a dozen `text-decoration: none !important`.
   `:not([class])` draws the line where it belongs: a bare <a> in a sentence is
   a link and should look like one; an <a> that carries a class is a component
   and decides its own hover. Components that do want an underline — the
   breadcrumbs, the document pages — set it explicitly. */
a:not([class]):hover { text-decoration: underline; }
img { max-width: 100%; }
:focus-visible { outline: 2px solid var(--ccm-link); outline-offset: 2px; }

.shell { max-width: var(--ccm-container); margin: 0 auto; padding: 0 16px; }

/* -------------------------------------------------------------------- hero */
.hero { background: var(--ccm-mint); border-bottom: 1px solid var(--ccm-rule); padding: 44px 0; }
.hero .shell { display: grid; grid-template-columns: 1fr; gap: 22px; align-items: center; }
.hero h1 { font-size: clamp(28px, 5vw, 44px); line-height: 1.1; letter-spacing: -.02em; }
.hero h1 .accent { color: var(--ccm-red); }
.hero p { font-size: 16px; margin: 14px 0 0; max-width: 46ch; }
.hero-actions { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 22px; }

.promise-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; margin-top: 30px; }
.promise { background: var(--ccm-bg); border: 1px solid var(--ccm-rule); border-radius: var(--ccm-radius); padding: 14px 16px; }
.promise strong { display: block; color: var(--ccm-ink); font-size: 13.5px; }
.promise span { font-size: 12.5px; color: var(--ccm-muted); }

/* --------------------------------------------------------------- offer band */
.offer-band {
    background: var(--ccm-red-band); color: var(--ccm-badge-ink);
    text-align: center; padding: 15px 0;
    font-size: clamp(20px, 3.4vw, 30px); font-weight: 600; letter-spacing: -.01em;
}
.delivery-band {
    background: var(--ccm-mint); text-align: center; padding: 13px 0;
    font-size: 12.5px; color: var(--ccm-ink); border-bottom: 1px solid var(--ccm-rule);
}
.delivery-band strong { letter-spacing: .04em; text-transform: uppercase; font-size: 11.5px; }

/* ------------------------------------------------------------------ buttons */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    padding: 11px 20px; font: inherit; font-weight: 600; cursor: pointer;
    border: 1px solid transparent; border-radius: var(--ccm-radius);
}
.btn:hover { text-decoration: none; filter: brightness(.96); }
.btn-primary { background: var(--ccm-amber); color: var(--ccm-amber-ink); }
.btn-ghost { background: var(--ccm-bg); color: var(--ccm-ink); border-color: var(--ccm-rule); }
.btn-danger { background: var(--ccm-red); color: var(--ccm-badge-ink); }
.btn-block { width: 100%; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-sm { padding: 7px 12px; font-size: 12.5px; }

/* -------------------------------------------------------------- section head */
section.row { padding: 34px 0; }
.row-head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 14px; border-bottom: 1px solid var(--ccm-rule);
    padding-bottom: 12px; margin-bottom: 20px;
}
.row-head h2 { font-size: 19px; }
.row-head a { font-size: 13px; }

/* ------------------------------------------------------------- product grid */
.grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
.card {
    border: 1px solid var(--ccm-rule); border-radius: var(--ccm-radius);
    background: var(--ccm-bg); display: flex; flex-direction: column;
    position: relative; overflow: hidden;
}
.card:hover { border-color: var(--ccm-amber); }
/* A fixed square, whatever the vendor uploaded.
   `aspect-ratio: 1` fixes the box and `object-fit: contain` fits the picture
   inside it, so nothing a vendor uploads can change the size of a card. Every
   image in this catalogue is 1800x1200 or 720x1200 -- not one is square -- and
   under the `cover` this used to have, a third of every wide photograph was
   cropped away. A shopper cannot judge a product whose edges have been cut off,
   and a row of cards that are all exactly the same size is worth more than a
   picture that fills its box.
   The max-width/max-height pair is belt to that braces: even with object-fit
   unsupported or overridden, the image cannot exceed its container. */
.card-media {
    display: block;
    aspect-ratio: 1;
    background: var(--ccm-bg);
    overflow: hidden;
}

.card-media img {
    width: 100%;
    height: 100%;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    object-position: center;
    display: block;
    /* A little air, so a photograph shot edge-to-edge does not touch the
       card's border and read as clipped. */
    padding: 6px;
    box-sizing: border-box;
}
.card-body { padding: 11px 12px 13px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.card-name { font-size: 13.5px; color: var(--ccm-ink); line-height: 1.35; }
.card-name:hover { color: var(--ccm-link); }
.card-cat { font-size: 11.5px; color: var(--ccm-muted); }
.card-price { margin-top: auto; }
.price { color: var(--ccm-red); font-weight: 700; font-size: 15px; }
.price-was { color: var(--ccm-muted); text-decoration: line-through; font-size: 12.5px; margin-left: 6px; }

.badge {
    position: absolute; top: 8px; left: 8px; z-index: 1;
    background: var(--ccm-orange); color: var(--ccm-badge-ink);
    font-size: 11px; font-weight: 700; padding: 3px 7px; border-radius: 2px;
}
.badge-out { background: var(--ccm-ink); }


/* -------------------------------------------------------------- product page */
.pdp { display: grid; gap: 28px; grid-template-columns: 1fr; padding: 28px 0; }
.pdp-gallery { display: flex; flex-direction: column; gap: 10px; }
/* White, not the surface grey.
   Fitting a landscape photograph into a square leaves a band above and below
   it. On grey that band draws a frame around the product; on white it is
   invisible against the white backdrop nearly all product photography is shot
   on, so the picture simply looks the shape it is. */
.pdp-main {
    border: 1px solid var(--ccm-rule); border-radius: var(--ccm-radius);
    background: var(--ccm-bg); aspect-ratio: 1; overflow: hidden;
}
/* The whole product, inside a fixed square. See .card-media above: this is
   the screen where cropping matters most, because it is the one where somebody
   decides whether to buy the thing. */
.pdp-main img {
    width: 100%;
    height: 100%;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    object-position: center;
    display: block;
    padding: 10px;
    box-sizing: border-box;
}
.pdp-thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: 8px; }
.pdp-thumbs img {
    width: 100%; aspect-ratio: 1;
    max-width: 100%; max-height: 100%;
    object-fit: contain; display: block;
    padding: 3px; box-sizing: border-box;
    border: 1px solid var(--ccm-rule); border-radius: 3px; background: var(--ccm-bg);
}
.pdp h1 { font-size: clamp(21px, 3vw, 27px); line-height: 1.25; }
.pdp-price { font-size: 27px; }
.pdp-meta { display: flex; gap: 8px; flex-wrap: wrap; margin: 12px 0; }
.chip { font-size: 11.5px; padding: 4px 9px; border-radius: 2px; border: 1px solid var(--ccm-rule); color: var(--ccm-body); }
.chip-stock { background: var(--ccm-mint); color: var(--ccm-ink); }
.chip-out { background: var(--ccm-ink); color: var(--ccm-badge-ink); border-color: var(--ccm-ink); }
.pdp-desc { border-top: 1px solid var(--ccm-rule); margin-top: 22px; padding-top: 18px; }

.qty-row input {
    width: 76px; padding: 10px; font: inherit; text-align: center;
    border: 1px solid var(--ccm-rule); border-radius: var(--ccm-radius);
    color: var(--ccm-ink); background: var(--ccm-bg);
}

/* --------------------------------------------------------------------- cart */
.cart-layout { display: grid; gap: 22px; grid-template-columns: 1fr; padding: 26px 0; }
.cart-line {
    display: grid; grid-template-columns: 74px 1fr; gap: 14px;
    padding: 15px 0; border-bottom: 1px solid var(--ccm-rule-soft);
}
/* 74 square, fixed. A basket line whose height depends on the shape of a
   photograph makes a list of five items five different heights. */
.cart-line img {
    width: 74px;
    height: 74px;
    max-width: 74px;
    max-height: 74px;
    flex: 0 0 74px;
    object-fit: contain;
    padding: 4px;
    box-sizing: border-box;
    border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius);
    background: var(--ccm-bg);
}
.cart-line.is-unavailable { opacity: .62; }
.cart-line-top { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.cart-actions input {
    width: 62px; padding: 6px 8px; font: inherit; text-align: center;
    border: 1px solid var(--ccm-rule); border-radius: var(--ccm-radius);
}

.summary {
    border: 1px solid var(--ccm-rule); border-radius: var(--ccm-radius);
    padding: 20px; background: var(--ccm-bg); align-self: start;
}
.summary-line { display: flex; justify-content: space-between; gap: 12px; padding: 7px 0; font-size: 13.5px; }
.summary-total {
    border-top: 1px solid var(--ccm-rule); margin-top: 10px; padding-top: 13px;
    font-size: 17px; font-weight: 700; color: var(--ccm-ink);
}
.vendor-group { border: 1px solid var(--ccm-rule-soft); border-radius: var(--ccm-radius); padding: 12px 14px; margin-bottom: 12px; }
.vendor-group h4 { font-size: 12.5px; color: var(--ccm-muted); font-weight: 600; }

/* ------------------------------------------------------------------- alerts */
.notice { padding: 12px 15px; border-radius: var(--ccm-radius); font-size: 13.5px; margin: 16px 0; border: 1px solid var(--ccm-rule); }
.notice-ok { background: var(--ccm-mint); color: var(--ccm-ink); }
.notice-bad { background: var(--ccm-bg); border-left: 3px solid var(--ccm-red); color: var(--ccm-ink); }
.notice-info { background: var(--ccm-surface); color: var(--ccm-ink); }

/* A condition somebody has to act on, so it carries the amber edge that means
   exactly that everywhere else on this site. */
.notice-warn { background: var(--ccm-bg); border-left: 3px solid var(--ccm-amber); color: var(--ccm-ink); }

.empty-state { text-align: center; padding: 56px 20px; color: var(--ccm-muted); border: 1px dashed var(--ccm-rule); border-radius: var(--ccm-radius); }

/* -------------------------------------------------------------- browse page */
.browse { display: grid; gap: 24px; grid-template-columns: 1fr; padding: 24px 0; }
/* ------------------------------------------------------------ browse sidebar
   One panel, sectioned by rules rather than three separate boxes: a stack of
   equally-weighted cards makes every filter look like a heading of its own,
   and the eye has nowhere to start.

   The links are plain markup and always on screen. An earlier version wrapped
   them in a <details> so a phone could collapse them, which nobody asked for
   and which hid the whole sidebar: browsers hide a closed <details>'s content
   in a way that `display: block` on the child does not override, so on desktop
   — where the summary was hidden too — the panel rendered empty with no way to
   open it. Navigation is the point of this column; it stays visible.

   Rows are full-width targets, not bare text links. A 13px word is a poor
   thing to hit with a thumb, and the old list gave no feedback at all on
   hover — you could not tell a category apart from a caption. */
.browse-side { align-self: start; }

.side-shell {
    border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius);
    background: var(--ccm-bg);
    overflow: hidden;
}

.side-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 13px 16px;
    background: var(--ccm-surface);
    border-bottom: 1px solid var(--ccm-rule);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .02em;
    color: var(--ccm-ink);
}
.side-head svg { width: 16px; height: 16px; color: var(--ccm-orange); }

/* Pushed to the far edge so it reads as an escape from the filters rather
   than another one of them. */
.side-clear {
    margin-left: auto;
    font-size: 12px;
    font-weight: 600;
    color: var(--ccm-orange);
}
.side-clear:hover { text-decoration: underline; }

.filters-panel { padding: 16px; }
.filters-panel + .filters-panel { border-top: 1px solid var(--ccm-rule); }
.filters-panel h3 {
    margin-bottom: 8px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--ccm-muted);
}

.filter-list { list-style: none; margin: 0 -6px; padding: 0; }

.filter-row {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--ccm-radius);
    font-size: 13.5px;
    line-height: 1.3;
    color: var(--ccm-body);
    transition: background .14s ease, color .14s ease;
}
.filter-row:hover { background: var(--ccm-surface); color: var(--ccm-ink); }

/* Children are indented with a guide rule rather than the "— " prefix the
   markup used to print. Punctuation standing in for structure reads as part
   of the category name, and it does not survive a screen reader. */
.filter-item { list-style: none; }

/* The department name and its fold control are two separate targets on one
   line. They used to be one link with a decorative caret drawn inside it,
   which is why tapping the caret only ever navigated: there was nothing
   underneath it to click. */
.filter-line { display: flex; align-items: stretch; gap: 2px; }
.filter-line .filter-row { flex: 1; min-width: 0; }
.filter-row.is-parent { font-weight: 600; color: var(--ccm-ink); }

.filter-branch {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    border-radius: var(--ccm-radius);
    color: var(--ccm-muted);
    transition: background .14s ease, color .14s ease;
}
.filter-branch:hover { background: var(--ccm-surface); color: var(--ccm-ink); }
.filter-branch.is-open { color: var(--ccm-orange); }

/* Points down when the branch below it is open, right when it is folded —
   the arrow indicates the direction the list will move. */
.filter-caret {
    width: 14px;
    height: 14px;
    transition: transform .18s ease;
}
.filter-branch.is-open .filter-caret { transform: rotate(90deg); }

.filter-kids { list-style: none; margin: 0; padding: 0; }
.filter-row.is-child { padding-left: 30px; font-size: 13px; }
/* A guide rule under the open department, rather than the "\2014 " that the
   markup used to print into the name — punctuation standing in for structure
   reads as part of the category and does not survive a screen reader. */
.filter-row.is-child::before {
    content: "";
    position: absolute;
    left: 14px;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--ccm-rule);
}
.filter-list li:last-child .filter-row.is-child::before { bottom: 50%; }

.filter-row.is-active {
    background: var(--ccm-mint);
    color: var(--ccm-ink);
    font-weight: 600;
}
/* The accent bar is what makes the selection findable at a glance in a long
   list; the tint alone is too quiet next to a hover. */
.filter-row.is-active::after {
    content: "";
    position: absolute;
    left: 0;
    top: 6px;
    bottom: 6px;
    width: 3px;
    border-radius: 0 2px 2px 0;
    background: var(--ccm-orange);
}
.filter-row.is-child.is-active::before { background: var(--ccm-orange); }

.filter-label { flex: 1; min-width: 0; overflow-wrap: anywhere; }

.filter-row .count {
    flex: none;
    padding: 1px 6px;
    border-radius: 8px;
    background: var(--ccm-surface);
    color: var(--ccm-muted);
    font-size: 11px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.filter-row:hover .count, .filter-row.is-active .count { background: var(--ccm-bg); }

/* Show only — toggles, because these two are on/off and a plain link gave no
   sign of which state a click would leave you in. */
.filter-toggles { display: flex; flex-wrap: wrap; gap: 7px; }
.filter-toggle {
    padding: 6px 13px;
    border: 1px solid var(--ccm-rule);
    border-radius: 999px;
    font-size: 12.5px;
    color: var(--ccm-body);
    transition: border-color .14s ease, background .14s ease, color .14s ease;
}
.filter-toggle:hover { border-color: var(--ccm-body); color: var(--ccm-ink); }
.filter-toggle.is-on {
    border-color: var(--ccm-orange);
    background: var(--ccm-orange);
    color: var(--ccm-badge-ink);
    font-weight: 600;
}

.browse-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.browse-head select, .price-filter input {
    padding: 8px 10px; font: inherit; font-size: 13px;
    border: 1px solid var(--ccm-rule); border-radius: var(--ccm-radius);
    color: var(--ccm-ink); background: var(--ccm-bg);
}
.price-filter { display: flex; flex-direction: column; gap: 10px; }
.price-row { display: flex; align-items: center; gap: 7px; }
.price-box {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 3px;
    padding: 0 9px;
    border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius);
    background: var(--ccm-bg);
}
.price-box:focus-within { border-color: var(--ccm-orange); }
.price-cue { flex: none; font-size: 12.5px; color: var(--ccm-muted); }
/* The box owns the border now, so the input inside must give its own up —
   otherwise the field reads as a box drawn inside a box. */
.price-filter .price-box input {
    width: 100%;
    min-width: 0;
    padding: 8px 0;
    border: 0;
    background: none;
    font-size: 13px;
}
.price-filter .price-box input:focus { outline: none; }
.price-dash { flex: none; color: var(--ccm-muted); font-size: 12px; }

/* On a phone the sidebar sits above the products. Only one department is
   expanded at a time, so the list is short enough to read without a scroll
   box of its own; the cap is a guard for a shop that grows a lot of
   departments, not the normal case. */
@media (max-width: 767px) {
    .filters-panel .filter-list { max-height: 340px; overflow-y: auto; }
}

.pager { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 26px; }
.pager a, .pager span {
    padding: 7px 12px; border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius); font-size: 13px; color: var(--ccm-body);
}
.pager .is-current { background: var(--ccm-mint); color: var(--ccm-ink); font-weight: 600; }
.pager .is-disabled { opacity: .45; }

/* ------------------------------------------------------------------- footer */
.shop-foot { background: var(--ccm-surface); border-top: 1px solid var(--ccm-rule); margin-top: 44px; padding: 34px 0 0; }
.foot-cols { display: grid; gap: 26px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.foot-cols h4 { font-size: 13px; margin-bottom: 11px; }
.foot-cols ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; font-size: 13px; }
.foot-bottom {
    border-top: 1px solid var(--ccm-rule); margin-top: 28px; padding: 15px 0;
    font-size: 12px; color: var(--ccm-muted);
    display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}

/* --------------------------------------------------------------- responsive */
/* Tablet and up: side-by-side layouts. Aligned to the same 768px the header
   bands use — two nearly-equal breakpoints 8px apart is how a layout ends up
   reflowing twice on the way through a tablet. */
@media (min-width: 768px) {
    .hero .shell { grid-template-columns: 1.15fr .85fr; }
    .pdp { grid-template-columns: 1fr 1fr; gap: 36px; }
    .cart-layout { grid-template-columns: 1fr 320px; }
    .browse { grid-template-columns: 248px 1fr; gap: 28px; }
    /* Follows the page down, so the categories are still reachable when a
       shopper is forty products into a long listing. */
    .browse-side { position: sticky; top: 16px; max-height: calc(100vh - 32px); overflow-y: auto; }
    .cart-line { grid-template-columns: 92px 1fr; }
    .cart-line img { width: 92px; height: 92px; }
}

@media (min-width: 1024px) {
    .grid { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* Breadcrumb and the inline saving chip on the product page. Separate classes
   rather than inline styles, because the CSP forbids style attributes. */
.breadcrumb { font-size: 11.5px; color: var(--ccm-muted); padding: 14px 0 0; }
.save-chip {
    display: inline-block; margin-left: 8px; vertical-align: middle;
    background: var(--ccm-orange); color: var(--ccm-badge-ink);
    font-size: 11px; font-weight: 700; padding: 3px 7px; border-radius: 2px;
}
.visually-hidden {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Cart line details. */
.breadcrumb-title { font-size: 24px; margin: 22px 0 4px; }
.cart-line-noimage {
    display: block; width: 74px; height: 74px;
    border: 1px solid var(--ccm-rule); border-radius: var(--ccm-radius);
    background: var(--ccm-surface);
}
.cart-line-price { text-align: right; }
.line-issue { color: var(--ccm-red); font-size: 12.5px; font-weight: 600; margin-top: 4px; }
.cart-clear { margin-top: 16px; }
.summary h2 { font-size: 16px; margin-bottom: 10px; }
.summary .card-cat { margin-top: 12px; }
.notice ul { margin: 8px 0 0; padding-left: 20px; }

/* =============================================================================
   Homepage slider
   -----------------------------------------------------------------------------
   Every slide occupies ONE grid cell and they cross-fade. That means the cell
   is as tall as the tallest slide, so unless every slide fills it, a shorter
   one leaves the backing showing — which is exactly the dark band that
   appeared under an image slide sitting beside a taller text slide.

   The fix is to give the band one height and make both kinds of slide fill it:
   the text slide by centring its content, the image by covering. No slide is
   allowed to size the band on its own.

   The first slide is visible with no JavaScript at all; the script only adds
   movement.
   ========================================================================== */

.hero-slider {
    position: relative;
    display: grid;
    /* One height for the whole band, at every width. Scales with the viewport
       rather than jumping between two fixed sizes. */
    min-height: clamp(280px, 42vw, 440px);
    background: var(--ccm-mint);
    overflow: hidden;
}

.hero-track {
    display: grid;
    grid-template-areas: "slide";
    min-height: inherit;
}

.hero-slide {
    grid-area: slide;
    min-height: inherit;
    opacity: 0;
    visibility: hidden;
    transition: opacity .45s ease;
}

.hero-slide.is-current { opacity: 1; visibility: visible; }

/* --- Text slide ----------------------------------------------------------- */

.hero-slide.is-text { display: flex; align-items: center; }
.hero-slide.is-text .hero { width: 100%; background: transparent; border: 0; padding: 32px 0; }

/* --- Image slide ---------------------------------------------------------- */

/* No dark backing. If the artwork ever fails to cover, the brand mint shows
   through, which is a background rather than a hole. */
.hero-slide.is-image { display: block; }

.hero-slide.is-image picture,
.hero-image-link {
    display: block;
    width: 100%;
    height: 100%;
}

.hero-image {
    display: block;
    width: 100%;
    height: 100%;
    /* cover, so the band is filled at every aspect ratio; centre, so a banner
       whose subject sits in the middle survives the crop on a narrow screen. */
    object-fit: cover;
    object-position: center;
}

/* --- Arrows and dots ------------------------------------------------------ */

.hero-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: var(--ccm-bg);
    color: var(--ccm-ink);
    box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
    cursor: pointer;
    opacity: .9;
}
.hero-nav:hover { opacity: 1; }
.hero-nav svg { width: 16px; height: 16px; }
.hero-prev { left: 14px; }
.hero-next { right: 14px; }

.hero-dots {
    position: absolute;
    left: 0; right: 0; bottom: 12px;
    z-index: 2;
    display: flex;
    justify-content: center;
    gap: 7px;
}
.hero-dot {
    width: 9px; height: 9px;
    border: 0; padding: 0;
    border-radius: 50%;
    background: var(--ccm-bg);
    opacity: .55;
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
}
.hero-dot.is-current { opacity: 1; background: var(--ccm-amber); }

@media (prefers-reduced-motion: reduce) {
    .hero-slide { transition: none; }
}

/* --- Phone ---------------------------------------------------------------- */

@media (max-width: 767px) {
    .hero-slider { min-height: clamp(200px, 56vw, 300px); }

    /* The four promise boxes are hidden on a phone. They are reassurance, not
       navigation, and on a small screen they push the actual products a full
       screen further down. The same promises are in the footer, where someone
       who wants them will look. */
    .promise-row { display: none; }

    .hero-slide.is-text .hero { padding: 22px 0; }
    .hero h1 { font-size: clamp(24px, 7vw, 32px); }
    .hero p  { font-size: 14px; }
    .hero-actions { margin-top: 16px; }
    .hero-nav { width: 30px; height: 30px; }
}

/* =============================================================================
   Header and departments — the responsive rules
   -----------------------------------------------------------------------------
   These come last on purpose: they supersede the earlier masthead and deptbar
   blocks, which were written before the client supplied the desktop reference.

   Three bands, and every one of them is a real device:

     up to 767px    phone      two stacked rows, icons only
     768–1023px     tablet     the desktop arrangement, tightened
     1024px and up  desktop    the client's reference, at full size

   The desktop arrangement is the default and phones are the override, rather
   than the other way round, because the department bar and the support block
   are the parts that need the most room and it is clearer to take things away
   than to bolt them on.
   ========================================================================== */

/* --- Masthead ------------------------------------------------------------- */

.masthead { border-bottom: 1px solid var(--ccm-rule); background: var(--ccm-bg); padding: 12px 0; }

.masthead .shell {
    display: flex;
    align-items: center;
    gap: 18px;
    flex-wrap: nowrap;
}

.brand { flex: none; }
.brand img { display: block; width: 200px; max-width: 100%; height: auto; }

/* The department control. Three bars, no library. */
.menu-toggle {
    flex: none;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 40px;
    height: 40px;
    padding: 0 6px;
    border: 0;
    background: transparent;
    cursor: pointer;
}
.menu-toggle span {
    display: block;
    height: 2.5px;
    border-radius: 2px;
    background: var(--ccm-ink);
    transition: background .15s;
}
.menu-toggle:hover span { background: var(--ccm-red); }

/* --- Search --------------------------------------------------------------- */

.searchbar { flex: 1 1 auto; display: flex; min-width: 0; }

.searchbar input {
    flex: 1 1 auto;
    min-width: 0;
    border: 1px solid var(--ccm-rule);
    border-right: 0;
    border-radius: 3px 0 0 3px;
    padding: 12px 14px;
    font-family: inherit;
    font-size: 14px;
    color: var(--ccm-ink);
    background: var(--ccm-bg);
    outline: none;
}
.searchbar input:focus { border-color: var(--ccm-muted); }

.searchbar button {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    border: 0;
    border-radius: 0 3px 3px 0;
    background: var(--ccm-amber);
    color: var(--ccm-ink);
    padding: 0 26px;
    cursor: pointer;
}
.searchbar button:hover { filter: brightness(.94); }
.searchbar button svg { width: 20px; height: 20px; }

/* --- Customer support ----------------------------------------------------- */

.head-support {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: var(--ccm-ink);
    text-decoration: none;
}
.head-support svg { width: 30px; height: 30px; color: var(--ccm-body); flex: none; }
.head-support-text { display: flex; flex-direction: column; line-height: 1.25; }
.head-support-text small {
    font-size: 11px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ccm-body);
}
.head-support-text strong { font-size: 15px; color: var(--ccm-amber); }
.head-support:hover .head-support-text strong { color: var(--ccm-red); }

/* --- Basket and account --------------------------------------------------- */

.head-actions { display: flex; align-items: center; gap: 20px; flex: none; }

.head-link {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-size: 13px;
    color: var(--ccm-ink);
    text-decoration: none;
}

.head-glyph { position: relative; display: inline-flex; flex: none; }
.head-glyph svg { width: 28px; height: 28px; }

.cart-pill {
    position: absolute;
    top: -5px;
    right: -8px;
    min-width: 19px;
    height: 19px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 5px;
    border-radius: 10px;
    background: var(--ccm-amber);
    color: var(--ccm-ink);
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
}

.head-stack { display: flex; flex-direction: column; line-height: 1.3; }
.head-stack strong { font-size: 13.5px; font-weight: 600; }
.head-stack small { font-size: 11.5px; color: var(--ccm-body); }
.head-stack a { color: var(--ccm-ink); text-decoration: none; }
.head-stack a:hover { color: var(--ccm-red); }

/* =============================================================================
   Department bar
   -----------------------------------------------------------------------------
   White ground, dark text, an amber underline on the current department — the
   live site's treatment, and the client's reference.
   ========================================================================== */

.deptbar { border-bottom: 1px solid var(--ccm-rule); background: var(--ccm-bg); }
.deptbar .shell { display: flex; align-items: stretch; gap: 2px; flex-wrap: wrap; }

.dept { position: relative; }

.dept-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 13px 14px;
    font-size: 14px;
    font-weight: 400;
    color: var(--ccm-ink);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    list-style: none;
    border-bottom: 2px solid transparent;
    background: transparent;
}

/* Safari still paints a disclosure triangle without both of these. */
.dept-link::-webkit-details-marker { display: none; }
.dept-link::marker { content: ''; }

.dept-link:hover,
.dept-link:focus-visible { color: var(--ccm-red); border-bottom-color: var(--ccm-amber); background: transparent; }
.dept-link.is-active { border-bottom-color: var(--ccm-amber); font-weight: 600; }

.dept-home svg { width: 19px; height: 19px; }
.dept-caret { width: 12px; height: 12px; color: var(--ccm-body); transition: transform .15s; }
.dept[open] .dept-caret { transform: rotate(180deg); }

.dept-panel {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 40;
    min-width: 250px;
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    border-top: 2px solid var(--ccm-amber);
    border-radius: 0 0 4px 4px;
    box-shadow: 0 10px 28px rgba(0, 0, 0, .14);
    padding: 10px 0;
}

.dept-all {
    display: block;
    padding: 7px 18px 9px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--ccm-rule-soft);
    font-size: 13px;
    font-weight: 700;
    color: var(--ccm-ink);
    text-decoration: none;
}
.dept-all:hover { color: var(--ccm-red); }
.dept-all .count { color: var(--ccm-muted); font-weight: 400; }

.dept-panel ul { list-style: none; margin: 0; padding: 0; }
.dept-panel li a {
    display: block;
    padding: 8px 18px;
    font-size: 13px;
    color: var(--ccm-body);
    text-decoration: none;
}
.dept-panel li a:hover { background: var(--ccm-mint); color: var(--ccm-ink); }

/* A mouse gets hover. Touch gets the <details> toggle, which needs no script —
   a menu that only opens on hover is a menu half the customers cannot open. */
@media (hover: hover) and (pointer: fine) {
    .dept:hover > .dept-panel { display: block; }
}

/* =============================================================================
   Tablet — 768px to 1023px
   -----------------------------------------------------------------------------
   The desktop arrangement, tightened. Everything the client's reference shows
   is still present; it is only narrower.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {
    .masthead .shell { gap: 12px; }
    .brand img { width: 168px; }

    .searchbar input  { padding: 10px 12px; font-size: 13.5px; }
    .searchbar button { padding: 0 18px; }

    /* The support label goes; the number stays, because the number is the
       part anybody actually uses. */
    .head-support svg { width: 26px; height: 26px; }
    .head-support-text small { display: none; }
    .head-support-text strong { font-size: 14px; }

    .head-actions { gap: 14px; }
    .head-glyph svg { width: 26px; height: 26px; }
    .head-word { display: none; }

    .dept-link { padding: 12px 10px; font-size: 13px; }
    .deptbar .shell { overflow-x: auto; flex-wrap: nowrap; }
}

/* =============================================================================
   Phone — up to 767px
   -----------------------------------------------------------------------------
   Two rows, as in the client's mobile reference: logo with the basket and
   account icons, then the menu button beside a full-width amber search.
   ========================================================================== */

@media (max-width: 767px) {
    .masthead .shell {
        display: grid;
        grid-template-columns: 1fr auto auto;
        grid-template-areas:
            "brand cart account"
            "menu  search search";
        gap: 12px 10px;
        align-items: center;
        flex-wrap: wrap;
    }

    .brand     { grid-area: brand; }
    .brand img { width: 165px; }

    .menu-toggle  { width: 34px; padding: 0; }
    .searchbar    { grid-area: search; }
    .head-actions { display: contents; }

    /* The support block belongs on a phone's dialler, not its header. The
       number is one tap away in the footer and on every product page. */
    .head-support { display: none; }

    .head-link:nth-of-type(1) { grid-area: cart;    justify-self: end; }
    .head-actions > :nth-child(2) { grid-area: account; justify-self: end; }

    .head-word { display: none; }
    .head-glyph svg { width: 26px; height: 26px; }

    .searchbar input  { padding: 11px 12px; font-size: 13.5px; }
    .searchbar button { padding: 0 20px; }

    /* The department strip becomes a drawer. */
    .deptbar { display: none; border-top: 1px solid var(--ccm-rule); }
    .deptbar.is-open { display: block; }
    .deptbar .shell { flex-direction: column; align-items: stretch; gap: 0; flex-wrap: nowrap; }

    .dept-link {
        justify-content: space-between;
        width: 100%;
        padding: 13px 4px;
        border-bottom: 1px solid var(--ccm-rule-soft);
    }
    .dept-link.is-active { border-bottom-color: var(--ccm-amber); }
    .dept-home { justify-content: flex-start; }

    .dept-panel {
        position: static;
        border: 0;
        border-radius: 0;
        box-shadow: none;
        background: var(--ccm-surface);
        padding: 4px 0 8px 14px;
    }

}

/* Very small phones: give the search its own row rather than crushing it. */
@media (max-width: 380px) {
    .brand img { width: 140px; }
    .head-actions { gap: 12px; }
    .head-glyph svg { width: 24px; height: 24px; }
}

/* =============================================================================
   Topbar
   -----------------------------------------------------------------------------
   Two facts, each with its own icon: where we deliver, and when. Dark ground so
   it separates cleanly from the white masthead below it without a rule.
   ========================================================================== */

.topbar {
    background: var(--ccm-ink);
    color: var(--ccm-bg);
    font-size: 12.5px;
    padding: 8px 0;
}

.topbar .shell {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.topbar a { color: var(--ccm-amber); text-decoration: none; }
.topbar a:hover { text-decoration: underline; }

.topbar-item {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    line-height: 1.4;
}

.topbar-item svg {
    width: 16px;
    height: 16px;
    flex: none;
    color: var(--ccm-amber);
}

.topbar-item strong { font-weight: 600; color: var(--ccm-bg); }
.topbar-sep { color: var(--ccm-muted); padding: 0 3px; }

/* =============================================================================
   Shop by category
   -----------------------------------------------------------------------------
   The tile carries an initial as its mark. Not decoration: with no per-category
   artwork in the system yet, a row of identical grey boxes is harder to scan
   than a row of distinct letters, and inventing placeholder imagery would mean
   shipping pictures that promise something the catalogue does not have.
   ========================================================================== */

.cat-grid {
    display: grid;
    gap: 14px;
    grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
}

.cat-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius);
    padding: 20px 14px 16px;
    text-align: center;
    background: var(--ccm-bg);
    color: var(--ccm-ink);
    text-decoration: none;
    transition: border-color .15s, box-shadow .15s, transform .15s;
}

.cat-tile:hover,
.cat-tile:focus-visible {
    border-color: var(--ccm-amber);
    box-shadow: 0 6px 18px rgba(0, 0, 0, .08);
    transform: translateY(-2px);
    text-decoration: none;
}

.cat-tile-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    margin-bottom: 8px;
    border-radius: 50%;
    background: var(--ccm-mint);
    color: var(--ccm-red);
    font-size: 20px;
    font-weight: 700;
    line-height: 1;
    transition: background .15s, color .15s;
}

.cat-tile:hover .cat-tile-mark { background: var(--ccm-amber); color: var(--ccm-ink); }

.cat-tile strong { display: block; font-size: 13.5px; line-height: 1.3; font-weight: 600; }
.cat-tile-count { font-size: 11.5px; color: var(--ccm-muted); }

/* An empty department is still listed — a shopper looking for Fashion should
   find the word Fashion — but it is visibly quieter than a stocked one. */
.cat-tile.is-empty .cat-tile-mark { background: var(--ccm-rule-soft); color: var(--ccm-muted); }
.cat-tile.is-empty strong { color: var(--ccm-body); }

/* The section heading gained a subtitle, so its row aligns to the top. */
.row-head { align-items: flex-start; }
.row-head a { white-space: nowrap; padding-top: 4px; }

@media (max-width: 767px) {
    .topbar { font-size: 11.5px; padding: 7px 0; }
    .topbar .shell { justify-content: center; text-align: center; gap: 4px 14px; }
    .topbar-item svg { width: 14px; height: 14px; }

    .cat-grid { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 10px; }
    .cat-tile { padding: 16px 10px 12px; }
    .cat-tile-mark { width: 40px; height: 40px; font-size: 17px; }
}

/* =============================================================================
   Password reveal
   -----------------------------------------------------------------------------
   A password nobody can read is a password typed wrong, especially on a phone
   keyboard. The toggle is a real <button> so it is reachable by keyboard, and
   it never submits the form.
   ========================================================================== */

.password-field { position: relative; display: block; }

.password-field input { width: 100%; padding-right: 44px; }

.password-toggle {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 0;
    border-radius: 4px;
    background: transparent;
    color: var(--ccm-muted);
    cursor: pointer;
}

.password-toggle:hover { color: var(--ccm-ink); }
.password-toggle:focus-visible { outline: 2px solid var(--ccm-link); outline-offset: 1px; }
.password-toggle svg { width: 19px; height: 19px; }

/* Two icons, one shown at a time — swapped by the button's aria-pressed state,
   so the visual and the announced state cannot drift apart. */
.password-toggle .icon-hide { display: none; }
.password-toggle[aria-pressed="true"] .icon-show { display: none; }
.password-toggle[aria-pressed="true"] .icon-hide { display: block; }

/* =============================================================================
   The department panel behind the button beside the logo
   -----------------------------------------------------------------------------
   Departments down the left; the one under the pointer opens its
   sub-categories on the right. Only department names are listed by default,
   because thirty sub-categories on screen at once is a wall of text to read
   rather than a menu to use.

   It reveals on hover and on keyboard focus, in CSS. The script only handles
   opening and closing the panel itself.
   ========================================================================== */

.menu-holder { position: relative; flex: none; }

.mega-panel {
    display: none;
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    z-index: 60;
    width: 268px;
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    border-top: 3px solid var(--ccm-amber);
    border-radius: 0 0 6px 6px;
    box-shadow: 0 16px 40px rgba(0, 0, 0, .16);
    padding: 8px 0 0;
}

.mega-panel.is-open { display: block; }

/* Bridges the gap between button and panel, so crossing it does not close the
   menu. Invisible, and it moves nothing. */
.mega-panel::before {
    content: '';
    position: absolute;
    top: -13px;
    left: 0;
    right: 0;
    height: 13px;
}

.mega-list { list-style: none; margin: 0; padding: 0; }

.mega-dept { position: relative; }

.mega-dept-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 11px 16px;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--ccm-ink);
    text-decoration: none;
    border-left: 3px solid transparent;
    transition: background .12s, border-color .12s, color .12s;
}

.mega-dept:hover > .mega-dept-link,
.mega-dept:focus-within > .mega-dept-link {
    background: var(--ccm-mint);
    border-left-color: var(--ccm-amber);
    color: var(--ccm-red);
}

.mega-caret { width: 13px; height: 13px; flex: none; color: var(--ccm-muted); }
.mega-dept:hover .mega-caret { color: var(--ccm-red); }

/* --- The flyout ----------------------------------------------------------- */

.mega-subs {
    display: none;
    position: absolute;
    top: -9px;
    left: 100%;
    min-width: 260px;
    max-width: 340px;
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    border-top: 3px solid var(--ccm-amber);
    border-radius: 0 6px 6px 0;
    box-shadow: 0 16px 40px rgba(0, 0, 0, .16);
    padding: 12px 0;
}

.mega-dept.has-subs:hover > .mega-subs,
.mega-dept.has-subs:focus-within > .mega-subs { display: block; }

.mega-subs-all {
    display: flex;
    align-items: baseline;
    gap: 7px;
    padding: 4px 18px 10px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--ccm-rule-soft);
    font-size: 13px;
    font-weight: 700;
    color: var(--ccm-ink);
    text-decoration: none;
}

.mega-subs-all:hover { color: var(--ccm-red); }
.mega-subs-all .count { font-size: 11px; font-weight: 400; color: var(--ccm-muted); }

.mega-subs ul { list-style: none; margin: 0; padding: 0; }

.mega-subs li a {
    display: block;
    padding: 6px 18px;
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--ccm-body);
    text-decoration: none;
}

.mega-subs li a:hover { background: var(--ccm-mint); color: var(--ccm-ink); }

/* --- Footer --------------------------------------------------------------- */

.mega-foot {
    display: block;
    margin-top: 6px;
    padding: 11px 16px;
    border-top: 1px solid var(--ccm-rule-soft);
    background: var(--ccm-surface);
    border-radius: 0 0 6px 6px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ccm-red);
    text-decoration: none;
}

.mega-foot:hover { background: var(--ccm-mint); }

/* If the panel would run off the right edge, flip the flyout to the left. */
@media (max-width: 1100px) {
    .mega-subs { left: auto; right: 100%; border-radius: 6px 0 0 6px; }
}

/* On a phone the button opens the department bar as a drawer instead, so the
   panel never appears — one list, reached two ways, rather than two lists. */
@media (max-width: 767px) {
    .mega-panel,
    .mega-panel.is-open { display: none; }

    .menu-holder { grid-area: menu; }
}

/* A folded department's own children sit one step in, so "Mens Fashion" reads
   as belonging to "Fashion" rather than sitting beside it. */
.mega-subs li.is-nested a { padding-left: 32px; color: var(--ccm-muted); }
.mega-subs li.is-nested a:hover { color: var(--ccm-ink); }

/* =============================================================================
   Checkout — the professional treatment
   -----------------------------------------------------------------------------
   Rewritten over the first pass. This is the screen where a shopper decides
   whether to trust the shop with money, so it is the one screen where the
   visual work is doing a job rather than decorating.

   Three decisions:

     * Numbered steps. A checkout that looks like one long form reads as
       long; the same fields under "1 Delivery / 2 Contact / 3 Payment" read as
       three short ones.
     * A summary that follows you down the page on a desktop, so the total is
       never scrolled off while you fill in an address.
     * The total set apart in the brand amber. It is the single number the
       customer is actually deciding about.
   ========================================================================== */

.checkout-layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: 26px;
    align-items: start;
    padding: 8px 0 48px;
}

/* --- Page heading --------------------------------------------------------- */

.checkout-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 26px 0 18px;
    border-bottom: 1px solid var(--ccm-rule);
    margin-bottom: 22px;
}

.checkout-head h1 { font-size: 26px; letter-spacing: -.02em; margin: 0; }
.checkout-head .sub { font-size: 13px; color: var(--ccm-muted); margin-top: 4px; }

.checkout-secure {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ccm-body);
}
.checkout-secure svg { width: 16px; height: 16px; color: var(--ccm-red); }

/* --- Panels as numbered steps --------------------------------------------- */

.panel {
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    border-radius: 6px;
    padding: 22px 24px 24px;
    margin-bottom: 18px;
}

.panel h2 {
    display: flex;
    align-items: center;
    gap: 11px;
    font-size: 16px;
    margin: 0 0 6px;
    letter-spacing: -.01em;
}

/* The step number. A counter rather than markup, so reordering the panels
   renumbers them automatically and no template carries a hard-coded "2". */
.checkout-layout { counter-reset: step; }

.panel-step h2::before {
    counter-increment: step;
    content: counter(step);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    flex: none;
    border-radius: 50%;
    background: var(--ccm-amber);
    color: var(--ccm-ink);
    font-size: 13px;
    font-weight: 700;
}

.panel > .card-cat { margin: 0 0 16px; }

/* --- Fields --------------------------------------------------------------- */

.field-row { display: grid; grid-template-columns: 1fr; gap: 0 16px; }

.checkout-layout .field { margin-bottom: 14px; }

.checkout-layout label {
    display: block;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ccm-ink);
    margin-bottom: 5px;
}

.checkout-layout input[type="text"],
.checkout-layout input[type="tel"],
.checkout-layout input[type="email"],
.checkout-layout select,
.checkout-layout textarea {
    width: 100%;
    border: 1px solid var(--ccm-rule);
    border-radius: 4px;
    padding: 11px 13px;
    font-family: inherit;
    font-size: 14px;
    color: var(--ccm-ink);
    background: var(--ccm-bg);
    outline: none;
    transition: border-color .12s, box-shadow .12s;
}

.checkout-layout input:focus,
.checkout-layout select:focus,
.checkout-layout textarea:focus {
    border-color: var(--ccm-amber);
    box-shadow: 0 0 0 3px var(--ccm-mint);
}

.checkout-layout input[aria-invalid="true"] { border-color: var(--ccm-red); }
.checkout-layout textarea { resize: vertical; min-height: 62px; }

/* --- Choosing an address or a payment method ------------------------------ */

.pick {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    border: 1px solid var(--ccm-rule);
    border-radius: 5px;
    padding: 13px 15px;
    margin-bottom: 9px;
    cursor: pointer;
    transition: border-color .12s, background .12s, box-shadow .12s;
}

.pick:hover { border-color: var(--ccm-muted); }
.pick input { margin-top: 3px; flex: none; accent-color: var(--ccm-red); }
.pick span { display: block; line-height: 1.5; }
.pick .card-cat { display: block; margin-top: 3px; }

.pick:has(input:checked) {
    border-color: var(--ccm-red);
    background: var(--ccm-mint);
    box-shadow: inset 0 0 0 1px var(--ccm-red);
}

.pick.is-disabled { opacity: .5; cursor: not-allowed; }
.pick.is-disabled:hover { border-color: var(--ccm-rule); }

/* --- The summary ---------------------------------------------------------- */

.summary {
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    border-radius: 6px;
    padding: 22px 24px;
}

.summary h2 {
    font-size: 15px;
    margin: 0 0 14px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--ccm-rule-soft);
    letter-spacing: -.01em;
}

.summary-line {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 14px;
    font-size: 13.5px;
    padding: 6px 0;
}

.summary-line > span:first-child { color: var(--ccm-body); }
.summary-line > span:last-child { font-weight: 600; text-align: right; }

.summary-rule {
    border-top: 1px solid var(--ccm-rule-soft);
    margin-top: 10px;
    padding-top: 12px;
}

/* The one number the customer is deciding about. */
.summary-total {
    margin-top: 12px;
    padding-top: 14px;
    border-top: 2px solid var(--ccm-ink);
    font-size: 17px;
}
.summary-total > span:first-child { color: var(--ccm-ink); font-weight: 700; }
.summary-total > span:last-child { font-weight: 700; font-size: 20px; }

.summary .btn-block { margin-top: 18px; }
.summary .card-cat { display: block; margin-top: 10px; line-height: 1.55; }

/* --- Reassurance under the button ----------------------------------------- */

.checkout-assure {
    list-style: none;
    margin: 16px 0 0;
    padding: 16px 0 0;
    border-top: 1px solid var(--ccm-rule-soft);
}

.checkout-assure li {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    font-size: 12px;
    line-height: 1.5;
    color: var(--ccm-body);
    padding: 5px 0;
}

.checkout-assure svg { width: 15px; height: 15px; flex: none; margin-top: 1px; color: var(--ccm-red); }

/* --- Wide screens --------------------------------------------------------- */

@media (min-width: 900px) {
    .checkout-layout { grid-template-columns: minmax(0, 1fr) 360px; }

    /* The total stays in view while the address is filled in. */
    .checkout-layout .summary { position: sticky; top: 18px; }
}

@media (max-width: 767px) {
    .panel { padding: 18px 16px 20px; border-radius: 5px; }
    .summary { padding: 18px 16px; }
    .checkout-head { padding: 18px 0 14px; }
    .checkout-head h1 { font-size: 22px; }
    .summary-total > span:last-child { font-size: 18px; }
}

/* --- Confirmation --------------------------------------------------------- */

.order-done { text-align: center; padding: 34px 0 8px; }

.order-done-mark {
    width: 62px;
    height: 62px;
    margin: 0 auto 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--ccm-mint);
    color: var(--ccm-red);
}
.order-done-mark svg { width: 30px; height: 30px; }

.order-done h1 { font-size: 26px; margin: 0 0 8px; }
.order-done-sub { margin: 0 0 16px; font-size: 15px; }

.track-link {
    display: inline-block;
    margin-top: 6px;
    padding: 6px 10px;
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    border-radius: 3px;
    font-size: 12px;
    word-break: break-all;
}

/* --- Status pill ---------------------------------------------------------- */

.order-pill {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 11px;
    font-size: 11.5px;
    font-weight: 700;
    line-height: 1.5;
    white-space: nowrap;
}

.order-pill-ok   { background: var(--ccm-mint);      color: var(--ccm-ink); }
.order-pill-wait { background: var(--ccm-rule-soft); color: var(--ccm-body); }
.order-pill-bad  { background: var(--ccm-red);       color: var(--ccm-bg); }

/* --- Timeline ------------------------------------------------------------- */

.timeline { list-style: none; margin: 10px 0 0; padding: 0 0 0 16px; border-left: 2px solid var(--ccm-rule); }

.timeline li {
    position: relative;
    padding: 0 0 14px 12px;
    font-size: 13px;
    line-height: 1.5;
}

.timeline li::before {
    content: '';
    position: absolute;
    left: -21px;
    top: 5px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ccm-amber);
}

.timeline li:last-child { padding-bottom: 0; }

.timeline-when {
    display: block;
    font-size: 11.5px;
    color: var(--ccm-muted);
}

@media (min-width: 768px) {
    .checkout-layout { grid-template-columns: 1fr 340px; }
    .field-row { grid-template-columns: 1fr 1fr; }
}

/* =============================================================================
   Quantity stepper and icon buttons
   -----------------------------------------------------------------------------
   A stepper rather than a bare number field: on a phone, tapping plus is one
   action where typing into a spinner is three. The field itself stays, because
   it is what submits and what a keyboard user edits.
   ========================================================================== */

.stepper {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--ccm-rule);
    border-radius: 4px;
    overflow: hidden;
    background: var(--ccm-bg);
}

.stepper-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    border: 0;
    background: var(--ccm-surface);
    color: var(--ccm-ink);
    cursor: pointer;
    padding: 0;
    transition: background .12s, color .12s;
}

.stepper-btn:hover { background: var(--ccm-amber); }
.stepper-btn:focus-visible { outline: 2px solid var(--ccm-link); outline-offset: -2px; }

.stepper-btn svg {
    width: 15px;
    height: 15px;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    fill: none;
}

.stepper input[type="number"] {
    width: 52px;
    border: 0;
    border-left: 1px solid var(--ccm-rule);
    border-right: 1px solid var(--ccm-rule);
    text-align: center;
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    color: var(--ccm-ink);
    background: var(--ccm-bg);
    padding: 9px 0;
    outline: none;
    /* The browser's own spinner would sit beside our buttons doing the same
       job, half the size and in the wrong place. */
    -moz-appearance: textfield;
    appearance: textfield;
}

.stepper input[type="number"]::-webkit-outer-spin-button,
.stepper input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* While a change is being sent, the control dims rather than jumping. */
.stepper[aria-busy="true"] { opacity: .55; pointer-events: none; }

/* --- Icon buttons --------------------------------------------------------- */

.icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border: 1px solid var(--ccm-rule);
    border-radius: 4px;
    background: var(--ccm-bg);
    color: var(--ccm-ink);
    cursor: pointer;
    text-decoration: none;
    padding: 0;
    transition: border-color .12s, background .12s, color .12s;
}

.icon-btn:hover {
    border-color: var(--ccm-amber);
    background: var(--ccm-amber);
    color: var(--ccm-ink);
}

.icon-btn svg { width: 20px; height: 20px; }

/* The quiet variant, for a destructive action that should not shout. */
.icon-btn-quiet {
    width: 34px;
    height: 34px;
    border-color: transparent;
    color: var(--ccm-muted);
}
.icon-btn-quiet:hover {
    background: transparent;
    border-color: var(--ccm-red);
    color: var(--ccm-red);
}
.icon-btn-quiet svg { width: 17px; height: 17px; }

/* An icon sitting inside a normal text button. */
.btn-icon {
    width: 15px;
    height: 15px;
    vertical-align: -2px;
    margin-right: 5px;
}

.qty-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin: 18px 0 0;
}

.cart-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 10px;
}

@media (max-width: 767px) {
    .stepper-btn { width: 42px; }
    .stepper input[type="number"] { width: 48px; padding: 11px 0; }
    .qty-row .btn { flex: 1 1 auto; }
}

/* A failed payment gets the same mark as a successful one, in the other tone. */
.order-done-mark.is-bad { background: var(--ccm-rule-soft); color: var(--ccm-red); }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12.5px; }

/* =============================================================================
   Add to basket — the in-place control
   -----------------------------------------------------------------------------
   The button and the stepper occupy the same slot, so swapping between them
   does not move anything else on the page. On a listing that matters: a card
   that changed height on add would shove the rest of the grid around under the
   shopper's finger.
   ========================================================================== */

.add-control { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 18px 0 0; }
.add-control.is-compact { margin: 0; gap: 8px; }

.add-live { display: flex; align-items: center; gap: 8px; }
.add-live[aria-busy="true"] { opacity: .55; pointer-events: none; }

.add-qty {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 46px;
    padding: 9px 4px;
    border-left: 1px solid var(--ccm-rule);
    border-right: 1px solid var(--ccm-rule);
    font-size: 14px;
    font-weight: 700;
    color: var(--ccm-ink);
    background: var(--ccm-bg);
}

.add-note {
    flex: 1 1 100%;
    font-size: 11.5px;
    color: var(--ccm-muted);
    min-height: 15px;
    line-height: 1.3;
}
.add-note.is-bad { color: var(--ccm-red); font-weight: 600; }

/* On a card the control fills the width, and the basket icon shrinks so the
   stepper keeps its target size. */
.add-control.is-compact .btn { flex: 1 1 100%; }
.add-control.is-compact .add-live { width: 100%; }
.add-control.is-compact .stepper { flex: 1 1 auto; }
.add-control.is-compact .add-qty { flex: 1 1 auto; }
.add-control.is-compact .icon-btn { width: 38px; height: 38px; flex: none; }
.add-control.is-compact .stepper-btn { width: 34px; }

/* -----------------------------------------------------------------------------
   [hidden] must actually hide.
   -----------------------------------------------------------------------------
   Any rule that sets `display` on an element beats the browser's built-in
   `[hidden] { display: none }`, because that default has the lowest possible
   precedence. `.add-live { display: flex }` therefore showed every quantity
   stepper on every product at once, whether the shopper had added it or not.
   This one line makes the attribute mean what it says, everywhere.
   -------------------------------------------------------------------------- */
[hidden] { display: none !important; }

/* =============================================================================
   Product image lightbox
   -----------------------------------------------------------------------------
   Tapping a product image opens it large, growing out of the thumbnail rather
   than appearing from nowhere — so it is obvious which picture opened and
   where it will go back to.

   The whole thing is one element appended to <body>, not a copy per image: a
   listing of forty products would otherwise carry forty hidden dialogs.
   ========================================================================== */

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(0, 0, 0, .82);
    opacity: 0;
    transition: opacity .22s ease;
}

.lightbox.is-open { opacity: 1; }

.lightbox-figure {
    position: relative;
    max-width: min(920px, 100%);
    max-height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    /* Grows from 92% as it opens: small enough to read as a zoom, large enough
       not to feel like a bounce. */
    transform: scale(.92);
    opacity: 0;
    transition: transform .26s cubic-bezier(.2, .8, .3, 1), opacity .2s ease;
}

.lightbox.is-open .lightbox-figure { transform: scale(1); opacity: 1; }

.lightbox-figure img {
    display: block;
    max-width: 100%;
    max-height: calc(100vh - 140px);
    object-fit: contain;
    border-radius: 6px;
    background: var(--ccm-bg);
    cursor: zoom-in;
    transition: transform .3s cubic-bezier(.2, .8, .3, 1);
    transform-origin: center;
}

/* A second tap zooms further, and the image can then be dragged by scrolling
   its container — the plain way, which works on every phone. */
.lightbox-figure img.is-zoomed { transform: scale(1.9); cursor: zoom-out; }

.lightbox-caption {
    color: var(--ccm-bg);
    font-size: 13.5px;
    text-align: center;
    max-width: 60ch;
    line-height: 1.5;
}

.lightbox-close {
    position: absolute;
    top: -14px;
    right: -14px;
    width: 38px;
    height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: var(--ccm-bg);
    color: var(--ccm-ink);
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .35);
}
.lightbox-close svg { width: 17px; height: 17px; }

/* Anything the lightbox can open gets the cursor that says so. */
/* Only the product page zooms. A card image showed a magnifier cursor
   too, which promised a zoom that quick view took over. */
.pdp-main img, .pdp-thumbs img { cursor: zoom-in; }

@media (prefers-reduced-motion: reduce) {
    .lightbox, .lightbox-figure, .lightbox-figure img { transition: none; }
}

@media (max-width: 767px) {
    .lightbox { padding: 14px; }
    .lightbox-close { top: -6px; right: -6px; }
    .lightbox-figure img { max-height: calc(100vh - 120px); }
}

/* The way back to the product page, for a picture opened from a listing. */
.lightbox-more {
    display: inline-block;
    padding: 9px 20px;
    border-radius: 20px;
    background: var(--ccm-amber);
    color: var(--ccm-ink);
    font-size: 13px;
    font-weight: 700;
    text-decoration: none;
}
.lightbox-more:hover { filter: brightness(.94); }

/* A quiet hint that the picture opens. */
.card-media { position: relative; }
.card-media::after {
    content: '';
    position: absolute;
    right: 8px;
    bottom: 8px;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--ccm-bg) url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='6'/%3E%3Cpath d='m20 20-3.6-3.6M11 9v4M9 11h4'/%3E%3C/svg%3E") center / 15px no-repeat;
    box-shadow: 0 1px 5px rgba(0, 0, 0, .22);
    opacity: 0;
    transition: opacity .15s;
    pointer-events: none;
}
.card:hover .card-media::after { opacity: .95; }

@media (hover: none) {
    /* No hover on a phone, so the hint is always there. */
    .card-media::after { opacity: .9; }
}

/* =============================================================================
   Quick view
   -----------------------------------------------------------------------------
   An eye on the picture, and the add-to-basket controls kept out of the way
   until the shopper shows interest in that card.

   The actions are hidden with opacity rather than display, and the card
   reserves their height either way — so revealing them does not reflow the
   grid under the pointer, which on a touch screen means tapping the wrong
   thing.
   ========================================================================== */

.quick-view {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(.8);
    z-index: 2;
    width: 46px;
    height: 46px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: var(--ccm-bg);
    color: var(--ccm-ink);
    cursor: pointer;
    opacity: 0;
    box-shadow: 0 4px 16px rgba(0, 0, 0, .25);
    transition: opacity .18s ease, transform .18s cubic-bezier(.2, .8, .3, 1), background .15s;
}

.quick-view svg { width: 21px; height: 21px; }

.card:hover .quick-view,
.card:focus-within .quick-view {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
}

.quick-view:hover { background: var(--ccm-amber); }
.quick-view:focus-visible { opacity: 1; transform: translate(-50%, -50%) scale(1); outline: 2px solid var(--ccm-link); }

/* --- The card's action area ----------------------------------------------- */

.card-actions {
    opacity: 0;
    transform: translateY(4px);
    transition: opacity .18s ease, transform .18s ease;
}

.card:hover .card-actions,
.card:focus-within .card-actions { opacity: 1; transform: none; }

/* A card holding something already in the basket keeps its stepper visible —
   hiding the quantity a shopper has chosen would be hiding information, not
   tidying it away. */
.card-actions:has(.add-live:not([hidden])) { opacity: 1; transform: none; }

/* Touch screens have no hover, so the actions are simply always there. */
@media (hover: none) {
    .card-actions { opacity: 1; transform: none; }
    .quick-view { opacity: .92; transform: translate(-50%, -50%) scale(1); }
}

/* =============================================================================
   The quick-view panel
   ========================================================================== */

.qv-figure {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
    width: min(940px, 100%);
    max-height: calc(100vh - 48px);
    background: var(--ccm-bg);
    border-radius: 8px;
    overflow: hidden;
    transform: scale(.92);
    opacity: 0;
    transition: transform .28s cubic-bezier(.2, .8, .3, 1), opacity .2s ease;
}

.lightbox.is-open .qv-figure { transform: scale(1); opacity: 1; }

.qv-image {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: var(--ccm-surface);
    min-height: 220px;
}
.qv-image img { max-width: 100%; max-height: 46vh; object-fit: contain; }

.qv-body { padding: 26px 28px 28px; overflow-y: auto; }

.qv-body h2 {
    font-size: 22px;
    line-height: 1.25;
    letter-spacing: -.02em;
    margin: 0 0 16px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--ccm-rule);
}

.qv-price {
    font-size: 28px;
    font-weight: 700;
    color: var(--ccm-ink);
    display: block;
    margin-bottom: 6px;
}
.qv-price-was {
    font-size: 16px;
    color: var(--ccm-muted);
    text-decoration: line-through;
    margin-left: 8px;
    font-weight: 400;
}

.qv-meta {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 14px 0;
    margin-bottom: 6px;
    border-top: 1px solid var(--ccm-rule);
    border-bottom: 1px solid var(--ccm-rule);
    font-size: 13.5px;
    color: var(--ccm-body);
}
.qv-meta strong { color: var(--ccm-link); }
.qv-meta .in-stock { color: var(--ccm-red); font-weight: 700; }
.qv-meta .out-stock { color: var(--ccm-muted); font-weight: 700; }
.qv-sep { color: var(--ccm-rule); }

.qv-actions { margin-top: 20px; }
.qv-actions .add-control { margin: 0; }

/* The panel borrows the card's own add control rather than cloning it, so a
   quantity set here is the quantity on the card behind the panel. It arrives
   at card size and is scaled up to suit the larger surface. */
.qv-control-slot .add-control { width: 100%; }
.qv-control-slot .add-live { justify-content: flex-start; }
.qv-control-slot .stepper-btn { width: 40px; height: 40px; }
.qv-control-slot .add-qty { min-width: 46px; font-size: 16px; }
.qv-actions .btn { padding: 13px 34px; font-size: 15px; }

.qv-more {
    display: inline-block;
    margin-top: 16px;
    font-size: 13px;
    color: var(--ccm-link);
}

.qv-close {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 3;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--ccm-body);
    cursor: pointer;
}
.qv-close:hover { color: var(--ccm-ink); }
.qv-close svg { width: 20px; height: 20px; }

.qv-loading { padding: 60px; text-align: center; color: var(--ccm-muted); font-size: 14px; }

@media (min-width: 768px) {
    .qv-figure { grid-template-columns: 1fr 1fr; }
    .qv-image { min-height: 380px; padding: 30px; }
    .qv-image img { max-height: 60vh; }
}

@media (prefers-reduced-motion: reduce) {
    .quick-view, .card-actions, .qv-figure { transition: none; }
}

/* ------------------------------------------------------- CMS sections (Phase 12)
   These render whatever the homepage layout asks for, so they have to look
   right anywhere on the page rather than only in the position they were
   originally written into. */

/* A preview is unmistakable on purpose. Someone looking at a draft must never
   wonder whether shoppers can see it too. */
.preview-band {
    background: var(--ccm-amber);
    color: var(--ccm-amber-ink);
    font-size: 13px;
    padding: 9px 0;
}
.preview-band a { color: var(--ccm-amber-ink); text-decoration: underline; }

.promo-banner {
    position: relative;
    border-radius: var(--ccm-radius);
    overflow: hidden;
    background: var(--ccm-surface);
}
.promo-banner img { display: block; width: 100%; height: auto; }
.promo-body { padding: 22px; }
.promo-body h2 { margin: 0 0 6px; font-size: 20px; }
.promo-body p { margin: 0 0 14px; color: var(--ccm-body); font-size: 14px; }

/* A banner with artwork puts its words over the picture from a tablet up,
   where there is room. On a phone they stack, because text over a photograph
   at that width is unreadable however carefully it is placed. */
@media (min-width: 768px) {
    .promo-banner:has(img) .promo-body {
        position: absolute;
        inset: 0;
        display: flex;
        flex-direction: column;
        justify-content: center;
        max-width: 52%;
        padding: 30px;
    }
}

.rich-text { max-width: 68ch; color: var(--ccm-body); font-size: 15px; line-height: 1.7; }

/* --------------------------------------------------- support dock and chat
   Two launchers, bottom right, in the tawk.to arrangement the client asked
   for. WhatsApp is a plain link so it works with no script at all; chat opens
   a panel that keeps the shopper on the site.

   The dock sits above everything except the lightbox, and clear of the safe
   area on phones with a home indicator — a support button under the gesture
   bar is a support button nobody can press. */
.support-dock {
    position: fixed;
    right: 16px;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    z-index: 90;
    display: flex;
    flex-direction: column-reverse;
    gap: 10px;
    align-items: flex-end;
}

.support-btn {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    height: 52px;
    padding: 0 18px 0 15px;
    border: 0;
    border-radius: 26px;
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 4px 16px rgba(0, 0, 0, .18);
    transition: transform .16s ease, filter .16s ease;
}
.support-btn:hover { transform: translateY(-1px); filter: brightness(.96); text-decoration: none; }
.support-btn svg { width: 22px; height: 22px; flex: none; }

/* Both buttons are in the Cape Coast palette, by client instruction: no colour
   on the storefront that is not the brand's own.
   
   That is a real trade-off worth naming. WhatsApp's green is how people
   recognise the button at a glance, and amber is not it — the icon's shape has
   to do that work alone here. The shape is the official mark and is unaltered,
   so it is still recognisable; it is simply quieter than it would be in green. */
.support-btn-wa   { background: var(--ccm-amber);  color: var(--ccm-amber-ink); }
.support-btn-chat { background: var(--ccm-orange); color: var(--ccm-badge-ink); }

/* On a phone the labels go and the buttons become discs. Two full-width pills
   stacked in the corner of a small screen cover the product a shopper is
   trying to read. */
@media (max-width: 767px) {
    .support-btn-label { display: none; }
    .support-btn { width: 52px; padding: 0; justify-content: center; }
}

.chat-panel {
    position: fixed;
    right: 16px;
    bottom: calc(82px + env(safe-area-inset-bottom, 0px));
    z-index: 91;
    width: min(370px, calc(100vw - 32px));
    max-height: min(560px, calc(100vh - 140px));
    display: flex;
    flex-direction: column;
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 12px 40px rgba(0, 0, 0, .22);
}

.chat-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px;
    background: var(--ccm-orange);
    color: var(--ccm-badge-ink);
}
.chat-head-sub { font-size: 12px; opacity: .9; margin-top: 2px; }
.chat-close {
    border: 0; background: none; color: var(--ccm-badge-ink);
    cursor: pointer; padding: 4px; line-height: 0;
}
.chat-close svg { width: 20px; height: 20px; }

.chat-log {
    flex: 1;
    min-height: 180px;
    overflow-y: auto;
    padding: 16px;
    background: var(--ccm-surface);
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.chat-msg { display: flex; flex-direction: column; max-width: 82%; }
.chat-msg-visitor { align-self: flex-end; align-items: flex-end; }
.chat-msg-staff, .chat-msg-system { align-self: flex-start; }

.chat-bubble {
    padding: 10px 13px;
    border-radius: 14px;
    font-size: 13.5px;
    line-height: 1.5;
    /* A pasted order number or a long URL must wrap rather than stretch the
       panel off the side of the screen. */
    overflow-wrap: anywhere;
}
.chat-msg-visitor .chat-bubble {
    background: var(--ccm-orange);
    color: var(--ccm-badge-ink);
    border-bottom-right-radius: 4px;
}
.chat-msg-staff .chat-bubble {
    background: var(--ccm-bg);
    color: var(--ccm-ink);
    border: 1px solid var(--ccm-rule);
    border-bottom-left-radius: 4px;
}
/* A system line is not a person and must not look like one. */
.chat-msg-system .chat-bubble {
    background: transparent;
    color: var(--ccm-body);
    border: 1px dashed var(--ccm-rule);
    font-size: 13px;
}
.chat-who { font-size: 11px; color: var(--ccm-muted); margin: 0 4px 3px; }

.chat-note {
    align-self: center;
    font-size: 12px;
    color: var(--ccm-muted);
    text-align: center;
}

.chat-form {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    border-top: 1px solid var(--ccm-rule);
    background: var(--ccm-bg);
}
.chat-form input {
    flex: 1;
    min-width: 0;
    padding: 10px 12px;
    border: 1px solid var(--ccm-rule);
    border-radius: 20px;
    font: inherit;
    font-size: 13.5px;
}
.chat-form input:focus { outline: none; border-color: var(--ccm-orange); }
.chat-send {
    flex: none;
    width: 40px; height: 40px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 0; border-radius: 50%;
    background: var(--ccm-orange); color: var(--ccm-badge-ink);
    cursor: pointer;
}
.chat-send svg { width: 18px; height: 18px; }

.chat-foot {
    margin: 0;
    padding: 0 14px 12px;
    font-size: 12px;
    color: var(--ccm-muted);
    background: var(--ccm-bg);
}

/* Visible to a screen reader, invisible on the page. */
.u-sr-only {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------------------------------------------- chat suggestions and handover
   Tappable common questions, and the way out to a person.

   The chips sit between the log and the composer rather than inside the log,
   so they do not scroll away with the conversation — somebody who has read two
   canned answers and still needs help must be able to find "talk to a person"
   without scrolling back up. */
.chat-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
    padding: 12px 14px 0;
    background: var(--ccm-bg);
}

.chat-chip {
    padding: 7px 13px;
    border: 1px solid var(--ccm-rule);
    border-radius: 999px;
    background: var(--ccm-bg);
    color: var(--ccm-body);
    font: inherit;
    font-size: 12.5px;
    cursor: pointer;
    transition: border-color .14s ease, color .14s ease;
}
.chat-chip:hover { border-color: var(--ccm-orange); color: var(--ccm-ink); }

.chat-human {
    padding: 10px 14px 0;
    background: var(--ccm-bg);
}

/* Quieter than the send button on purpose. It is an escape hatch, not the
   thing we are steering people towards — but it is never hidden behind
   anything either, because somebody who wants a person should not have to
   hunt. */
.chat-human-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 14px;
    border: 1px solid var(--ccm-orange);
    border-radius: 999px;
    background: var(--ccm-bg);
    color: var(--ccm-orange);
    font: inherit;
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
}
.chat-human-btn:hover { background: var(--ccm-orange); color: var(--ccm-badge-ink); }
.chat-human-btn:disabled { opacity: .5; cursor: default; }
.chat-human-btn svg { width: 15px; height: 15px; }

/* ------------------------------------------------------ dialogs and toasts
   The SweetAlert experience, in the project's own markup.

   Not SweetAlert2 itself: this site runs `style-src 'self'` with no
   `unsafe-inline`, and that library sets inline style attributes on the nodes
   it creates. Bundling it would have meant weakening the CSP for a dialog box.

   No inline styles here, and every colour is a token. */
.ccm-dialog-backdrop {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(0, 0, 0, .45);
    opacity: 0;
    transition: opacity .18s ease;
}
.ccm-dialog-backdrop.is-open { opacity: 1; }

.ccm-dialog {
    width: min(420px, 100%);
    background: var(--ccm-bg);
    border-radius: 16px;
    padding: 28px 26px 22px;
    text-align: center;
    box-shadow: 0 18px 50px rgba(0, 0, 0, .28);
    transform: scale(.94);
    transition: transform .18s ease;
}
.ccm-dialog-backdrop.is-open .ccm-dialog { transform: scale(1); }

.ccm-dialog-mark {
    width: 62px; height: 62px;
    margin: 0 auto 16px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
}
.ccm-dialog-mark svg { width: 30px; height: 30px; }
.ccm-dialog-mark-warning { background: var(--ccm-amber); color: var(--ccm-amber-ink); }
.ccm-dialog-mark-danger  { background: var(--ccm-red-band); color: var(--ccm-badge-ink); }
.ccm-dialog-mark-success { background: var(--ccm-mint); color: var(--ccm-ink); }
.ccm-dialog-mark-info    { background: var(--ccm-surface); color: var(--ccm-body); }

.ccm-dialog-title { margin: 0 0 8px; font-size: 20px; font-weight: 700; color: var(--ccm-ink); }
.ccm-dialog-text  { margin: 0 0 20px; font-size: 14px; line-height: 1.6; color: var(--ccm-body); }
.ccm-dialog-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.ccm-dialog-actions .btn { min-width: 128px; }

/* Nothing scrolls behind an open dialog. */
body.ccm-dialog-lock { overflow: hidden; }

.ccm-toasts {
    position: fixed;
    right: 16px;
    bottom: 16px;
    z-index: 210;
    display: flex;
    flex-direction: column-reverse;
    gap: 10px;
    max-width: min(380px, calc(100vw - 32px));
}

.ccm-toast {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    padding: 13px 14px;
    border-radius: 12px;
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    box-shadow: 0 8px 26px rgba(0, 0, 0, .16);
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--ccm-ink);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity .2s ease, transform .2s ease;
}
.ccm-toast.is-open { opacity: 1; transform: none; }
.ccm-toast .ccm-dialog-mark { width: 26px; height: 26px; margin: 0; flex: none; }
.ccm-toast .ccm-dialog-mark svg { width: 15px; height: 15px; }
.ccm-toast-success { border-left: 3px solid var(--ccm-mint); }
.ccm-toast-error   { border-left: 3px solid var(--ccm-red-band); }

.ccm-toast-x {
    margin-left: auto;
    border: 0; background: none; cursor: pointer;
    color: var(--ccm-muted); font-size: 18px; line-height: 1;
    padding: 0 2px;
}
.ccm-toast-x:hover { color: var(--ccm-ink); }

/* On a phone the toasts span the width, above the support dock. */
@media (max-width: 767px) {
    .ccm-toasts { left: 16px; right: 16px; bottom: 82px; max-width: none; }
}

/* ------------------------------------------------------------ product gallery
   Arrows sit on the picture rather than under it, so moving between
   photographs does not move the eye away from the photograph. */
.pdp-main { position: relative; }

.pdp-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: var(--ccm-bg);
    color: var(--ccm-ink);
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
    opacity: 0;
    transition: opacity .16s ease, background .16s ease;
}
.pdp-main:hover .pdp-arrow { opacity: 1; }
.pdp-arrow:hover  { background: var(--ccm-orange); color: var(--ccm-badge-ink); }
.pdp-arrow:focus-visible { opacity: 1; }
.pdp-arrow svg { width: 20px; height: 20px; }
.pdp-arrow-prev { left: 10px; }
.pdp-arrow-next { right: 10px; }

/* A phone has no hover, so the arrows are simply always there. A control that
   only appears on hover is a control a touch user does not have. */
@media (hover: none) {
    .pdp-arrow { opacity: 1; }
}

.pdp-count {
    position: absolute;
    right: 10px;
    bottom: 10px;
    z-index: 2;
    padding: 3px 9px;
    border-radius: 999px;
    background: rgba(0, 0, 0, .55);
    color: var(--ccm-bg);
    font-size: 11.5px;
    font-variant-numeric: tabular-nums;
}

/* The thumbnails are buttons now, not bare images. */
.pdp-thumb {
    padding: 0;
    border: 2px solid transparent;
    border-radius: var(--ccm-radius);
    background: none;
    cursor: pointer;
    line-height: 0;
    overflow: hidden;
    transition: border-color .14s ease, opacity .14s ease;
}
.pdp-thumb img {
    display: block;
    width: 100%;
    height: 100%;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    padding: 3px;
    box-sizing: border-box;
}
.pdp-thumb:hover { opacity: .85; }
.pdp-thumb.is-current { border-color: var(--ccm-orange); }

/* =============================================================================
   Search suggestions
   =============================================================================
   The panel hangs off the search form, which is why the form is the
   positioning context. It sits above the sticky header, so its z-index has to
   clear the header's — a suggestion list that appears *behind* the thing it
   drops out of is a bug that only shows up on a real page.
   ========================================================================== */

.searchbar { position: relative; }

.suggest {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 300;
    max-height: min(70vh, 480px);
    overflow-y: auto;
    background: #FFFFFF;
    border: 1px solid var(--ccm-rule);
    border-radius: 3px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .14);
    padding: 4px;
}

.suggest-head {
    font-size: 10.5px;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--ccm-muted);
    padding: 9px 10px 5px;
}

.suggest-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border-radius: 3px;
    color: var(--ccm-ink);
    text-decoration: none;
}

/* Hover and keyboard selection look identical on purpose: there is one
   highlighted row at a time, however it got that way. */
.suggest-row:hover,
.suggest-row.is-cursor { background: var(--ccm-mint); }

.suggest-thumb {
    width: 38px; height: 38px;
    max-width: 38px; max-height: 38px;
    flex: 0 0 38px;
    object-fit: contain;
    padding: 2px;
    box-sizing: border-box;
    border: 1px solid var(--ccm-rule);
    border-radius: 2px;
    background: #FFFFFF;
}

.suggest-text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }

.suggest-text strong {
    font-size: 13px; font-weight: 500; line-height: 1.3;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.suggest-text small { font-size: 11px; color: var(--ccm-muted); }

.suggest-tail {
    font-size: 12.5px; font-weight: 600; color: var(--ccm-red);
    flex: 0 0 auto; white-space: nowrap;
}

.suggest-none {
    padding: 16px 12px; font-size: 13px; color: var(--ccm-muted); text-align: center;
}

.suggest-all {
    border-top: 1px solid var(--ccm-rule-soft);
    margin-top: 4px;
    justify-content: center;
}

.suggest-all strong { font-size: 12.5px; color: var(--ccm-link); font-weight: 600; }

@media (max-width: 720px) {
    .suggest-thumb { width: 32px; height: 32px; }
}

/* =============================================================================
   Order tracking
   ========================================================================== */

.track-form { max-width: 460px; }

.track-list { display: flex; flex-direction: column; gap: 12px; margin-top: 14px; }

.track-card {
    display: block;
    padding: 15px 17px;
    border: 1px solid var(--ccm-rule);
    border-radius: 3px;
    text-decoration: none;
    color: inherit;
    background: #FFFFFF;
}

.track-card:hover { border-color: var(--ccm-amber); }

.track-card-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
}

/* The road, including the parts not yet travelled. Horizontal on a wide
   screen; on a phone it becomes a vertical list, because five labels across
   360px is five illegible labels. */
.track-rail {
    display: flex;
    list-style: none;
    margin: 16px 0 0;
    padding: 0;
    counter-reset: step;
}

.track-step {
    flex: 1 1 0;
    min-width: 0;
    position: relative;
    padding-top: 20px;
    text-align: center;
}

/* The connecting line, drawn behind the dots. */
.track-step::before {
    content: "";
    position: absolute;
    top: 5px;
    left: -50%;
    width: 100%;
    height: 2px;
    background: var(--ccm-rule);
}

.track-step:first-child::before { display: none; }
.track-step.is-done::before { background: var(--ccm-amber); }

.track-dot {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 12px; height: 12px;
    border-radius: 50%;
    background: #FFFFFF;
    border: 2px solid var(--ccm-rule);
}

.track-step.is-done .track-dot { background: var(--ccm-amber); border-color: var(--ccm-amber); }

/* The step the order is actually on gets a ring, so "reached here" is
   distinguishable from "passed through here" at a glance. */
.track-step.is-now .track-dot {
    box-shadow: 0 0 0 4px rgba(252, 184, 0, .28);
}

.track-step-label {
    font-size: 11px;
    color: var(--ccm-muted);
    display: block;
    padding: 0 4px;
    line-height: 1.35;
}

.track-step.is-done .track-step-label { color: var(--ccm-body); }
.track-step.is-now .track-step-label  { color: var(--ccm-ink); font-weight: 600; }

@media (max-width: 640px) {
    .track-rail { flex-direction: column; gap: 10px; }

    .track-step { text-align: left; padding: 0 0 0 24px; }
    .track-step::before {
        left: 5px; top: -10px; width: 2px; height: 10px;
    }
    .track-dot { left: 0; transform: none; top: 2px; }
    .track-step-label { padding: 0; font-size: 12.5px; }
}

/* Reusing the last delivery address. */
.reuse-address { border-color: var(--ccm-amber); }

.reuse-card {
    display: block;
    padding: 13px 15px;
    background: var(--ccm-mint);
    border: 1px solid var(--ccm-rule);
    border-radius: 3px;
    margin: 12px 0 14px;
    font-size: 13.5px;
}

.reuse-card .card-cat { display: block; margin-top: 3px; }

.reuse-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

/* A button that reads as a link. It is a <button> because it acts on this
   page rather than navigating, and an <a href="#"> that runs script is a link
   that lies about what it does. */
.btn-link {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: var(--ccm-link);
    text-decoration: underline;
    cursor: pointer;
}

.btn-link:hover { color: var(--ccm-red); }

/* Discount code at checkout. */
.coupon-box { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--ccm-rule); }
.coupon-box label { display: block; font-size: 12.5px; margin-bottom: 6px; color: var(--ccm-body); }

.coupon-row { display: flex; gap: 8px; }
.coupon-row input { flex: 1 1 auto; min-width: 0; text-transform: uppercase; }
.coupon-row .btn { flex: 0 0 auto; }

.coupon-applied {
    margin: 0; font-size: 13px; color: var(--ccm-body);
    background: var(--ccm-mint); border: 1px solid var(--ccm-rule);
    border-radius: 3px; padding: 9px 11px;
}

.coupon-applied strong { color: var(--ccm-ink); }
.coupon-applied a { margin-left: 6px; font-size: 12px; }

.coupon-error { margin: 7px 0 0; font-size: 12.5px; color: var(--ccm-red); }

/* A line that takes money off reads differently from one that adds it. */
.summary-line.is-saving span:last-child { color: var(--ccm-ink); font-weight: 700; }
.summary-line.is-saving small { display: block; font-size: 11px; color: var(--ccm-muted); }

/* ---------------------------------------------------------------------------
   Public order tracking  (/orders/track/{number})

   The page somebody opens from a text message when they want to know where
   their parcel is. Built entirely from the tokens already defined at the top
   of app.css -- amber for the live state, the brand red for a failed one, mint
   for a delivered one -- so it inherits the site's colours and its dark theme
   without introducing either.
   --------------------------------------------------------------------------- */

.trk-hero {
    display: flex; align-items: center; justify-content: space-between; gap: 20px;
    background: var(--ccm-surface);
    border: 1px solid var(--ccm-rule);
    border-left: 5px solid var(--ccm-amber);
    border-radius: var(--ccm-radius);
    padding: 22px 24px;
    margin: 18px 0 14px;
}

/* Delivered and cancelled are the two states worth recognising before
   reading. Everything in between is "on its way", and shares one look. */
.trk-hero.is-done   { border-left-color: var(--ccm-amber); background: var(--ccm-mint); }
.trk-hero.is-failed { border-left-color: var(--ccm-red); }

.trk-hero-main { min-width: 0; }

.trk-eyebrow {
    margin: 0 0 4px; font-size: 12.5px; letter-spacing: .04em;
    text-transform: uppercase; color: var(--ccm-muted);
}

.trk-eyebrow .mono { text-transform: none; letter-spacing: 0; color: var(--ccm-body); }

.trk-status {
    margin: 0; font-size: 26px; line-height: 1.15; color: var(--ccm-ink);
}

.trk-hero.is-failed .trk-status { color: var(--ccm-red); }

.trk-detail { margin: 6px 0 0; color: var(--ccm-body); font-size: 14px; }

.trk-facts {
    display: flex; flex-wrap: wrap; gap: 22px;
    list-style: none; margin: 16px 0 0; padding: 0;
}

.trk-fact-label {
    display: block; font-size: 11px; text-transform: uppercase;
    letter-spacing: .05em; color: var(--ccm-muted);
}

.trk-fact-value { display: block; font-size: 15px; font-weight: 600; color: var(--ccm-ink); }

/* Large enough to read at arm's length on a phone held in daylight, which is
   where this page is actually opened. */
.trk-hero-mark {
    flex: 0 0 auto;
    display: flex; align-items: center; justify-content: center;
    width: 76px; height: 76px; border-radius: 50%;
    background: var(--ccm-amber); color: var(--ccm-amber-ink);
    font-size: 26px; font-weight: 700; line-height: 1;
}

.trk-hero.is-failed .trk-hero-mark { background: var(--ccm-red); color: var(--ccm-badge-ink); }
.trk-of { font-size: 14px; font-weight: 500; opacity: .7; }

.trk-rail-panel { padding-top: 22px; padding-bottom: 18px; }

/* The date each stage was reached, under its label. A rail of ticks says how
   far along you are; the dates say whether anything has moved today. */
.trk-when {
    display: block; margin-top: 3px; font-size: 11px; color: var(--ccm-muted);
    min-height: 14px;
}

/* --- the history ------------------------------------------------------- */

.trk-log { list-style: none; margin: 14px 0 0; padding: 0; }

.trk-log-row {
    position: relative; display: flex; gap: 12px;
    padding: 0 0 16px 18px;
}

/* One continuous line down the left, stopping at the last entry so it does
   not trail off into nothing. */
.trk-log-row::before {
    content: ""; position: absolute; left: 4px; top: 6px; bottom: -6px;
    width: 1px; background: var(--ccm-rule);
}

.trk-log-row:last-child { padding-bottom: 0; }
.trk-log-row:last-child::before { display: none; }

.trk-log-dot {
    position: absolute; left: 0; top: 5px;
    width: 9px; height: 9px; border-radius: 50%;
    background: var(--ccm-rule); border: 2px solid var(--ccm-bg);
}

/* The most recent entry is the one somebody is looking for. */
.trk-log-row:first-child .trk-log-dot { background: var(--ccm-amber); }

.trk-log-body { min-width: 0; }
.trk-log-what { font-size: 14px; color: var(--ccm-ink); }
.trk-log-when { font-size: 12px; color: var(--ccm-muted); margin-top: 2px; }

/* --- what is in it ------------------------------------------------------ */

.trk-items { list-style: none; margin: 14px 0 0; padding: 0; }

.trk-item {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 0; border-bottom: 1px solid var(--ccm-rule-soft);
}

.trk-item:last-child { border-bottom: 0; }

.trk-item-pic {
    flex: 0 0 auto; width: 56px; height: 56px;
    display: flex; align-items: center; justify-content: center;
    background: var(--ccm-surface); border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius); overflow: hidden;
}

.trk-item-pic img {
    width: 100%;
    height: 100%;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    padding: 4px;
    box-sizing: border-box;
    display: block;
}

/* No picture: the quantity, which is the next most useful thing that square
   can say. */
.trk-item-qty { font-size: 16px; font-weight: 700; color: var(--ccm-body); }

.trk-item-body { flex: 1 1 auto; min-width: 0; }
.trk-item-name {
    font-size: 14px; color: var(--ccm-ink);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.trk-item-meta  { font-size: 12.5px; color: var(--ccm-muted); margin-top: 2px; }
.trk-item-total { flex: 0 0 auto; font-size: 14px; font-weight: 600; color: var(--ccm-ink); }

/* --- the sidebar -------------------------------------------------------- */

.trk-address { font-size: 14px; color: var(--ccm-body); line-height: 1.6; margin: 8px 0 0; }
.trk-address strong { color: var(--ccm-ink); }

.trk-help, .trk-keep {
    margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--ccm-rule);
}

.btn-block { display: block; width: 100%; text-align: center; }

@media (max-width: 640px) {
    .trk-hero { flex-direction: column; align-items: flex-start; padding: 18px; }
    .trk-hero-mark { width: 56px; height: 56px; font-size: 20px; }
    .trk-status { font-size: 22px; }
    .trk-facts { gap: 16px; }
    /* The rail is already stacked below 640px by the .track-rail rules above;
       the dates go beside the label rather than under it so the column does
       not become a very tall list of two-line steps. */
    .trk-when { display: inline; margin-left: 8px; }
}

/* ---------------------------------------------------------------------------
   The "you might also like" rail

   Six product cards on screen, the rest reachable with the arrows. A grid was
   the wrong shape for this: it either wraps onto a second line, which competes
   with the page below it, or it caps at four and hides the other fourteen
   behind a text link nobody clicks.

   Built from the tokens in app.css, so it inherits the site's colours and its
   dark theme without introducing either.
   --------------------------------------------------------------------------- */

.rail-head { align-items: center; gap: 16px; flex-wrap: wrap; }
.rail-title h2 { margin: 0; }

/* Naming the category is not decoration -- it is the promise the rail keeps.
   Every card below it is in that category. */
.rail-sub { margin: 2px 0 0; font-size: 13px; color: var(--ccm-body); }
.rail-sub strong { color: var(--ccm-ink); }

.rail-tools { display: flex; align-items: center; gap: 8px; margin-left: auto; }

.rail-arrow {
    width: 34px; height: 34px; flex: 0 0 auto;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--ccm-bg); color: var(--ccm-ink);
    border: 1px solid var(--ccm-rule); border-radius: 50%;
    font-size: 20px; line-height: 1; cursor: pointer;
    transition: background .12s ease, border-color .12s ease;
}

.rail-arrow:hover:not(:disabled) { background: var(--ccm-amber); border-color: var(--ccm-amber); color: var(--ccm-amber-ink); }
.rail-arrow:focus-visible        { outline: 2px solid var(--ccm-link); outline-offset: 2px; }

/* Disabled rather than hidden: a control that disappears at the end of a list
   moves everything beside it, and the row jumps as you use it. */
.rail-arrow:disabled { opacity: .35; cursor: default; }

/* "See all Kitchen Ware" — a button, because it is the thing somebody wants
   when the rail has not shown them what they were after, and a 13px text link
   beside a heading was not something anybody found. */
.rail-more { white-space: nowrap; }
.rail-more span { margin-left: 4px; }

.rail { position: relative; margin-top: 14px; }

.rail-track {
    display: grid;
    grid-auto-flow: column;
    /* Exactly six across, so the rail is a full row and not a ragged one.
       Expressed as a custom property so the breakpoints below change one
       number rather than restating the whole calc(). */
    --rail-cols: 6;
    grid-auto-columns: calc((100% - ((var(--rail-cols) - 1) * 14px)) / var(--rail-cols));
    gap: 14px;
    overflow-x: auto;
    scroll-behavior: smooth;
    scroll-snap-type: x mandatory;
    /* Room for the focus ring, and for a card's shadow, without clipping. */
    padding: 4px 2px 8px;
    /* The scrollbar is redundant next to the arrows and takes a row of height
       on Windows; the rail is still scrollable by wheel, touch and keyboard. */
    scrollbar-width: none;
}

.rail-track::-webkit-scrollbar { display: none; }
.rail-track:focus-visible { outline: 2px solid var(--ccm-link); outline-offset: 2px; }

.rail-item { scroll-snap-align: start; min-width: 0; }

/* The arrows at the two ends, over the rail itself. These are the ones the
   brief asked for; the pair beside the heading do the same job for a reader
   who is already up there. */
.rail-edge {
    position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
    width: 38px; height: 38px;
    display: none; align-items: center; justify-content: center;
    background: var(--ccm-bg); color: var(--ccm-ink);
    border: 1px solid var(--ccm-rule); border-radius: 50%;
    font-size: 22px; line-height: 1; cursor: pointer;
    box-shadow: var(--ccm-shadow-sm, 0 1px 2px rgba(0,0,0,.05));
}

.rail-edge:hover { background: var(--ccm-amber); border-color: var(--ccm-amber); color: var(--ccm-amber-ink); }
.rail-edge-prev  { left: -19px; }
.rail-edge-next  { right: -19px; }

/* Shown only when there is somewhere to go. `is-scrollable` is set by the
   script once it knows the track overflows, so a rail of three products on a
   wide screen has no arrows to press and nothing to disappoint. */
.rail.is-scrollable .rail-edge { display: flex; }
.rail-edge:disabled { display: none; }

@media (max-width: 1100px) {
    /* Off the ends and inside the rail, where there is room for them. */
    .rail-edge-prev { left: 4px; }
    .rail-edge-next { right: 4px; }
}

@media (max-width: 900px) {
    .rail-track { --rail-cols: 4; }
}

@media (max-width: 700px) {
    .rail-track { --rail-cols: 2.2; }
    .rail-head  { gap: 10px; }
    .rail-tools { width: 100%; margin-left: 0; }
    .rail-more  { margin-left: auto; }
    /* On a phone the thumb does this better than a button can. */
    .rail.is-scrollable .rail-edge { display: none; }
}

/* ===========================================================================
   THE FOOTER

   A dark ground, and that is the one real decision here.

   A footer the same white as the page has no edge, so the shop appears to
   trail off rather than end — and a visitor who has scrolled to the bottom
   looking for a telephone number has to hunt for it in the same visual weight
   as everything above. Grounding it in `--ccm-ink` gives the page a floor,
   pushes the amber support strip forward as the brightest thing on the screen,
   and costs nothing: black is already the site's heading colour, so no new
   colour enters the palette.

   Above it sits the support strip, in amber. It is the loudest element in the
   footer on purpose — "call us" is the most useful thing this shop can say to
   somebody who has read all the way down.
   =========================================================================== */

.shop-foot {
    margin-top: 48px;
    background: var(--ccm-ink);
    color: rgba(255, 255, 255, .72);
    font-size: 13.5px;
    line-height: 1.65;
}

/* --------------------------------------------------------- support strip */

.foot-support {
    background: var(--ccm-amber);
    color: var(--ccm-amber-ink);
}

/* The number on the left, the hours on the right, and the row centred in the
   band's height.
   Two columns rather than three: the support block takes the space it needs at
   the leading edge, the hours sit against the trailing edge, and `align-items:
   center` with equal padding puts both on the band's optical centre line.
   Centring the block horizontally was tried and is wrong — it leaves the band
   empty at both ends and the telephone number floating, when the thing a
   reader's eye looks for at the foot of a page is a left edge to start from. */
.foot-support-inner {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: 16px 24px;
    padding: 14px 0;
    min-height: 62px;
}

.foot-support-block {
    grid-column: 1;
    display: flex;
    align-items: center;
    gap: 14px;
}

.foot-support-mark {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, .1);
}

.foot-support-mark svg { width: 21px; height: 21px; }

.foot-support-label {
    display: block;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    opacity: .7;
}

.foot-support-phone {
    display: block;
    font-size: 22px;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -.01em;
    color: var(--ccm-amber-ink);
    text-decoration: none;
}

.foot-support-phone:hover { text-decoration: underline; }

/* The trailing edge, on the same centre line as the number beside it.
   Dropped onto its own line on a narrow screen rather than squeezed — trading
   hours that wrap into three words per line read as broken. */
.foot-support-hours {
    grid-column: 2;
    justify-self: end;
    margin: 0;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.4;
    opacity: .82;
    text-align: right;
}

/* --------------------------------------------------------------- columns */

/* `>`, not a descendant selector.
   The support strip's container carries `shell` too, so a descendant rule put
   40px of padding on top of it and pushed the telephone number twenty pixels
   below the centre line of its own band — while every measurement of the band
   itself looked correct. Only the columns block is a direct child of the
   footer, which is exactly the element this padding is for. */
.shop-foot > .shell { padding-top: 40px; padding-bottom: 0; }

.foot-cols {
    display: grid;
    gap: 32px 28px;
    align-items: start;
    /* The brand column is wider than the link columns because it carries a
       paragraph; the rest share what is left equally. */
    grid-template-columns: 1.6fr repeat(4, 1fr);
    padding-bottom: 36px;
}

.foot-cols h4 {
    margin: 0 0 14px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: #FFFFFF;
}

.foot-cols ul { list-style: none; margin: 0; padding: 0; }
.foot-cols li { margin-bottom: 9px; }

.foot-cols a {
    color: rgba(255, 255, 255, .72);
    text-decoration: none;
    transition: color .12s ease;
}

/* Amber is the feedback; an underline on top of it is noise. These have no
   class of their own, so the prose rule at the top of this file would give
   them one. */
.foot-cols a:hover { color: var(--ccm-amber); text-decoration: none; }

.foot-cols a:focus-visible {
    outline: 2px solid var(--ccm-amber);
    outline-offset: 2px;
    border-radius: 2px;
}

/* --------------------------------------------------------------- brand */

.foot-brand p {
    margin: 14px 0 0;
    max-width: 34ch;
    font-size: 13px;
    line-height: 1.7;
    color: rgba(255, 255, 255, .62);
}

/* The logo is a dark-on-light mark, so it needs a light plate to sit on
   rather than being inverted — inverting a brand mark is a change to the
   brand, and the client asked for their logo, not a version of it. */
.foot-logo {
    display: block;
    height: auto;
    max-width: 152px;
    padding: 9px 12px;
    background: #FFFFFF;
    border-radius: var(--ccm-radius);
}

.foot-social {
    display: flex;
    gap: 9px;
    list-style: none;
    margin: 18px 0 0;
    padding: 0;
}

.foot-social a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, .22);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .02em;
    color: rgba(255, 255, 255, .8);
    transition: background .12s ease, border-color .12s ease, color .12s ease;
}

.foot-social a:hover {
    background: var(--ccm-amber);
    border-color: var(--ccm-amber);
    color: var(--ccm-amber-ink);
}

/* --------------------------------------------------------------- contact */

/* Label above value, not beside it. "Kotokuraba Market BFS026, Cape Coast,
   Ghana" does not fit on one line next to the word Address on any phone, and
   an address that wraps around its own label reads as two addresses. */
.foot-contact li { margin-bottom: 13px; }

.foot-contact-label {
    display: block;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .42);
    margin-bottom: 2px;
}

.foot-contact span:not(.foot-contact-label) { color: rgba(255, 255, 255, .72); }

/* ---------------------------------------------------------- what we take */

.foot-pay {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 20px 0;
    border-top: 1px solid rgba(255, 255, 255, .12);
}

.foot-pay-label {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .42);
}

.foot-pay-list {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    list-style: none;
    margin: 0;
    padding: 0;
}

/* Words, not logos. A card logo is a trademark used under licence, and a row
   of them is also the easiest thing in a footer to forget when a payment
   method is switched off — which would leave the shop advertising something
   checkout refuses. These are generated from the configured channels. */
.foot-pay-chip {
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .01em;
    padding: 5px 11px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, .2);
    color: rgba(255, 255, 255, .82);
}

/* ---------------------------------------------------------- bottom bar */

.foot-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 16px 0 20px;
    border-top: 1px solid rgba(255, 255, 255, .12);
    font-size: 12.5px;
    color: rgba(255, 255, 255, .5);
}

.foot-meta { color: rgba(255, 255, 255, .4); }

@media (max-width: 1023px) {
    .foot-cols { grid-template-columns: 1fr 1fr 1fr; }
    .foot-brand { grid-column: 1 / -1; }
    .foot-brand p { max-width: 52ch; }
}

@media (max-width: 767px) {
    .shop-foot { margin-top: 32px; }
    .shop-foot > .shell { padding-top: 30px; }
    .foot-cols { grid-template-columns: 1fr 1fr; gap: 26px 20px; }

    /* One column on a phone: there is no room to hold a left edge against a
       right one, and the hours below the number is the reading order anyway. */
    .foot-support-inner { grid-template-columns: 1fr; gap: 8px; min-height: 0; }
    .foot-support-block { grid-column: 1; }
    .foot-support-hours { grid-column: 1; justify-self: start; text-align: left; }
    .foot-support-phone { font-size: 19px; }
    .foot-bottom { flex-direction: column; align-items: flex-start; gap: 6px; }
}

@media (max-width: 380px) {
    .foot-cols { grid-template-columns: 1fr; }
}

/* ===========================================================================
   DOCUMENT PAGES — about, terms, sell on this platform

   Three pages that are read rather than shopped, and they need a different
   discipline from a product grid: a measure short enough to read, a hierarchy
   you can skim, and — for the terms, which are long — a way to get to clause
   nine without scrolling past eight.
   =========================================================================== */

.page-shell { padding-top: 20px; padding-bottom: 8px; }

/* --------------------------------------------------------------- crumbs */

.crumbs {
    display: flex;
    gap: 8px;
    align-items: center;
    font-size: 12.5px;
    color: var(--ccm-muted);
    margin-bottom: 18px;
}

.crumbs a { color: var(--ccm-body); text-decoration: none; }
.crumbs a:hover { color: var(--ccm-link); text-decoration: underline; }
.crumbs span[aria-hidden] { color: var(--ccm-rule); }

/* ----------------------------------------------------------------- hero */

/* A band rather than a headline on white. It separates "what this page is"
   from "what it says", which is the distinction a reader makes first — and on
   the terms it is where the last-updated date belongs, because that is the
   thing a returning reader checks before anything else. */
.page-doc-head {
    padding: 34px 36px;
    margin-bottom: 34px;
    background: var(--ccm-surface);
    border: 1px solid var(--ccm-rule);
    border-left: 4px solid var(--ccm-amber);
    border-radius: var(--ccm-radius);
}

.page-doc-head h1 {
    margin: 0 0 10px;
    font-size: 32px;
    line-height: 1.15;
    letter-spacing: -.015em;
}

.page-doc-lede {
    margin: 0;
    max-width: 62ch;
    font-size: 16.5px;
    line-height: 1.65;
    color: var(--ccm-body);
}

.page-doc-head .btn { margin-top: 20px; }

/* ------------------------------------------------------------- the body */

/* Roughly 70 characters. Terms nobody can read are terms nobody reads, and a
   full-width line of legal text on a desktop is exactly that.
   Centred, so a document page is a column on the page rather than a column
   pinned to its left edge. */
.page-doc { max-width: 72ch; margin-inline: auto; }

/* Inside the two-column terms layout the article is already placed by the
   grid, so it must not centre itself a second time. */
.doc-layout .page-doc { margin-inline: 0; }

.page-doc h2 {
    margin: 38px 0 12px;
    padding-top: 22px;
    font-size: 19px;
    line-height: 1.3;
    letter-spacing: -.01em;
    border-top: 1px solid var(--ccm-rule-soft);
}

.page-doc-head + h2,
.page-doc > h2:first-of-type { margin-top: 0; }

.page-doc h3 { margin: 22px 0 8px; font-size: 15px; }

/* `--ccm-body`, like everything else on the site.
   A darker grey was tried here and reverted: the client's palette is closed,
   and the brand rule in the Phase 5 suite enforces it. It was also not needed
   -- #666 on white at 15px is about 5.7:1, comfortably past the 4.5:1 that
   normal text has to clear. What actually makes a long document readable is
   the size and the leading, and both are set generously here. */
.page-doc p {
    margin: 0 0 15px;
    font-size: 15px;
    line-height: 1.78;
    color: var(--ccm-body);
}

/* Underlined, because an unmarked link in a paragraph of legal text is a link
   nobody sees. Buttons are exempt: a button that is also underlined reads as
   broken, and it is already unmistakably a control. */
.page-doc a:not(.btn) {
    color: var(--ccm-link);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.page-doc .btn { text-decoration: none; }
.page-doc strong { color: var(--ccm-ink); font-weight: 600; }

/* Numbered steps, with the number as a mark rather than a list bullet — it
   makes a four-step process read as a process instead of as a list. */
.page-steps {
    counter-reset: step;
    list-style: none;
    margin: 0 0 18px;
    padding: 0;
}

.page-steps li {
    counter-increment: step;
    position: relative;
    margin-bottom: 16px;
    padding-left: 44px;
    font-size: 15px;
    line-height: 1.72;
    color: var(--ccm-body);
}

.page-steps li::before {
    content: counter(step);
    position: absolute;
    left: 0;
    top: 1px;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--ccm-amber);
    color: var(--ccm-amber-ink);
    font-size: 13px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.page-steps strong,
.sell-list strong { color: var(--ccm-ink); font-weight: 600; }

/* A closing note, in the soft panel colour so it reads as an aside rather
   than as another clause. */
.page-doc-foot {
    margin-top: 34px;
    padding: 18px 20px;
    background: var(--ccm-mint);
    border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius);
    font-size: 14.5px;
    line-height: 1.7;
}

.page-doc-foot p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------- contact */

/* Four facts, and the grid must not care how many columns they land in.
   The first version drew its dividing rules by showing a grey container
   through one-pixel gaps, which is a neat trick until the item count does not
   divide by the column count — then the leftover cells show as grey blocks
   with nothing in them, which is exactly what happened with four facts in
   three columns. Borders on the cells themselves have no such failure mode:
   where there is no cell there is nothing to see. */
.page-contact {
    display: grid;
    margin: 6px 0 18px;
    /* Two columns, not auto-fit.
       There are four facts, and four divides evenly by two and by four but
       not by three — which is what auto-fit chose at this measure, leaving the
       fourth alone on a row beside a stretch of nothing. A fixed two keeps
       every row full at every width the document column can take, and each
       fact gets enough room that the address does not wrap into three lines. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius);
    overflow: hidden;
    background: var(--ccm-bg);
}

/* One per row on a phone: two columns of an address at 160px each is worse
   than four rows anybody can read. */
@media (max-width: 480px) {
    .page-contact { grid-template-columns: 1fr; }
}

.page-contact > div {
    padding: 16px 18px;
    border-right: 1px solid var(--ccm-rule);
    border-bottom: 1px solid var(--ccm-rule);
}

/* Every cell draws a right and a bottom rule, which doubles up against the
   container's own border on the last column and the last row. Shifting the
   grid one pixel down-right and clipping it hides exactly those two, without
   the stylesheet ever needing to know how many columns auto-fit chose. */
.page-contact > div { margin: 0 -1px -1px 0; }

.page-contact p { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--ccm-ink); }

.page-contact-label {
    display: block;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--ccm-muted);
    margin-bottom: 5px;
}

@media (max-width: 767px) {
    .page-doc-head { padding: 24px 20px; margin-bottom: 26px; }
    .page-doc-head h1 { font-size: 25px; }
    .page-doc-lede { font-size: 15px; }
    .page-doc h2 { font-size: 17px; margin-top: 30px; }
    .page-steps li { padding-left: 38px; }
}

/* ===========================================================================
   SELL ON THIS PLATFORM

   The one page here that has to persuade rather than inform, so it gets a
   landing-page shape: the cost answered in the first screen, the process as
   numbered steps, and the same call to action at both ends — a trader who is
   convinced by the third paragraph should not have to scroll back up.
   =========================================================================== */

/* Wide enough for three cost cards, and no wider.
   The first version let this run the full 1170px while capping the prose at
   72ch, which put every paragraph in the left two-thirds and left the right
   third empty on every screen — the text looked misaligned rather than
   measured. Constraining the whole article to a little over the width three
   cards want makes the prose and the cards share one edge. */
.page-doc.is-wide { max-width: 940px; margin-inline: auto; }

.page-doc.is-wide > p,
.page-doc.is-wide > h2,
.page-doc.is-wide > .page-steps,
.page-doc.is-wide > .sell-list { max-width: 74ch; }

.sell-grid {
    display: grid;
    gap: 16px;
    margin: 6px 0 24px;
    grid-template-columns: repeat(auto-fit, minmax(212px, 1fr));
}

.sell-card {
    padding: 22px;
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    border-top: 3px solid var(--ccm-amber);
    border-radius: var(--ccm-radius);
}

/* The figure is the answer to the question the trader actually came with, so
   it is the biggest thing on the card and the heading beneath it is the
   caption — not the other way round. */
.sell-card-figure {
    display: block;
    font-size: 26px;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -.02em;
    color: var(--ccm-ink);
}

.sell-card h3 {
    margin: 6px 0 8px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--ccm-muted);
}

.sell-card p { margin: 0; font-size: 13.5px; line-height: 1.68; color: var(--ccm-body); }

/* A tick rather than a bullet: every line in these lists is something the
   platform gives or asks, and a tick says so at a glance. */
.sell-list { list-style: none; margin: 0 0 18px; padding: 0; }

.sell-list li {
    position: relative;
    margin-bottom: 11px;
    padding-left: 28px;
    font-size: 15px;
    line-height: 1.72;
    color: var(--ccm-body);
}

.sell-list li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 8px;
    width: 15px;
    height: 9px;
    border-left: 2px solid var(--ccm-amber);
    border-bottom: 2px solid var(--ccm-amber);
    transform: rotate(-45deg);
}

.sell-cta {
    margin-top: 30px;
    padding: 28px;
    background: var(--ccm-surface);
    border: 1px solid var(--ccm-rule);
    border-left: 4px solid var(--ccm-amber);
    border-radius: var(--ccm-radius);
}

.sell-cta p:last-child { margin-bottom: 0; }
.sell-cta .muted { font-size: 13.5px; color: var(--ccm-muted); }

/* ===========================================================================
   TERMS — a contents rail

   Thirteen clauses is a long page, and the reader who opens it usually wants
   one of them: what happens if I return something, what happens to my
   information. Scrolling past twelve to find the thirteenth is the difference
   between terms that are published and terms that are read.

   Sticky on a desktop, a plain list on a phone — a sticky sidebar on a narrow
   screen eats the screen.
   =========================================================================== */

/* Centred as a unit, not stretched across the shell.
   The contents rail plus a 72ch column is about 900px. Letting the grid fill
   the full 1170px container put the document hard against the rail with 250px
   of nothing to its right, which reads as a layout that failed rather than one
   that chose its measure. */
.doc-layout {
    display: grid;
    gap: 44px;
    align-items: start;
    grid-template-columns: 210px minmax(0, 72ch);
    justify-content: center;
    margin: 0 auto;
}

.doc-toc { position: sticky; top: 20px; }

.doc-toc-title {
    margin: 0 0 12px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--ccm-muted);
}

.doc-toc ol { list-style: none; margin: 0; padding: 0; counter-reset: toc; }

.doc-toc li { counter-increment: toc; }

.doc-toc a {
    display: block;
    padding: 6px 10px 6px 0;
    font-size: 13px;
    line-height: 1.45;
    color: var(--ccm-body);
    text-decoration: none;
    border-left: 2px solid var(--ccm-rule);
    padding-left: 12px;
    transition: color .12s ease, border-color .12s ease;
}

.doc-toc a:hover {
    color: var(--ccm-ink);
    border-left-color: var(--ccm-amber);
}

/* Anchored headings must not slide under the sticky header when jumped to. */
.page-doc h2[id] { scroll-margin-top: 24px; }

@media (max-width: 1023px) {
    .doc-layout { grid-template-columns: 1fr; gap: 24px; }

    .doc-toc {
        position: static;
        padding: 18px 20px;
        background: var(--ccm-surface);
        border: 1px solid var(--ccm-rule);
        border-radius: var(--ccm-radius);
    }

    /* Two columns of links on a tablet, so the contents does not become a
       screen of its own before the document starts. */
    .doc-toc ol { columns: 2; column-gap: 20px; }
    .doc-toc a { border-left: 0; padding-left: 0; }
}

@media (max-width: 767px) {
    /* Capped and scrollable, not a full screen of links.
       Thirteen clauses in one column is 400px of navigation before the
       document begins -- which is the failure a contents rail exists to
       prevent, arriving one screen earlier. Five visible and the rest a short
       scroll keeps every clause reachable and gives the page back to the
       terms. */
    .doc-toc ol {
        /* `columns: auto`, not `columns: 1`.
           A multi-column box under a max-height overflows sideways rather than
           down -- it makes a second column outside the box -- so the capped
           list grew a horizontal scrollbar and hid clauses 5 to 13 off the
           right edge. Turning the column formatting off entirely is what makes
           overflow-y mean what it says. */
        columns: auto;
        max-height: 168px;
        overflow-y: auto;
        overflow-x: hidden;
        -webkit-overflow-scrolling: touch;
    }

    /* Something to scroll towards: without it a clipped list looks like a
       complete list that happens to end at "5. Paying". */
    .doc-toc {
        position: relative;
        padding-bottom: 22px;
    }

    .doc-toc::after {
        content: "";
        position: absolute;
        left: 1px;
        right: 1px;
        bottom: 1px;
        height: 30px;
        pointer-events: none;
        background: linear-gradient(to bottom, transparent, var(--ccm-surface));
        border-radius: 0 0 var(--ccm-radius) var(--ccm-radius);
    }

    .sell-card-figure { font-size: 22px; }
    .sell-cta { padding: 20px; }
}

.foot-social svg { width: 17px; height: 17px; display: block; }

/* ===========================================================================
   FORM FIELDS ON THE STOREFRONT

   `.field` was styled only inside `.checkout-layout`, so every other form on
   the shop — order tracking among them — rendered with its label inline
   against its input and its hint wrapped around the box. The rules were always
   general; only their selector was not.
   =========================================================================== */

/* Unscoped, deliberately.
   shop.css is loaded by the storefront layout and by nothing else, so the file
   itself is the scope. The first version qualified these with `.shop-main` and
   `.page-shell`, which missed the order-tracking form — and missing one form is
   how a rule like this comes to be written a second time somewhere else.
   `.checkout-layout` has its own, more specific rules and still wins. */
.field { margin-bottom: 16px; }

.field label {
    display: block;
    margin-bottom: 6px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ccm-ink);
}

.field input,
.field select,
.field textarea {
    display: block;
    width: 100%;
    padding: 11px 13px;
    font: inherit;
    font-size: 14.5px;
    color: var(--ccm-ink);
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
    border-color: var(--ccm-link);
    outline: 2px solid rgba(0, 102, 204, .18);
    outline-offset: 0;
}

/* A hint belongs under its field on its own line. Inline, it wraps around the
   input and reads as part of the next control. */
.field > .muted,
.field > .text-sm,
.field > .field-hint {
    display: block;
    margin-top: 6px;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--ccm-muted);
}

/* ===========================================================================
   TRACK YOUR ORDER — the lookup

   The page a customer opens when they are anxious about a parcel. It should
   look like one job: a box, a button, and nothing competing with them.
   =========================================================================== */

.track-hub { max-width: 720px; margin: 0 auto; }

.track-hub .page-head { margin-bottom: 22px; }
.track-hub .page-head h1 { font-size: 28px; letter-spacing: -.015em; }
.track-hub .page-head .sub { margin-top: 6px; font-size: 14.5px; color: var(--ccm-body); }

.track-hub .panel {
    padding: 26px 28px;
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius);
}

/* The lookup card is the one thing on the page worth doing, so it carries the
   amber edge and the panel below it does not. */
.track-hub .panel.is-primary { border-left: 4px solid var(--ccm-amber); }

.track-hub .panel h2 { font-size: 17px; margin-bottom: 6px; }
.track-hub .panel > .muted { font-size: 14px; line-height: 1.65; color: var(--ccm-body); }

/* Two fields side by side above 560px: an order number and a short code are
   both narrow, and stacking them makes the form look longer than the work it
   asks for. */
.track-form { margin-top: 18px; }

.track-form .track-form-row {
    display: grid;
    gap: 0 16px;
    grid-template-columns: 1fr;
}

@media (min-width: 560px) {
    .track-form .track-form-row { grid-template-columns: 1fr 1fr; }
}

.track-form .btn { margin-top: 2px; }
.track-form input { font-variant-numeric: tabular-nums; letter-spacing: .01em; }

/* The signed-in alternative, quieter than the form above it. */
.track-alt {
    margin-top: 16px;
    padding: 18px 20px;
    background: var(--ccm-surface);
    border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius);
    font-size: 14px;
    line-height: 1.65;
    color: var(--ccm-body);
}

.track-alt h2 { font-size: 15px; margin-bottom: 4px; }
.track-alt p { margin: 0; }

@media (max-width: 767px) {
    .track-hub .panel { padding: 20px; }
    .track-hub .page-head h1 { font-size: 23px; }
}

/* ===========================================================================
   NEED A HAND?

   The last thing on the homepage before the footer, and what somebody who has
   scrolled this far without finding what they wanted is looking for. Three
   things a person can act on, each with a tap target big enough for a thumb.
   =========================================================================== */

.help-strip {
    display: grid;
    gap: 22px;
    align-items: center;
    grid-template-columns: minmax(200px, 260px) 1fr;
    padding: 24px 26px;
    background: var(--ccm-surface);
    border: 1px solid var(--ccm-rule);
    border-left: 4px solid var(--ccm-amber);
    border-radius: var(--ccm-radius);
}

.help-intro h2 { margin: 0 0 5px; font-size: 19px; letter-spacing: -.01em; }
.help-intro p  { margin: 0; font-size: 13px; line-height: 1.6; color: var(--ccm-body); }

.help-ways {
    display: grid;
    gap: 10px;
    list-style: none;
    margin: 0;
    padding: 0;
    /* 230, not 210: at the smaller figure a card was too narrow for
       hello@capecoastmall.com and the address broke across two lines in the
       middle of a word. An email split as "…capecoastmall.co / m" is one
       nobody can read back to somebody over the telephone. */
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

.help-way {
    display: flex;
    align-items: center;
    gap: 12px;
    height: 100%;
    padding: 13px 15px;
    text-decoration: none;
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius);
    transition: border-color .12s ease, transform .12s ease;
}

.help-way:hover { border-color: var(--ccm-amber); transform: translateY(-1px); }

/* The address is not a link, so it must not behave like one. */
.help-way.is-static { cursor: default; }
.help-way.is-static:hover { border-color: var(--ccm-rule); transform: none; }

/* `flex: 0 0 auto` and a fixed box.
   Without it the circle is a flex item that can grow, and the SVG inside it
   has a viewBox and no width — so it takes the width offered and scales its
   height to match. On the homepage that rendered these three icons at
   1098 x 1098 pixels each. An inline SVG must always be given a size by
   something; a viewBox is a coordinate system, not a dimension. */
.help-way-mark {
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--ccm-amber);
    color: var(--ccm-amber-ink);
}

.help-way-mark svg {
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    display: block;
}

.help-way-body { min-width: 0; }

.help-way-label {
    display: block;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--ccm-muted);
}

/* Wraps rather than truncates: an address cut off mid-word is worse than one
   on two lines, and a telephone number must never be clipped. */
.help-way-value {
    display: block;
    margin-top: 1px;
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--ccm-ink);
    /* `break-word`, not `anywhere`: it breaks only when a word genuinely
       cannot fit, and prefers a sensible point when it must. */
    overflow-wrap: break-word;
}

@media (max-width: 767px) {
    .help-strip { grid-template-columns: 1fr; padding: 18px; }
}

/* ===========================================================================
   PEOPLE ARE BUYING

   A small panel that appears once somebody has scrolled. It gets out of the
   way of the footer, and it closes.
   =========================================================================== */

.buzz {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 40;
    width: 340px;
    max-width: calc(100vw - 24px);
    background: var(--ccm-bg);
    border: 1px solid var(--ccm-rule);
    border-radius: var(--ccm-radius);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
    overflow: hidden;
}

.buzz-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--ccm-rule-soft);
}

.buzz-title { margin: 0; font-size: 13px; }

/* A real button, sized for a thumb. A 12-pixel cross only a mouse can hit is
   how a dismissible panel becomes an undismissable one on a phone. */
.buzz-close {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: 0;
    border-radius: 50%;
    font-size: 20px;
    line-height: 1;
    color: var(--ccm-muted);
    cursor: pointer;
}

.buzz-close:hover { background: var(--ccm-surface); color: var(--ccm-ink); }
.buzz-close:focus-visible { outline: 2px solid var(--ccm-link); outline-offset: 1px; }

/* Two across, and short. This is a nudge, not a second listing page. */
.buzz-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1px;
    background: var(--ccm-rule-soft);
    max-height: 46vh;
    overflow-y: auto;
}

.buzz-item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 9px 10px;
    background: var(--ccm-bg);
    text-decoration: none;
    min-width: 0;
}

.buzz-item:hover { background: var(--ccm-surface); }

.buzz-item-pic {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    max-width: 40px;
    max-height: 40px;
    object-fit: contain;
    padding: 2px;
    box-sizing: border-box;
    border-radius: var(--ccm-radius);
    background: var(--ccm-bg);
}

.buzz-item-body { min-width: 0; }

.buzz-item-name {
    display: block;
    font-size: 12.5px;
    color: var(--ccm-ink);
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.buzz-item-meta {
    display: block;
    margin-top: 1px;
    font-size: 11px;
    color: var(--ccm-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

@media (max-width: 520px) {
    .buzz { right: 10px; left: 10px; bottom: 10px; width: auto; }
    .buzz-grid { grid-template-columns: 1fr; max-height: 38vh; }
}

@media (prefers-reduced-motion: reduce) {
    .help-way:hover { transform: none; }
}

/* ---------------------------------------------------------------------------
   A safety net for every inline icon.

   An <svg> with a viewBox and no width is not "24 pixels" — it is a shape with
   a coordinate system, and it will take whatever width its container offers
   and scale its height to match. Where a container is a flex or grid item that
   can grow, that is however wide the page is. This caps any icon nobody has
   sized explicitly at something recognisably an icon, so the failure is a
   slightly wrong glyph rather than a picture the size of the screen.
   --------------------------------------------------------------------------- */
svg:not([width]):not([height]) { max-width: 100%; max-height: 100%; }
