/**
 * Wishlist button and page (snippets/wishlist-button.liquid,
 * sections/wishlist.liquid).
 */

/* Hidden without JavaScript. The list lives in localStorage, so with no script
   this is a button that cannot do its job - and a control that silently
   ignores you is worse than one that was never offered. */
html:not(.js) .wishlist-btn,
html:not(.js) .header__wishlist {
  display: none;
}

.wishlist-btn {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--color-line);
  border-radius: 50%;
  background-color: var(--color-bg);
  color: var(--color-ink);
  cursor: pointer;
}

/* Both hearts share one cell and cross-fade. A single path cannot morph
   between outline and filled in CSS, and swapping the markup would mean
   re-rendering the button every time it is pressed. */
.wishlist-btn__icon {
  grid-area: 1 / 1;
}

.wishlist-btn__icon--filled {
  opacity: 0;
  scale: 0.6;
  color: var(--color-brand);
}

.wishlist-btn__icon--outline {
  opacity: 1;
  scale: 1;
}

.wishlist-btn.is-saved .wishlist-btn__icon--filled {
  opacity: 1;
  scale: 1;
}

.wishlist-btn.is-saved .wishlist-btn__icon--outline {
  opacity: 0;
  scale: 0.6;
}

.wishlist-btn.is-saved {
  border-color: var(--color-brand);
}

.wishlist-btn:hover {
  border-color: var(--color-ink);
}

.wishlist-btn:focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: 2px;
}

/* The press bounce, same as the social icons: a tap should feel like it
   landed. Quick and linear on the way down because the finger is already
   moving; the release springs back through an overshoot curve, which is what
   reads as a bounce. */
@media (prefers-reduced-motion: no-preference) {
  .wishlist-btn {
    transition: transform 450ms cubic-bezier(0.34, 1.56, 0.64, 1),
      border-color 200ms ease;
  }

  .wishlist-btn__icon {
    transition: opacity 220ms ease, scale 320ms cubic-bezier(0.34, 1.56, 0.64, 1);
  }

  .wishlist-btn:active {
    transform: scale(0.86);
    transition-duration: 90ms;
    transition-timing-function: ease-out;
  }
}

/* On a card the heart sits in the corner of the image, over photography, so it
   needs its own ground to stay visible on a dark shot. */
.wishlist-btn--compact {
  position: absolute;
  top: var(--space-2);
  inset-inline-end: var(--space-2);
  z-index: 2;
  width: 32px;
  height: 32px;
  border-color: transparent;
  background-color: rgb(255 255 255 / 88%);
  color: #1f1f21;
}

/* ------------------------------------------------------------------ */
/* Header count                                                        */
/* ------------------------------------------------------------------ */
.header__wishlist {
  position: relative;
}

.header__wishlist-count {
  position: absolute;
  top: -2px;
  inset-inline-end: -2px;
  min-width: 16px;
  height: 16px;
  padding-inline: 4px;
  border-radius: var(--radius-pill);
  background-color: var(--color-brand);
  color: var(--color-bg);
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.header__wishlist-count[hidden] {
  display: none;
}

/* ------------------------------------------------------------------ */
/* The wishlist page                                                   */
/* ------------------------------------------------------------------ */
/* Heading and count share a baseline so the count reads as part of the
   title rather than a line of its own, and the rule under them gives the
   page a top edge - without it the cards float directly under the navbar
   and the page reads as a fragment of something larger. */
.wishlist__header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-4);
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--color-line);
}

.wishlist__heading {
  margin: 0;
}

.wishlist__count {
  margin: 0;
  color: var(--color-muted);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

.wishlist__count[hidden] {
  display: none;
}

/* Fixed column counts rather than auto-fit. auto-fit sizes tracks from the
   number of items, so a wishlist holding one product stretched that card
   across the full page - and auto-fill, the other way round, reserved an
   empty track beside four cards. Naming the counts makes a saved product
   the same size here as it is in every other grid on the site, whether
   there is one of them or nine. */
.wishlist__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6) var(--space-5);
}

@media screen and (min-width: 750px) {
  .wishlist__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media screen and (min-width: 990px) {
  .wishlist__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Shown until the script has had a chance to fill the grid. Without it the
   page flashes "your wishlist is empty" at someone whose wishlist is not
   empty, which is the one message it must never get wrong. */
.wishlist__empty {
  display: none;
  padding-block: var(--space-10);
  text-align: center;
}

.wishlist--empty .wishlist__empty {
  display: block;
}

.wishlist__empty-heading {
  margin: 0 0 var(--space-3);
}

/* Held to a comfortable measure and centred: full-width centred text is
   hard to track back to the start of the next line. */
.wishlist__empty-text {
  max-width: 42ch;
  margin: 0 auto var(--space-6);
  color: var(--color-muted);
}

/* Save burst: a brand ring spreads out from the heart and fades
   (assets/wishlist.js adds .is-bursting on a save). */
@media (prefers-reduced-motion: no-preference) {
  .wishlist-btn.is-bursting {
    animation: wishlist-burst 600ms ease-out;
  }
}

@keyframes wishlist-burst {
  0% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-brand) 55%, transparent);
  }

  100% {
    box-shadow: 0 0 0 12px color-mix(in srgb, var(--color-brand) 0%, transparent);
  }
}
