/* The basket in lines: the small basket of a plain stationery shop, in the minimal style. A white page, black ink,
   hairlines and one vermilion kept for the line that strikes a product out. Everything is set in Roboto Flex, a
   variable sans whose width, weight and grade axes the script moves while the figures roll. The lines are placed
   by the script, each on its own spring. To put the basket back where it lives (a drawer on the right of a shop),
   give .stage `justify-items: end` and `align-content: start`. */
:root {
  --page: #ffffff;                  /* the page */
  --ink: #141414;                   /* the words, the figures and the rules */
  --muted: #8b877e;                 /* the small lines under the names and a line struck out */
  --soft: rgba(20, 20, 20, 0.12);   /* the hairlines between the products */
  --accent: #e2432a;                /* the line that strikes a product out, and Undo */
  --label: #ffffff;                 /* the word on the Checkout pill */
  --off: #d9d6cf;                   /* the pill when the basket is empty */
}

* {
  box-sizing: border-box;
}

/* a tap is a click at once: no wait for a double tap */
html {
  touch-action: manipulation;
}

html,
body {
  margin: 0;
  overflow-x: clip;
}

body {
  min-height: 100svh;
  background: var(--page);
  color: var(--ink);
  font-family: 'Roboto Flex Variable', 'Roboto Flex', 'Helvetica Neue', Arial, sans-serif;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
}

/* the basket hangs from the top, near the middle: a line folding away moves its bottom, never its heading */
.stage {
  min-height: 100svh;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  align-content: start;
  padding: max(32px, calc(50svh - 290px)) 16px 40px;
}

button {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

button:focus {
  outline: none;
}

.cart {
  position: relative;
  width: min(440px, 100%);
}

/* ---------------------------------------------------------------- the heading */
.cart__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 14px;
}

.cart__title {
  margin: 0;
  font-size: 26px;
  font-weight: 640;
  font-stretch: 72%;
  line-height: 1;
  letter-spacing: -0.01em;
}

.cart__side {
  display: flex;
  align-items: center;
  gap: 16px;
}

.cart__count {
  display: flex;
  align-items: center;
  gap: 0.3em;
  margin: 0;
  color: var(--muted);
  font-size: 13px;
  font-weight: 450;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.cart__rule {
  display: block;
  height: 1px;
  background: var(--ink);
  transform-origin: 0 50%;
}

/* Undo: it stays a few seconds after a product goes, the hairline under it says how long */
.undo {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 0 5px;
  color: var(--accent);
  font-size: 13px;
  font-weight: 560;
  line-height: 1;
}

.undo[hidden] {
  display: none;
}

.undo__icon {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.45s cubic-bezier(0.3, 1.7, 0.5, 1);
}

.undo__word {
  display: block;
  font-stretch: 100%;
  transition: font-stretch 0.45s cubic-bezier(0.3, 1.7, 0.5, 1);
}

.undo__time {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: currentColor;
  transform-origin: 0 50%;
}

@media (hover: hover) {
  .undo:hover .undo__icon {
    transform: rotate(-40deg);
  }

  .undo:hover .undo__word {
    font-stretch: 118%;
  }
}

.undo:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 4px;
  border-radius: 2px;
}

/* ---------------------------------------------------------------- the lines */
/* the lines are absolute: the script writes where each one is (its spring) and how tall the list is */
.lines {
  position: relative;
}

.lines__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.lines__empty {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  margin: 0;
  padding: 26px 0;
  color: var(--muted);
  font-size: 15px;
  opacity: 0;
  pointer-events: none;
}

.line {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  perspective: 900px;
}

/* a line: the name with its size under it, the quantity, the price and the sign to take it away; the quantity, the
   price and the sign stand on the name's line, which is as tall as the buttons */
.line__body {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto 4.7em 28px;
  column-gap: 12px;
  align-items: start;
  padding: 12px 0 14px;
  border-bottom: 1px solid var(--soft);
  background: var(--page);
}

.line__text {
  min-width: 0;
}

.line__name {
  margin: 0;
  overflow: hidden;
  font-size: 16px;
  font-weight: 520;
  font-stretch: 92%;
  line-height: 32px;
  white-space: nowrap;
  text-overflow: ellipsis;
  transition: color 0.35s ease;
}

.line__sub {
  margin: -3px 0 0;
  color: var(--muted);
  font-size: 13px;
  font-weight: 400;
  line-height: 16px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.line__price {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  height: 32px;
  margin: 0;
  font-size: 16px;
  font-weight: 520;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  transition: color 0.35s ease;
}

.line.is-struck .line__name,
.line.is-struck .line__price {
  color: var(--muted);
}

.line.is-struck .qty,
.line.is-struck .line__x {
  opacity: 0.35;
}

/* the hairline that strikes a product out: drawn from the left by GSAP across the name's line */
.line__strike {
  position: absolute;
  left: -4px;
  right: 34px;
  top: 28px;
  height: 1.5px;
  background: var(--accent);
  transform-origin: 0 50%;
  transform: scaleX(0);
  pointer-events: none;
}

/* the two halves of a line that folds shut: copies of the line, each showing half of it */
.half {
  position: absolute;
  left: 0;
  right: 0;
  overflow: hidden;
  backface-visibility: hidden;
  pointer-events: none;
  transform-origin: 50% 0;
}

.half::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--ink);
  opacity: var(--shade, 0);
}

.half > .line__body {
  position: absolute;
  left: 0;
  right: 0;
}

/* the quantity: minus, the figure, plus */
.qty {
  display: flex;
  align-items: center;
  height: 32px;
  transition: opacity 0.35s ease;
}

.qty__b {
  position: relative;
  display: grid;
  place-items: center;
  width: 30px;
  height: 32px;
  color: var(--ink);
}

.qty__b svg {
  width: 12px;
  height: 12px;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  transition: transform 0.4s cubic-bezier(0.3, 1.8, 0.5, 1);
}

/* the ring that shows a press: thin, and only for a moment */
.qty__b::before,
.line__x::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  border: 1px solid var(--ink);
  border-radius: 50%;
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.3s ease, transform 0.45s cubic-bezier(0.3, 1.6, 0.5, 1);
  pointer-events: none;
}

.qty__b.is-pressed::before,
.line__x.is-pressed::before {
  opacity: 0.22;
  transform: scale(1);
  transition-duration: 0.08s, 0.3s;
}

.qty__b[aria-disabled='true'] {
  color: var(--soft);
  cursor: default;
}

.qty__n {
  position: relative;
  top: 1px;
  min-width: 14px;
  font-size: 15px;
  font-weight: 560;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.qty__n .roll {
  justify-content: center;
}

/* the sign to take a product away */
.line__x {
  position: relative;
  display: grid;
  place-items: center;
  width: 28px;
  height: 32px;
  color: var(--muted);
  transition: color 0.25s ease, opacity 0.35s ease;
}

.line__x svg {
  width: 10px;
  height: 10px;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  transition: transform 0.5s cubic-bezier(0.3, 1.7, 0.5, 1);
}

@media (hover: hover) {
  .qty__b:not([aria-disabled='true']):hover svg {
    transform: scale(1.35);
  }

  .line__x:hover {
    color: var(--accent);
  }

  .line__x:hover svg {
    transform: rotate(90deg);
  }
}

.qty__b:active:not([aria-disabled='true']) svg {
  transform: scale(0.8);
}

.qty__b:focus-visible::before,
.line__x:focus-visible::before {
  opacity: 1;
  transform: scale(1);
}

/* ---------------------------------------------------------------- the rolling figures */
/* a figure is a row of cells: a digit cell is a window on a strip of digits, as wide as one digit */
.roll {
  display: inline-flex;
  align-items: flex-start;
  white-space: nowrap;
}

.c {
  display: block;
  height: 1.3em;
  line-height: 1.3em;
  overflow: hidden;
}

.d {
  position: relative;
  width: var(--dw, 0.56em);
  -webkit-mask-image: linear-gradient(transparent, #000 16%, #000 84%, transparent);
  mask-image: linear-gradient(transparent, #000 16%, #000 84%, transparent);
}

.d__strip {
  display: block;
  will-change: transform;
}

.d__strip > span {
  display: block;
  height: 1.3em;
  text-align: center;
}

/* ---------------------------------------------------------------- the sum */
.sum {
  padding-top: 14px;
}

/* the rule of the sum, as in a column added up by hand: as wide as the total, with a small plus on its left */
.sum__rule {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  height: 10px;
  margin-right: 40px;
}

.sum__plus {
  width: 9px;
  height: 9px;
  flex: none;
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.2;
  stroke-linecap: round;
}

.sum__line {
  display: block;
  width: 96px;
  height: 1px;
  background: var(--ink);
  transform-origin: 100% 50%;
}

.sum__total {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin: -2px 40px 0 0;
}

.sum__label {
  font-size: 15px;
  font-weight: 560;
  font-stretch: 92%;
}

.sum__figure {
  display: inline-flex;
  align-items: flex-start;
  font-size: 44px;
  font-weight: 420;
  font-stretch: 78%;
  line-height: 1.3;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

.sum__cur {
  display: block;
  margin-right: 0.04em;
}

.sum__note {
  margin: 2px 0 0;
  color: var(--muted);
  font-size: 13px;
}

/* ---------------------------------------------------------------- Checkout: the elastic pill */
/* the fill and the word are moved by the script, on springs: the fill swells past its edges and the word widens on
   the width axis */
.go {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  height: 56px;
  margin-top: 22px;
  border-radius: 999px;
  color: var(--label);
  isolation: isolate;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}

.go__fill {
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--ink);
  transition: background-color 0.3s ease;
}

.go__label {
  display: block;
  font-size: 16px;
  font-weight: 600;
  font-variation-settings: 'wdth' 100;
  letter-spacing: 0.01em;
  line-height: 1;
}

.go:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 5px;
}

.go[aria-disabled='true'] {
  cursor: default;
}

.go[aria-disabled='true'] .go__fill {
  background: var(--off);
}

/* the rings of the focus show for the keys, not after a finger or the mouse */
html[data-using='pointer'] .qty__b:focus-visible::before,
html[data-using='pointer'] .line__x:focus-visible::before {
  opacity: 0;
}

html[data-using='pointer'] .go:focus-visible,
html[data-using='pointer'] .undo:focus-visible {
  outline: none;
}

.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------------------------------------------------------------- a phone: the same, a little tighter */
@media (max-width: 480px) {
  .line__body {
    grid-template-columns: minmax(0, 1fr) auto 4.5em 26px;
    column-gap: 8px;
  }

  .line__name {
    font-size: 15px;
  }

  .line__price {
    font-size: 15px;
  }

  .line__x {
    width: 26px;
  }

  .qty__b {
    width: 28px;
  }

  .sum__rule,
  .sum__total {
    margin-right: 34px;
  }

  .sum__figure {
    font-size: 38px;
  }
}
