/* ==========================================================================
   PddFalcon storefront — site chrome, premium pass

   Loaded after snap.css / snap-inner.css / home-premium.css and immediately
   before site-premium.css, so it refines the chrome without !important and
   without standing in the way of the footer layer that follows it.

   Scope: the furniture that is on every single page — the announcement bar,
   the header, the category row and its menus, the two drawers, the search
   suggestions, the toast region and the back-to-top button. Nothing here
   changes the layout language, the palette or the component vocabulary; it
   changes how considered they feel while they move.

   Three standing rules the whole file keeps:
     1. Every colour is a token, or an rgb()/color-mix() built from one.
     2. Motion is transform and opacity only — nothing that costs a frame on a
        phone, nothing that reflows.
     3. Everything added here is cancelled by prefers-reduced-motion, in one
        block at the foot of the file.
   ========================================================================== */

:root {
  /* One curve for the chrome, so a drawer, a dropdown and an underline all
     decelerate the same way. Same value as --sp-ease; named separately so the
     intent is legible where it is used. */
  --cp-ease: cubic-bezier(.22, 1, .36, 1);

  /* The three inks the chrome uses for edges, at the weights that read as a
     hairline rather than a border. */
  --cp-edge: rgb(13 36 84 / .08);
  --cp-edge-soft: rgb(13 36 84 / .05);
}

/* ==========================================================================
   The announcement bar
   ========================================================================== */

/*
 * It was a flat navy strip. Two changes, no new colours: the navy deepens at
 * both ends so the bar reads as lit from the centre rather than printed, and a
 * gold hairline closes it off against the white header beneath.
 */
.sp-announce {
  position: relative;
  overflow: hidden;
  background: linear-gradient(90deg,
    var(--s-brand-950) 0%,
    var(--s-brand-800) 26%,
    var(--s-brand-800) 74%,
    var(--s-brand-950) 100%);
  box-shadow: inset 0 -1px 0 rgb(255 184 0 / .26);
}

.sp-announce p {
  padding-block: .5rem;
  letter-spacing: .012em;
}

/*
 * A single slow pass of light, once every nine seconds. Transform only, on a
 * pseudo-element, so it never touches layout; at 6% white over navy it is
 * something you notice on the second look, which is the point.
 */
.sp-announce::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: 32%;
  pointer-events: none;
  background: linear-gradient(90deg,
    transparent,
    rgb(255 255 255 / .06) 42%,
    rgb(255 184 0 / .07) 58%,
    transparent);
  transform: translateX(-130%);
  animation: cp-sheen 9s var(--cp-ease) 2.5s infinite;
}

@keyframes cp-sheen {
  0%        { transform: translateX(-130%); }
  55%, 100% { transform: translateX(430%); }
}

/* ==========================================================================
   The header shell, and the moment it becomes stuck
   ========================================================================== */

/*
 * The stuck state used to be one box-shadow appearing. The height must not
 * change — the header is `sticky`, so shrinking it while stuck would drag the
 * whole page up under the reader's eyes — so the arrival is carried by a
 * shadow that deepens and a hairline that draws itself across the bottom edge.
 *
 * The hairline is the same three inks as the rule the footer opens with
 * (site-premium.css), so the page is closed top and bottom by the same device.
 */
.sp-header {
  transition: box-shadow .32s var(--cp-ease);
}

.sp-header.is-stuck {
  box-shadow:
    0 1px 0 var(--cp-edge-soft),
    0 14px 34px -22px rgb(13 36 84 / .55);
}

.sp-header::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  block-size: 1px;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(90deg,
    transparent,
    rgb(196 38 12 / .55) 22%,
    rgb(255 184 0 / .55) 52%,
    rgb(13 36 84 / .45) 78%,
    transparent);
  opacity: 0;
  transform: scaleX(.35);
  transform-origin: 50% 50%;
  transition: transform .55s var(--cp-ease), opacity .3s linear;
}

.sp-header.is-stuck::after {
  opacity: 1;
  transform: scaleX(1);
}

/* The category row rides under the stuck header on desktop, so it takes the
   same lift rather than keeping its resting shadow. */
.sp-header.is-stuck + .sp-nav {
  box-shadow: 0 12px 28px -22px rgb(13 36 84 / .5);
}

/* The logo answers the pointer by the smallest amount that still registers. */
.sp-brand img {
  transform-origin: 0% 50%;
  transition: transform .4s var(--cp-ease);
}
.sp-brand:hover img { transform: scale(1.035); }
.sp-brand:active img { transform: scale(.99); }

/* ==========================================================================
   The search field
   ========================================================================== */

/*
 * The one control on every page. Focus already lit the ring (site-premium);
 * what was missing was everything around it answering at the same moment — the
 * magnifier taking the brand ink, the field warming off its grey, the button
 * standing up.
 */
.sp-search__form {
  transition:
    border-color .22s var(--cp-ease),
    background-color .22s var(--cp-ease),
    box-shadow .28s var(--cp-ease);
}

@media (hover: hover) {
  .sp-search__form:hover:not(:focus-within) { background: var(--s-line-soft); }
}

.sp-search__form > svg {
  transition: color .22s var(--cp-ease), transform .3s var(--cp-ease);
}
.sp-search__form:focus-within > svg {
  color: var(--s-brand-800);
  transform: scale(1.06);
}

/*
 * The Search button measured 80×36 — a real target on a mouse, under the 44px
 * minimum on a thumb. The visible pill is left exactly as designed and the
 * touch area is grown behind it, so nothing on screen moves.
 */
.sp-search__go {
  position: relative;
  transition: background-color .2s var(--cp-ease), transform .18s var(--cp-ease), box-shadow .24s var(--cp-ease);
  box-shadow: 0 8px 18px -12px rgb(196 38 12 / .8), inset 0 1px 0 rgb(255 255 255 / .18);
}
.sp-search__go::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-start: 50%;
  block-size: 44px;
  transform: translateY(-50%);
}
.sp-search__go:hover { transform: translateY(-1px); box-shadow: 0 12px 22px -12px rgb(196 38 12 / .85), inset 0 1px 0 rgb(255 255 255 / .22); }
.sp-search__go:active { transform: translateY(0) scale(.98); box-shadow: 0 4px 10px -8px rgb(196 38 12 / .9); }

/* ==========================================================================
   The suggestion list
   ========================================================================== */

/*
 * The panel arrives rather than appears.
 *
 * It is shown by dropping the `hidden` attribute, so the animation is hung off
 * :not([hidden]) — it plays once, when the list first opens, and does not
 * replay on every keystroke while the list is already up.
 */
.sp-suggest {
  transform-origin: 50% 0;
  box-shadow: 0 24px 48px -24px rgb(13 36 84 / .38), 0 2px 6px -2px rgb(13 36 84 / .1);
  border-color: var(--cp-edge);
}
.sp-suggest:not([hidden]) { animation: cp-drop-in .28s var(--cp-ease) both; }

@keyframes cp-drop-in {
  from { opacity: 0; transform: translateY(-8px) scale(.985); }
  to   { opacity: 1; transform: none; }
}

/*
 * The rows carried a real defect, not only a want of polish: the product name
 * and its category are two spans inside one flex row, so they ran together as
 * a single string — "Recta 2 in 1 Kids Lunch Boxes" read as one product name.
 * They are a stack now, and the price is held on one line at the far end.
 */
.s-suggest__item {
  position: relative;
  align-items: center;
  gap: .75rem;
  min-block-size: 3.25rem;
  padding: .55rem .9rem;
  transition: background-color .18s var(--cp-ease);
}
.s-suggest__item > span:not([class]) {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  min-inline-size: 0;
  flex: 1;
}
.s-suggest__name {
  font-weight: 650;
  color: var(--s-ink);
  line-height: 1.25;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.s-suggest__meta {
  font-size: var(--s-text-xs);
  color: var(--s-muted);
  line-height: 1.2;
}
.s-suggest__price {
  flex: none;
  margin-inline-start: auto;
  font-size: var(--s-text-xs);
  font-weight: 800;
  color: var(--s-brand-800);
  white-space: nowrap;
  text-align: end;
}
.s-suggest__thumb {
  flex: none;
  border-radius: 10px;
  background: var(--sp-tile);
  border: 1px solid var(--sp-line);
}

/* A mark, not only a wash — colour alone is the one signal a red-green
   deficiency cannot read. */
.s-suggest__item::before {
  content: "";
  position: absolute;
  inset-block: .45rem;
  inset-inline-start: 0;
  inline-size: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--s-accent-500);
  transform: scaleY(0);
  transform-origin: 50% 50%;
  transition: transform .22s var(--cp-ease);
}
.s-suggest__item:hover,
.s-suggest__item:focus-visible,
.s-suggest__item[aria-selected="true"] { background: var(--sp-tile); }
.s-suggest__item:hover::before,
.s-suggest__item:focus-visible::before,
.s-suggest__item[aria-selected="true"]::before { transform: scaleY(1); }

.s-suggest__item + .s-suggest__item { border-block-start: 1px solid var(--s-line-soft); }

/* Each row lands a beat after the one above it. Capped at five, and short
   enough that a refreshed list reads as an update rather than a re-open. */
.s-suggest__item { animation: cp-rise .24s var(--cp-ease) both; }
.s-suggest__item:nth-child(2) { animation-delay: .03s; }
.s-suggest__item:nth-child(3) { animation-delay: .06s; }
.s-suggest__item:nth-child(4) { animation-delay: .09s; }
.s-suggest__item:nth-child(n + 5) { animation-delay: .12s; }

@keyframes cp-rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* "Nothing matched …" was an unstyled 25px line of text in a white box. */
.s-suggest__empty {
  margin: 0;
  padding: 1rem .9rem;
  text-align: center;
  font-size: var(--s-text-sm);
  color: var(--s-muted);
}

/* ==========================================================================
   The header actions, the cart button and the counts
   ========================================================================== */

/*
 * Pincode, language, wishlist, account: between 26px and 39px tall, all of
 * them under the 44px minimum. As with the Search button the visible chip is
 * left alone — growing it would push the badge off the heart it belongs to —
 * and the target is grown behind it.
 */
.sp-action { transition: background-color .2s var(--cp-ease), color .2s var(--cp-ease), transform .18s var(--cp-ease); }
.sp-action::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-start: 50%;
  block-size: 44px;
  transform: translateY(-50%);
}
.sp-action:hover { background: var(--sp-tile); }
.sp-action:active { transform: scale(.97); }
.sp-action svg { transition: transform .28s var(--cp-ease), color .2s var(--cp-ease); }
.sp-action:hover svg { transform: scale(1.08); }

/* The saved list is the one action whose icon carries the brand's red. */
a.sp-action[aria-label="Wishlist"]:hover { color: var(--s-accent-500); }

/* The burger is the only chrome control that can simply be the right size. */
.sp-header__burger {
  inline-size: 2.75rem;
  block-size: 2.75rem;
  transition: background-color .2s var(--cp-ease), transform .18s var(--cp-ease);
}
.sp-header__burger:hover { background: var(--sp-tile); }
.sp-header__burger:active { transform: scale(.94); }

/* The logo is a link; it gets the same floor. */
.sp-brand { align-items: center; min-block-size: 44px; }

/*
 * The cart. It is the one navy control in a white header, so its press is the
 * one that has to feel like a press: a lift on hover with the shadow the navy
 * would actually cast, and a shorter shadow the moment it goes down.
 */
.sp-cart {
  transition: background-color .2s var(--cp-ease), transform .2s var(--cp-ease), box-shadow .24s var(--cp-ease);
  box-shadow: 0 10px 22px -14px rgb(13 36 84 / .85), inset 0 1px 0 rgb(255 255 255 / .12);
}
.sp-cart::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-start: 50%;
  block-size: 44px;
  transform: translateY(-50%);
}
.sp-cart:hover { transform: translateY(-1px); box-shadow: 0 14px 26px -14px rgb(13 36 84 / .9), inset 0 1px 0 rgb(255 255 255 / .16); }
.sp-cart:active { transform: translateY(0) scale(.97); box-shadow: 0 5px 12px -10px rgb(13 36 84 / .9); }
.sp-cart svg { transition: transform .3s var(--cp-ease); }
.sp-cart:hover svg { transform: translateX(1px); }

/* The count reads on white and on navy alike. */
.sp-count { box-shadow: 0 2px 6px -2px rgb(196 38 12 / .7); }

/* ==========================================================================
   The language menu
   ========================================================================== */

.sp-lang__list {
  transform-origin: 100% 0;
  border-color: var(--cp-edge);
  box-shadow: 0 22px 44px -22px rgb(13 36 84 / .4);
}
.sp-lang__list:not([hidden]) { animation: cp-drop-in .22s var(--cp-ease) both; }
.sp-lang__list a { min-block-size: 2.5rem; display: flex; align-items: center; transition: background-color .18s var(--cp-ease), color .18s var(--cp-ease); }
.sp-lang__list a[aria-selected="true"] { font-weight: 700; color: var(--s-brand-800); }

/* ==========================================================================
   The category row — desktop
   ========================================================================== */

@media (min-width: 62rem) {
  /*
   * The active rule used to flip from transparent to red with the colour. A
   * rule that grows out from its own centre says the same thing and says it in
   * a way you can watch; the 2px transparent border already reserves the
   * space, so nothing shifts by a pixel.
   */
  .sp-nav__link { position: relative; }
  .sp-nav__link::after {
    content: "";
    position: absolute;
    inset-inline: .35rem;
    inset-block-end: -2px;
    block-size: 2px;
    border-radius: 2px;
    background: var(--s-accent-500);
    transform: scaleX(0);
    transform-origin: 50% 50%;
    transition: transform .34s var(--cp-ease);
  }
  .sp-nav__link:hover,
  .sp-nav__link:focus-visible,
  .sp-nav__link.is-active { border-color: transparent; }
  .sp-nav__link:hover::after,
  .sp-nav__link:focus-visible::after,
  .sp-nav__link.is-active::after { transform: scaleX(1); }

  .sp-nav__item--all:hover > .sp-nav__link::after,
  .sp-nav__item--all:focus-within > .sp-nav__link::after { transform: scaleX(1); }
  .sp-nav__item--all:hover > .sp-nav__link,
  .sp-nav__item--all:focus-within > .sp-nav__link { color: var(--s-accent-500); }

  /* The slab pills measured 31px tall. Same treatment as the header actions:
     the pill keeps its size, the thumb gets its 44. */
  .sp-slabs a {
    position: relative;
    transition: background-color .2s var(--cp-ease), color .2s var(--cp-ease), transform .18s var(--cp-ease), border-color .2s var(--cp-ease);
  }
  .sp-slabs a::before {
    content: "";
    position: absolute;
    inset-inline: 0;
    inset-block-start: 50%;
    block-size: 44px;
    transform: translateY(-50%);
  }
  .sp-slabs a:hover { transform: translateY(-1px); }
  .sp-slabs a:active { transform: translateY(0) scale(.97); }
}

/* ==========================================================================
   The category row — phone and tablet
   ========================================================================== */

@media (max-width: 61.99rem) {
  /* The pills measured 42px. Two pixels short, and two pixels is still short. */
  .sp-nav__link { position: relative; }
  .sp-nav__link::before {
    content: "";
    position: absolute;
    inset-inline: 0;
    inset-block-start: 50%;
    block-size: 46px;
    transform: translateY(-50%);
  }
  .sp-nav__link { transition: background-color .2s var(--cp-ease), border-color .2s var(--cp-ease), color .2s var(--cp-ease), transform .18s var(--cp-ease); }
  .sp-nav__link:active { transform: scale(.96); }
  .sp-nav__ico { transition: transform .25s var(--cp-ease); }
  .sp-nav__link:active .sp-nav__ico { transform: scale(1.05); }

  /*
   * The row scrolls sideways and always will — it is 1034px of pills in 358px
   * of viewport. Without an edge it simply stops at the gutter and reads as
   * content that has been cut off. A short fade in the row's own white says
   * "there is more this way" and costs nothing: it is painted over the gutter,
   * not masked onto the scroller, so it cannot clip a menu.
   */
  .sp-nav__row { position: relative; }
  .sp-nav__row::after {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-end: 0;
    inline-size: 2.25rem;
    pointer-events: none;
    background: linear-gradient(to left, #fff 38%, rgb(255 255 255 / 0));
  }
}

/* ==========================================================================
   The dropdowns and the mega menu
   ========================================================================== */

@media (min-width: 62rem) {
  /*
   * A panel that belongs to the row it hangs from: it grows down out of the
   * bar rather than sliding in from nowhere, and the top corners stay square
   * so the join is a join.
   */
  .sp-nav__item:hover > .sp-drop,
  .sp-nav__item:focus-within > .sp-drop,
  .sp-nav__item--all:hover > .sp-mega,
  .sp-nav__item--all:focus-within > .sp-mega {
    display: block;
    animation: cp-menu-in .26s var(--cp-ease) both;
  }

  .sp-drop, .sp-mega {
    transform-origin: 50% 0;
    border-block-start: 0;
    border-color: var(--cp-edge);
    box-shadow: 0 30px 60px -30px rgb(13 36 84 / .45), 0 4px 10px -6px rgb(13 36 84 / .12);
  }

  /*
   * The mega panel's columns are as ragged as the merchant's own catalogue —
   * two links in one, seven in the next — so the short ones end in white. A
   * hairline down the gaps turns that space into structure instead of absence,
   * the same argument the footer's column rules already make.
   */
  .sp-mega__col { position: relative; }
  .sp-mega__col + .sp-mega__col::before {
    content: "";
    position: absolute;
    inset-block: .15rem 0;
    inset-inline-start: -.625rem;
    inline-size: 1px;
    background: linear-gradient(180deg, var(--sp-line), rgb(13 36 84 / .05) 60%, transparent);
  }

  .sp-mega__head img,
  .sp-drop img { transition: transform .3s var(--cp-ease); }
  .sp-mega__head:hover img,
  .sp-drop a:hover img { transform: scale(1.06); }
  .sp-mega__head { transition: color .2s var(--cp-ease); }
  .sp-mega__head:hover { color: var(--s-accent-500); }

  /* Child links answer with a mark and a nudge, not with a colour alone. */
  .sp-mega__col li a {
    position: relative;
    padding-inline-start: 0;
    transition: color .2s var(--cp-ease), padding-inline-start .2s var(--cp-ease);
  }
  .sp-mega__col li a::before {
    content: "";
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 50%;
    inline-size: 0;
    block-size: 2px;
    border-radius: 2px;
    background: var(--s-accent-500);
    transform: translateY(-50%);
    transition: inline-size .2s var(--cp-ease);
  }
  .sp-mega__col li a:hover,
  .sp-mega__col li a:focus-visible { padding-inline-start: .85rem; }
  .sp-mega__col li a:hover::before,
  .sp-mega__col li a:focus-visible::before { inline-size: .6rem; }

  .sp-drop a { transition: background-color .18s var(--cp-ease), color .18s var(--cp-ease), transform .2s var(--cp-ease); }
  .sp-drop a:hover { background: var(--sp-tile); transform: translateX(2px); }
}

@keyframes cp-menu-in {
  from { opacity: 0; transform: translateY(-8px) scaleY(.97); }
  to   { opacity: 1; transform: none; }
}

/* ==========================================================================
   The scrim
   ========================================================================== */

/*
 * Deeper, and lit from the side the drawer arrives on, so the panel reads as
 * being in front of the page rather than pasted onto it. The fade is left at
 * its 220ms: the controller restores `hidden` 260ms after a close, and a
 * longer fade would be cut off half way.
 */
.s-scrim {
  background:
    radial-gradient(120% 90% at 50% 100%, rgb(6 16 49 / .2), transparent 60%),
    rgb(6 16 49 / .62);
}

/* ==========================================================================
   The phone menu drawer
   ========================================================================== */

/*
 * Opening is the gesture the visitor asked for, so it takes its time;
 * closing is a dismissal, so it gets out of the way. The shorter duration on
 * the resting rule is the one that runs when `is-open` is removed.
 */
.s-menu,
.s-cart {
  transition: translate .24s var(--cp-ease);
  box-shadow: 0 0 0 1px var(--cp-edge-soft);
}
.s-menu.is-open,
.s-cart.is-open { transition: translate .42s var(--cp-ease); }

.s-menu.is-open { box-shadow: 24px 0 60px -30px rgb(6 16 49 / .6), 0 0 0 1px var(--cp-edge-soft); }
.s-cart.is-open { box-shadow: -24px 0 60px -30px rgb(6 16 49 / .6), 0 0 0 1px var(--cp-edge-soft); }

/*
 * The head carried the full-colour logo — a navy wordmark on a navy field, all
 * but invisible. A white plate behind it is the smallest honest fix and it
 * gives the drawer a masthead.
 */
.s-menu__head {
  background: linear-gradient(135deg, var(--s-brand-700), var(--s-brand-800) 55%, var(--s-brand-950));
  box-shadow: inset 0 -1px 0 rgb(255 184 0 / .28);
  padding-block: var(--s-4);
}
.s-menu__head img {
  padding: .3rem .55rem;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 6px 16px -10px rgb(6 16 49 / .8);
}
.s-menu__head .s-icon-btn {
  inline-size: 2.75rem;
  block-size: 2.75rem;
  background: rgb(255 255 255 / .1);
  transition: background-color .2s var(--cp-ease), transform .3s var(--cp-ease);
}
.s-menu__head .s-icon-btn:hover { background: rgb(255 255 255 / .2); transform: rotate(90deg); }

/*
 * The list ends well above the bottom of a tall phone, and the client's
 * standing rule is that space must never read as a hole. A wash of the brand
 * navy, pinned to the drawer's own box rather than to the scrolling content,
 * closes the column off the way the footer's does.
 */
.s-menu__body {
  padding-block-end: calc(var(--s-8) + var(--s-safe-bottom));
  background: linear-gradient(0deg, rgb(13 36 84 / .05), rgb(13 36 84 / 0) 11rem) no-repeat bottom / 100% 11rem;
}

.s-menu__link { transition: background-color .18s var(--cp-ease), color .18s var(--cp-ease), padding-inline-start .18s var(--cp-ease); }
.s-menu__link:hover,
.s-menu__link:focus-visible { padding-inline-start: calc(var(--s-3) + .35rem); }
.s-menu__group-label { padding-block: var(--s-5) var(--s-2); }

/*
 * The rows land one after another behind the panel. `both` with no resting
 * opacity of their own: with scripts blocked `is-open` never appears, no
 * animation runs, and every link is simply there.
 */
.s-menu.is-open .s-menu__body > * { animation: cp-rise .34s var(--cp-ease) both; }
.s-menu.is-open .s-menu__body > :nth-child(2)  { animation-delay: .03s; }
.s-menu.is-open .s-menu__body > :nth-child(3)  { animation-delay: .06s; }
.s-menu.is-open .s-menu__body > :nth-child(4)  { animation-delay: .09s; }
.s-menu.is-open .s-menu__body > :nth-child(5)  { animation-delay: .12s; }
.s-menu.is-open .s-menu__body > :nth-child(6)  { animation-delay: .15s; }
.s-menu.is-open .s-menu__body > :nth-child(n + 7) { animation-delay: .18s; }

/* ==========================================================================
   The cart drawer
   ========================================================================== */

/*
 * Every rule below is held to `[data-cart]` — the drawer aside itself.
 * `.s-cart__total` and friends are shared with the bag page, the checkout and
 * the order receipt, none of which are this sheet's business.
 */

/*
 * At 432px and under the drawer is the full width of the screen, and a 22px
 * radius on an edge with nothing behind it showed as two dark notches against
 * the scrim. Measured at 390: panel left 0, right 390 — the corner had no page
 * to sit on.
 */
@media (max-width: 27rem) {
  .s-cart[data-cart] { border-radius: 0; }
  .s-cart[data-cart] .s-cart__foot { border-radius: 0; }
}

.s-cart[data-cart] .s-cart__head {
  position: relative;
  padding-block: var(--s-4);
}
.s-cart[data-cart] .s-cart__head::after {
  content: "";
  position: absolute;
  inset-inline: var(--s-4);
  inset-block-end: -1px;
  block-size: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--s-accent-500), rgb(196 38 12 / 0) 55%);
}
.s-cart[data-cart] .s-cart__head .s-icon-btn {
  inline-size: 2.75rem;
  block-size: 2.75rem;
  color: var(--s-brand-800);
  transition: background-color .2s var(--cp-ease), color .2s var(--cp-ease), transform .3s var(--cp-ease);
}
.s-cart[data-cart] .s-cart__head .s-icon-btn:hover { background: var(--s-brand-800); color: #fff; transform: rotate(90deg); }

/*
 * An empty bag left its card at the top of a 780px panel with the rest white.
 * Scoped with :has so it can only ever apply while the bag is empty — the
 * moment a line is rendered the body is untouched flow again.
 */
.s-cart[data-cart] .s-cart__body:has(> .s-empty) {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.s-cart[data-cart] .s-cart__body > .s-empty { inline-size: 100%; }

.s-cart[data-cart] .s-cart__foot {
  position: relative;
  padding-block-end: calc(var(--s-4) + var(--s-safe-bottom));
  box-shadow: 0 -14px 30px -24px rgb(13 36 84 / .5);
}
.s-cart[data-cart] .s-cart__foot::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-start: -1px;
  block-size: 1px;
  background: linear-gradient(90deg, transparent, var(--cp-edge) 20%, var(--cp-edge) 80%, transparent);
}
.s-cart[data-cart] .s-cart__total { align-items: center; }
.s-cart[data-cart] .s-cart__total [data-cart-total] {
  font-family: var(--s-font-display);
  font-weight: 800;
  font-size: var(--s-text-xl);
  color: var(--s-brand-800);
}

/* Head, list and foot settle in that order once the panel has arrived. */
.s-cart[data-cart].is-open .s-cart__head { animation: cp-rise .34s var(--cp-ease) .06s both; }
.s-cart[data-cart].is-open .s-cart__body { animation: cp-rise .38s var(--cp-ease) .1s both; }
.s-cart[data-cart].is-open .s-cart__foot { animation: cp-rise .38s var(--cp-ease) .14s both; }

/* ==========================================================================
   The toast region
   ========================================================================== */

/*
 * It rose 10px and stopped. It now rises and settles, and carries a mark on
 * its leading edge so the kind of message is not read from the background
 * colour alone.
 */
.s-toast {
  position: relative;
  padding-inline-start: 1.35rem;
  animation: cp-toast-in .36s var(--cp-ease) both;
  box-shadow: 0 24px 48px -24px rgb(6 16 49 / .75), inset 0 1px 0 rgb(255 255 255 / .12);
}
/* Held inside the 14px radius rather than run to the edge, where the corner
   clipped it into a tab. */
.s-toast::before {
  content: "";
  position: absolute;
  inset-block: .5rem;
  inset-inline-start: .55rem;
  inline-size: 3px;
  border-radius: 3px;
  background: var(--s-cool-500);
}
.s-toast--success::before, .s-toast.is-success::before { background: rgb(255 255 255 / .75); }
.s-toast--error::before, .s-toast.is-error::before { background: var(--s-cool-500); }

@keyframes cp-toast-in {
  from { opacity: 0; transform: translateY(14px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

/* ==========================================================================
   Back to the top
   ========================================================================== */

/*
 * It faded in at full size, which on a phone is a button that materialises
 * under the thumb. It now comes up from below the fold it belongs to.
 */
.s-totop {
  transform: translateY(10px) scale(.85);
  transition: opacity .28s var(--cp-ease), transform .34s var(--cp-ease), background-color .2s var(--cp-ease), box-shadow .24s var(--cp-ease);
  box-shadow: 0 14px 30px -16px rgb(6 16 49 / .75), inset 0 1px 0 rgb(255 255 255 / .14);
}
.s-totop.is-on { transform: none; }
.s-totop:hover { background: var(--s-brand-700); transform: translateY(-2px); box-shadow: 0 18px 34px -16px rgb(6 16 49 / .8), inset 0 1px 0 rgb(255 255 255 / .18); }
.s-totop:active { transform: translateY(0) scale(.94); }
.s-totop svg { transition: transform .3s var(--cp-ease); }
.s-totop:hover svg { transform: translateY(-2px); }

/* ==========================================================================
   Focus, everywhere the chrome goes dark
   ========================================================================== */

/*
 * The global ring is --s-brand-500 on white. On the navy cart button, the navy
 * drawer head, the navy announcement bar and the navy back-to-top it is very
 * nearly invisible. Those five get a white ring with a navy halo behind it, so
 * the ring reads whichever surface it lands on.
 */
.sp-cart:focus-visible,
.s-totop:focus-visible,
.s-menu__head .s-icon-btn:focus-visible,
.sp-announce a:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
  box-shadow: 0 0 0 5px rgb(13 36 84 / .45);
}

/* And on white, the chrome's own controls take the brand red rather than the
   link blue, so a keyboard ring is unmistakably this shop's. */
.sp-action:focus-visible,
.sp-header__burger:focus-visible,
.sp-search__go:focus-visible,
.sp-nav__link:focus-visible,
.sp-slabs a:focus-visible,
.s-suggest__item:focus-visible,
.s-cart__head .s-icon-btn:focus-visible {
  outline: 2px solid var(--s-accent-500);
  outline-offset: 2px;
}

/* The skip link is the first thing a keyboard meets on every page. */
.s-skip {
  box-shadow: 0 14px 30px -16px rgb(6 16 49 / .7);
  transition: inset-block-start .2s var(--cp-ease);
}
.s-skip:focus { outline: 2px solid var(--s-cool-500); outline-offset: 3px; }

/* ==========================================================================
   prefers-reduced-motion — every animation added above, cancelled
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .sp-announce::after,
  .sp-header,
  .sp-header::after,
  .sp-brand img,
  .sp-search__form,
  .sp-search__form > svg,
  .sp-search__go,
  .sp-suggest,
  .sp-suggest:not([hidden]),
  .s-suggest__item,
  .s-suggest__item::before,
  .sp-action,
  .sp-action svg,
  .sp-header__burger,
  .sp-cart,
  .sp-cart svg,
  .sp-lang__list,
  .sp-lang__list:not([hidden]),
  .sp-lang__list a,
  .sp-nav__link,
  .sp-nav__link::after,
  .sp-nav__ico,
  .sp-slabs a,
  .sp-nav__item:hover > .sp-drop,
  .sp-nav__item:focus-within > .sp-drop,
  .sp-nav__item--all:hover > .sp-mega,
  .sp-nav__item--all:focus-within > .sp-mega,
  .sp-drop a,
  .sp-drop img,
  .sp-mega__head,
  .sp-mega__head img,
  .sp-mega__col li a,
  .sp-mega__col li a::before,
  .s-menu,
  .s-menu.is-open,
  .s-menu__link,
  .s-menu__head .s-icon-btn,
  .s-menu.is-open .s-menu__body > *,
  .s-cart,
  .s-cart.is-open,
  .s-cart__head .s-icon-btn,
  .s-cart.is-open .s-cart__head,
  .s-cart.is-open .s-cart__body,
  .s-cart.is-open .s-cart__foot,
  .s-toast,
  .s-totop,
  .s-totop svg,
  .s-skip {
    animation: none !important;
    transition: none !important;
  }

  /* The sheen is motion and nothing else; there is nothing to hold still. */
  .sp-announce::after { display: none; }

  /* States that were being reached by a transition still have to be reached. */
  .sp-header.is-stuck::after { opacity: 1; transform: scaleX(1); }
  .s-totop { transform: none; }
}
