/* Product detail page. Figma node 25:1117 ("Сторінка з товаром", 1440x2003):
   a plain-text breadcrumb, a 485x620 tinted cover panel beside the overview,
   then a full-width "Про книгу" block. Everything is on the 1200px container. */

.product-details-page .page-body,
.breadcrumb {
  width: min(100%, calc(var(--container-max) + 2 * var(--gutter)));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ---- Breadcrumb ----
   nopCommerce emits a <ul>; Figma shows one quiet line of text, so the list
   semantics stay for assistive tech while the markers and spacing go. */

.breadcrumb {
  padding-top: var(--space-2xl);
}

.breadcrumb ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

.breadcrumb li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  font-size: var(--font-size-xs);
  color: var(--color-muted);
}

.breadcrumb a {
  color: var(--color-muted);
  text-decoration: none;
}

.breadcrumb a:hover {
  color: var(--color-action);
}

.breadcrumb .current-item {
  color: var(--color-muted);
}

/* ---- Essential: cover panel + overview ---- */

/* Cover and overview are two columns of one grid row, top-aligned. The overview
   previously carried `padding-top: 11rem` to fake the Figma baseline; that put
   176px of dead space above the title, pushed the description below the fold and
   left the tinted panel 191px taller than the text beside it. Alignment does the
   same job without stealing the fold. */
.book-detail__essential {
  /* Shared by the grid and the specs table, whose values line up with the
     overview column above them. */
  --book-detail-cover-width: 30.3125rem; /* 485 */
  --book-detail-column-gap: var(--space-4xl);

  display: grid;
  grid-template-columns: minmax(0, var(--book-detail-cover-width)) minmax(0, 1fr);
  grid-template-areas:
    "gallery overview"
    "specs   specs";
  gap: var(--space-3xl) var(--book-detail-column-gap);
  align-items: start;
  padding-block: var(--space-xl) var(--space-3xl);
}

.book-detail__gallery {
  --gallery-padding: var(--space-xl);

  grid-area: gallery;
  background-color: var(--color-surface);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--gallery-padding);
}

/* The panel's height is its content's, never a cap of its own: a capped panel
   with more content than cap (a book with several photos) spills that content
   over the breadcrumb and specs. The viewport cap is applied to the cover
   instead, less the panel padding and the thumbnail row when there is one, so
   the whole panel still stays within --gallery-max-height. */
.book-detail__gallery .picture-gallery {
  --gallery-cover-max-height: calc(var(--gallery-max-height) - 2 * var(--gallery-padding));

  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  min-width: 0;
  max-width: 100%;
}

.book-detail__gallery .picture-gallery:has(.picture-thumbs) {
  --gallery-cover-max-height: calc(var(--gallery-max-height) - 2 * var(--gallery-padding)
    - var(--gallery-thumb-height) - 2 * var(--space-3xs) - 2 * var(--stroke-control) - var(--space-sm));
}

.book-detail__gallery .picture {
  background: transparent;
  border-radius: 0;
  overflow: visible;
}

.book-detail__gallery .picture img {
  width: auto;
  max-width: 100%;
  max-height: var(--gallery-cover-max-height);
  height: auto;
  display: block;
  margin-inline: auto;
}

/* One button per photo; the one on show carries the accent frame. */
.book-detail__gallery .picture-thumbs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2xs);
}

.book-detail__gallery .thumb-item {
  appearance: none;
  display: block;
  padding: var(--space-3xs);
  border: var(--stroke-control) solid var(--color-border);
  border-radius: var(--radius-sm);
  background-color: var(--color-canvas);
  cursor: pointer;
}

.book-detail__gallery .thumb-item[aria-pressed="true"] {
  border-color: var(--color-action);
}

.book-detail__gallery .thumb-item img {
  display: block;
  width: auto;
  height: var(--gallery-thumb-height);
}

/* ---- Cover, and the lightbox it opens --------------------------------------
   The cover is a button so enlarging works from the keyboard, but it must not
   read as one: no chrome of its own, the photo is the whole control. The
   zoom-in cursor is the affordance on a pointer, the accessible name the one
   everywhere else. */
.book-detail__gallery .picture__zoom {
  appearance: none;
  display: block;
  max-width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: zoom-in;
}

/* A <dialog> is display:none until it opens, so `display` belongs on the open
   state only -- setting it here would show the photo inside the closed page.

   The photo is sized to fit inside the dialog exactly, and a <dialog> scrolls
   whatever does not fit: the photo's height cap is therefore the dialog's own
   cap less the frame around it, padding and border both, from the same two
   properties. Leaving the border out made the dialog two pixels too short for
   a tall cover, and it showed a scrollbar. */
.photo-lightbox {
  --photo-lightbox-max-height: calc(100dvh - var(--gutter) - var(--gutter));
  --photo-lightbox-frame: calc(var(--space-sm) + var(--stroke-hairline));

  width: fit-content;
  max-width: calc(100vw - var(--gutter) - var(--gutter));
  max-height: var(--photo-lightbox-max-height);
  padding: var(--space-sm);
  border: var(--stroke-hairline) solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-canvas);
  box-shadow: var(--shadow-dialog);
}

.photo-lightbox::backdrop {
  background-color: var(--color-dialog-backdrop);
}

.photo-lightbox[open] {
  display: flex;
}

/* The photo is the dialog's only content, so it takes whatever room the
   viewport cap leaves and keeps its aspect ratio inside it. */
.photo-lightbox__image {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: calc(var(--photo-lightbox-max-height) - 2 * var(--photo-lightbox-frame));
  margin: auto;
  object-fit: contain;
}

/* Sits on the photo's top-right corner rather than in a title bar: the dialog
   has no header, and the photo fills it. It stays inside the dialog box so a
   full-height photo cannot push it past the edge of the viewport; the disc is
   what keeps the × legible over a dark image. The mark itself comes from the
   shared close affordance in components.css. */
.photo-lightbox__close,
.photo-lightbox__step {
  position: absolute;
  width: var(--tap-target);
  height: var(--tap-target);
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  background-color: var(--color-canvas);
  box-shadow: var(--shadow-dialog);
  cursor: pointer;
}

.photo-lightbox__close {
  top: var(--space-sm);
  right: var(--space-sm);
}

/* One step per side, centred on the photo. They sit on the image rather than
   outside it: the dialog is only as wide as the photo, and on a phone there is
   no margin to put them in. The chevron mark comes from the shared `.ui-chevron`
   in components.css. */
.photo-lightbox__step {
  --chevron-size: max(0.625rem, 10px); /* 10: a touch larger than the pager's, at tap size */

  top: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translateY(-50%);
}

.photo-lightbox__step--previous {
  left: var(--space-sm);
}

.photo-lightbox__step--next {
  right: var(--space-sm);
}

/* The arrowhead is drawn from borders on a rotated box, so it is optically
   off-centre inside a round button; nudging it back by a quarter of its own
   size sets it on the disc's middle. */
.photo-lightbox__step--previous::after {
  margin-left: calc(var(--chevron-size) * 0.25);
}

.photo-lightbox__step--next::after {
  margin-right: calc(var(--chevron-size) * 0.25);
}

.book-detail__overview {
  grid-area: overview;
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  max-width: 34.6875rem; /* 555 */
}

/* The flex gap owns the rhythm now, so the per-element margins go. */
.book-detail__overview .product-name h1,
.book-detail__overview .manufacturers,
.book-detail__overview .short-description {
  margin: 0;
}

/* Figma: title Raleway 700 / 30, leading 1.17. */
.book-detail__overview .product-name h1 {
  font-size: var(--font-size-3xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
}

/* Figma: author Raleway 400 / 18, in the readable muted grey like the card's
   author rather than Figma's light one. */
.book-detail__overview .manufacturers {
  color: var(--color-muted);
  font-size: var(--font-size-md);
}

.book-detail__overview .manufacturers a {
  color: inherit;
  text-decoration: none;
}

.book-detail__overview .short-description {
  font-size: var(--font-size-md);
  line-height: var(--line-height-snug);
}

/* ---- Price and add to cart share one row ---- */

.book-detail__purchase {
  display: flex;
  align-items: center;
  gap: var(--space-2xl);
  flex-wrap: wrap;
}

.book-detail__price {
  display: inline-flex;
  align-items: center;
}

.book-detail__price .prices {
  margin: 0;
}

/* The approximate price's note opens as a bubble under its amount instead of
   in the flow, so opening it moves neither the price nor add to cart. */
.book-detail__price .price-approx--note {
  position: relative;
}

.book-detail__price .price-approx__note {
  position: absolute;
  z-index: var(--toast-z);
  top: 100%;
  left: 0;
  width: max-content;
  max-inline-size: min(var(--info-note-max-width), calc(100vw - var(--gutter) - var(--gutter)));
}

.book-detail__add-to-cart {
  display: inline-flex;
  align-items: center;
  gap: var(--space-md);
}

/* Figma has no quantity control on this page; the form still posts qty 1. */
.book-detail__add-to-cart .qty-label,
.book-detail__add-to-cart .qty-input,
.book-detail__add-to-cart .qty-dropdown {
  display: none;
}

.book-detail__add-to-cart .add-to-cart-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  min-width: 10.25rem; /* 164 */
  height: var(--action-height);
  padding-inline: var(--space-lg);
  border: 0;
  border-radius: var(--radius-pill);
  background-color: var(--color-action);
  color: var(--color-ink);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  cursor: pointer;
  transition: filter var(--motion-card) var(--ease-in);
}

/* The native details button renders without an icon, while the card action has
   one. Same action, so same appearance: the icon is added here as a mask rather
   than by overriding nopCommerce's _AddToCart partial, and `currentColor` keeps
   it in step with the label, hover included. See docs/style-guide.md, "The same
   element looks the same everywhere". */
.book-detail__add-to-cart .add-to-cart-button::before {
  content: "";
  flex-shrink: 0;
  width: 1.125rem;
  height: 1.125rem;
  background-color: currentColor;
  -webkit-mask: url("../../../images/figma/icon-cart-small.svg") no-repeat center / contain;
  mask: url("../../../images/figma/icon-cart-small.svg") no-repeat center / contain;
}

/* The price row and the action sit side by side, as one line in the design. */
.book-detail__overview .book-detail__price,
.book-detail__overview .book-detail__add-to-cart {
  vertical-align: middle;
}



/* ---- Full description ----
   Rendered inside the overview column so a few lines land above the fold, with
   the rest one click away. -webkit-line-clamp is the only cross-browser way to
   clamp by line count; it is well supported and degrades to full text. */

.book-detail__full-description {
  font-size: var(--font-size-md);
  line-height: var(--line-height-snug);
}

.book-detail__full-description h2 {
  margin: 0 0 var(--space-2xs);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
}

.book-detail__full-description p {
  margin: 0 0 var(--space-xs);
}

.book-detail__full-description--collapsed .book-detail__full-description-body {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---- Specifications ----
   Not in the Figma frame, but real catalogue data worth keeping; styled to the
   same type scale so it reads as part of the page. On desktop it spans the full
   container below the cover and overview. */

.book-detail__specs {
  grid-area: specs;
}

.product-specs-box .title {
  margin: 0 0 var(--space-md);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
}

/* `separate` with no spacing, not `collapse`: collapsed cells ignore
   border-radius, and the striped rows need rounded ends. */
.product-specs-box table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--font-size-md);
}

/* "Attribute name / Attribute value" adds nothing to a labelled two-column list. */
.product-specs-box thead {
  display: none;
}

.product-specs-box td {
  padding: var(--space-sm) var(--space-md);
  vertical-align: top;
}

/* Alternate rows take the cover panel's tint, so the stripes read as part of
   the same page. The theme's _ProductSpecifications restarts its odd/even
   classes under each group heading, so every labelled group starts on a
   tinted row; :nth-child would count the heading rows too. */
.product-specs-box tr.odd td {
  background-color: var(--color-surface);
}

.product-specs-box td:first-child {
  border-start-start-radius: var(--radius-md);
  border-end-start-radius: var(--radius-md);
}

.product-specs-box td:last-child {
  border-start-end-radius: var(--radius-md);
  border-end-end-radius: var(--radius-md);
}

/* The name cell is as wide as the cover column plus the gutter, and the value
   cell drops its leading padding, so the values start on the same line as the
   title and description above. */
.product-specs-box td.spec-name {
  width: calc(var(--book-detail-cover-width) + var(--book-detail-column-gap));
  color: var(--color-muted);
}

.product-specs-box td.spec-value {
  padding-inline-start: 0;
  font-weight: var(--font-weight-medium);
}

.product-specs-box td.spec-group-name {
  padding-top: var(--space-lg);
  font-weight: var(--font-weight-bold);
}

/* ---- Responsive ---- */

@media (max-width: 61.9375rem) {
  .book-detail__essential {
    grid-template-columns: 1fr;
    grid-template-areas:
      "gallery"
      "overview"
      "specs";
    gap: var(--space-lg);
  }

  .product-specs-box td.spec-name {
    width: 40%;
  }

  /* No overview column to align with in one column; the cells need their
     own gap. */
  .product-specs-box td.spec-value {
    padding-inline-start: var(--space-xs);
  }

  .book-detail__overview {
    max-width: none;
  }
}

@media (max-width: 36.25rem) {
  .book-detail__overview .product-name h1 {
    font-size: var(--font-size-xl);
  }

  /* Price and action stay on one row, pushed to opposite edges, so the
     action sits under the thumb instead of spanning the column. */
  .book-detail__purchase {
    justify-content: space-between;
    gap: var(--space-md);
  }

  /* The pill's desktop width left no room for a four-digit price (most
     discounted books) beside it and the heart on an iPhone, so the row wrapped
     and the action dropped under the price. Here it is as wide as its label. */
  .book-detail__add-to-cart .add-to-cart-button {
    min-width: 0;
  }

  /* On a phone the buy row is the first thing to reach, so it moves up to
     directly under the title and author, ahead of the short description and
     anything else the overview holds; that copy follows it in source order.
     Desktop keeps the Figma order, where the description sits beside the
     cover and the buy row is already in view. */
  .book-detail__overview > .discontinued-product,
  .book-detail__overview > .product-name,
  .book-detail__overview > .book-detail__authors {
    order: -2;
  }

  .book-detail__overview > .book-detail__purchase {
    order: -1;
  }

  /* The phone cover is capped on the image itself and the panel sizes to it
     plus its padding, so the tint always frames the cover instead of the
     cover filling the panel edge to edge. */
  .book-detail__gallery {
    --gallery-padding: var(--space-lg);
  }

  .book-detail__gallery .picture img {
    max-height: var(--gallery-cover-height-compact);
  }

  .product-specs-box table {
    font-size: var(--font-size-xs);
  }

  /* A phone row has no room to spare: tighter row ends, the gap between name
     and value from the value cell alone, and columns sized by their content
     rather than a fixed split, so a typical label and value each keep to one
     line. */
  .product-specs-box td {
    padding: var(--space-xs) var(--space-2xs);
  }

  .product-specs-box td.spec-name {
    width: auto;
    padding-inline-end: 0;
  }
}
