/* ==========================================================================
   PddFalcon storefront — the bag and the checkout, refined

   Loaded after snap.css, snap-inner.css and home-premium.css and immediately
   before site-premium.css, so it refines the structural sheets without
   `!important` and never fights the two sheets that own the home bands and the
   shared furniture. Where site-premium already has an opinion — the bag line's
   name-and-total top row, the primary button's lit edge, the field focus ring —
   this sheet builds on it rather than restating it.

   Every colour is a token from tokens.css or an rgb()/color-mix() built from
   the brand's own values: navy #0d2454, deep navy #061031, red #c4260c,
   gold #ffb800, canvas #f4f6fa, tile #f3f5f8, hairline #e6eaf2.

   The brief for this pass, in the client's words, is that paying should feel
   PREMIUM — and on a checkout premium does not mean louder. It means calm and
   certain: money that reads as a ledger rather than a list, one obvious next
   action, a control that answers every touch, and nothing that moves when you
   did not ask it to.

   Contents
     1  Local values
     2  Page rhythm — the panels and their headings
     3  The bag line
     4  The stepper and Remove
     5  The empty bag
     6  The summary card
     7  The coupon field
     8  The offers list
     9  The checkout's fields
    10  The choice cards — a saved address, a way to pay
    11  The order page
    12  Entrances
    13  Reduced motion cancels every one of them
   ========================================================================== */

/* ==========================================================================
   1  Local values

   Scoped to the three surfaces rather than :root, so nothing here can leak
   into a screen this sheet was not asked to touch.
   ========================================================================== */

.s-cartpage,
.s-checkout {
  /* The hairline the whole bag is drawn with. One value, so a card, a ledger
     row and a field can never disagree by a shade. */
  --cp-line: var(--s-line);
  --cp-line-soft: color-mix(in srgb, var(--s-line) 55%, #fff);

  /* The tile the quiet grounds are filled with — a thumbnail, a chosen card. */
  --cp-tile: var(--s-cream);
  --cp-tint: color-mix(in srgb, var(--s-brand-800) 4%, #fff);

  /* Navy at the three strengths this sheet needs it: a ring, a lift, a rule. */
  --cp-ring: rgb(13 36 84 / .10);
  --cp-lift: 0 1px 2px rgb(13 36 84 / .04), 0 14px 34px -18px rgb(13 36 84 / .28);
  --cp-lift-lg: 0 2px 4px rgb(13 36 84 / .05), 0 26px 56px -26px rgb(13 36 84 / .34);

  --cp-ease: cubic-bezier(.22, 1, .36, 1);
}

/* ==========================================================================
   2  Page rhythm — the panels and their headings

   Every heading in the bag and the checkout is an `h2.s-pdp__block-title`, and
   base.css resets `h1..h4` to `margin: 0`. Nothing put the space back, so
   "Where should we send it?" sat 10px above the first label and every panel
   read as one undifferentiated block of text. A heading that owns a rule and a
   hairline turns each panel into a section a shopper can find their place in.
   ========================================================================== */

.s-cartpage .s-panel > .s-pdp__block-title,
.s-checkout .s-panel > .s-pdp__block-title {
  position: relative;
  margin-block-end: 1.15rem;
  padding-block-end: .8rem;
  font-size: var(--s-text-lg);
  letter-spacing: -.005em;
  border-block-end: 1px solid var(--cp-line);
}

/* The same red rule the page title carries, at the same weight, so a panel
   heading is recognisably a smaller member of the same family. */
.s-cartpage .s-panel > .s-pdp__block-title::after,
.s-checkout .s-panel > .s-pdp__block-title::after {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block-end: -1px;
  inline-size: 1.9rem;
  block-size: 2px;
  border-radius: 2px;
  background: var(--s-accent-500);
}

/* The panels themselves. A little more room inside, a hairline that reads as
   drawn rather than as a default, and a shadow with two stops so the card sits
   on the canvas instead of floating above it. */
.s-checkout .s-panel,
.s-cartpage .s-summary {
  padding: 1.4rem 1.5rem;
  border-color: var(--cp-line);
  box-shadow: var(--cp-lift);
}

@media (max-width: 47.99rem) {
  .s-checkout .s-panel,
  .s-cartpage .s-summary { padding: 1.15rem 1.15rem; }
}

/* The gap the two columns stand in, and the space under them.

   3rem of padding plus the section's own 1.5rem plus the phone's 3.75rem of
   bottom-bar clearance stacked up to 144px of nothing between the last card
   and the footer — which is exactly the dead space the client keeps asking us
   to take out. The bar's clearance is already on `body`; this only needs to
   clear the card, not the bar as well. */
.s-cartpage,
.s-checkout { gap: 1.5rem; }

@media (min-width: 62rem) {
  .s-cartpage,
  .s-checkout { gap: 2rem; padding-block-end: var(--s-8); }
}

@media (max-width: 61.99rem) {
  .s-cartpage,
  .s-checkout { padding-block-end: var(--s-4); }
}

/*
 * A grid track may not be widened by what is inside it.
 *
 * On one column the bag's cards were sized to the widest thing they contained
 * rather than to the page: at 360 the track measured 330.7px inside a 328px
 * wrap, so both cards sat 2.7px into the right-hand gutter and the page's
 * scrollWidth followed them out. `min-inline-size: 0` is what a grid item needs
 * to be allowed to be narrower than its own content, and with it the track is
 * the page's width and nothing else.
 */
.s-cartpage > *,
.s-checkout > *,
.s-checkout__main > * { min-inline-size: 0; }

/* ==========================================================================
   3  The bag line

   site-premium.css already moved the line total up beside the name and put the
   stepper and Remove on a row of their own. What was left was a card that did
   not answer the pointer and a picture sitting flat on the tile.
   ========================================================================== */

.s-cartpage .s-line {
  align-items: center;
  padding: 1rem 1.15rem;
  border-color: var(--cp-line);
  transition:
    border-color .3s var(--cp-ease),
    box-shadow .3s var(--cp-ease),
    translate .3s var(--cp-ease);
}

/*
 * On a phone the padding gives way rather than the controls.
 *
 * site-premium.css asked for the stepper and Remove to share a row on a phone,
 * and they only fit if the line spends its width on them. At 390 the body has
 * 202.8px to give and the pair now needs 197.3 — the buttons stayed at the
 * full 44px and the number between them gave up 8px instead, because a number
 * is read and not pressed. At 360 there is no arrangement that fits and Remove
 * wraps under the stepper, which is the honest answer.
 */
@media (max-width: 47.99rem) {
  .s-cartpage .s-line { padding: .9rem .85rem; }
}

/*
 * The smallest phones still in real use — 360 and 375 CSS pixels.
 *
 * There the body has 172.8px and the stepper with Remove needs 197.3, so the
 * pair wrapped and the line stood 222px tall for a 96px picture, with white
 * down one side of it. The picture goes back to the 4.5rem layout.css always
 * gave it, which buys 28px, and the line comes back to a single tidy block.
 */
@media (max-width: 23.4375rem) {
  .s-cartpage .s-line { grid-template-columns: 4.5rem minmax(0, 1fr); gap: .75rem; }
  .s-cartpage .s-line__thumb { inline-size: 4.5rem; block-size: 4.5rem; }
}

/*
 * On a wide bag the lines get the room the column has anyway.
 *
 * At 1440 two lines stood 290px against a 385px summary, and the difference
 * was white. A bigger picture and a little more padding is worth having on its
 * own — this is a shop that sells on how the steel looks — and it closes most
 * of that gap as a side effect rather than as a trick.
 */
@media (min-width: 62rem) {
  .s-cartpage .s-line { grid-template-columns: 7rem minmax(0, 1fr); gap: 1.25rem; padding: 1.25rem 1.4rem; }
  .s-cartpage .s-line__thumb { inline-size: 7rem; block-size: 7rem; }
  .s-cartpage .s-line + .s-line { margin-block-start: .9rem; }
}

.s-cartpage .s-line:hover {
  border-color: rgb(13 36 84 / .16);
  box-shadow: var(--cp-lift);
  translate: 0 -2px;
}

/* A keyboard reaching the line gets the same answer the pointer gets, so the
   two ways of using the bag feel like the same shop. */
.s-cartpage .s-line:focus-within {
  border-color: rgb(13 36 84 / .22);
  box-shadow: var(--cp-lift);
}

/* The picture. A ring inside the tile rather than a border outside it, so the
   thumbnail keeps its full 6rem and the edge still reads. */
.s-cartpage .s-line__thumb {
  background: var(--cp-tile);
  box-shadow: inset 0 0 0 1px var(--cp-line);
  transition: scale .4s var(--cp-ease);
}

.s-cartpage .s-line:hover .s-line__thumb { scale: 1.03; }

/* Names and versions. The name is the thing being bought and reads as a link
   the moment the pointer is near it; the version is a whisper under it. */
.s-cartpage .s-line__name {
  font-size: var(--s-text-md);
  line-height: 1.35;
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: .22em;
  transition: text-decoration-color .2s var(--cp-ease), color .2s var(--cp-ease);
}

.s-cartpage .s-line__name:hover {
  color: var(--s-accent-500);
  text-decoration-color: currentColor;
}

.s-cartpage .s-line__meta {
  color: var(--s-muted);
  letter-spacing: .01em;
}

/* A price that changed while the bag was sitting there. Said in the warn ink
   the token already carries, with a mark in front of it — the client's shops
   are read by people who cannot separate this amber from this grey by hue. */
.s-cartpage .s-line__meta--warn {
  display: flex;
  align-items: flex-start;
  gap: .4rem;
  margin-block-start: .3rem;
  padding: .4rem .6rem;
  border-radius: 8px;
  background: var(--s-warn-soft);
  color: var(--s-warn);
  font-weight: 600;
}

.s-cartpage .s-line__meta--warn::before {
  content: "!";
  flex: none;
  display: grid;
  place-items: center;
  inline-size: 1.05rem;
  block-size: 1.05rem;
  border-radius: 50%;
  background: var(--s-warn);
  color: #fff;
  font-size: .65rem;
  font-weight: 800;
  line-height: 1;
}

/* Money is read down a column, not across a sentence. Tabular figures keep the
   rupee amounts on one axis however many digits they run to. */
.s-cartpage .s-line__price,
.s-cartpage .s-cart__total span,
.s-checkout .s-cart__total span,
.s-checkout .s-sumline span:last-child { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   4  The stepper and Remove

   Both were under the 44px a thumb needs: the stepper's buttons measured
   40×40 and Remove measured 53×26. Neither is a style question — a control
   the client's customers miss on the first tap is a control that costs an
   order.
   ========================================================================== */

.s-cartpage .s-qty {
  border-color: var(--cp-line);
  background: #fff;
  box-shadow: inset 0 1px 2px rgb(13 36 84 / .03);
}

.s-cartpage .s-qty__btn {
  inline-size: 2.75rem;
  block-size: 2.75rem;
  font-size: 1.15rem;
  color: var(--s-brand-800);
  transition: background-color .18s var(--cp-ease), color .18s var(--cp-ease), scale .12s var(--cp-ease);
}

.s-cartpage .s-qty__btn:hover:not(:disabled) {
  background: var(--s-brand-800);
  color: #fff;
}

/* The press itself. A stepper that does not move under the thumb feels broken
   on a phone, where there is no hover to tell you the tap landed. */
.s-cartpage .s-qty__btn:active:not(:disabled) { scale: .9; }

.s-cartpage .s-qty__btn:disabled { opacity: .45; cursor: not-allowed; }

/* The number between them. A grid rather than a bare span, so a one-digit and
   a three-digit quantity sit on the same centre line. */
.s-cartpage .s-qty__value {
  display: grid;
  place-items: center;
  inline-size: 3rem;
  block-size: 2.75rem;
  border-color: var(--cp-line);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--s-brand-800);
}

/* While the change is in flight.

   `shop.js` marks the pressed button `is-busy` and then reloads the page, so
   without this the bag sat looking untouched for the whole round trip and a
   shopper on a slow connection pressed + again. The line answers instead: it
   settles back, and the stepper says it is working. */
.s-cartpage .s-line:has(.is-busy) {
  translate: 0;
  box-shadow: none;
}

.s-cartpage .s-line:has(.is-busy) .s-line__body { opacity: .55; }

.s-cartpage .s-line__body { transition: opacity .2s var(--cp-ease); }

.s-cartpage .s-qty__btn.is-busy {
  background: var(--s-brand-800);
  color: transparent;
  position: relative;
}

.s-cartpage .s-qty__btn.is-busy::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  margin: -.45rem 0 0 -.45rem;
  inline-size: .9rem;
  block-size: .9rem;
  border: 2px solid rgb(255 255 255 / .35);
  border-block-start-color: #fff;
  border-radius: 50%;
  animation: cp-spin .7s linear infinite;
}

/* Remove. Quiet until it is wanted, red the moment it is, and a full 44px of
   height to press whichever it happens to be. */
.s-cartpage .s-line__remove {
  display: inline-flex;
  align-items: center;
  min-block-size: 2.75rem;
  padding-inline: .35rem;
  border-radius: 8px;
  font-size: var(--s-text-sm);
  font-weight: 600;
  text-decoration-color: transparent;
  text-underline-offset: .22em;
  transition: color .2s var(--cp-ease), text-decoration-color .2s var(--cp-ease);
}

.s-cartpage .s-line__remove:hover {
  color: var(--s-accent-500);
  text-decoration-color: currentColor;
}

/*
 * The stepper and Remove sit together as one set of controls rather than two
 * things that happen to be on the same line — and they wrap rather than push.
 *
 * site-premium.css put them on a row of their own and asked for them to share
 * it on a phone rather than stack, which they do at 390 and above. At 360 they
 * cannot: a 138px stepper and a 62px Remove need 205px and the line's body has
 * 179px, and before this the pair simply hung 0.6px past the viewport and took
 * the whole page's scrollWidth to 361 with them. `flex-wrap` changes nothing
 * wherever they fit and drops Remove onto its own line where they do not.
 */
.s-cartpage .s-line__foot {
  flex-wrap: wrap;
  gap: .35rem;
  row-gap: .5rem;
  margin-block-start: .55rem;
}

/*
 * The one place a phone gets a narrower control — and it is not a target.
 *
 * At 390 the line's body has 200.8px and the pair needs 205.3, so something
 * had to give 5px. The two buttons are what a thumb aims at and they keep
 * their full 44×44; the number between them is read rather than pressed, so it
 * gives up 8px and the stepper and Remove stay on one row, which is what
 * site-premium.css asked for. Written after the rule it narrows, because the
 * two have the same specificity and the later one wins.
 */
@media (max-width: 47.99rem) {
  .s-cartpage .s-qty__value { inline-size: 2.5rem; }
}

@keyframes cp-spin { to { rotate: 360deg; } }

/* ==========================================================================
   5  The empty bag

   The one screen in this whole surface that is nothing but space. It cannot be
   filled with anything invented, so it is given presence instead: a ground
   that is lit rather than flat, and a mark that looks placed.
   ========================================================================== */

.s-cartpage + .s-empty,
.s-section > .s-empty {
  position: relative;
  overflow: hidden;
  padding-block: 4rem;
  background: linear-gradient(180deg, var(--cp-tint), var(--s-cream) 70%);
  border: 1px solid var(--cp-line);
}

.s-section > .s-empty::before {
  content: "";
  position: absolute;
  inset: -40% 30% auto auto;
  inline-size: 22rem;
  block-size: 22rem;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgb(196 38 12 / .07), transparent);
  pointer-events: none;
}

.s-section > .s-empty > * { position: relative; }

.s-section > .s-empty__mark,
.s-section > .s-empty .s-empty__mark {
  box-shadow: 0 1px 2px rgb(13 36 84 / .05), 0 18px 38px -20px rgb(13 36 84 / .38);
}

.s-section > .s-empty .s-empty__body {
  max-inline-size: 26rem;
  margin-inline: auto;
  color: var(--s-muted);
}

/* ==========================================================================
   6  The summary card

   The card that decides whether the order happens. Three things were asked of
   it: a hierarchy, stickiness that behaves, and a total that looks like the
   answer rather than another row.
   ========================================================================== */

.s-summary {
  border-color: var(--cp-line);
  box-shadow: var(--cp-lift-lg);

  /* The brand's three inks across the top edge, clipped by the card's own
     radius so it reads as an inlay rather than a stripe laid on top. The
     footer opens with the same gesture; this closes the page with it. */
  background-image: linear-gradient(90deg, var(--s-accent-500), var(--s-cool-500) 46%, var(--s-brand-500));
  background-repeat: no-repeat;
  background-size: 100% 3px;
  background-position: 0 0;
}

/* Sticky only where there is something for it to be sticky against. Below the
   two-column breakpoint the summary is the last thing on the page, so `sticky`
   buys nothing and only risks an ancestor's overflow surprising it. */
@media (max-width: 61.99rem) {
  .s-summary { position: static; }
}

/* The ledger.

   Every money row on the same rhythm, hairlines between them, the label muted
   and the figure in navy. Read down, it is a column of numbers; read across,
   each row says what it is. */
.s-summary .s-cart__total {
  margin-block-end: 0;
  padding-block: .65rem;
  font-size: var(--s-text-md);
  font-weight: 600;
}

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

.s-summary .s-cart__total:not(.s-cart__total--grand) > span:first-child {
  color: var(--s-muted);
  font-weight: 600;
}

.s-summary .s-cart__total > span:last-child {
  color: var(--s-brand-800);
  font-weight: 700;
  white-space: nowrap;
}

/* The figure the shopper actually came for.

   On the checkout and the order page that is the row already marked `--grand`.
   On the bag there is no grand row until a code is applied, so the last money
   row — whichever it turns out to be — takes the weight. Scoped to the bag,
   because the order page can print a Refunded row *after* its total and that
   row must never be mistaken for the amount owed. */
.s-summary .s-cart__total--grand,
.s-cartpage .s-summary .s-cart__total:not(:has(~ .s-cart__total)) {
  margin-block-start: .3rem;
  padding-block: .9rem .2rem;
  border-block-start: 1px solid rgb(13 36 84 / .16);
  font-family: var(--s-font-display);
  font-size: var(--s-text-xl);
  font-weight: 800;
  color: var(--s-brand-800);
}

.s-summary .s-cart__total--grand > span:first-child,
.s-cartpage .s-summary .s-cart__total:not(:has(~ .s-cart__total)) > span:first-child {
  color: var(--s-brand-800);
  font-weight: 800;
}

/* The checkout's own list of what is in the order. Quiet, tight, and the last
   one loses its rule so the Subtotal underneath begins the ledger cleanly. */
.s-checkout .s-sumline {
  gap: .75rem;
  padding-block: .55rem;
  border-block-end-color: var(--cp-line-soft);
  color: var(--s-ink-soft);
}

.s-checkout .s-sumline > span:first-child { min-inline-size: 0; }
.s-checkout .s-sumline > span:last-child { flex: none; font-weight: 600; color: var(--s-brand-800); }
.s-checkout .s-sumline:last-of-type { border-block-end: 0; }
.s-checkout .s-sumline__version { font-size: var(--s-text-xs); }
.s-checkout .s-sumline__qty { font-weight: 600; white-space: nowrap; }

/* The one obvious next action. The lit edge and the pressed shadow are
   site-premium's; this gives it the height a thumb wants, a little more
   presence in the type, and a lift the pointer can feel. */
.s-summary .s-btn--block {
  min-block-size: 3.25rem;
  border-radius: var(--s-radius-pill);
  letter-spacing: .01em;
}

.s-summary .s-btn--primary {
  position: relative;
  overflow: hidden;
  font-size: var(--s-text-md);
  font-weight: 700;
  transition:
    background-color .2s var(--cp-ease),
    box-shadow .25s var(--cp-ease),
    translate .25s var(--cp-ease),
    transform .15s var(--cp-ease);
}

.s-summary .s-btn--primary:hover:not(:disabled) { translate: 0 -2px; }
.s-summary .s-btn--primary:active:not(:disabled) { translate: 0 0; }

/* A single pass of light across the button on hover. `::before`, because
   `::after` is the busy spinner's and a button that cannot show it is working
   is worse than a button that does not shine. */
.s-summary .s-btn--primary::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: -60%;
  inline-size: 45%;
  background: linear-gradient(100deg, transparent, rgb(255 255 255 / .22), transparent);
  translate: -20% 0;
  opacity: 0;
  pointer-events: none;
}

/*
 * The reassurance under it.
 *
 * Calm rather than fine print, and *not* a callout. account-premium.css boxes
 * `.s-panel > .s-note` for the empty-list sentence on the account pages, and
 * the summary is a panel too — so "Delivery is worked out at checkout", the
 * sign-in warning and the phone number all arrived as three dashed grey boxes
 * stacked under the Checkout button, which is three alarms where the shop
 * meant to be quietly reassuring. Here they are sentences again.
 */
.s-cartpage .s-summary > .s-note,
.s-checkout .s-summary > .s-note {
  max-inline-size: none;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 0;
}

.s-summary .s-note {
  font-size: var(--s-text-xs);
  line-height: 1.6;
}

.s-summary > .s-note + .s-note { margin-block-start: .55rem; }
.s-summary > .s-btn--block + .s-note { margin-block-start: .85rem; }

.s-summary .s-note a { text-decoration: underline; text-underline-offset: .18em; }

/* The card's own breathing. Snap-inner gives the summary 1.4rem all round;
   these are the pieces inside it that had none. */
.s-summary > .s-btn--block { margin-block-start: 1rem; }
.s-summary > .s-offers { margin-block: 1rem 0; }

/* ==========================================================================
   7  The coupon field

   Two controls with a gap between them became one control with an action
   inside it — the same shape as the header's search, which is the shop's
   established way of saying "type something here". The whole shell answers the
   focus, so a keyboard sees one thing rather than two.
   ========================================================================== */

.s-coupon { padding-block-start: 1rem; }

.s-coupon__label {
  display: flex;
  align-items: center;
  gap: .45rem;
  margin-block-end: .55rem;
  font-size: var(--s-text-sm);
  font-weight: 700;
  color: var(--s-ink);
}

/* A little tag, drawn rather than written, so the row is recognisable before
   it is read. Decorative only — the label already says what this is. */
.s-coupon__label::before {
  content: "";
  flex: none;
  inline-size: 1rem;
  block-size: 1rem;
  background: var(--s-accent-500);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.6 13.4 12 22l-9-9V3h10l7.6 7.6a2 2 0 0 1 0 2.8Z'/%3E%3Ccircle cx='7.5' cy='7.5' r='1.2' fill='%23000'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.6 13.4 12 22l-9-9V3h10l7.6 7.6a2 2 0 0 1 0 2.8Z'/%3E%3Ccircle cx='7.5' cy='7.5' r='1.2' fill='%23000'/%3E%3C/svg%3E") center / contain no-repeat;
}

.s-coupon__row {
  display: flex;
  align-items: center;
  gap: .4rem;
  min-inline-size: 0;
  padding: .3rem .3rem .3rem 1rem;
  border: 1.5px solid var(--cp-line);
  border-radius: var(--s-radius-pill);
  background: var(--s-cream);
  transition: border-color .2s var(--cp-ease), background-color .2s var(--cp-ease), box-shadow .2s var(--cp-ease);
}

.s-coupon__row:focus-within {
  border-color: var(--s-brand-800);
  background: #fff;
  box-shadow: 0 0 0 4px var(--cp-ring);
}

/* The input gives up its own box to the shell that now holds it. */
.s-coupon__row .s-coupon__input {
  flex: 1 1 auto;
  min-inline-size: 0;
  min-block-size: 2.75rem;
  padding-inline: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  font-size: var(--s-text-sm);
  font-weight: 700;
  letter-spacing: .08em;
}

.s-coupon__row .s-coupon__input:focus {
  border: 0;
  background: transparent;
  box-shadow: none;
}

.s-coupon__row .s-coupon__input::placeholder {
  color: var(--s-muted);
  font-weight: 600;
  letter-spacing: .06em;
}

/* Apply. Navy against the red Checkout below it, so the page never offers two
   things that look equally like the thing to press. */
.s-coupon__row .s-btn {
  flex: none;
  min-block-size: 2.75rem;
  padding-inline: 1.1rem;
  border-radius: var(--s-radius-pill);
  font-size: var(--s-text-sm);
  font-weight: 700;
}

/* The answer. A mark as well as a colour, because red and green are the one
   pair a shopper with a deficiency cannot separate — and this row is nothing
   but a colour otherwise. */
.s-coupon__ok,
.s-coupon__bad {
  display: flex;
  align-items: flex-start;
  gap: .4rem;
  margin-block-start: .6rem;
  font-size: var(--s-text-xs);
  line-height: 1.5;
  font-weight: 600;
}

.s-coupon__ok::before,
.s-coupon__bad::before {
  flex: none;
  display: grid;
  place-items: center;
  inline-size: 1.05rem;
  block-size: 1.05rem;
  border-radius: 50%;
  color: #fff;
  font-size: .65rem;
  font-weight: 800;
  line-height: 1;
}

.s-coupon__ok::before { content: "\2713"; background: var(--s-success); }
.s-coupon__bad::before { content: "!"; background: var(--s-danger); }

.s-coupon__clear {
  display: inline-flex;
  align-items: center;
  min-block-size: 2.75rem;
  padding-inline: .35rem;
  font-size: var(--s-text-xs);
  font-weight: 600;
  text-underline-offset: .2em;
  transition: color .2s var(--cp-ease);
}

.s-coupon__clear:hover { color: var(--s-accent-500); }

/* ==========================================================================
   8  The offers list

   The client asked for every offer to be shown with its condition, the usable
   ones takeable in a tap and the rest greyed rather than hidden. That is all
   in the markup already; what it needed was to stop looking like a dashed
   coupon clipping and start looking like part of the summary.
   ========================================================================== */

.s-cartpage .s-offers,
.s-checkout .s-offers { gap: .5rem; }

.s-cartpage .s-offers__title,
.s-checkout .s-offers__title {
  font-size: var(--s-text-2xs);
  font-weight: 800;
  letter-spacing: var(--s-tracking-caps);
  text-transform: uppercase;
  color: var(--s-muted);
}

.s-cartpage .s-offer,
.s-checkout .s-offer {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: .35rem .75rem;
  padding: .8rem .9rem;
  border: 1px solid var(--cp-line);
  border-radius: 12px;
  background: var(--cp-tint);
  transition: border-color .25s var(--cp-ease), background-color .25s var(--cp-ease);
}

.s-cartpage .s-offer:hover,
.s-checkout .s-offer:hover { border-color: rgb(13 36 84 / .2); }

.s-cartpage .s-offer__main,
.s-checkout .s-offer__main { min-inline-size: 0; }

.s-cartpage .s-offer__action,
.s-checkout .s-offer__action { grid-column: 2; grid-row: 1; margin-block-start: 0; }

.s-cartpage .s-offer__code,
.s-checkout .s-offer__code { font-size: var(--s-text-sm); letter-spacing: .06em; }

.s-cartpage .s-offer__head,
.s-checkout .s-offer__head { flex-wrap: wrap; gap: .2rem .5rem; }

.s-cartpage .s-offer__action .s-btn,
.s-checkout .s-offer__action .s-btn { min-block-size: 2.5rem; border-radius: var(--s-radius-pill); }

/* Applied. A green word is not enough on its own; it gets the tick too. */
.s-cartpage .s-offer.is-on,
.s-checkout .s-offer.is-on {
  border-color: color-mix(in srgb, var(--s-success) 35%, var(--cp-line));
  background: var(--s-success-soft);
}

.s-cartpage .s-offer__applied,
.s-checkout .s-offer__applied {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  white-space: nowrap;
}

.s-cartpage .s-offer__applied::before,
.s-checkout .s-offer__applied::before {
  content: "\2713";
  display: grid;
  place-items: center;
  inline-size: 1rem;
  block-size: 1rem;
  border-radius: 50%;
  background: var(--s-success);
  color: #fff;
  font-size: .6rem;
}

/* Not yet. Held back rather than switched off — the reason is printed under it
   and the shopper is meant to read it. */
.s-cartpage .s-offer.is-out,
.s-checkout .s-offer.is-out {
  background: #fff;
  border-style: dashed;
}

.s-cartpage .s-offer__locked,
.s-checkout .s-offer__locked {
  display: inline-block;
  padding: .3rem .6rem;
  border: 1px solid var(--cp-line);
  border-radius: var(--s-radius-pill);
  background: var(--s-cream);
  color: var(--s-muted);
  font-size: var(--s-text-2xs);
  font-weight: 700;
  letter-spacing: .02em;
  white-space: nowrap;
}

.s-cartpage .s-offer__why,
.s-checkout .s-offer__why { color: var(--s-ink-soft); }

/* ==========================================================================
   9  The checkout's fields

   Nothing here changes what is asked or in what order. It changes how sure the
   asking looks: the label owns the field, the help sits under it as help, and
   the group being filled is visibly the live one.
   ========================================================================== */

.s-checkout .s-fields { gap: 1.15rem 1.25rem; }

.s-checkout .s-field { gap: .4rem; min-inline-size: 0; }

.s-checkout .s-field > label {
  display: flex;
  align-items: baseline;
  gap: .4rem;
  font-size: var(--s-text-sm);
  font-weight: 700;
  color: var(--s-ink);
  transition: color .2s var(--cp-ease);
}

/* The field being filled is the live thing on the screen — site-premium
   already lights the input; this brings its label with it. */
.s-checkout .s-field:focus-within > label { color: var(--s-brand-800); }

.s-checkout .s-optional {
  padding: .1rem .4rem;
  border-radius: var(--s-radius-pill);
  background: var(--s-cream);
  color: var(--s-muted);
  font-size: var(--s-text-2xs);
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: lowercase;
}

.s-checkout .s-field__help {
  font-size: var(--s-text-xs);
  line-height: 1.5;
  color: var(--s-muted);
}

/* A field that is wrong says so with a mark as well as with red. */
.s-checkout .s-field__error {
  display: flex;
  align-items: flex-start;
  gap: .4rem;
  font-size: var(--s-text-xs);
  line-height: 1.5;
}

.s-checkout .s-field__error::before {
  content: "!";
  flex: none;
  display: grid;
  place-items: center;
  inline-size: 1.05rem;
  block-size: 1.05rem;
  border-radius: 50%;
  background: var(--s-danger);
  color: #fff;
  font-size: .65rem;
  font-weight: 800;
  line-height: 1;
}

.s-checkout .s-field input:not([type="checkbox"]):not([type="radio"]),
.s-checkout .s-field textarea,
.s-checkout .s-field select { min-inline-size: 0; }

/* A field the browser has filled, and one the shopper has: both read as done
   rather than as still waiting. */
.s-checkout .s-field input:not(:placeholder-shown):not(:focus) { background: #fff; }

.s-checkout .s-field textarea { min-block-size: 5rem; }

/* "Keep this address for next time" and "Same as the delivery address" — a
   checkbox and its words, given a row a thumb can hit. */
.s-checkout .s-check:not(.s-check--pay) {
  align-items: center;
  min-block-size: 2.75rem;
  padding-block: .35rem;
}

.s-checkout .s-check:not(.s-check--pay) input { flex: none; }

/* The block that folds away when billing is the same address. It is in the
   page either way so the form still works with scripts blocked; when it is
   showing it should look like it belongs to the panel above it. */
.s-checkout [data-billing-fields]:not([hidden]) {
  margin-block-start: 1rem;
  padding-block-start: 1.15rem;
  border-block-start: 1px solid var(--cp-line);
}

/* ==========================================================================
   10  The choice cards — a saved address, a way to pay

   The same component does both jobs. Its label carries a `<strong>` and one or
   two lines of help, and all of it ran together on one line: "Home Ananya
   Sharma · 9876543210 Flat 402, Sunrise Residency, Sector 21…". Stacked, with
   the radio held at the top of its own column, an address is readable before
   it is chosen — which is the whole reason the client asked for radios rather
   than a select.
   ========================================================================== */

.s-checkout .s-check--pay {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: .1rem .85rem;
  padding: 1rem 1.1rem;
  border-color: var(--cp-line);
  background: #fff;
  cursor: pointer;
  transition:
    border-color .25s var(--cp-ease),
    background-color .25s var(--cp-ease),
    box-shadow .25s var(--cp-ease),
    translate .25s var(--cp-ease);
}

.s-checkout .s-check--pay + .s-check--pay { margin-block-start: .6rem; }

.s-checkout .s-check--pay > input {
  margin-block-start: .2rem;
  inline-size: 1.2rem;
  block-size: 1.2rem;
}

.s-checkout .s-check--pay > label {
  display: grid;
  gap: .25rem;
  min-inline-size: 0;
  cursor: pointer;
  overflow-wrap: anywhere;
}

.s-checkout .s-check--pay > label > strong {
  font-size: var(--s-text-md);
  font-weight: 700;
  color: var(--s-brand-800);
}

.s-checkout .s-check--pay .s-field__help {
  font-size: var(--s-text-xs);
  line-height: 1.55;
  color: var(--s-muted);
}

.s-checkout .s-check--pay:hover {
  border-color: rgb(13 36 84 / .22);
  box-shadow: var(--cp-lift);
}

/* Chosen. A ring and a tick, not only a tint — the third of the hard rules,
   and the one a shop breaks most often on exactly this control. */
.s-checkout .s-check--pay:has(input:checked) {
  border-color: var(--s-brand-800);
  box-shadow: 0 0 0 3px var(--cp-ring);
}

.s-checkout .s-check--pay::after {
  content: "";
  grid-column: 3;
  grid-row: 1;
  align-self: center;
  inline-size: 1.4rem;
  block-size: 1.4rem;
  border-radius: 50%;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / .85rem no-repeat,
    var(--s-brand-800);
  opacity: 0;
  scale: .6;
  transition: opacity .2s var(--cp-ease), scale .2s var(--cp-ease);
}

.s-checkout .s-check--pay:has(input:checked)::after { opacity: 1; scale: 1; }

/*
 * The panel that says nothing can be paid yet. It is the shop admitting a
 * problem, so it is drawn as a notice rather than as a tip.
 *
 * Scoped to the checkout's own form on purpose: the order page uses the same
 * component for the merchant's cash-on-delivery reminder, and a reminder is
 * not an alarm. That one keeps the calm brand blue it has always had.
 */
form.s-checkout .s-callout {
  border-inline-start-color: var(--s-accent-500);
  background: var(--s-accent-100);
  color: var(--s-brand-900);
  line-height: 1.6;
}

form.s-checkout .s-callout a { color: var(--s-accent-600); font-weight: 700; }

/* The order page's callout, given the same rhythm as everything around it. */
.s-checkout .s-callout { line-height: 1.6; }
.s-checkout .s-callout + .s-pdp__block-title { margin-block-start: 1.35rem; }

/* ==========================================================================
   11  The order page

   Same `.s-checkout` scaffold, different job: it is read, not filled in.
   ========================================================================== */

/*
 * The line that was broken.
 *
 * On this page a line is `[picture?] <div>name + meta</div> <span>total</span>`
 * — three children, or two when the item has no picture. The bag's two-column
 * grid put the name in the 6rem picture column and squeezed it to a wrap, and
 * the total dropped onto a row of its own; with no picture the name took the
 * 6rem column outright. Measured at 1440 before this: the name column was 96px
 * wide and the price sat 684px wide underneath it. A flex row reads the same
 * markup correctly whichever of the two shapes it is.
 */
.s-checkout .s-line {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: .9rem 1rem;
  border: 1px solid var(--cp-line);
  border-radius: var(--sp-radius, 14px);
  background: #fff;
}

.s-checkout .s-line + .s-line { margin-block-start: .6rem; }

.s-checkout .s-line > img {
  flex: none;
  inline-size: 4rem;
  block-size: 4rem;
  border-radius: 10px;
  background: var(--cp-tile);
  object-fit: cover;
  box-shadow: inset 0 0 0 1px var(--cp-line);
}

.s-checkout .s-line > div { flex: 1 1 auto; min-inline-size: 0; }

.s-checkout .s-line .s-line__name {
  display: block;
  font-size: var(--s-text-md);
  font-weight: 700;
  color: var(--s-brand-800);
}

.s-checkout .s-line .s-line__meta { margin-block-start: .15rem; }

.s-checkout .s-line > .s-line__price {
  flex: none;
  margin-inline-start: auto;
  font-size: var(--s-text-lg);
  font-weight: 800;
  color: var(--s-brand-800);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/*
 * On a phone the price wraps only if it has to.
 *
 * A line with no picture — most of them — has room for the name and the total
 * side by side even at 360, and forcing the total onto a row of its own put a
 * left-aligned rupee amount under the item like a third fact about it. Wrapping
 * without a fixed basis lets it stay on the row where it fits and drop to the
 * right-hand end of the next one where it does not.
 */
@media (max-width: 30rem) {
  .s-checkout .s-line { flex-wrap: wrap; gap: .5rem .75rem; padding: .9rem; }
  .s-checkout .s-line > div { flex: 1 1 8rem; }
}

/*
 * Where the order has got to.
 *
 * The pill held a status and a whole sentence of stamp on one line. The status
 * stays a pill; the stamp moves under it, where a date belongs.
 */
.s-checkout .s-orderstate {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: .1rem .6rem;
  margin-block-end: 1.1rem;
  padding: .85rem 1.1rem;
  border-radius: 14px;
  background: var(--cp-tint);
  box-shadow: inset 0 0 0 1px var(--cp-line);
  font-size: var(--s-text-md);
}

.s-checkout .s-orderstate__dot {
  margin-block-start: .45rem;
  inline-size: .5rem;
  block-size: .5rem;
  box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 18%, transparent);
}

.s-checkout .s-orderstate > span:last-child { display: grid; gap: .15rem; min-inline-size: 0; }
.s-checkout .s-orderstate strong { font-size: var(--s-text-md); font-weight: 800; }
.s-checkout .s-orderstate .s-field__help { font-size: var(--s-text-xs); font-weight: 500; color: var(--s-muted); }

.s-checkout .s-orderstate--paid,
.s-checkout .s-orderstate--delivered { background: var(--s-success-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--s-success) 25%, transparent); }

.s-checkout .s-orderstate--cancelled,
.s-checkout .s-orderstate--failed { background: var(--s-danger-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--s-danger) 25%, transparent); }

/* Where it is going. An address is read as lines, so it is set as lines. */
.s-checkout .s-address {
  padding: 1rem 1.15rem;
  background: var(--cp-tile);
  border-color: var(--cp-line);
  line-height: 1.75;
  color: var(--s-ink-soft);
  overflow-wrap: anywhere;
}

/* What has happened so far. */
.s-checkout .s-timeline li { padding-block: .4rem 1rem; }
.s-checkout .s-timeline strong { display: block; color: var(--s-brand-800); font-weight: 700; }
.s-checkout .s-timeline .s-field__help { font-size: var(--s-text-xs); color: var(--s-muted); }

/* A return or an exchange the customer has asked for. */
.s-checkout .s-request {
  padding: .9rem 1rem;
  border: 1px solid var(--cp-line);
  border-radius: 12px;
  background: var(--cp-tint);
}

.s-checkout .s-request + .s-request { margin-block-start: .6rem; }
.s-checkout .s-request .s-line__meta { margin-block-start: .25rem; line-height: 1.55; }
.s-checkout .s-request__actions { margin-block-start: .75rem; }

/*
 * Leaving a review.
 *
 * One form per line that can still be written about, and with nothing between
 * them the two ran together as a single very long form. A rule and a gap say
 * where one ends.
 */
.s-checkout .s-panel > form.s-fields + form.s-fields {
  margin-block-start: 1.5rem;
  padding-block-start: 1.5rem;
  border-block-start: 1px solid var(--cp-line);
}

.s-checkout .s-panel > form.s-fields { margin-block-start: 1.25rem; }

.s-checkout .s-panel > form.s-fields > .s-field > strong {
  font-size: var(--s-text-md);
  color: var(--s-brand-800);
}

/*
 * The order page's secondary actions.
 *
 * Tax invoice, Cancel, Return — three navy blocks stacked under one another,
 * each as loud as the next. They are all things a customer may want and none
 * of them is *the* thing to do, so they read as a quiet set instead.
 */
.s-checkout .s-summary .s-btn--block:not(.s-btn--primary) {
  background: #fff;
  border-color: var(--cp-line);
  color: var(--s-brand-800);
  font-weight: 700;
  transition: background-color .2s var(--cp-ease), border-color .2s var(--cp-ease), color .2s var(--cp-ease);
}

.s-checkout .s-summary .s-btn--block:not(.s-btn--primary):hover:not(:disabled) {
  background: var(--s-brand-800);
  border-color: var(--s-brand-800);
  color: #fff;
}

.s-checkout .s-summary form + form,
.s-checkout .s-summary form > .s-btn--block { margin-block-start: .6rem; }

/* ==========================================================================
   12  Entrances

   Held to what the hard rules allow: transform and opacity, nothing that
   reflows, and short enough that a shopper who is already scrolling never
   waits on it. Section 13 cancels the lot.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  @keyframes cp-rise {
    from { opacity: 0; translate: 0 14px; }
    to { opacity: 1; translate: 0 0; }
  }

  .s-cartpage .s-line,
  .s-checkout__main > .s-panel,
  .s-summary {
    animation: cp-rise .5s var(--cp-ease) both;
  }

  .s-cartpage .s-line:nth-child(2) { animation-delay: 60ms; }
  .s-cartpage .s-line:nth-child(3) { animation-delay: 120ms; }
  .s-cartpage .s-line:nth-child(4) { animation-delay: 180ms; }
  .s-cartpage .s-line:nth-child(n + 5) { animation-delay: 220ms; }

  .s-checkout__main > .s-panel:nth-child(2) { animation-delay: 70ms; }
  .s-checkout__main > .s-panel:nth-child(3) { animation-delay: 140ms; }
  .s-checkout__main > .s-panel:nth-child(n + 4) { animation-delay: 200ms; }

  .s-summary { animation-delay: 90ms; }

  /* A line that is mid-change must not re-enter on the reload — it settles. */
  .s-cartpage .s-line:has(.is-busy) { animation: none; }

  /* The pass of light across the primary action. */
  @keyframes cp-shine {
    from { translate: -20% 0; opacity: 0; }
    35%  { opacity: 1; }
    to   { translate: 320% 0; opacity: 0; }
  }

  .s-summary .s-btn--primary:hover:not(:disabled)::before {
    animation: cp-shine .85s var(--cp-ease) 1;
  }
}

/* ==========================================================================
   13  Reduced motion cancels every one of them

   Not softened — cancelled. A visitor who has asked their device for less
   movement has asked this shop too, and a checkout is the last screen on which
   to argue about it.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .s-cartpage .s-line,
  .s-cartpage .s-line__thumb,
  .s-cartpage .s-line__body,
  .s-cartpage .s-line__name,
  .s-cartpage .s-line__remove,
  .s-cartpage .s-qty__btn,
  .s-cartpage .s-qty__btn.is-busy::after,
  .s-checkout__main > .s-panel,
  .s-checkout .s-check--pay,
  .s-checkout .s-check--pay::after,
  .s-checkout .s-field > label,
  .s-checkout .s-offer,
  .s-cartpage .s-offer,
  .s-summary,
  .s-summary .s-btn--primary,
  .s-summary .s-btn--primary::before,
  .s-checkout .s-summary .s-btn--block,
  .s-coupon__row,
  .s-coupon__row .s-btn,
  .s-cartpage .s-offer__action .s-btn,
  .s-checkout .s-offer__action .s-btn,
  .s-coupon__clear {
    animation: none !important;
    transition: none !important;
    translate: none;
    scale: none;
  }

  .s-cartpage .s-line:hover { translate: none; }
  .s-cartpage .s-line:hover .s-line__thumb { scale: none; }
  .s-summary .s-btn--primary:hover:not(:disabled) { translate: none; }
}
