/* ==========================================================================
   Korjin — product page (pdp / pitch / xsell). Ported from source
   css/pages/product.css. Tokens only — no literal colours (see tokens.css).
   ========================================================================== */

/* ---- layout ---------------------------------------------------------------- */

.pdp {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: var(--sp-8);
  align-items: start;
  padding-block: var(--sp-5) var(--sp-9);
}

/* ---- gallery ---------------------------------------------------------------- */

.pdp__gallery {
  position: sticky;
  top: calc(var(--header-h) + var(--sp-4));
}

/* --pdp-ratio is the section's Gallery shape. Photographs are fitted, not
   covered: with a square frame and cover, every 3:2 shot lost a third of its
   width (Justin, 6 Oct). */
.pdp__stage {
  position: relative;
  aspect-ratio: var(--pdp-ratio, 1);
  overflow: hidden;
  background: var(--ground-sunken);
}

.pdp__stage img,
.pdp__stage video {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* The stage photo opens the lightbox (Leo, 21 Oct). */
.pdp__zoom {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}

.pdp__zoom:focus-visible {
  outline: 2px solid var(--accent-surface);
  outline-offset: -2px;
}

/* One equal column per picture, so the row runs the stage's full width
   instead of stopping short of its right edge. */
.pdp__thumbs {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: var(--sp-2);
  margin-top: var(--sp-3);
  min-height: 64px; /* reserved — thumbs are rendered by pdp.js */
}

/* ---- swipe gallery (mobile) + lightbox ------------------------------------- */

.pdp__swipe {
  display: none;
}

.pdp__track {
  display: flex;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.pdp__track::-webkit-scrollbar {
  display: none;
}

.pdp__slide {
  flex: 0 0 100%;
  scroll-snap-align: center;
  aspect-ratio: var(--pdp-ratio, 1);
  background: var(--ground-sunken);
}

.pdp__slide img,
.pdp__slide video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.pdp__dots {
  display: flex;
  justify-content: center;
  gap: var(--sp-1);
  margin-top: var(--sp-3);
}

/* 7px dot, 24px target — WCAG 2.5.8 comes from the button, not the mark. */
.pdp__dots button {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
}

.pdp__dots button::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--rule-strong);
  transition: background var(--dur-fast) var(--ease-out);
}

.pdp__dots button[aria-selected="true"]::before {
  background: var(--accent-surface);
}

.pdp__lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  background: var(--ground);
  display: grid;
  grid-template-rows: 1fr auto;
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}

.pdp__lightbox.is-open {
  opacity: 1;
}

.pdp__lightbox[hidden] {
  display: none;
}

.pdp__lightbox-close {
  position: absolute;
  top: var(--sp-3);
  right: var(--sp-3);
  z-index: 1;
}

/* min-height:0 is load-bearing: as a grid item this defaults to min-height:auto,
   which lets the track grow to its tallest image instead of being bounded by
   the 1fr row — a portrait packshot then overflows past the dots. */
.pdp__lightbox-track {
  height: 100%;
  min-height: 0;
}

/* Uncropped here — the point of opening it full-screen is to see the whole
   frame, which is the opposite of the square cover crop in the track. The
   picture keeps its own box, centred, so the space around it is empty and a
   click there closes the lightbox. */
.pdp__lightbox-track .pdp__slide {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  aspect-ratio: auto;
  background: none;
  padding: var(--sp-8) var(--sp-3) 0;
}

.pdp__lightbox-track .pdp__slide img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

/* Previous / next, beside the picture. On phones the track is swiped. */
.pdp__lightbox-nav {
  position: absolute;
  top: 50%;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  margin-top: -24px;
  border: 1px solid var(--rule-strong);
  border-radius: 50%;
  background: var(--ground);
  color: var(--ink);
  transition: border-color var(--dur-fast) var(--ease-out);
}

.pdp__lightbox-nav:hover,
.pdp__lightbox-nav:focus-visible {
  border-color: var(--accent-surface);
}

.pdp__lightbox-nav svg {
  width: 20px;
  height: 20px;
}

.pdp__lightbox-nav--prev {
  left: var(--sp-4);
}

.pdp__lightbox-nav--next {
  right: var(--sp-4);
}

.pdp__lightbox-nav[hidden] {
  display: none;
}

.pdp__lightbox .pdp__dots {
  margin: 0;
  padding-block: var(--sp-4) var(--sp-6);
}

/* Thumbnails take the frame's shape too, so each shows its whole picture. */
.pdp__thumbs button {
  position: relative;
  width: 100%;
  aspect-ratio: var(--pdp-ratio, 1);
  overflow: hidden;
  border: 1px solid transparent;
  background: var(--ground-sunken);
  transition: border-color var(--dur-fast) var(--ease-out);
}

.pdp__thumbs button img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pdp__thumbs button[aria-selected="true"] {
  border-color: var(--accent-surface);
}

.pdp__play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
}

/* solid disc so the glyph reads over any frame, light or dark */
.pdp__play::before {
  content: "▶";
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  padding-left: 2px;
  border-radius: 50%;
  background: var(--korjin-black);
  color: var(--korjin-cream);
  font-size: var(--label-size);
}

/* ---- panel ---------------------------------------------------------------- */

.pdp__panel .eyebrow {
  margin-bottom: var(--sp-3);
}

.pdp__reviews {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
  color: var(--ink-muted);
  border-bottom: 1px solid transparent;
}

.pdp__reviews:hover {
  color: var(--accent-text);
  border-bottom-color: currentcolor;
}

.pdp__stars {
  letter-spacing: 0.1em;
  color: var(--gold-text);
}

.pdp__lede {
  margin-block: var(--sp-4) var(--sp-5);
  max-width: 52ch;
}

.pdp__buybox > * + * {
  margin-top: var(--sp-4);
}

/* The footer's "Bundles" and "Subscriptions" links land on #buy; clear the
   sticky bar and header. */
.pdp__buybox {
  scroll-margin-top: calc(var(--header-h) + var(--announce-h) + var(--sp-4));
}

.pdp__interval[hidden] {
  display: none;
}

.pdp__interval .label {
  margin-bottom: var(--sp-2);
}

.pdp__interval .pdp__interval-row + .label {
  margin-top: var(--sp-4);
}

.pdp__interval-row {
  display: flex;
  gap: var(--sp-2);
  min-height: 45px; /* reserved — rendered by pdp.js */
}

.pdp__interval-row button {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  padding: var(--sp-3) var(--sp-2);
  border: 1px solid var(--rule-strong);
  font-size: var(--step--1);
  transition: border-color var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

.pdp__interval-row button[aria-checked="true"] {
  background: var(--ground-inverse);
  border-color: var(--ground-inverse);
  color: var(--ink-inverse);
}

.pdp__interval-row button[aria-checked="true"] .muted {
  color: inherit;
  opacity: 0.72;
}

.buy__variant-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: var(--sp-3);
}

.buy__variant {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--rule);
  text-align: center;
}

.buy__variant[aria-checked="true"] {
  border-color: var(--gold-line);
  background: var(--ground-raised);
}

.buy__variant-row:has(.buy__variant--alt) {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}

.buy__variant--alt {
  flex-direction: row;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border: 0;
  border-top: 1px solid var(--rule);
  text-align: left;
  color: var(--ink-muted);
}

/* The other pack, under the buttons: a line that switches the box to it. */
.buy__variant--alt:hover,
.buy__variant--alt:focus-visible {
  color: var(--ink);
  border-top-color: var(--gold-line);
}

/* A pack with nothing to choose still names itself where the purchase types
   would be. It is a statement, not a control. */
.buy__plan--solo {
  cursor: default;
}

.buy__variant[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
  text-decoration: line-through;
  text-decoration-color: var(--rule-strong);
}

/* AtC dominance (UPLIFT-0791): primary solid + full width; express ghost */
.pdp__cta {
  width: 100%;
  padding-block: 1.25rem;
}

.pdp__express {
  width: 100%;
  color: var(--ink-muted);
}

.pdp__delivery {
  text-align: center;
  color: var(--ink-muted);
}

.pdp__delivery strong {
  color: var(--ink);
  font-weight: 500;
}

.pdp__assurances {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
  list-style: none;
  padding: var(--sp-4) 0 0;
  border-top: 1px solid var(--rule);
}

.pdp__assurances a {
  border-bottom: 1px solid currentcolor;
}

.pdp__assurances a:hover {
  color: var(--accent-text);
}

/* prototype-only control */
.pdp__state-demo {
  display: block;
  margin-inline: auto;
  color: var(--ink-faint);
  font-size: var(--label-xs);
  border: 1px dashed var(--rule-strong);
  padding: var(--sp-2) var(--sp-3);
}

.pdp__state-demo:hover {
  color: var(--ink-muted);
}

/* ---- phases strip ---------------------------------------------------------- */

.pdp__phases {
  margin-top: var(--sp-6);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--rule);
}

.pdp__phases > .label {
  margin-bottom: var(--sp-3);
}

.pdp__phase-row {
  display: flex;
  gap: var(--sp-3);
  list-style: none;
  padding: 0;
}

.pdp__phase-row li {
  flex: 1;
  text-align: center;
}

.pdp__phase-row img {
  /* transparent packshot — contain so the box isn't cropped, and no
     placeholder ground behind it (see tools/cutout-packshots.py) */
  aspect-ratio: 3 / 4;
  width: 100%;
  object-fit: contain;
  margin-bottom: var(--sp-2);
}

/* ---- accordions ---------------------------------------------------------- */

.pdp__accordions {
  margin-top: var(--sp-6);
  border-top: 1px solid var(--rule);
}

.pdp__acc {
  border-bottom: 1px solid var(--rule);
}

.pdp__acc summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-4) 0;
  cursor: pointer;
  list-style: none;
  color: var(--ink);
}

.pdp__acc summary::-webkit-details-marker {
  display: none;
}

.pdp__acc summary::after {
  content: "+";
  font-family: var(--font-display);
  font-size: var(--step-2);
  color: var(--accent-text);
  line-height: 1;
}

.pdp__acc[open] summary::after {
  content: "−";
}

.pdp__acc-body {
  padding-bottom: var(--sp-5);
  max-width: 56ch;
}

.pdp__acc-body p + p {
  margin-top: var(--sp-3);
}

/* supplement facts table */
.facts {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid var(--rule-strong);
  margin-bottom: var(--sp-3);
}

.facts th,
.facts td {
  text-align: left;
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--rule);
}

.facts th:last-child,
.facts td:last-child,
.facts th:nth-child(2),
.facts td:nth-child(2) {
  text-align: right;
  white-space: nowrap;
}

.facts thead th {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--label-size);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.facts tfoot td {
  font-size: var(--label-size);
  color: var(--ink-faint);
  border-bottom: none;
}

/* ---- sticky bar ---------------------------------------------------------- */

.stickybar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-header);
  background: var(--ground-raised);
  border-top: 1px solid var(--rule);
  box-shadow: var(--shadow-soft);
  animation: stickybar-in var(--dur) var(--ease-out);
}

@keyframes stickybar-in {
  from { transform: translateY(100%); }
}

.stickybar__in {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding-block: var(--sp-3);
}

.stickybar img {
  width: 44px;
  height: 44px;
  object-fit: cover;
  background: var(--ground-sunken);
}

.stickybar__name {
  flex: 1;
}

.stickybar__price {
  color: var(--ink-muted);
  font-size: var(--step--1);
}

.stickybar .btn {
  padding-block: 0.8125rem;
}

/* ---- pitch (marketing band) ------------------------------------------------ */

.pitch__grid {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: var(--sp-8);
  align-items: start;
}

.pitch__grid .title-xl {
  margin-top: var(--sp-3);
}

.pitch__cells {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.pitch__cells > div {
  padding-block: var(--sp-5);
  border-top: 1px solid var(--band-dark-rule);
}

.pitch__cells .title-sm {
  margin-bottom: var(--sp-2);
}

/* ---- cross-sell ---------------------------------------------------------------- */

.xsell__grid {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: var(--sp-8);
  align-items: center;
}

.xsell__grid img {
  aspect-ratio: 4 / 3;
  width: 100%;
  object-fit: cover;
}

.xsell__grid .title-lg {
  margin-block: var(--sp-2) var(--sp-4);
}

.xsell__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-4) var(--sp-5);
  margin-top: var(--sp-5);
}

/* ---- responsive ---------------------------------------------------------------- */

@media (max-width: 860px) {
  .pdp {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-6);
  }

  .pdp__gallery {
    position: static;
  }

  /* stage + thumb grid give way to the swipe track */
  .pdp__stage,
  .pdp__thumbs {
    display: none;
  }

  /* …and the swipe track is built by JS, so between first paint and the
     module running this column has NO height at all: the buy panel below it
     was laid out 389px too high and then pushed down, which is most of the
     product page's mobile CLS. Reserve the track's own shape — a square slide
     plus the dot row — and drop the reservation the moment the track exists. */
  .pdp__gallery:not(:has(.pdp__swipe))::before {
    content: "";
    display: block;
    aspect-ratio: var(--pdp-ratio, 1);
    margin-bottom: calc(24px + var(--sp-3));
    background: var(--ground-sunken);
  }

  .pdp__swipe {
    display: block;
  }

  .pdp__lightbox-nav {
    display: none;
  }

  .pitch__grid,
  .xsell__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-6);
  }

  .stickybar__name {
    display: none;
  }
}

/* The in-the-box strip is a benefit list now, not three packshots. */
.pdp__benefit-row {
  list-style: none;
  margin: var(--sp-3) 0 var(--sp-4);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-3);
}

.pdp__benefit-row li {
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--rule);
  color: var(--ink-muted);
}
