/* Classic
 * ---------------------------------------------------------------------------
 * The three column shop front: a rail of categories on the left, the shop in
 * the middle, the search, basket and account on the right. Every panel is a
 * white box with a coloured bar across its head, which is the shape a shopper
 * who has been buying online for twenty years already knows how to read.
 *
 * Two rules hold the whole thing together. Colour is declared once as a token
 * and every rule below uses the token, so a shop that changes its colour
 * changes the theme rather than fighting it. And the dark scheme is the same
 * tokens with different values, so nothing below this block ever needs to know
 * which scheme is running. A fixed colour sitting next to a token is how a
 * panel ends up unreadable at night.
 */

:root {
    --cl-primary: var(--color-primary, #1565C0);
    --cl-secondary: var(--color-secondary, #3A3A3A);

    /* White. The layout this follows sat the whole shop on a light grey,
       which made sense when every panel it held was white and needed
       separating from the page. Ours separates them with a border instead, so
       the grey was doing nothing but greying the shop. */
    --cl-page: var(--color-background, #FFFFFF);
    --cl-panel: var(--color-surface, #FFFFFF);
    --cl-ink: var(--color-text, #333333);
    --cl-muted: var(--color-muted, #767676);

    --cl-line: #D8D8D8;
    --cl-line-soft: #ECECEC;
    --cl-bar: var(--cl-secondary);
    --cl-bar-ink: #FFFFFF;

    /* Named for what they are, and aliased for what the shared partials ask
       for. A partial that reaches for a token nothing defines gets nothing,
       which is how a band ends up with no background and white text on it. */
    --cl-accent: var(--color-accent, #0D47A1);

    /* The shop's colour, and the shop's colour when it has to be read as text.
       The brand colour does not change between the schemes, but the panel it
       sits on does, so the blue that reads cleanly on white is far too dark on
       a dark panel. Derived rather than fixed, so it follows whatever colour
       the shop chooses instead of being right for one blue only. */
    --cl-primary-text: var(--cl-primary);
    /* The soft band, which used to be an alias of the page. Once the page
       went white an aliased band was white on white: the quiet sections and
       the category list's hover both vanished. It is its own light grey now. */
    --cl-sand: #F2F2F2;
    --cl-marquee-speed: 30s;

    --cl-danger: #B3261E;
    --cl-danger-on-bar: #FCA5A5;
    --cl-ok: #2E7D32;

    --cl-radius: 3px;
    --cl-pill: 999px;

    /* Taken from the layout this theme is modelled on, which runs to 1518px
       with each rail at 17% of it: 258px at full width, and proportional all
       the way down rather than fixed. A fixed rail at 232px was both too
       narrow at 1518 and too wide at 1100.
    
       The gutter is added to the max-width rather than eaten out of it, so
       the content box really is 1518 and the rails really are 258. Everything
       is border-box here, so a plain max-width of 1518 would have left 1478
       of content and 251px rails. */
    --cl-content: 1518px;
    --cl-gutter: clamp(0.75rem, 2vw, 1.25rem);
    --cl-measure: calc(var(--cl-content) + (var(--cl-gutter) * 2));
    --cl-band: clamp(1.25rem, 3vw, 2.25rem);
    --cl-rail: 17%;

    --cl-display: var(--font-heading, 'Oswald', 'Arial Narrow', sans-serif);
    --cl-body: var(--font-body, 'Open Sans', Arial, sans-serif);
}

/* The dark scheme is the same tokens with different values. The blue stays:
   it is the shop's own colour and a shop does not change its sign at night. */
:root.dark {
    --cl-page: #17181A;
    --cl-panel: #202225;

    /* Sand follows. It stopped being an alias of the page when the page went
       white, so without this it would have stayed a light grey at night. */
    --cl-sand: #26282B;
    --cl-ink: #E6E6E6;
    --cl-muted: #9BA0A6;

    /* Lifted towards white by just enough to read on a dark panel. */
    --cl-primary-text: color-mix(in srgb, var(--cl-primary) 52%, #FFFFFF);

    --cl-line: rgba(230, 230, 230, 0.18);
    --cl-line-soft: rgba(230, 230, 230, 0.10);
    --cl-bar: #2A2D31;
    --cl-bar-ink: #F2F2F2;

    --cl-danger: #FCA5A5;
    --cl-danger-on-bar: #FCA5A5;
    --cl-ok: #6EE7B7;
}

:root.dark body { background: var(--cl-page); color: var(--cl-ink); }

/* ---------- foundations ---------- */

body.cl-body {
    background: var(--cl-page);
    color: var(--cl-ink);
    font-family: var(--cl-body);
    font-size: 0.875rem;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

.cl-wrap {
    width: 100%;
    max-width: var(--cl-measure);
    margin-inline: auto;
    padding-inline: var(--cl-gutter);
}

.cl-wrap--narrow { max-width: 48rem; }
.cl-wrap--mid { max-width: 62rem; }
.cl-wrap--full { max-width: none; padding-inline: 0; }

/* Inside the three column shell the middle column is already narrower
   than those maxima: about 970px against Medium's 992 and Wide's 1518.
   Both clamped to the column and came out the same number, so three of
   the four choices drew an identical band and the Width control looked
   broken. With a rail showing they are shares of the column instead,
   which is the only thing that can be measured there. Narrow lands
   within two pixels of the 48rem it used to be, so nothing already set
   to it moves. A page with both rails off keeps the maxima above, where
   they mean what they say. */
.cl-shell--both .cl-main .cl-wrap--narrow,
.cl-shell--left .cl-main .cl-wrap--narrow,
.cl-shell--right .cl-main .cl-wrap--narrow { max-width: 79%; }

.cl-shell--both .cl-main .cl-wrap--mid,
.cl-shell--left .cl-main .cl-wrap--mid,
.cl-shell--right .cl-main .cl-wrap--mid { max-width: 90%; }

.cl-display { font-family: var(--cl-display); font-weight: 500; letter-spacing: 0.01em; }
.cl-h1 { font-size: clamp(1.5rem, 3vw, 2rem); line-height: 1.2; }
.cl-h2 { font-size: clamp(1.25rem, 2.2vw, 1.625rem); line-height: 1.25; }
.cl-h3 { font-size: 1.0625rem; line-height: 1.3; }
.cl-lede { font-size: 0.9375rem; line-height: 1.7; color: var(--cl-muted); max-width: 46ch; }
.cl-lede--span { max-width: none; }
.cl-muted { color: var(--cl-muted); }
.cl-center { text-align: center; }
.cl-center .cl-lede { margin-inline: auto; }

.cl-label {
    font-family: var(--cl-display);
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 500;
}

.cl-sr {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* The anchor reset belongs in a layer and the layout already has it there.
   This unlayered copy was quietly beating every utility that sets a colour,
   because an unlayered rule wins against a layered one however weak its
   selector: the Checkout link in the cart drawer and on the cart page carries
   text-white and came out in the body ink, black on the shop's blue.
   
   The layout's @layer base copy does the same job and loses to utilities, as
   it should. This one simply goes. */
.cl-link { color: var(--cl-primary-text); }
.cl-link:hover { text-decoration: underline; }

/* ---------- the panel, which is the whole theme ---------- */

/* A white box with a coloured bar across its head. Used by the rails, by the
   shop's own blocks and by the account pages, so one shape carries the theme. */
.cl-panel {
    background: var(--cl-panel);
    border: 1px solid var(--cl-line);
    border-radius: var(--cl-radius);
    margin-bottom: 1rem;
}

.cl-panel__head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.625rem 0.875rem;
    background: var(--cl-primary);
    color: #FFFFFF;
    font-family: var(--cl-display);
    font-size: 0.8125rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 500;
    border-radius: calc(var(--cl-radius) - 1px) calc(var(--cl-radius) - 1px) 0 0;
}

/* A second colour for the heads that are not the shop's own colour, so a rail
   of eight orange bars does not read as eight alarms. */
.cl-panel__head--quiet { background: var(--cl-bar); color: var(--cl-bar-ink); }

.cl-panel__body { padding: 0.875rem; }
.cl-panel__body--flush { padding: 0; }

/* A list inside a panel: rows divided by a hairline, the last one without. */
.cl-list { display: flex; flex-direction: column; }
.cl-list a,
.cl-list > span {
    padding: 0.5rem 0.875rem;
    border-bottom: 1px solid var(--cl-line-soft);
    font-size: 0.8125rem;
}
.cl-list > :last-child { border-bottom: 0; }
.cl-list a:hover { background: var(--cl-sand); color: var(--cl-primary-text); }

/* ---------- the three columns ---------- */

.cl-shell {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr;
    padding-block: 1rem;
}

/* Three columns down to 800px, which is the step the original takes, and the
   rails fold under the shop below it.

   The original drops them entirely at that width. This keeps them, because
   ours carry the search box and the basket as well as the category list, and
   a shopper on a phone who cannot search is worse off than one who has to
   scroll past a category list.

   The percentage rails mean there is no second breakpoint to tune: between
   800 and 1518 the whole thing scales, which is what the original does. */
@media (min-width: 50rem) {
    .cl-shell--both { grid-template-columns: var(--cl-rail) minmax(0, 1fr) var(--cl-rail); }
    .cl-shell--left { grid-template-columns: var(--cl-rail) minmax(0, 1fr); }
    .cl-shell--right { grid-template-columns: minmax(0, 1fr) var(--cl-rail); }
}

/* The original's own step at 1024, where it stops running edge to edge and
   takes a margin. Ours already has a gutter, so this just opens it a little. */
@media (max-width: 64rem) {
    .cl-shell { gap: 0.75rem; }
}

/* Folded into one column, the shop comes first. The rails are a category
   list, a search box and the basket, all of which are things you reach for
   after seeing what is on the page: ahead of it they pushed the reason for
   the page below the fold. Ordered rather than moved in the markup, because
   on a wide page the left rail genuinely is first. */
@media (max-width: 49.9375rem) {
    .cl-shell > .cl-main { order: -1; }
}

.cl-side { min-width: 0; }
.cl-main { min-width: 0; }

/* A row of products. It scrolls sideways where there is no room to wrap, and
   becomes a grid once there is. The breakpoints are lower than a full width
   theme would use because the middle column here is sharing the page with two
   rails, so "enough room" arrives sooner than the window suggests. */
.cl-rail {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 72%;
    gap: 1rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    padding-bottom: 0.25rem;
}

.cl-rail::-webkit-scrollbar { display: none; }
.cl-rail > * { scroll-snap-align: start; }

@media (min-width: 30rem) { .cl-rail { grid-auto-columns: 44%; } }

@media (min-width: 48rem) {
    .cl-rail { grid-auto-columns: unset; grid-auto-flow: row; overflow: visible; grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .cl-rail--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .cl-rail--4 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 72rem) {
    .cl-rail--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    /* A row that keeps scrolling beside a column of words, rather than wrapping
       and stranding the words at the top of a tall empty column. */
    .cl-rail--keep { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); overflow-x: auto; }
}

/* ---------- the top strips ---------- */

.cl-util {
    background: var(--cl-bar);
    color: var(--cl-bar-ink);
    font-size: 0.75rem;
}

.cl-util__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-block: 0.375rem;
    flex-wrap: wrap;
}

.cl-util a:hover { color: var(--cl-primary-text); }

/* On a phone the two halves of this bar stop fitting side by side and
   wrap onto their own lines, where space-between has nothing left to
   space and leaves both hanging off the left edge. Each line takes the
   full width and centres itself instead. */
@media (max-width: 40rem) {
    .cl-util__inner { justify-content: center; text-align: center; }
    .cl-util__inner > * { width: 100%; justify-content: center; }
}

/* The account and basket links, each with its mark. Set apart from the
   dark mode toggle and from each other, because at the old 1rem they
   read as one run of small grey words rather than three things you can
   go to. Wraps to its own line on a narrow screen rather than squeezing
   the gaps back out. */
.cl-util__acts {
    display: flex;
    align-items: center;
    gap: 1.75rem;
    flex-wrap: wrap;
}

.cl-util__act {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
}

/* Sized here, not on the element, so the two marks cannot drift apart.
   flex: none stops a long label squeezing the glyph out of shape. */
.cl-util__act svg {
    width: 0.9375rem;
    height: 0.9375rem;
    flex: none;
}

.cl-head { background: var(--cl-panel); border-bottom: 1px solid var(--cl-line); }

.cl-head__inner {
    display: flex;
    align-items: center;
    gap: clamp(1rem, 3vw, 2.5rem);
    padding-block: 1rem;
    flex-wrap: wrap;
}

.cl-wordmark {
    font-family: var(--cl-display);
    font-size: clamp(1.5rem, 3vw, 2.125rem);
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--cl-primary-text);
    white-space: nowrap;
}

.cl-wordmark img { max-height: 3rem; width: auto; }

/* The telephone, which is the thing this kind of shop puts in its masthead
   because its customers ring up. */
.cl-phone { display: flex; align-items: center; gap: 0.625rem; margin-inline-start: auto; }
.cl-phone__icon {
    display: grid; place-items: center;
    width: 2.25rem; height: 2.25rem;
    border-radius: var(--cl-pill);
    background: var(--cl-primary); color: #FFFFFF;
    flex: none;
}
.cl-phone__label { font-size: 0.6875rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--cl-muted); }
.cl-phone__number { font-family: var(--cl-display); font-size: 1rem; color: var(--cl-primary-text); }

/* The search, with its category select, as one joined control. */
.cl-search { display: flex; min-width: 0; flex: 1 1 18rem; max-width: 30rem; }

.cl-search select,
.cl-search input {
    border: 1px solid var(--cl-line);
    background: var(--cl-panel);
    color: var(--cl-ink);
    font: inherit;
    font-size: 0.8125rem;
    padding: 0.5rem 0.625rem;
    min-width: 0;
}

.cl-search input { flex: 1; border-radius: var(--cl-radius) 0 0 var(--cl-radius); border-inline-end: 0; }

/* The chevron drawn here rather than left to the browser.
   
   A native select paints its arrow hard against the inside edge, and this one
   sits immediately beside the search button, so the two were touching with no
   air between them. Taking the appearance off lets the arrow be placed, and
   it is set in from the edge with the text padded clear of it. */
.cl-search select {
    border-inline-end: 0;
    max-width: 11rem;
    appearance: none;
    -webkit-appearance: none;
    padding-inline-end: 2.25rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23767676' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.875rem center;
    background-size: 0.7rem;
}

/* Right to left puts the arrow on the other side, so the padding has to move
   with it. */
[dir="rtl"] .cl-search select { background-position: left 0.875rem center; }
.cl-search button {
    border: 0; cursor: pointer;
    background: var(--cl-secondary); color: #FFFFFF;
    padding-inline: 0.875rem;
    border-radius: 0 var(--cl-radius) var(--cl-radius) 0;
}
.cl-search button:hover { background: var(--cl-primary); }

/* ---------- the navigation bar ---------- */

.cl-nav { background: var(--cl-bar); color: var(--cl-bar-ink); }
.cl-nav__inner { display: flex; align-items: stretch; justify-content: space-between; gap: 1rem; }
.cl-nav__list { display: flex; align-items: stretch; margin: 0; padding: 0; list-style: none; min-width: 0; }

.cl-nav__link {
    display: inline-flex;
    align-items: center;
    /* Two rems either side, which is the 32px the original gives each item.
       At 20px the words sat closer together than the dividers between them
       and the row read as one run of text. */
    padding: 0.875rem 2rem;
    font-family: var(--cl-display);
    font-size: 0.8125rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
}

/* The divider is a short rule between the links, not a border down the side
   of each one.
   
   As a border it ran the full height of the bar and turned the navigation
   into a row of boxes. The original draws about two thirds of the bar's
   height, centred, with clear space above and below: measured there as a 40px
   rule in a 62px bar. It is a pseudo-element so it can be that height without
   the link having to be.
   
   On the item rather than the link, and not on the last one, so the row does
   not end in a rule hanging off the final word. */
.cl-nav__list > li { position: relative; }

.cl-nav__list > li::after {
    content: "";
    position: absolute;
    inset-inline-end: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 1px;
    height: 65%;
    background: rgba(255, 255, 255, 0.18);
    pointer-events: none;
}

.cl-nav__list > li:last-child::after { content: none; }

/* A hovered item paints to the full height of the bar, so the rule beside it
   would cut across the fill. It goes while the fill is there. */
.cl-nav__list > li:hover::after { content: none; }

/* The rule that used to open the row is gone with the rest: the original has
   nothing before its first link. */
.cl-nav__link:hover { background: var(--cl-primary); color: #FFFFFF; }

/* Tucked away, not taken down: the list keeps a width to measure when it is
   hidden, or the next measurement reads zero and the bar flickers. */
.cl-nav--tucked {
    position: absolute;
    visibility: hidden;
    pointer-events: none;
    inset-inline-start: -9999px;
}

.cl-burger {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.875rem 1rem;
    border: 0;
    background: transparent;
    color: inherit;
    cursor: pointer;
    font: inherit;
    font-family: var(--cl-display);
    font-size: 0.8125rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.cl-burger:hover { background: var(--cl-primary); color: #FFFFFF; }

@media (max-width: 25rem) {
    .cl-burger { gap: 0; padding-inline: 0.75rem; }
    .cl-burger span { display: none; }
}

.cl-navpanel {
    position: absolute;
    left: 0; right: 0;
    z-index: 42;
    background: var(--cl-panel);
    /* The panel sits inside .cl-nav, which paints its text the bar's
       white. On the panel's own pale background that was white on
       white: every top level link was invisible, and only the ones
       that set a colour of their own could be read. */
    color: var(--cl-ink);
    border-bottom: 1px solid var(--cl-line);
    box-shadow: 0 18px 40px -26px rgba(0, 0, 0, 0.45);
    max-height: calc(100vh - 100%);
    overflow-y: auto;
    padding-block: 0.25rem 0.75rem;
}

.cl-navpanel__link {
    display: block;
    padding: 0.6875rem 0.875rem;
    border-bottom: 1px solid var(--cl-line-soft);
    font-family: var(--cl-display);
    font-size: 0.9375rem;
}

.cl-navpanel__link:last-child { border-bottom: 0; }
.cl-navpanel__link:hover { color: var(--cl-primary-text); }
.cl-navpanel__link--child { padding-inline-start: 1.75rem; font-size: 0.8125rem; color: var(--cl-muted); }

/* The departments, shut until asked for. The row reads like the links
   above it rather than like a heading, because it is something to
   press. */
.cl-navpanel__group > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    cursor: pointer;
    list-style: none;
}
.cl-navpanel__group > summary::-webkit-details-marker { display: none; }
/* Hidden explicitly, because the browser closes a details element by
   setting display:none on its children from the UA stylesheet, and an
   author rule beats that. .cl-navpanel__link sets display:block, so
   the departments stayed on screen with the panel shut. */
.cl-navpanel__group:not([open]) > .cl-navpanel__link--child { display: none; }
.cl-navpanel__group > summary:focus-visible { outline: 2px solid var(--cl-accent); outline-offset: -2px; }
.cl-navpanel__mark { flex: none; transition: transform 0.2s; color: var(--cl-muted); }
.cl-navpanel__group[open] > summary > .cl-navpanel__mark { transform: rotate(180deg); }
/* The last department carries the rule the closed row used to, so the
   open list does not run into whatever follows it. */
.cl-navpanel__group[open] > summary { border-bottom-color: var(--cl-line-soft); }

/* The basket, sitting on the end of the bar in the shop's own colour, which is
   where this kind of shop has always kept it. */
.cl-cartblock {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.5rem 1rem;
    background: var(--cl-primary);
    color: #FFFFFF;
    border: 0;
    cursor: pointer;
    font: inherit;
    text-align: start;
    flex: none;
}

/* The same width as a rail, so the block on the end of the bar lines up with
   the panel underneath it: 17% of the same 1518 content box, which is the
   258.047px the rail computes to. Below 800 the rails fold away and the block
   takes only what it needs. */
@media (min-width: 50rem) {
    .cl-cartblock { width: 17%; }
}

.cl-cartblock:hover { background: var(--cl-accent, var(--cl-primary)); filter: brightness(0.94); }
.cl-cartblock__text { min-width: 0; }
.cl-cartblock__title { font-family: var(--cl-display); font-size: 0.75rem; letter-spacing: 0.06em; text-transform: uppercase; display: block; }
.cl-cartblock__sub { font-size: 0.6875rem; opacity: 0.9; display: block; white-space: nowrap; }
.cl-cartblock__total { font-weight: 700; margin-inline-start: 0.25rem; }

/* ---------- the basket in the rail ---------- */

/* Every line, up to about six of them, and then it scrolls. Showing the
   basket is the point of this panel, but a twenty line basket would run the
   rail past the fold and push the sign-in panel off the bottom of the page. */
.cl-cartrail {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 21rem;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.cl-cartrail__empty { font-size: 0.8125rem; text-align: center; }

.cl-cartrail__line {
    display: grid;
    grid-template-columns: 2.5rem minmax(0, 1fr) auto;
    gap: 0.5rem;
    align-items: start;
    padding-block: 0.5rem;
    border-bottom: 1px solid var(--cl-line-soft);
}

.cl-cartrail__line:last-child { border-bottom: 0; }

.cl-cartrail__pic {
    display: block;
    width: 2.5rem;
    height: 2.5rem;
    border: 1px solid var(--cl-line-soft);
    background: var(--cl-sand);
    overflow: hidden;
}

.cl-cartrail__pic img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* The stand-in is a picture of nothing in particular rather than a photograph
   of this product, so it is shown whole with a little air round it instead of
   being cropped to fill the square. */
.cl-cartrail__pic img.is-placeholder { object-fit: contain; padding: 0.25rem; }

.cl-cartrail__about { min-width: 0; display: grid; gap: 0.125rem; }

/* Two lines of a long product name, then an ellipsis. A rail is 258px wide and
   a six word title would otherwise push the price out of the panel. */
.cl-cartrail__name {
    font-size: 0.8125rem;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.cl-cartrail__name:hover { color: var(--cl-primary-text); }
.cl-cartrail__opt { font-size: 0.6875rem; color: var(--cl-muted); }
.cl-cartrail__sum { font-size: 0.6875rem; color: var(--cl-muted); }
.cl-cartrail__line-total { font-size: 0.8125rem; font-weight: 700; white-space: nowrap; }

.cl-cartrail__foot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: 0.625rem;
    padding-top: 0.625rem;
    border-top: 1px solid var(--cl-line);
}

.cl-cartrail__go { margin-top: 0.75rem; display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap; }

/* ---------- bands and sections ---------- */

.cl-band { padding-block: var(--cl-band); }
.cl-band--tight { padding-block: clamp(0.75rem, 2vw, 1.25rem); }

/* The tabs stay tucked under the product, where they belong, but they
   had the same small gap underneath and ran straight into whatever
   follows. Room below only, so the top is unchanged. */
.cl-band--tabs { padding-bottom: clamp(2.5rem, 6vw, 4.5rem); }
.cl-band--flush { padding-block: 0; }
.cl-band--flush-top { padding-block-start: 0; }
.cl-band--flush-bottom { padding-block-end: 0; }
.cl-band--crumbs { padding-block-start: 0.75rem; }
.cl-band--sand { background: var(--cl-sand); }
.cl-band--ink { background: var(--cl-bar); color: var(--cl-bar-ink); }
.cl-band--ink a { color: inherit; }
.cl-band--ink .cl-muted,
.cl-band--ink .cl-lede { color: color-mix(in srgb, var(--cl-bar-ink) 72%, transparent); }
.cl-band--ink .cl-label { color: inherit; }

/* Anything standing on the dark band is painted from the band's own two
   colours, never from white, so it follows when the scheme changes. */
.cl-band--ink .cl-field {
    background: transparent;
    border-color: color-mix(in srgb, var(--cl-bar-ink) 28%, transparent);
    color: var(--cl-bar-ink);
}
.cl-band--ink .cl-field::placeholder { color: color-mix(in srgb, var(--cl-bar-ink) 58%, transparent); }
.cl-band--ink .cl-btn--light { background: var(--cl-bar-ink); color: var(--cl-bar); border-color: var(--cl-bar-ink); }
.cl-band--ink .cl-btn--ghost { color: var(--cl-bar-ink); border-color: color-mix(in srgb, var(--cl-bar-ink) 50%, transparent); }
.cl-band--ink .cl-btn--ghost:hover { background: var(--cl-bar-ink); color: var(--cl-bar); }

.cl-note { margin-top: 0.625rem; font-size: 0.8125rem; color: color-mix(in srgb, var(--cl-ink) 78%, transparent); }
.cl-note--error { color: var(--cl-danger); }
.cl-band--ink .cl-note { color: color-mix(in srgb, var(--cl-bar-ink) 75%, transparent); }
.cl-band--ink .cl-note--error { color: var(--cl-danger-on-bar); }

/* A heading with a rule running off it, which is how this kind of shop labels
   a row of products. */
.cl-sectionhead {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    margin-bottom: 0.875rem;
}

.cl-sectionhead::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--cl-line);
}

.cl-sectionhead h2 {
    font-family: var(--cl-display);
    font-size: 1.0625rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
}

/* ---------- buttons ---------- */

.cl-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.5rem 1.125rem;
    border-radius: var(--cl-radius);
    background: var(--cl-secondary);
    color: #FFFFFF;
    border: 1px solid var(--cl-secondary);
    font-family: var(--cl-display);
    font-size: 0.8125rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}

.cl-btn:hover { background: var(--cl-primary); border-color: var(--cl-primary-text); color: #FFFFFF; }

.cl-btn--primary { background: var(--cl-primary); border-color: var(--cl-primary-text); }
.cl-btn--primary:hover { filter: brightness(0.93); }

.cl-btn--ghost { background: transparent; color: var(--cl-ink); border-color: var(--cl-line); }
.cl-btn--ghost:hover { background: var(--cl-secondary); color: #FFFFFF; border-color: var(--cl-secondary); }

.cl-btn--light { background: #FFFFFF; color: var(--cl-secondary); border-color: #FFFFFF; }
.cl-btn--block { width: 100%; }
.cl-btn--sm { padding: 0.375rem 0.75rem; font-size: 0.6875rem; }
.cl-btn[disabled] { opacity: 0.45; cursor: not-allowed; }

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

.cl-field {
    width: 100%;
    padding: 0.5rem 0.625rem;
    border: 1px solid var(--cl-line);
    border-radius: var(--cl-radius);
    background: var(--cl-panel);
    color: var(--cl-ink);
    font: inherit;
    font-size: 0.8125rem;
}

.cl-field:focus { outline: 2px solid var(--cl-primary); outline-offset: -2px; border-color: transparent; }
textarea.cl-field { min-height: 7rem; }

/* ---------- grids and the product card ---------- */

.cl-grid { display: grid; gap: 1rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 40rem) { .cl-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 40rem) { .cl-grid--4 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 64rem) { .cl-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* The card is a bordered box with everything centred, and the price sits beside
   the button rather than above it, which is the arrangement this kind of shop
   has used for twenty years. */
.cl-product {
    display: flex;
    flex-direction: column;
    background: var(--cl-panel);
    border: 1px solid var(--cl-line);
    border-radius: var(--cl-radius);
    padding: 0.875rem;
    text-align: center;
    height: 100%;
}

.cl-product:hover { border-color: var(--cl-primary-text); }

.cl-product__media { display: block; position: relative; }
.cl-product__brand { display: block; margin-top: 0.625rem; font-size: 0.6875rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--cl-muted); }
.cl-product__brand:hover { color: var(--cl-primary-text); }
.cl-product__title { display: block; margin-top: 0.25rem; font-size: 0.875rem; line-height: 1.4; }
.cl-product__title:hover { color: var(--cl-primary-text); }

.cl-product__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--cl-line-soft);
}

.cl-product__price { font-family: var(--cl-display); font-size: 1rem; color: var(--cl-primary-text); font-style: italic; }
.cl-product__was { margin-inline-start: 0.375rem; font-size: 0.8125rem; color: var(--cl-muted); text-decoration: line-through; font-style: normal; }

.cl-product__badge {
    position: absolute; top: 0.5rem; inset-inline-start: 0.5rem;
    padding: 0.125rem 0.5rem;
    border-radius: var(--cl-radius);
    background: var(--cl-secondary); color: #FFFFFF;
    font-size: 0.625rem; letter-spacing: 0.06em; text-transform: uppercase;
}

.cl-product__badge--accent { background: var(--cl-primary); }

/* ---------- media ---------- */

.cl-media { display: block; position: relative; overflow: hidden; background: var(--cl-page); border-radius: var(--cl-radius); }
.cl-media::before { content: ''; display: block; padding-top: 100%; }
.cl-media > img,
.cl-media > svg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: var(--product-img-fit, contain); }
.cl-media--4x5::before { padding-top: 125%; }
.cl-media--3x4::before { padding-top: 133.333%; }
.cl-media--1x1::before { padding-top: 100%; }
.cl-media--16x9::before { padding-top: 56.25%; }
.cl-zoom img { transition: transform 0.4s; }
.cl-zoom:hover img { transform: scale(1.04); }

/* ---------- prose ---------- */

.cl-prose { line-height: 1.75; }
.cl-prose p { margin-block: 0 1em; }
.cl-prose h2, .cl-prose h3 { font-family: var(--cl-display); margin-block: 1.5em 0.5em; }
.cl-prose h2 { font-size: 1.25rem; }
.cl-prose h3 { font-size: 1.0625rem; }
/* The markers, which the global reset clears and the indent alone does not
   bring back. A policy page written as a list rendered as a run of
   indented sentences with nothing to tell one obligation from the next. */
.cl-prose ul, .cl-prose ol { margin-block: 0 1em; padding-inline-start: 1.5rem; }
.cl-prose ul { list-style: disc; }
.cl-prose ol { list-style: decimal; }
.cl-prose ul ul { list-style: circle; }
.cl-prose li { margin-block: 0.35em; }
.cl-prose a { color: var(--cl-primary-text); text-decoration: underline; text-underline-offset: 2px; }
.cl-prose img { max-width: 100%; height: auto; border-radius: var(--cl-radius); }
.cl-prose blockquote {
    margin: 1.25em 0;
    padding: 0.75em 1em;
    border-inline-start: 3px solid var(--cl-primary);
    background: var(--cl-page);
}

/* ---------- the footer ---------- */

.cl-foot { background: var(--cl-bar); color: var(--cl-bar-ink); margin-top: 1.5rem; }

/* Five across: the menus, the newsletter, the contact details and the
   mark, which used to be a fourth row on its own because the track was
   set to four and there were five children.

   Flex rather than grid, and the widths are grow ratios rather than
   tracks, because a shop decides how many of these columns exist. A
   grid of five tracks leaves holes on the right for a shop with no
   footer menus; with ratios the columns that are there simply take the
   room. The newsletter gets the largest share since it holds a field
   and a button, and the lists get the least. */
.cl-foot__cols { display: flex; flex-wrap: wrap; gap: 2rem 2.75rem; padding-block: 3.5rem 2.5rem; }
.cl-foot__cols > * { flex: 1 1 11rem; min-width: 0; }

@media (min-width: 64rem) {
    .cl-foot__cols > * { flex-basis: 0; }
    .cl-foot__cols > :nth-child(1) { flex-grow: 20; }
    .cl-foot__cols > :nth-child(2) { flex-grow: 16; }
    .cl-foot__cols > :nth-child(3) { flex-grow: 26; }
    .cl-foot__cols > :nth-child(4) { flex-grow: 19; }
    .cl-foot__cols > :nth-child(5) { flex-grow: 16; }
}

.cl-foot h2 {
    font-family: var(--cl-display);
    font-size: 0.9375rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin-bottom: 0.875rem;
}

/* The chevron list, which is this layout's signature in the footer. */
.cl-foot__list { display: grid; gap: 0.5rem; font-size: 0.8125rem; }
.cl-foot__list a { display: inline-flex; align-items: baseline; gap: 0.5rem; color: color-mix(in srgb, var(--cl-bar-ink) 82%, transparent); }
.cl-foot__list a::before { content: '\203A'; color: var(--cl-primary-text); font-size: 1rem; line-height: 1; }
.cl-foot__list a:hover { color: var(--cl-primary-text); }

/* The contact details are not a list of places to go, so they take a
   mark that says what each one is rather than the chevron that says
   "and here is another link". The address is not a link at all and had
   no mark under the old rule, which left it sitting out of line with
   the two below it. */
.cl-foot__contact { display: grid; gap: 0.75rem; font-size: 0.8125rem; }
.cl-foot__contact > * {
    display: grid;
    grid-template-columns: 1rem minmax(0, 1fr);
    gap: 0.625rem;
    align-items: start;
    color: color-mix(in srgb, var(--cl-bar-ink) 82%, transparent);
}
.cl-foot__contact a:hover { color: var(--cl-primary-text); }

/* The newsletter column is the widest because it holds a field and a
   button, but the form was taking all of it and finishing hard against
   the contact details. Its words and its form stop short of the column
   edge, so there is air between the two rather than a field that looks
   like it has run into its neighbour. */
.cl-foot__news > * { max-width: 20rem; }
/* Nudged down so the glyph sits on the first line of the words rather
   than on the cap line above them. */
.cl-foot__contact svg { width: 1rem; height: 1rem; color: var(--cl-primary-text); margin-top: 0.1rem; }

.cl-foot__brand {
    font-family: var(--cl-display);
    font-size: 1.375rem;
    font-weight: 600;
    color: var(--cl-primary-text);
    text-align: start;
}

.cl-foot__brand img { max-height: 2.75rem; width: auto; }

.cl-foot__bar {
    border-top: 1px solid color-mix(in srgb, var(--cl-bar-ink) 14%, transparent);
    padding-block: 0.875rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
    align-items: center;
    justify-content: space-between;
    font-size: 0.75rem;
    color: color-mix(in srgb, var(--cl-bar-ink) 75%, transparent);
}

/* ---------- odds and ends the sections need ---------- */

.cl-split { display: grid; gap: 1.5rem; grid-template-columns: 1fr; align-items: start; }
@media (min-width: 52rem) { .cl-split { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.cl-split--flip > :first-child { order: 2; }

/* As many across as there are, up to four. Fixed at three, a fourth promise
   dropped onto a row of its own and sat alone under the other three. */
.cl-trust { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 40rem) { .cl-trust { grid-template-columns: repeat(min(var(--cl-trust, 3), 2), minmax(0, 1fr)); } }
@media (min-width: 52rem) { .cl-trust { grid-template-columns: repeat(min(var(--cl-trust, 3), 4), minmax(0, 1fr)); } }
.cl-trust__item { display: flex; gap: 0.75rem; align-items: flex-start; background: var(--cl-panel); border: 1px solid var(--cl-line); border-radius: var(--cl-radius); padding: 0.875rem; }

/* The icon takes the shop's colour and sits level with the title rather than
   with the top of the box, so it reads as a mark against the promise. */
.cl-trust__icon { flex: none; color: var(--cl-primary-text); display: flex; margin-top: 0.05rem; }
.cl-trust__icon svg { width: 1.625rem; height: 1.625rem; }
.cl-num { display: grid; place-items: center; flex: none; width: 1.75rem; height: 1.75rem; border-radius: var(--cl-pill); background: var(--cl-primary); color: #FFFFFF; font-family: var(--cl-display); font-size: 0.8125rem; }

.cl-marquee { overflow: hidden; background: var(--cl-primary); color: #FFFFFF; }
.cl-marquee__track { display: flex; width: max-content; animation: cl-slide var(--cl-marquee-speed, 30s) linear infinite; }
.cl-marquee:hover .cl-marquee__track { animation-play-state: paused; }
.cl-marquee__item { display: inline-flex; align-items: center; gap: 1.25rem; padding: 0.625rem 1.25rem; font-size: 0.8125rem; white-space: nowrap; }
/* Fixed both sides: the strip is the shop's colour in either scheme, so the
   button on it must not follow the scheme on one side only. */
.cl-marquee__item .cl-btn { background: #FFFFFF; color: #333333; border-color: #FFFFFF; }
@keyframes cl-slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
    .cl-marquee__track { animation: none; width: 100%; justify-content: center; flex-wrap: wrap; }
}

.cl-units { display: inline-flex; margin-top: 1rem; border: 1px solid var(--cl-line); border-radius: var(--cl-radius); overflow: hidden; }
.cl-units button { border: 0; background: transparent; cursor: pointer; font: inherit; font-size: 0.6875rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--cl-muted); padding: 0.4rem 0.875rem; }
.cl-units button.is-on { background: var(--cl-secondary); color: #FFFFFF; }

.cl-mode {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.75rem; height: 1.75rem;
    border: 0; background: transparent; color: inherit; cursor: pointer;
}
.cl-mode:hover { color: var(--cl-primary-text); }

.cl-drawer__scrim { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.45); z-index: 50; }
.cl-drawer { position: fixed; inset-block: 0; inset-inline-end: 0; width: min(22rem, 90vw); background: var(--cl-panel); z-index: 51; overflow-y: auto; }
.cl-drawer__head { display: flex; align-items: center; justify-content: space-between; padding: 0.875rem; border-bottom: 1px solid var(--cl-line); }

.cl-mega { display: none; }
.cl-has-mega:hover .cl-mega,
.cl-has-mega:focus-within .cl-mega {
    display: block;
    position: absolute;
    /* Below the bar, not over the item that opened it. */
    top: 100%;
    /* Anchored to its own item and sized to what is in it. Stretched edge
       to edge of the item instead, the panel was as wide as the word that
       opened it, so a dropdown under "Shop" was a sliver with its contents
       hanging outside it. */
    inset-inline-start: 0;
    inset-inline-end: auto;
    min-width: 14rem;
    width: max-content;
    max-width: min(92vw, 44rem);
    z-index: 40;
    background: var(--cl-panel);
    /* The same trap the mobile panel fell into: this sits inside .cl-nav,
       which paints its text the bar's white, and the panel's own
       background is pale. Every link in it was white on white, which
       reads as an empty box rather than as a fault. */
    color: var(--cl-ink);
    border: 1px solid var(--cl-line);
    box-shadow: 0 18px 40px -26px rgba(0, 0, 0, 0.4);
}

.cl-mega a { color: inherit; }
.cl-mega a:hover { color: var(--cl-primary); }

/* The items at the end of the bar open leftwards, or the panel would run
   off the side of the page. */
.cl-nav__list > li:nth-last-child(-n+2) .cl-mega {
    inset-inline-start: auto;
    inset-inline-end: 0;
}
.cl-mega__cols { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); padding: 1.25rem; }
.cl-mega__list { display: grid; gap: 0.375rem; margin-top: 0.5rem; font-size: 0.8125rem; }

/* ---------- the banner ---------- */

/* The rotating banner this layout has always opened with. Slides are stacked
   and cross-faded rather than tracked sideways: there is no horizontal scroll
   to get wrong, and the band never shifts the page under itself. */
.cl-slider {
    position: relative;
    overflow: hidden;
    border: 1px solid var(--cl-line);
    border-radius: var(--cl-radius);
    background: var(--cl-sand);
    min-height: var(--cl-slide-height, 20rem);
}

.cl-slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.4s ease;
}

.cl-slide.is-on { opacity: 1; visibility: visible; }

/* The no-script fallback, and only that.

   Written as ".cl-slide:first-child { opacity: 1 }" it had the same
   specificity as ".cl-slide.is-on" and came later in the file, so it won
   outright: the first slide stayed fully opaque for ever, sitting behind
   every other slide rather than giving way to it.

   Scoped to the band before Alpine has touched it instead. The component sets
   data-ready on itself in init(), at which point this selector stops matching
   at all and the is-on class is the only thing deciding what is shown. */
.cl-slider:not([data-ready]) .cl-slide:first-child { opacity: 1; visibility: visible; }

@media (prefers-reduced-motion: reduce) {
    .cl-slide { transition: none; }
}

.cl-slide__bg { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; }
.cl-slide__veil { position: absolute; inset: 0; }

.cl-slide__inner {
    position: relative;
    display: flex;
    align-items: center;
    min-height: var(--cl-slide-height, 20rem);
    padding: clamp(1.25rem, 4vw, 3rem);
}

.cl-slide__copy { max-width: 32rem; display: grid; gap: 0.5rem; justify-items: start; }
.cl-slide__copy[style*="center"] { justify-items: center; margin-inline: auto; }

.cl-slide__label {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    opacity: 0.85;
}

.cl-slide__heading {
    font-family: var(--cl-display);
    font-size: clamp(1.5rem, 3.4vw, 2.5rem);
    line-height: 1.15;
    font-weight: 700;
}

.cl-slide__text { font-size: 0.9375rem; line-height: 1.6; opacity: 0.9; max-width: 34ch; }
.cl-slide__foot { margin-top: 0.75rem; }

/* ---------- the banner's controls ---------- */

.cl-slider__arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 999px;
    /* Fixed rather than taken from the palette. These sit on top of a
       photograph, not on the page, so following the theme meant a dark
       plate with a pale glyph landing on a dark picture and disappearing.
       A white control with a dark glyph and a shadow under it reads on
       whatever the slide happens to be. */
    background: rgba(255, 255, 255, 0.92);
    color: #1F2937;
    border: 1px solid rgba(0, 0, 0, 0.14);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.28);
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s, background-color 0.15s;
}

.cl-slider:hover .cl-slider__arrow,
.cl-slider:focus-within .cl-slider__arrow { opacity: 1; }

/* Always there for a finger. The hover reveal is a pointer affordance, and a
   touch screen has no hover: the arrows simply never appeared. */
@media (hover: none) {
    .cl-slider__arrow { opacity: 1; }
}

.cl-slider__arrow:hover { background: #FFFFFF; }
.cl-slider__arrow:focus-visible { opacity: 1; outline: 2px solid var(--cl-primary); outline-offset: 2px; }
.cl-slider__arrow--prev { inset-inline-start: 0.75rem; }
.cl-slider__arrow--next { inset-inline-end: 0.75rem; }

/* The dots carry their own plate rather than a pseudo-element behind them.
   A ::before at z-index -1 inside a positioned parent slides behind that
   parent's own background, so the plate was invisible and the dots were left
   sitting on whatever the slide happened to be. */
.cl-slider__dots {
    position: absolute;
    inset-inline: 0;
    bottom: 0.75rem;
    z-index: 2;
    display: flex;
    justify-content: center;
    gap: 0.4rem;
    pointer-events: none;
}

.cl-slider__dots > * { pointer-events: auto; }

.cl-slider__dots::after {
    content: none;
}

.cl-slider__dot {
    width: 0.625rem;
    height: 0.625rem;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: color-mix(in srgb, var(--cl-ink) 42%, transparent);
    cursor: pointer;
    transition: background-color 0.15s, width 0.15s;
}

.cl-slider__dot.is-on { background: var(--cl-primary); width: 1.5rem; }
.cl-slider__dot:focus-visible { outline: 2px solid var(--cl-primary); outline-offset: 2px; }

/* The plate the dots stand on, so they survive a pale photograph. Wrapped
   around them rather than painted behind them. */
.cl-slider__dot { box-shadow: 0 0 0 1px color-mix(in srgb, var(--cl-paper) 70%, transparent); }

/* ---------- the listing's bar and its filter menu ---------- */

.cl-shop__bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--cl-line);
    margin-bottom: 2rem;
}

.cl-shop__tools { display: flex; align-items: center; gap: 1rem; }

/* The anchor the panel hangs from. Positioned here rather than on the bar, so
   the panel lines up with the button and not with the whole row. */
.cl-filter { position: relative; }

.cl-filter__btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.875rem;
    border: 1px solid var(--cl-line);
    background: var(--cl-panel);
    color: var(--cl-ink);
    font: inherit;
    font-family: var(--cl-display);
    font-size: 0.8125rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
}

.cl-filter__btn:hover,
.cl-filter__btn.is-open { border-color: var(--cl-primary); color: var(--cl-primary-text); }

/* How many facets are on, so a shopper who filtered three pages ago and
   forgot can see it without opening the panel. */
.cl-filter__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.125rem;
    height: 1.125rem;
    padding-inline: 0.25rem;
    border-radius: 999px;
    background: var(--cl-primary);
    color: #FFFFFF;
    font-size: 0.6875rem;
    font-weight: 700;
}

.cl-filter__panel {
    position: absolute;
    z-index: 20;
    inset-inline-start: 0;
    top: calc(100% + 0.5rem);
    width: min(22rem, calc(100vw - 2rem));
    background: var(--cl-panel);
    border: 1px solid var(--cl-line);
    box-shadow: 0 16px 30px -18px rgba(0, 0, 0, 0.45);
}

/* Floating over a listing means it can be taller than what is under it. It
   scrolls rather than running off the bottom of the page. */
.cl-filter__body {
    max-height: min(26rem, 60vh);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 1rem;
    display: grid;
    gap: 1.25rem;
}

.cl-filter__group { border: 0; margin: 0; padding: 0; min-width: 0; }

.cl-filter__group legend {
    padding: 0;
    font-family: var(--cl-display);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--cl-muted);
    margin-bottom: 0.5rem;
}

/* A long brand list gets its own scroll rather than pushing everything below
   it out of reach: a shop with eighty makers would otherwise bury the price
   fields under them. */
.cl-filter__list { display: grid; gap: 0.375rem; max-height: 11rem; overflow-y: auto; }

.cl-filter__check {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.875rem;
    cursor: pointer;
    min-height: 1.5rem;
}

.cl-filter__check input { flex: none; accent-color: var(--cl-primary); }

.cl-filter__price { display: flex; align-items: center; gap: 0.5rem; }
.cl-filter__price .cl-field { min-width: 0; }

.cl-filter__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    border-top: 1px solid var(--cl-line);
    background: var(--cl-sand);
}

/* Near the right edge of a narrow window the panel would hang off the page.
   It anchors to the other side instead. */
@media (max-width: 30rem) {
    .cl-filter__panel { inset-inline-start: auto; inset-inline-end: 0; }
}

/* ---------- the departments row ---------- */

/* However many there are, evenly across one row. The count comes in from the
   template so a shop showing four gets four columns rather than three and a
   widow sitting on its own underneath. */
.cl-cats {
    display: grid;
    gap: clamp(0.5rem, 1.5vw, 1rem);
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 30rem) { .cl-cats { grid-template-columns: repeat(min(var(--cl-cats, 6), 3), minmax(0, 1fr)); } }
@media (min-width: 50rem) { .cl-cats { grid-template-columns: repeat(var(--cl-cats, 6), minmax(0, 1fr)); } }

.cl-cat { display: block; min-width: 0; text-align: center; }
.cl-cat__pic { position: relative; display: block; border: 1px solid var(--cl-line); background: var(--cl-sand); }

/* Square, not 3x4. Six tiles across the middle column are about 150px each,
   and a portrait crop at that width is a letterbox. */
.cl-cat__name {
    display: block;
    margin-top: 0.5rem;
    font-family: var(--cl-display);
    font-size: 0.8125rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    line-height: 1.3;
}

.cl-cat:hover .cl-cat__name { color: var(--cl-primary-text); }

/* ---------- the product page's tabs ---------- */

/* Classic shipped with the tab markup and no styles for it at all, so the
   strip rendered as three default browser buttons with nothing to say which
   one was open. The panels were switching the whole time; there was simply no
   sign of it, which from the outside is a tab strip that does not work.
   
   The selected tab covers the strip's bottom rule and so joins the panel
   under it, which is how this kind of shop front has always drawn them. */
.cl-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    border-bottom: 1px solid var(--cl-line);
}

.cl-tab {
    appearance: none;
    cursor: pointer;
    font: inherit;
    font-family: var(--cl-display);
    font-size: 0.875rem;
    letter-spacing: 0.02em;
    padding: 0.625rem 1.125rem;
    /* Pulled down over the strip's rule, so the selected tab can hide it. */
    margin-bottom: -1px;
    border: 1px solid var(--cl-line);
    border-radius: var(--cl-radius) var(--cl-radius) 0 0;
    background: var(--cl-sand);
    color: var(--cl-muted);
}

.cl-tab:hover { color: var(--cl-ink); }

/* Driven by the attribute Alpine already binds, so the look and the state
   cannot drift apart. */
.cl-tab[aria-selected="true"] {
    background: var(--cl-panel);
    border-bottom-color: var(--cl-panel);
    color: var(--cl-ink);
}

.cl-tab:focus-visible { outline: 2px solid var(--cl-primary); outline-offset: -2px; }

.cl-tab__count { color: var(--cl-muted); font-size: 0.8125rem; }
.cl-tab[aria-selected="true"] .cl-tab__count { color: inherit; opacity: 0.65; }

/* ---------- the shared pages' background ---------- */

/* The account pages, the basket, checkout and the invoice all open with
   <div class="min-h-screen bg-gray-50">, a grey chosen when this theme's page
   was grey too. Classic's page is white and its cards are told apart by their
   borders, so that slab made every shared page the odd one out.
   
   Only the page wrapper. bg-gray-50 is used another thirty-odd times inside
   those same templates for table headings and row hovers, and those should
   stay exactly as they are, so the two classes are required together.
   
   Deliberately unlayered: Tailwind's utilities sit in @layer utilities, and an
   unlayered rule is the only way to beat one without !important. That is the
   same mechanism that made a stray "a { color: inherit }" black out white
   button text earlier; the difference is that this names one thing on purpose
   rather than every anchor on the page. */
.min-h-screen.bg-gray-50 { background-color: var(--cl-page, #FFFFFF); }

/* ---------- the shop's own details ---------- */

/* As many across as fit, rather than a fixed two or three that leaves the
   fifth item sitting alone on a row of its own. */
.cl-contact {
    display: grid;
    gap: 1.25rem 2rem;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    margin: 0;
}

.cl-contact__value { margin: 0.35rem 0 0; white-space: pre-line; overflow-wrap: anywhere; font-size: 0.9375rem; line-height: 1.55; }

/* The quantity stepper, which was a row of inline styles in the buy form while
   every other theme had it as a rule. Same shape, same place as the rest. */
.cl-qty {
    display: flex;
    align-items: center;
    border: 1px solid var(--cl-line);
}

.cl-qty input { width: 3.25rem; text-align: center; border: 0; font: inherit; background: transparent; color: inherit; }
.cl-qty .cl-btn { border-radius: 0; border: 0; }

/* The quantity stepper's two buttons each hold a single sign. The tracking
   every button label carries was adding a space after that sign and pushing it
   left of centre, and letting the buttons size to their content made the minus
   narrower than the plus, so the field between them sat off centre too. Equal
   fixed widths, no tracking, and a glyph big enough to aim at. */
.cl-qty .cl-btn {
    width: 2.5rem;
    padding: 0.5rem 0;
    font-size: 1rem;
    line-height: 1;
    letter-spacing: 0;
}

/* A long category description, folded. Some shops write a page of copy above
   the grid, and a shopper who came to look at products should not have to
   scroll past all of it first. The fold only appears when there is enough to
   be worth folding, which the page works out from the rendered height rather
   than from a character count, since a count cannot see pictures.

   x-cloak keeps the button out of sight until Alpine has decided; these
   themes never declared it, so anything using it flashed on load. */
[x-cloak] { display: none !important; }

.cl-clamp { position: relative; transition: max-height 0.25s ease; }
.cl-clamp.is-clamped {
    max-height: 16rem;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(to bottom, #000 60%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 60%, transparent 100%);
}
.cl-clamp-toggle {
    margin-top: 0.75rem;
    background: none;
    border: 0;
    padding: 0 0 2px;
    cursor: pointer;
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 600;
    color: inherit;
    border-bottom: 2px solid currentColor;
}
.cl-clamp-toggle:hover { opacity: 0.7; }
