/*
 * A set's parts (src/Sets/View/Parts.php), which both blocks that show sets draw, the Product Sets block
 * (plugin/blocks/sets/style.css) and the Product Set Hero (plugin/blocks/set-hero/style.css), each laying them out in
 * its own stylesheet; both blocks carry `lanternwp-sets`. A set's photo is on `media` with `radius.media`. A
 * point is a 32px `base` disc with the item's number, ringed in `base` at 40%, its target 44px, in a spot beside its
 * card; on hover or keyboard focus it shows the card, the product's thumbnail, its name as a link stretched over the
 * card, the values its row shows and its price, which fades and lifts in on `motion.fast` (above the point, or below
 * it where the module finds no room above; shifted between the photo's sides in its container units; never on a touch
 * screen) and stays open while the pointer crosses into it. As the set enters the screen its points arrive one after
 * another, on `motion.slow` (the module's `is-waiting` and `is-arriving`). A point and its row are one product: the
 * module lights both (`is-lit`: the point filled in `contrast`, the row's name underlined and its number filled) and
 * dims the other points; a click on a point holds it (`is-held`): its card open and its row marked by a `contrast`
 * ring inside its thumbnail, as a link to the row marks it without the module (`:target`). Each
 * item is a row between lines: the box that keeps it in the set, a 72px thumbnail with its number on it, its name in
 * `sm` semibold with This item on the page's own product, what the set pins in `xs` and `muted`, a small select per
 * option it leaves to the shopper, and its price for its quantity with the price of one under it; a sold-out row is
 * `muted`, with Sold out and Notify me. The button is the theme's button across the column, with a message under it
 * only when something went wrong. A phone opens a product in a sheet from the bottom of the screen.
 * The interaction roles are the theme's (docs/design-tokens.html#roles): a point is a control, the names are plain
 * links, the boxes and selects are fields.
 */

/* A set's tile links to it on a product page (Sets\View\Tile): keep it clear of the window's edge. */
.lanternwp-sets__set {
  container: lanternwp-set / inline-size;
  margin: 0;
  scroll-margin-block-start: var(--wp--preset--spacing--60);
}

.lanternwp-sets__photo {
  container: lanternwp-sets-photo / inline-size;
  position: relative;
  margin: 0;
  border-radius: var(--wp--custom--radius--media);
  background: var(--wp--custom--color--media);

  & .lanternwp-sets__picture {
    display: block;
    inline-size: 100%;
    block-size: 100%;
    border-radius: inherit;
    object-fit: cover;
  }
}

/* A point's spot: no size of its own, at the point's middle on the photo, so the point and its card stand round it. */
.lanternwp-sets__spot {
  --lanternwp-point: 32px;
  --lanternwp-target: 44px;

  position: absolute;

  /* Lit or held, the disc grows by 15% in size rather than by `scale`, which would grow its card with it. */
  &:has(> .is-lit) {
    --lanternwp-point: 37px;
  }

  /* Above the other points and cards: the one under the pointer or the focus, then the held one. */
  &.is-held {
    z-index: 1;
  }

  &:is(:hover, :focus-within) {
    z-index: 2;
  }
}

/* Physical, as the spot's place on the photo: the point's middle on the spot. */
.lanternwp-sets .lanternwp-sets__point {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  inline-size: var(--lanternwp-point);
  block-size: var(--lanternwp-point);
  border-radius: 50%;
  background: var(--wp--preset--color--base);
  color: var(--wp--preset--color--contrast);
  font-size: var(--wp--preset--font-size--xs);
  font-weight: var(--wp--custom--weight--bold);
  line-height: var(--lanternwp-point);
  text-align: center;
  text-decoration: none;
  outline: 4px solid color-mix(in srgb, var(--wp--preset--color--base) 40%, transparent);
  box-shadow: inset 0 0 0 100vmax color-mix(in srgb, currentcolor var(--lanternwp-tint, 0%), transparent);
  translate: -50% -50%;
  transition-property: --lanternwp-tint, inline-size, block-size, line-height, scale, opacity, background-color, color;
  transition-duration: var(--wp--custom--motion--fast);
  transition-timing-function: var(--wp--custom--motion--easing);

  /* The target: 44px around the 32px disc. */
  &::before {
    content: '';
    position: absolute;
    inset: calc((var(--lanternwp-point) - var(--lanternwp-target)) / 2);
    border-radius: 50%;
  }

  &.is-lit {
    background: var(--wp--preset--color--contrast);
    color: var(--wp--preset--color--base);
  }

  &:focus-visible {
    outline: 2px solid var(--wp--preset--color--contrast);
    outline-offset: 2px;
  }

  &:active {
    scale: var(--wp--custom--interaction--press);
  }
}

.is-lighting .lanternwp-sets__point:not(.is-lit) {
  opacity: 0.6;
}

/* The card is centred on its point and shifts to keep 0.5rem inside the photograph: the point's place across it
   (`--lanternwp-x`, 0 to 100) in the photograph's container units. The picture stands level with the name's first
   line, however many lines the name takes. Open, it takes the pointer: its name's link stretches over it, and a
   bridge as wide as it spans the gap to the point, so the pointer goes from the point into it without closing it.
   Physical across, as the spot's place on the photo. */
.lanternwp-sets__card {
  --lanternwp-shift: clamp(
    calc(0.5rem - var(--lanternwp-x, 50) * 1cqi),
    -50%,
    calc(100cqi - 100% - 0.5rem - var(--lanternwp-x, 50) * 1cqi)
  );
  --lanternwp-card-gap: var(--wp--preset--spacing--20);

  position: absolute;
  inset-block-end: calc(var(--lanternwp-point) / 2 + var(--lanternwp-card-gap));
  left: 0;
  display: flex;
  align-items: flex-start;
  gap: var(--wp--preset--spacing--30);
  box-sizing: border-box;
  inline-size: max-content;
  max-inline-size: min(16rem, 100cqi - 1rem);
  padding: var(--wp--preset--spacing--20) var(--wp--preset--spacing--30) var(--wp--preset--spacing--20)
    var(--wp--preset--spacing--20);
  border-radius: var(--wp--custom--radius--panel);
  background: var(--wp--preset--color--base);
  box-shadow: var(--wp--preset--shadow--md);
  color: var(--wp--preset--color--contrast);
  font-weight: var(--wp--custom--weight--regular);
  line-height: var(--wp--custom--line-height--normal);
  text-align: start;
  visibility: hidden;
  opacity: 0;
  translate: var(--lanternwp-shift) var(--wp--preset--spacing--10);
  pointer-events: none;
  transition:
    opacity var(--wp--custom--motion--fast) var(--wp--custom--motion--easing-exit),
    translate var(--wp--custom--motion--fast) var(--wp--custom--motion--easing-exit),
    visibility 0s linear var(--wp--custom--motion--fast);

  &::before {
    content: '';
    position: absolute;
    inset-block: 100% calc(-1 * var(--lanternwp-card-gap) - var(--wp--preset--spacing--10));
    inset-inline: 0;
  }

  & img {
    flex: none;
    inline-size: 3rem;
    block-size: auto;
    aspect-ratio: var(--wp--custom--media--product-ratio, 1);
    border-radius: var(--wp--custom--radius--media);
    background: var(--wp--custom--color--media);
    object-fit: cover;
  }
}

/* A touch screen has no hover: a tap opens the product's sheet, so the card takes no room off the screen's edge. */
@media (hover: none) {
  .lanternwp-sets__card {
    display: none;
  }
}

.lanternwp-sets__card-text {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--10);
  min-inline-size: 0;
  font-size: var(--wp--preset--font-size--sm);
}

/* The name, a plain link stretched over the card. On two lines it splits them evenly and keeps them close, as a heading
   does. */
.lanternwp-sets .lanternwp-sets__card-name {
  color: inherit;
  font-weight: var(--wp--custom--weight--semibold);
  line-height: var(--wp--custom--line-height--snug);
  text-decoration-line: underline;
  text-decoration-color: transparent;
  text-underline-offset: 3px;
  text-wrap: balance;
  transition: text-decoration-color var(--wp--custom--motion--fast) var(--wp--custom--motion--easing);

  &::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
  }
}

.lanternwp-sets__card-values {
  color: var(--wp--preset--color--muted);
  font-size: var(--wp--preset--font-size--xs);

  &[hidden] {
    display: none;
  }
}

.lanternwp-sets__card-price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 var(--wp--preset--spacing--20);
}

.is-below > .lanternwp-sets__card {
  inset-block: calc(var(--lanternwp-point) / 2 + var(--lanternwp-card-gap)) auto;

  &::before {
    inset-block: calc(-1 * var(--lanternwp-card-gap) - var(--wp--preset--spacing--10)) 100%;
  }
}

/* Open: under the pointer, held by a click, or on a point or a link of its in focus from the keyboard; not after
   Escape until the pointer or the focus leaves it (`is-dismissed`). */
@media (hover: hover) {
  .lanternwp-sets .lanternwp-sets__point:hover {
    --lanternwp-tint: var(--wp--custom--interaction--tint);
  }

  .lanternwp-sets__spot:not(.is-dismissed):hover > .lanternwp-sets__card {
    visibility: visible;
    opacity: 1;
    translate: var(--lanternwp-shift) 0;
    pointer-events: auto;
    transition:
      opacity var(--wp--custom--motion--fast) var(--wp--custom--motion--easing),
      translate var(--wp--custom--motion--fast) var(--wp--custom--motion--easing),
      visibility 0s linear 0s;
  }
}

.lanternwp-sets__spot:not(.is-dismissed):is(.is-held, :has(:focus-visible)) > .lanternwp-sets__card {
  visibility: visible;
  opacity: 1;
  translate: var(--lanternwp-shift) 0;
  pointer-events: auto;
  transition:
    opacity var(--wp--custom--motion--fast) var(--wp--custom--motion--easing),
    translate var(--wp--custom--motion--fast) var(--wp--custom--motion--easing),
    visibility 0s linear 0s;
}

/* The points before their photo enters the screen, then on their way one after another; the module adds neither under
   reduced motion, and without it the points stand at once. They leave at once: a fade out could end (transitionend)
   after a photo that enters the screen right away has begun to arrive, and the module would take it for the end. Above
   the dimmed points' opacity (lit, sold out), which would otherwise show a waiting point. */
.lanternwp-sets .lanternwp-sets__photo.is-waiting .lanternwp-sets__point {
  opacity: 0;
  scale: 0.5;
  transition: none;
}

.lanternwp-sets__photo.is-arriving .lanternwp-sets__point {
  transition:
    opacity var(--wp--custom--motion--slow) var(--wp--custom--motion--easing),
    scale var(--wp--custom--motion--slow) var(--wp--custom--motion--easing);
  transition-delay: calc(var(--lanternwp-order, 0) * var(--wp--custom--motion--fast) / 2);
}

.lanternwp-sets__side {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--30);
  min-inline-size: 0;
}

.lanternwp-sets__title {
  margin: 0;
  font-size: var(--wp--preset--font-size--lg);
}

.lanternwp-sets__items {
  margin: 0;
  padding: 0;
  border-block-start: 1px solid var(--wp--preset--color--border-subtle);
  list-style: none;
}

.lanternwp-sets__item {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: var(--wp--custom--choice--size, 1.25rem) 4.5rem minmax(0, 1fr) auto;
  gap: var(--wp--preset--spacing--30);
  align-items: center;
  padding-block: var(--wp--preset--spacing--30);
  border-block-end: 1px solid var(--wp--preset--color--border-subtle);
  scroll-margin-block: var(--wp--preset--spacing--60);

  &.is-out {
    color: var(--wp--preset--color--muted);
  }

  &:is(.is-out, .is-excluded) .lanternwp-sets__thumb {
    opacity: 0.5;
  }

  &.is-excluded :is(.lanternwp-sets__name, .lanternwp-sets__price) {
    color: var(--wp--preset--color--muted);
  }
}

.lanternwp-sets__include {
  display: grid;
  place-items: center;

  /* The boards' box, the theme's choice role: 1.5px `border-strong` on the page, the field radius at 0.6, checked a
     `contrast` fill with a `base` tick; hovering darkens an unchecked box's border. */
  & input {
    display: inline-grid;
    place-content: center;
    box-sizing: border-box;
    inline-size: var(--wp--custom--choice--size, 1.25rem);
    block-size: var(--wp--custom--choice--size, 1.25rem);
    margin: 0;
    padding: 0;
    border: 1.5px solid var(--wp--preset--color--border-strong);
    border-radius: calc(var(--wp--custom--radius--field) * 0.6);
    background: var(--wp--preset--color--base);
    cursor: pointer;
    appearance: none;
    transition: border-color var(--wp--custom--motion--fast) var(--wp--custom--motion--easing);

    &:checked {
      border-color: var(--wp--preset--color--contrast);
      background: var(--wp--preset--color--contrast);
    }

    &:checked::before {
      content: '';
      inline-size: 0.875rem;
      block-size: 0.875rem;
      background-color: var(--wp--preset--color--base);
      mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
        center / contain no-repeat;
    }

    &:disabled {
      border-color: var(--wp--preset--color--border-subtle);
      background: var(--wp--preset--color--surface);
      cursor: not-allowed;
    }

    &:focus-visible {
      outline: 2px solid var(--wp--preset--color--contrast);
      outline-offset: 2px;
    }
  }
}

@media (hover: hover) {
  .lanternwp-sets__include:hover input:not(:checked, :disabled) {
    border-color: var(--wp--preset--color--contrast);
  }
}

.lanternwp-sets__thumb {
  position: relative;
  display: block;
  aspect-ratio: var(--wp--custom--media--product-ratio, 1);
  border-radius: var(--wp--custom--radius--media);
  overflow: hidden;
  background: var(--wp--custom--color--media);
  transition: opacity var(--wp--custom--motion--fast) var(--wp--custom--motion--easing);

  & img {
    display: block;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
  }

  /* The row of a held point, or the one a point leads to without the module: a `contrast` ring inside the thumbnail's
     edge with a `base` line inside it, which holds on any photo and any palette, inside its box, which a list that
     scrolls would clip. */
  &::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    box-shadow:
      inset 0 0 0 2px var(--wp--preset--color--contrast),
      inset 0 0 0 4px var(--wp--preset--color--base);
    opacity: 0;
    transition: opacity var(--wp--custom--motion--fast) var(--wp--custom--motion--easing);
  }

  :is(.is-held, :target) > &::after {
    opacity: 1;
  }
}

/* Over the thumbnail's ring. */
.lanternwp-sets__number {
  position: absolute;
  z-index: 1;
  inset-block-start: var(--wp--preset--spacing--10);
  inset-inline-start: var(--wp--preset--spacing--10);
  display: grid;
  place-items: center;
  inline-size: 1.5rem;
  block-size: 1.5rem;
  border-radius: 50%;
  background: var(--wp--preset--color--base);
  color: var(--wp--preset--color--contrast);
  font-size: var(--wp--preset--font-size--2-xs);
  font-weight: var(--wp--custom--weight--bold);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--wp--preset--color--base) 40%, transparent);
  transition:
    background-color var(--wp--custom--motion--fast) var(--wp--custom--motion--easing),
    color var(--wp--custom--motion--fast) var(--wp--custom--motion--easing);

  :is(.is-lit, .is-held, :target) > .lanternwp-sets__thumb & {
    background: var(--wp--preset--color--contrast);
    color: var(--wp--preset--color--base);
  }
}

.lanternwp-sets__info {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--wp--preset--spacing--10);
  min-inline-size: 0;
}

.lanternwp-sets .lanternwp-sets__name {
  color: inherit;
  font-size: var(--wp--preset--font-size--sm);
  font-weight: var(--wp--custom--weight--semibold);
  text-decoration-line: underline;
  text-decoration-color: transparent;
  text-underline-offset: 3px;
  transition: text-decoration-color var(--wp--custom--motion--fast) var(--wp--custom--motion--easing);

  .is-lit > .lanternwp-sets__info > & {
    text-decoration-color: currentcolor;
  }
}

/* The thumbnail opens what the name opens, and says so on the name. */
@media (hover: hover) {
  .lanternwp-sets :is(.lanternwp-sets__name, .lanternwp-sets__card-name):hover,
  .lanternwp-sets .lanternwp-sets__item:has(> .lanternwp-sets__thumb:hover) .lanternwp-sets__name {
    text-decoration-color: currentcolor;
  }
}

.lanternwp-sets__pinned,
.lanternwp-sets__note {
  color: var(--wp--preset--color--muted);
  font-size: var(--wp--preset--font-size--xs);
}

.lanternwp-sets .lanternwp-sets__view {
  color: inherit;
  font-size: var(--wp--preset--font-size--xs);
  text-underline-offset: 3px;
}

.lanternwp-sets__choices {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--wp--preset--spacing--10) var(--wp--preset--spacing--20);
  margin-block-start: var(--wp--preset--spacing--10);

  & .wp-block-lanternwp-option-guide {
    margin: 0;
    font-size: var(--wp--preset--font-size--xs);
    white-space: nowrap;
  }
}

/* The plugin's select (resources/front/select.css) at the board's size: small and semibold beside the product. */
.lanternwp-sets__choice {
  --lanternwp-select-padding: var(--wp--preset--spacing--20);
  --lanternwp-select-icon: 0.375rem;

  max-inline-size: 100%;

  & select {
    min-block-size: 2rem;
    max-inline-size: 100%;
    font: inherit;
    font-size: var(--wp--preset--font-size--xs);
    font-weight: var(--wp--custom--weight--semibold);

    /* A choice missing when the button is pressed: the plugin select's `sale` border and a ring. */
    &[aria-invalid='true'] {
      outline: 2px solid var(--wp--preset--color--sale);
    }
  }
}

.lanternwp-sets__card-price,
.lanternwp-sets__price {
  font-weight: var(--wp--custom--weight--semibold);

  & del {
    color: var(--wp--preset--color--muted);
    font-weight: var(--wp--custom--weight--regular);
  }

  & ins {
    text-decoration: none;
  }
}

.lanternwp-sets__price {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--wp--preset--spacing--10);
  font-size: var(--wp--preset--font-size--sm);
  white-space: nowrap;
}

.lanternwp-sets__each {
  color: var(--wp--preset--color--muted);
  font-size: var(--wp--preset--font-size--xs);
  font-weight: var(--wp--custom--weight--regular);
}

/* The name with This item beside it on the page's own product: the boards' outline badge in the label's type. */
.lanternwp-sets__named {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--wp--preset--spacing--10) var(--wp--preset--spacing--20);
}

.lanternwp-sets__here {
  display: inline-flex;
  align-items: center;
  block-size: 1.5rem;
  padding-inline: var(--wp--preset--spacing--20);
  border-radius: var(--wp--custom--radius--badge);
  background: var(--wp--preset--color--base);
  box-shadow: inset 0 0 0 1px var(--wp--preset--color--border-subtle);
  color: var(--wp--preset--color--muted);
  font-family: var(--wp--custom--label--family);
  font-size: var(--wp--preset--font-size--2-xs);
  font-weight: var(--wp--custom--label--weight, var(--wp--custom--weight--semibold));
  letter-spacing: var(--wp--custom--label--tracking);
  text-transform: var(--wp--custom--label--transform);
  white-space: nowrap;
}

/* A sold-out item's line: Sold out, and Notify me as a small link with its envelope. */
.lanternwp-sets__sold-out {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--wp--preset--spacing--10) var(--wp--preset--spacing--30);
}

.lanternwp-sets .lanternwp-sets__notify {
  display: inline-flex;
  align-items: center;
  gap: var(--wp--preset--spacing--10);
  color: var(--wp--preset--color--contrast);
  font-size: var(--wp--preset--font-size--xs);
  font-weight: var(--wp--custom--weight--semibold);
  text-underline-offset: 3px;

  & svg {
    inline-size: 0.875rem;
    block-size: 0.875rem;
  }
}

.lanternwp-sets__point.is-out:not(.is-lit) {
  opacity: 0.6;
}

.lanternwp-sets__add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--wp--preset--spacing--20);
  inline-size: 100%;

  &[aria-busy='true'] {
    cursor: progress;
  }
}

.lanternwp-sets__status {
  margin: 0;
  color: var(--wp--preset--color--sale);
  font-size: var(--wp--preset--font-size--sm);

  /* A success is said to screen readers only; the cart drawer shows it. */
  &:not(.is-error) {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

.lanternwp-sets__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--wp--preset--spacing--50);
}

.lanternwp-sets__count {
  margin: 0;
  color: var(--wp--preset--color--muted);
  font-size: var(--wp--preset--font-size--xs);
}

/* The sheet a phone opens a product in: the plugin's dialog, from the bottom of the screen. */
.lanternwp-dialog.lanternwp-sets__sheet {
  inline-size: 100%;
  max-inline-size: 32rem;
  margin-block: auto 0;
  border-end-start-radius: 0;
  border-end-end-radius: 0;

  @starting-style {
    translate: 0 100%;
  }
}

.lanternwp-sets__sheet-body {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--40);

  & .lanternwp-sets__item {
    grid-template-columns: 5.5rem minmax(0, 1fr) auto;
    padding-block: 0;
    border: 0;
  }

  & .lanternwp-sets__choice select {
    min-block-size: 2.75rem;
    font-size: var(--wp--preset--font-size--sm);
  }
}

@media (prefers-reduced-motion: reduce) {
  .lanternwp-sets .lanternwp-sets__point,
  .lanternwp-sets__card,
  .lanternwp-sets__thumb,
  .lanternwp-sets__thumb::after,
  .lanternwp-sets__number {
    transition: none;
  }

  .lanternwp-sets__card {
    translate: var(--lanternwp-shift) 0;
  }
}
